From b3ba7162b71dc68b13424c1fffeceb86c6ca2c02 Mon Sep 17 00:00:00 2001 From: afonya2 Date: Thu, 29 May 2025 21:36:51 +0200 Subject: [PATCH] added more operations to compiler --- src/compiler.rs | 49 ++++++++++++++++++++++++++++++++++++++++++++----- test.as | 2 +- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/compiler.rs b/src/compiler.rs index 86015f3..6920de4 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -78,16 +78,54 @@ fn allocate_register(registers: &Vec) -> AllocateResult { }; } +fn garbage_collect_registers(registers: &mut Vec) { + for register in registers { + if register.used && register.variable == 0 { + register.used = false; + register.last_used = 0; + } + } +} + fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec, var_ids: &mut HashMap, next_var_id: &mut u32, registers: &mut Vec) -> u8 { *op_count += 1; match ast_op { ASTPart::Number(num) => { let reg = allocate_register(registers); if reg.unbind_before { - ops.push(Opeartion { opcode: 0x08, arg1: Some(reg.register), arg2: None, arg3: None }); + ops.push(Opeartion { opcode: 8, arg1: Some(reg.register), arg2: None, arg3: None }); + } + ops.push(Opeartion { opcode: 3, arg1: Some(reg.register), arg2: Some(num.value as u32), arg3: None }); + set_register(registers, RegisterState { id: reg.register, used: true, variable: 0, last_used: *op_count }); + return reg.register; + }, + ASTPart::Operation(op) => { + let left_reg = do_ast_op(*op.left, op_count, ops, var_ids, next_var_id, registers); + let right_reg = do_ast_op(*op.right, op_count, ops, var_ids, next_var_id, registers); + let reg = allocate_register(registers); + if reg.unbind_before { + ops.push(Opeartion { opcode: 8, arg1: Some(reg.register), arg2: None, arg3: None }); set_register(registers, RegisterState { id: reg.register, used: true, variable: 0, last_used: *op_count }); } - ops.push(Opeartion { opcode: 0x03, arg1: Some(reg.register), arg2: Some(num.value as u32), arg3: None }); + let opcode = match op.operator.as_str() { + "+" => 10, + "-" => 11, + "*" => 12, + "/" => 13, + "^" => 14, + "%" => 15, + "&" => 16, + "|" => 17, + "==" => 18, + "!=" => 19, + ">" => 20, + ">=" => 21, + "<" => 22, + "<=" => 23, + _ => panic!("Unknown operator {}", op.operator), + }; + ops.push(Opeartion { opcode, arg1: Some(left_reg), arg2: Some(right_reg as u32), arg3: Some(reg.register) }); + set_register(registers, RegisterState { id: reg.register, used: true, variable: 0, last_used: *op_count }); return reg.register; }, ASTPart::Assigment(asign) => { @@ -97,8 +135,9 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec, va var_ids.insert(asign.variable.clone(), *next_var_id); *next_var_id += 1; let reg = do_ast_op(*asign.value, op_count, ops, var_ids, next_var_id, registers); - ops.push(Opeartion { opcode: 0x07, arg1: Some(reg), arg2: Some(var_ids[&asign.variable.clone()]), arg3: None }); + ops.push(Opeartion { opcode: 7, arg1: Some(reg), arg2: Some(var_ids[&asign.variable.clone()]), arg3: None }); set_register(registers, RegisterState { id: reg, used: true, variable: var_ids[&asign.variable.clone()], last_used: *op_count }); + garbage_collect_registers(registers); }, _ => {} } @@ -123,8 +162,8 @@ pub fn compile(ast: Vec) -> Vec { let mut op_count = 0; for ast_op in ast { do_ast_op(ast_op, &mut op_count, &mut ops, &mut var_ids, &mut next_var_id, &mut registers); - println!("Operations: {:?}", ops); - println!("Registers: {:?}", registers); + println!("Operations: {:?}\n", ops); + println!("Registers: {:?}\n", registers); println!("Variable IDs: {:?}", var_ids); println!("=========================="); } diff --git a/test.as b/test.as index fcae62f..a5739f3 100644 --- a/test.as +++ b/test.as @@ -1 +1 @@ -gethelj a = 69 \ No newline at end of file +gethelj a = 1 + 1 - 1 \ No newline at end of file