From 44a455f5427d6ed648e9b5694d66ff18cbb145c0 Mon Sep 17 00:00:00 2001 From: afonya2 Date: Sun, 1 Jun 2025 13:39:57 +0200 Subject: [PATCH] added for loops and return to the compiler --- src/compiler.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/src/compiler.rs b/src/compiler.rs index f60c267..1822b4f 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -334,7 +334,7 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec, va } } } - ops.push(Operation { opcode: 25, arg1: Some(condition_reg), arg2: Some(start as i64), arg3: None }); + ops.push(Operation { opcode: 25, arg1: None, arg2: Some(start as i64), arg3: None }); ops[op_placeholder] = Operation { opcode: 26, arg1: Some(condition_reg), @@ -364,6 +364,62 @@ fn do_ast_op(ast_op: ASTPart, op_count: &mut usize, ops: &mut Vec, va ASTPart::Continue(_) => { panic!("Unexpected continue outside of loop at {}", op_count); }, + ASTPart::For(for_part) => { + do_ast_op(*for_part.init, op_count, ops, var_ids, next_var_id, strings, next_string_id, functions, next_function_id, registers); + let start = ops.len(); + let condition_reg = do_ast_op(*for_part.condition, op_count, ops, var_ids, next_var_id, strings, next_string_id, functions, next_function_id, registers); + ops.push(Operation { opcode: 30, arg1: Some(condition_reg), arg2: Some(2), arg3: None }); + ops.push(Operation { opcode: 24, arg1: Some(condition_reg), arg2: Some(condition_reg as i64), arg3: None }); + + let op_placeholder = ops.len(); + let mut breaks: Vec = vec![]; + let mut continues: Vec = vec![]; + ops.push(Operation { opcode: 0, arg1: None, arg2: None, arg3: None }); + for for_op in for_part.body { + match for_op { + ASTPart::Break(_) => { + breaks.push(ops.len()); + ops.push(Operation { opcode: 0, arg1: None, arg2: None, arg3: None }); + }, + ASTPart::Continue(_) => { + continues.push(ops.len()); + ops.push(Operation { opcode: 0, arg1: None, arg2: None, arg3: None }); + }, + _ => { + do_ast_op(for_op, op_count, ops, var_ids, next_var_id, strings, next_string_id, functions, next_function_id, registers); + } + } + } + do_ast_op(*for_part.update, op_count, ops, var_ids, next_var_id, strings, next_string_id, functions, next_function_id, registers); + + ops.push(Operation { opcode: 25, arg1: None, arg2: Some(start as i64), arg3: None }); + ops[op_placeholder] = Operation { + opcode: 26, + arg1: Some(condition_reg), + arg2: Some(ops.len() as i64), + arg3: None, + }; + for brk in breaks { + ops[brk] = Operation { + opcode: 25, + arg1: None, + arg2: Some(ops.len() as i64), + arg3: None, + }; + } + for cont in continues { + ops[cont] = Operation { + opcode: 25, + arg1: None, + arg2: Some(start as i64), + arg3: None, + }; + } + }, + ASTPart::Return(ret) => { + let ret_reg = do_ast_op(*ret.value, op_count, ops, var_ids, next_var_id, strings, next_string_id, functions, next_function_id, registers); + ops.push(Operation { opcode: 29, arg1: Some(ret_reg), arg2: None, arg3: None }); + }, ASTPart::Operation(op) => { let left_reg = do_ast_op(*op.left, op_count, ops, var_ids, next_var_id, strings, next_string_id, functions, next_function_id, registers); let right_reg = do_ast_op(*op.right, op_count, ops, var_ids, next_var_id, strings, next_string_id, functions, next_function_id, registers);