From 4faabe0d9c3f19bedccd33d529efabc29835ef15 Mon Sep 17 00:00:00 2001 From: afonya2 Date: Tue, 3 Jun 2025 19:39:17 +0200 Subject: [PATCH] added tables to the execution part --- src/compiler.rs | 16 +++- src/parser.rs | 9 +++ src/virtualmachine.rs | 166 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 182 insertions(+), 9 deletions(-) diff --git a/src/compiler.rs b/src/compiler.rs index 228de4c..a5456c4 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -177,7 +177,7 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec, va if reg.unbind_before { ops.push(Operation { opcode: 8, arg1: Some(reg.register), arg2: None, arg3: None }); } - ops.push(Operation { opcode: 6, arg1: Some(reg.register), arg2: None, arg3: None }); + ops.push(Operation { opcode: 6, arg1: Some(reg.register), arg2: Some(0), arg3: None }); set_register(registers, RegisterState { id: reg.register, used: true, variable: 0, last_used: *op_count }); return reg.register; }, @@ -516,6 +516,20 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec, va set_register(registers, RegisterState { id: reg, used: true, variable: get_variable_by_name(variables, &asign.variable, ops.len()).expect("Variable should exist").id, last_used: *op_count }); garbage_collect_registers(registers); }, + ASTPart::Table(tbl) => { + let reg = allocate_register(registers); + if reg.unbind_before { + ops.push(Operation { opcode: 8, arg1: Some(reg.register), arg2: None, arg3: None }); + } + ops.push(Operation { opcode: 6, arg1: Some(reg.register), arg2: Some(1), arg3: None }); + set_register(registers, RegisterState { id: reg.register, used: true, variable: 0, last_used: *op_count }); + for val in tbl.values { + let key_reg = do_ast_op(val.key, op_count, ops, variables, next_var_id, strings, next_string_id, functions, next_function_id, registers); + let value_reg = do_ast_op(val.value, op_count, ops, variables, next_var_id, strings, next_string_id, functions, next_function_id, registers); + ops.push(Operation { opcode: 31, arg1: Some(reg.register), arg2: Some(key_reg as i64), arg3: Some(value_reg) }); + } + return reg.register; + }, _ => {} } return 0; diff --git a/src/parser.rs b/src/parser.rs index 1bd4bc6..9cd9974 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -341,6 +341,15 @@ fn read_table(input: &Vec, pos: &mut usize) -> ASTPart { if input[*pos].typ == TokenType::SEPARATOR && input[*pos].value == "[" { *pos += 1; let keyy = read_exp(pos, input, &key_ends, &key_ends); + match keyy { + ASTPart::Table(_) => { + panic!("Table keys cannot be tables at {}", input[*pos].pos); + }, + ASTPart::Function(_) => { + panic!("Table keys cannot be functions at {}", input[*pos].pos); + }, + _ => {} + } if input[*pos].typ != TokenType::SEPARATOR || input[*pos].value != "]" { panic!("Unexpected end of key at {}", input[*pos].pos); } diff --git a/src/virtualmachine.rs b/src/virtualmachine.rs index d67d070..eac5ac7 100644 --- a/src/virtualmachine.rs +++ b/src/virtualmachine.rs @@ -9,6 +9,7 @@ pub enum VMMemory { Boolean(VMMemoryBoolean), Function(VMMemoryFunction), Null(VMMemoryNull), + Table(VMMemoryTable), } #[derive(Debug, Clone)] @@ -35,6 +36,17 @@ pub struct VMMemoryFunction { pub struct VMMemoryNull { pub variable_id: u32, } +#[derive(Debug, Clone)] +pub struct VMMemoryTable { + pub values: Vec, + pub variable_id: u32, +} +#[derive(Debug, Clone)] +pub struct TableValue { + pub key: VMMemory, + pub value: VMMemory, + pub pos: usize +} #[derive(Debug, Clone)] struct DecompiledFunction { @@ -161,12 +173,50 @@ fn get_mem_pos_by_var_id(memory: &Vec, var_id: u32) -> Option { VMMemory::Boolean(bool) if bool.variable_id == var_id => return Some(i), VMMemory::Null(null) if null.variable_id == var_id => return Some(i), VMMemory::Function(func) if func.variable_id == var_id => return Some(i), + VMMemory::Table(tbl) if tbl.variable_id == var_id => return Some(i), _ => continue } } None } +fn set_mem_tbl_val(tbl: &mut VMMemoryTable, key: VMMemory, value: VMMemory) { + for i in 0..tbl.values.len() { + let found = match (&tbl.values[i].key, &key) { + (VMMemory::Number(num1), VMMemory::Number(num2)) => num1.value == num2.value, + (VMMemory::String(str1), VMMemory::String(str2)) => str1.value == str2.value, + (VMMemory::Boolean(bool1), VMMemory::Boolean(bool2)) => bool1.value == bool2.value, + (VMMemory::Null(_), VMMemory::Null(_)) => true, + (VMMemory::Function(_), VMMemory::Function(_)) => false, + (VMMemory::Table(_), VMMemory::Table(_)) => false, + _ => false, + }; + if found { + tbl.values[i].value = value; + return; + } + } + tbl.values.push(TableValue { key, value, pos: tbl.values.len() }); +} + +fn get_mem_tbl_val(tbl: &VMMemoryTable, key: VMMemory) -> Option<&VMMemory> { + for i in 0..tbl.values.len() { + let found = match (&tbl.values[i].key, &key) { + (VMMemory::Number(num1), VMMemory::Number(num2)) => num1.value == num2.value, + (VMMemory::String(str1), VMMemory::String(str2)) => str1.value == str2.value, + (VMMemory::Boolean(bool1), VMMemory::Boolean(bool2)) => bool1.value == bool2.value, + (VMMemory::Null(_), VMMemory::Null(_)) => true, + (VMMemory::Function(_), VMMemory::Function(_)) => false, + (VMMemory::Table(_), VMMemory::Table(_)) => false, + _ => false, + }; + if found { + return Some(&tbl.values[i].value); + } + } + None +} + fn do_operation_operation(registers: &mut Vec, memory: &mut Vec, operation: &DecompiledOperation) { let reg_clone = registers.clone(); let reg1 = get_register_by_id(®_clone, operation.arg1); @@ -292,6 +342,7 @@ fn do_operation_operation(registers: &mut Vec, memory: &mut Vec bool.variable_id, VMMemory::Null(null) => null.variable_id, VMMemory::Function(func) => func.variable_id, + VMMemory::Table(tbl) => tbl.variable_id, }; match &mut result { VMMemory::String(str) => { @@ -309,6 +360,9 @@ fn do_operation_operation(registers: &mut Vec, memory: &mut Vec { func.variable_id = var_id; }, + VMMemory::Table(tbl) => { + tbl.variable_id = var_id; + }, } memory[reg3_pointer] = result; } @@ -482,8 +536,13 @@ impl Machine { }, 6 => { //LDN - self.memory.push(VMMemory::Null(VMMemoryNull { variable_id: 0 })); - set_register(&mut self.registers, Register { id: operation.arg1, pointer: self.memory.len() - 1 }); + if operation.arg2 > 0 { + self.memory.push(VMMemory::Table(VMMemoryTable { values: vec![], variable_id: 0 })); + set_register(&mut self.registers, Register { id: operation.arg1, pointer: self.memory.len() - 1 }); + } else { + self.memory.push(VMMemory::Null(VMMemoryNull { variable_id: 0 })); + set_register(&mut self.registers, Register { id: operation.arg1, pointer: self.memory.len() - 1 }); + } }, 7 => { //ASS @@ -513,6 +572,9 @@ impl Machine { VMMemory::Function(func) => { func.variable_id = 0; }, + VMMemory::Table(tbl) => { + tbl.variable_id = 0; + }, } } match &mut self.memory[reg.pointer] { @@ -531,6 +593,9 @@ impl Machine { VMMemory::Function(func) => { func.variable_id = operation.arg2 as u32; }, + VMMemory::Table(tbl) => { + tbl.variable_id = operation.arg2 as u32; + }, } }, 8 => { @@ -583,6 +648,7 @@ impl Machine { VMMemory::Boolean(bool) => bool.variable_id, VMMemory::Null(null) => null.variable_id, VMMemory::Function(func) => func.variable_id, + VMMemory::Table(tbl) => tbl.variable_id, }; match &mut result { VMMemory::String(str) => { @@ -600,6 +666,9 @@ impl Machine { VMMemory::Function(func) => { func.variable_id = var_id; }, + VMMemory::Table(tbl) => { + tbl.variable_id = var_id; + }, } self.memory[reg2.unwrap().pointer] = result; }, @@ -691,15 +760,96 @@ impl Machine { executed_stack = &mut self.call_stack[last_stack]; }, 30 => { - //not implemented yet + //GET + let reg_clone = self.registers.clone(); + let reg = 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 reg.is_none() || reg2.is_none() || reg3.is_none() { + panic!("One or more registers not found for SET operation"); + } + let mem1 = self.memory.get(reg.unwrap().pointer); + let mem2 = self.memory.get(reg2.unwrap().pointer); + if mem1.is_none() || mem2.is_none() { + panic!("Memory location not found for one or more registers"); + } + let mem1 = mem1.unwrap().clone(); + let mem2 = mem2.unwrap().clone(); + let mut value: VMMemory; + match mem1 { + VMMemory::Table(tbl) => { + let tvalue = get_mem_tbl_val(&tbl, mem2); + if tvalue.is_none() { + value = VMMemory::Null(VMMemoryNull { variable_id: 0 }); + } else { + value = tvalue.unwrap().clone(); + } + }, + _ => { + panic!("Invalid memory type for SET operation"); + } + } + let mut reg3_pointer = reg3.unwrap().pointer; + if reg3_pointer >= self.memory.len() || reg3_pointer < 1 { + reg3_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: reg3_pointer }); + } + let var_id = match &self.memory[reg3.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, + VMMemory::Table(tbl) => tbl.variable_id, + }; + match &mut value { + 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; + }, + VMMemory::Table(tbl) => { + tbl.variable_id = var_id; + }, + } + self.memory[reg3.unwrap().pointer] = value; }, 31 => { - //GET - //not implemented yet - }, - 32 => { //SET - //not implemented yet + let reg = get_register_by_id(&self.registers, operation.arg1); + let reg2 = get_register_by_id(&self.registers, operation.arg2 as u8); + let reg3 = get_register_by_id(&self.registers, operation.arg3); + if reg.is_none() || reg2.is_none() || reg3.is_none() { + panic!("One or more registers not found for SET operation"); + } + let mem1 = self.memory.get(reg.unwrap().pointer); + let mem2 = self.memory.get(reg2.unwrap().pointer); + let mem3 = self.memory.get(reg3.unwrap().pointer); + if mem1.is_none() || mem2.is_none() || mem3.is_none() { + panic!("Memory location not found for one or more registers"); + } + let mem2 = mem2.unwrap().clone(); + let mem3 = mem3.unwrap().clone(); + let mem1 = self.memory.get_mut(reg.unwrap().pointer).expect("Memory location should exist"); + match mem1 { + VMMemory::Table(tbl) => { + set_mem_tbl_val(tbl, mem2, mem3); + }, + _ => { + panic!("Invalid memory type for SET operation"); + } + } }, _ => { panic!("Unknown operation code: {}", operation.opcode);