fix: operations and assignment
This commit is contained in:
parent
6f99f9ef62
commit
431b04cf2a
2 changed files with 169 additions and 117 deletions
|
@ -178,152 +178,152 @@ fn get_mem_pos_by_var_id(memory: &Vec<VMMemory>, var_id: u32) -> Option<usize> {
|
|||
}
|
||||
|
||||
fn do_operation_operation(registers: &mut Vec<Register>, memory: &mut Vec<VMMemory>, operation: &DecompiledOperation) {
|
||||
let reg1 = get_register_by_id(registers, operation.arg1);
|
||||
let reg2 = get_register_by_id(registers, operation.arg2 as u8);
|
||||
let reg3 = get_register_by_id(registers, operation.arg3);
|
||||
let reg_clone = registers.clone();
|
||||
let reg1 = get_register_by_id(®_clone, operation.arg1);
|
||||
let reg2 = get_register_by_id(®_clone, operation.arg2 as u8);
|
||||
let reg3 = get_register_by_id(®_clone, operation.arg3);
|
||||
if reg1.is_none() || reg2.is_none() || reg3.is_none() {
|
||||
panic!("One or more registers not found for operation");
|
||||
}
|
||||
let mem1 = reg1.unwrap().pointer;
|
||||
let mem2 = reg2.unwrap().pointer;
|
||||
let mut mem3 = reg3.unwrap().pointer;
|
||||
if memory.get(mem1).is_none() || memory.get(mem2).is_none() {
|
||||
panic!("Memory location not found for registers");
|
||||
if mem1 >= memory.len() || mem2 >= memory.len() || mem1 < 1 || mem2 < 1 {
|
||||
panic!("Memory location out of bounds for registers {} and {}", operation.arg1, operation.arg2);
|
||||
}
|
||||
//TODO: use set memory or something instead of this
|
||||
let change_mem_type = reg3.unwrap().pointer == 0 || match operation.opcode {
|
||||
10 => true,
|
||||
11 | 12 | 13 | 14 | 15 => {
|
||||
match memory.get(mem3).unwrap() {
|
||||
VMMemory::Number(_) => false,
|
||||
_ => true,
|
||||
}
|
||||
},
|
||||
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 => {
|
||||
match memory.get(mem3).unwrap() {
|
||||
VMMemory::Boolean(_) => false,
|
||||
_ => true,
|
||||
}
|
||||
},
|
||||
_ => false
|
||||
};
|
||||
if change_mem_type {
|
||||
match operation.opcode {
|
||||
10 => {
|
||||
match memory.get(mem1).unwrap() {
|
||||
VMMemory::String(_) => {
|
||||
memory.push(VMMemory::String(VMMemoryString { value: String::new(), variable_id: 0 }));
|
||||
set_register(registers, Register { id: operation.arg3, pointer: memory.len() - 1 });
|
||||
mem3 = memory.len() - 1;
|
||||
}
|
||||
VMMemory::Number(_) => {
|
||||
memory.push(VMMemory::Number(VMMemoryNumber { value: 0, variable_id: 0 }));
|
||||
set_register(registers, Register { id: operation.arg3, pointer: memory.len() - 1 });
|
||||
mem3 = memory.len() - 1;
|
||||
}
|
||||
_ => {
|
||||
panic!("Invalid memory type for operation");
|
||||
}
|
||||
}
|
||||
},
|
||||
11 | 12 | 13 | 14 | 15 => {
|
||||
memory.push(VMMemory::Number(VMMemoryNumber { value: 0, variable_id: 0 }));
|
||||
set_register(registers, Register { id: operation.arg3, pointer: memory.len() - 1 });
|
||||
mem3 = memory.len() - 1;
|
||||
},
|
||||
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 => {
|
||||
memory.push(VMMemory::Boolean(VMMemoryBoolean { value: false, variable_id: 0 }));
|
||||
set_register(registers, Register { id: operation.arg3, pointer: memory.len() - 1 });
|
||||
mem3 = memory.len() - 1;
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
let temp_mem = memory.clone();
|
||||
match (&temp_mem[mem1], &temp_mem[mem2], &mut memory[mem3]) {
|
||||
(VMMemory::Number(num1), VMMemory::Number(num2), VMMemory::Number(num3)) => {
|
||||
let mut result: VMMemory;
|
||||
match (&memory[mem1], &memory[mem2]) {
|
||||
(VMMemory::Number(num1), VMMemory::Number(num2)) => {
|
||||
match operation.opcode {
|
||||
10 => {
|
||||
num3.value = num1.value + num2.value;
|
||||
result = VMMemory::Number(VMMemoryNumber { value: num1.value + num2.value, variable_id: 0 });
|
||||
},
|
||||
11 => {
|
||||
num3.value = num1.value - num2.value;
|
||||
result = VMMemory::Number(VMMemoryNumber { value: num1.value - num2.value, variable_id: 0 });
|
||||
},
|
||||
12 => {
|
||||
num3.value = num1.value * num2.value;
|
||||
result = VMMemory::Number(VMMemoryNumber { value: num1.value * num2.value, variable_id: 0 });
|
||||
},
|
||||
13 => {
|
||||
if num2.value == 0 {
|
||||
panic!("Division by zero");
|
||||
}
|
||||
num3.value = num1.value / num2.value;
|
||||
result = VMMemory::Number(VMMemoryNumber { value: num1.value / num2.value, variable_id: 0 });
|
||||
},
|
||||
14 => {
|
||||
num3.value = num1.value.pow(num2.value as u32);
|
||||
result = VMMemory::Number(VMMemoryNumber { value: num1.value.pow(num2.value as u32), variable_id: 0 });
|
||||
},
|
||||
15 => {
|
||||
num3.value = num1.value % num2.value;
|
||||
result = VMMemory::Number(VMMemoryNumber { value: num1.value % num2.value, variable_id: 0 });
|
||||
},
|
||||
_ => {
|
||||
panic!("Invalid operation for number operation")
|
||||
}
|
||||
}
|
||||
},
|
||||
(VMMemory::Number(num1), VMMemory::Number(num2), VMMemory::Boolean(bool3)) => {
|
||||
match operation.opcode {
|
||||
18 => {
|
||||
bool3.value = num1.value == num2.value;
|
||||
result = VMMemory::Boolean(VMMemoryBoolean { value: num1.value == num2.value, variable_id: 0 });
|
||||
},
|
||||
19 => {
|
||||
bool3.value = num1.value != num2.value;
|
||||
result = VMMemory::Boolean(VMMemoryBoolean { value: num1.value != num2.value, variable_id: 0 });
|
||||
},
|
||||
20 => {
|
||||
bool3.value = num1.value > num2.value;
|
||||
result = VMMemory::Boolean(VMMemoryBoolean { value: num1.value > num2.value, variable_id: 0 });
|
||||
},
|
||||
21 => {
|
||||
bool3.value = num1.value >= num2.value;
|
||||
result = VMMemory::Boolean(VMMemoryBoolean { value: num1.value >= num2.value, variable_id: 0 });
|
||||
},
|
||||
22 => {
|
||||
bool3.value = num1.value < num2.value;
|
||||
result = VMMemory::Boolean(VMMemoryBoolean { value: num1.value < num2.value, variable_id: 0 });
|
||||
},
|
||||
23 => {
|
||||
bool3.value = num1.value <= num2.value;
|
||||
result = VMMemory::Boolean(VMMemoryBoolean { value: num1.value <= num2.value, variable_id: 0 });
|
||||
},
|
||||
_ => panic!("Invalid operation for boolean operation"),
|
||||
}
|
||||
_ => {
|
||||
panic!("Unknown operation code for number operation: {}", operation.opcode);
|
||||
}
|
||||
};
|
||||
},
|
||||
(VMMemory::String(str1), VMMemory::String(str2), VMMemory::Boolean(bool3)) => {
|
||||
match operation.opcode {
|
||||
18 => {
|
||||
bool3.value = str1.value == str2.value;
|
||||
},
|
||||
19 => {
|
||||
bool3.value = str1.value != str2.value;
|
||||
},
|
||||
_ => panic!("Invalid operation for string operation"),
|
||||
}
|
||||
},
|
||||
(VMMemory::String(str1), VMMemory::String(str2), VMMemory::String(str3)) => {
|
||||
(VMMemory::String(str1), VMMemory::String(str2)) => {
|
||||
match operation.opcode {
|
||||
10 => {
|
||||
str3.value = str1.value.clone() + &str2.value;
|
||||
result = VMMemory::String(VMMemoryString { value: str1.value.clone() + &str2.value, variable_id: 0 });
|
||||
},
|
||||
_ => panic!("Invalid operation for string operation"),
|
||||
}
|
||||
18 => {
|
||||
result = VMMemory::Boolean(VMMemoryBoolean { value: str1.value == str2.value, variable_id: 0 });
|
||||
},
|
||||
19 => {
|
||||
result = VMMemory::Boolean(VMMemoryBoolean { value: str1.value != str2.value, variable_id: 0 });
|
||||
},
|
||||
_ => {
|
||||
panic!("Unknown operation code for string operation: {}", operation.opcode);
|
||||
}
|
||||
};
|
||||
},
|
||||
(VMMemory::Boolean(bool1), VMMemory::Boolean(bool2), VMMemory::Boolean(bool3)) => {
|
||||
(VMMemory::Boolean(bool1), VMMemory::Boolean(bool2)) => {
|
||||
match operation.opcode {
|
||||
16 => {
|
||||
bool3.value = bool1.value && bool2.value;
|
||||
result = VMMemory::Boolean(VMMemoryBoolean { value: bool1.value && bool2.value, variable_id: 0 });
|
||||
},
|
||||
17 => {
|
||||
bool3.value = bool1.value || bool2.value;
|
||||
result = VMMemory::Boolean(VMMemoryBoolean { value: bool1.value || bool2.value, variable_id: 0 });
|
||||
},
|
||||
_ => panic!("Invalid operation for boolean operation"),
|
||||
}
|
||||
18 => {
|
||||
result = VMMemory::Boolean(VMMemoryBoolean { value: bool1.value == bool2.value, variable_id: 0 });
|
||||
},
|
||||
19 => {
|
||||
result = VMMemory::Boolean(VMMemoryBoolean { value: bool1.value != bool2.value, variable_id: 0 });
|
||||
},
|
||||
_ => {
|
||||
panic!("Unknown operation code for boolean operation: {}", operation.opcode);
|
||||
}
|
||||
};
|
||||
},
|
||||
_ => panic!("Invalid memory types for operation, OP: {:?}", operation),
|
||||
(VMMemory::Null(_), VMMemory::Null(_)) => {
|
||||
match operation.opcode {
|
||||
18 => {
|
||||
result = VMMemory::Boolean(VMMemoryBoolean { value: true, variable_id: 0 });
|
||||
},
|
||||
19 => {
|
||||
result = VMMemory::Boolean(VMMemoryBoolean { value: false, variable_id: 0 });
|
||||
},
|
||||
_ => {
|
||||
panic!("Unknown operation code for null operation: {}", operation.opcode);
|
||||
}
|
||||
};
|
||||
},
|
||||
_ => {
|
||||
panic!("Invalid memory types for operation: {} and {}", mem1, mem2);
|
||||
}
|
||||
}
|
||||
let mut reg3_pointer = reg3.unwrap().pointer;
|
||||
if reg3_pointer < 1 {
|
||||
reg3_pointer = memory.len();
|
||||
memory.push(VMMemory::Null(VMMemoryNull { variable_id: 0 }));
|
||||
set_register(registers, Register { id: operation.arg3, pointer: reg3_pointer });
|
||||
}
|
||||
if reg3_pointer >= memory.len() || reg3_pointer < 1 {
|
||||
panic!("Register {} points to an invalid memory location", reg3.unwrap().id);
|
||||
}
|
||||
let var_id = match &memory[reg3_pointer] {
|
||||
VMMemory::String(str) => str.variable_id,
|
||||
VMMemory::Number(num) => num.variable_id,
|
||||
VMMemory::Boolean(bool) => bool.variable_id,
|
||||
VMMemory::Null(null) => null.variable_id,
|
||||
VMMemory::Function(func) => func.variable_id,
|
||||
};
|
||||
match &mut result {
|
||||
VMMemory::String(str) => {
|
||||
str.variable_id = var_id;
|
||||
},
|
||||
VMMemory::Number(num) => {
|
||||
num.variable_id = var_id;
|
||||
},
|
||||
VMMemory::Boolean(bool) => {
|
||||
bool.variable_id = var_id;
|
||||
},
|
||||
VMMemory::Null(null) => {
|
||||
null.variable_id = var_id;
|
||||
},
|
||||
VMMemory::Function(func) => {
|
||||
func.variable_id = var_id;
|
||||
},
|
||||
}
|
||||
memory[reg3_pointer] = result;
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
|
@ -501,6 +501,26 @@ impl Machine {
|
|||
if reg.pointer >= self.memory.len() || reg.pointer < 1 {
|
||||
panic!("Register {} points to an invalid memory location", operation.arg1);
|
||||
}
|
||||
let used_var = get_mem_pos_by_var_id(&self.memory, operation.arg2 as u32);
|
||||
if let Some(pos) = used_var {
|
||||
match &mut self.memory[pos] {
|
||||
VMMemory::Number(num) => {
|
||||
num.variable_id = 0;
|
||||
},
|
||||
VMMemory::String(str) => {
|
||||
str.variable_id = 0;
|
||||
},
|
||||
VMMemory::Boolean(bool) => {
|
||||
bool.variable_id = 0;
|
||||
},
|
||||
VMMemory::Null(null) => {
|
||||
null.variable_id = 0;
|
||||
},
|
||||
VMMemory::Function(func) => {
|
||||
func.variable_id = 0;
|
||||
},
|
||||
}
|
||||
}
|
||||
match &mut self.memory[reg.pointer] {
|
||||
VMMemory::Number(num) => {
|
||||
num.variable_id = operation.arg2 as u32;
|
||||
|
@ -538,28 +558,59 @@ impl Machine {
|
|||
},
|
||||
24 => {
|
||||
//NOT
|
||||
let reg1 = get_register_by_id(&self.registers, operation.arg1);
|
||||
let reg2 = get_register_by_id(&self.registers, operation.arg2 as u8);
|
||||
let reg_clone = self.registers.clone();
|
||||
let reg1 = get_register_by_id(®_clone, operation.arg1);
|
||||
let reg2 = get_register_by_id(®_clone, operation.arg2 as u8);
|
||||
if reg1.is_none() || reg2.is_none() {
|
||||
panic!("One or more registers not found for NOT operation");
|
||||
panic!("One or more registers not found for operation");
|
||||
}
|
||||
let mem1 = reg1.unwrap().pointer;
|
||||
let mut mem2 = reg2.unwrap().pointer;
|
||||
if self.memory.get(mem1).is_none() {
|
||||
panic!("Memory location not found for register {}", operation.arg1);
|
||||
if mem1 >= self.memory.len() || mem1 < 1 {
|
||||
panic!("Memory location out of bounds for register {}", operation.arg1);
|
||||
}
|
||||
if reg2.unwrap().pointer == 0 {
|
||||
self.memory.push(VMMemory::Boolean(VMMemoryBoolean { value: false, variable_id: 0 }));
|
||||
set_register(&mut self.registers, Register { id: operation.arg3, pointer: self.memory.len() - 1 });
|
||||
mem2 = self.memory.len() - 1;
|
||||
}
|
||||
let temp_mem = self.memory.clone();
|
||||
match (&temp_mem[mem1], &mut self.memory[mem2]) {
|
||||
(VMMemory::Boolean(bool1), VMMemory::Boolean(bool2)) => {
|
||||
bool2.value = !bool1.value;
|
||||
let mut result: VMMemory;
|
||||
match &self.memory[mem1] {
|
||||
VMMemory::Boolean(bool) => {
|
||||
result = VMMemory::Boolean(VMMemoryBoolean { value: !bool.value, variable_id: 0 });
|
||||
},
|
||||
_ => panic!("Invalid memory types for NOT operation"),
|
||||
_ => {
|
||||
panic!("Invalid memory types for operation: {}", mem1);
|
||||
}
|
||||
}
|
||||
let mut reg2_pointer = reg2.unwrap().pointer;
|
||||
if reg2_pointer >= self.memory.len() || reg2_pointer < 1 {
|
||||
reg2_pointer = self.memory.len();
|
||||
self.memory.push(VMMemory::Null(VMMemoryNull { variable_id: 0 }));
|
||||
set_register(&mut self.registers, Register { id: operation.arg2 as u8, pointer: reg2_pointer });
|
||||
}
|
||||
if reg2_pointer >= self.memory.len() || reg2_pointer < 1 {
|
||||
panic!("Register {} points to an invalid memory location", reg2.unwrap().id);
|
||||
}
|
||||
let var_id = match &self.memory[reg2.unwrap().pointer] {
|
||||
VMMemory::String(str) => str.variable_id,
|
||||
VMMemory::Number(num) => num.variable_id,
|
||||
VMMemory::Boolean(bool) => bool.variable_id,
|
||||
VMMemory::Null(null) => null.variable_id,
|
||||
VMMemory::Function(func) => func.variable_id,
|
||||
};
|
||||
match &mut result {
|
||||
VMMemory::String(str) => {
|
||||
str.variable_id = var_id;
|
||||
},
|
||||
VMMemory::Number(num) => {
|
||||
num.variable_id = var_id;
|
||||
},
|
||||
VMMemory::Boolean(bool) => {
|
||||
bool.variable_id = var_id;
|
||||
},
|
||||
VMMemory::Null(null) => {
|
||||
null.variable_id = var_id;
|
||||
},
|
||||
VMMemory::Function(func) => {
|
||||
func.variable_id = var_id;
|
||||
},
|
||||
}
|
||||
self.memory[reg2.unwrap().pointer] = result;
|
||||
},
|
||||
25 => {
|
||||
//JMP
|
||||
|
|
3
test.as
3
test.as
|
@ -5,4 +5,5 @@ ha geny (a < b) {
|
|||
gethelj d = 69
|
||||
} ha nem geny {
|
||||
gethelj de = 420
|
||||
}
|
||||
}
|
||||
d = d + 1
|
Loading…
Add table
Add a link
Reference in a new issue