From eaf5e9a30a7f32972756d611fe4ada7b1caeec45 Mon Sep 17 00:00:00 2001 From: Sofia Date: Mon, 16 Mar 2026 15:36:29 +0200 Subject: [PATCH] Add if-statements, fix some bugs --- src/compile.rs | 83 ++++++++++++++++++++++++++++---------------------- src/vm.rs | 5 +-- 2 files changed, 49 insertions(+), 39 deletions(-) diff --git a/src/compile.rs b/src/compile.rs index 743cfeb..8fdb19a 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -112,10 +112,20 @@ impl Statement { match self { Statement::Assignment(access_modifier, names, expr_list) => { - instructions.push(Instruction::LoadNil( - scope.register_counter.0 + 1, - scope.register_counter.0 + names.len() as u16, - )); + let new_registers = if *access_modifier == Some(AccessModifier::Local) { + let min_reg = scope.register_counter.0 + 1; + let max_reg = scope.register_counter.0 + names.len() as u16; + instructions.push(Instruction::LoadNil(min_reg, max_reg)); + scope.register_counter.0 += names.len() as u16; + + let mut new_registers = Vec::new(); + for i in min_reg..=max_reg { + new_registers.push(i); + } + new_registers + } else { + Vec::new() + }; let mut expr_regs = Vec::new(); for expr in &expr_list.0 { @@ -131,57 +141,45 @@ impl Statement { instructions.extend(instr); expr_regs.extend(regs); } + match access_modifier { Some(AccessModifier::Local) => { for (i, name) in names.iter().enumerate() { - scope.locals.insert( - name.kind.clone(), - expr_regs - .get(i) - .cloned() - .unwrap_or(scope.register_counter.0 + i as u16), - ); + instructions.push(Instruction::Move( + *new_registers.get(i).unwrap(), + expr_regs.get(i).cloned().unwrap(), + )); + scope + .locals + .insert(name.kind.clone(), *new_registers.get(i).unwrap()); } - dbg!(&scope.locals); } Some(AccessModifier::Global) => { for (i, name) in names.iter().enumerate() { let global = state.get_constant(&Constant::String(name.kind.clone())); instructions.push(Instruction::SetGlobal( - expr_regs - .get(i) - .cloned() - .unwrap_or(scope.register_counter.0 + i as u16), + expr_regs.get(i).cloned().unwrap(), global, )); } } None => { for (i, name) in names.iter().enumerate() { - if scope.locals.contains_key(&name.kind) { - scope.locals.insert( - name.kind.clone(), - expr_regs - .get(i) - .cloned() - .unwrap_or(scope.register_counter.0 + i as u16), - ); + if let Some(reg) = scope.locals.get(&name.kind) { + instructions.push(Instruction::Move( + *reg, + expr_regs.get(i).cloned().unwrap(), + )); } else if let Some(upval_reg) = scope.upvalues.get(&name.kind) { instructions.push(Instruction::SetUpVal( *upval_reg, - expr_regs - .get(i) - .cloned() - .unwrap_or(scope.register_counter.0 + i as u16), + expr_regs.get(i).cloned().unwrap(), )); } else { let global = state.get_constant(&Constant::String(name.kind.clone())); instructions.push(Instruction::SetGlobal( - expr_regs - .get(i) - .cloned() - .unwrap_or(scope.register_counter.0 + i as u16), + expr_regs.get(i).cloned().unwrap(), global, )); } @@ -218,13 +216,22 @@ impl Statement { *ret_register = new_reg; } - dbg!(&ret_registers); instructions.push(Instruction::Return( *ret_registers.first().unwrap_or(&scope.register_counter.0), *ret_registers.last().unwrap_or(&0), )); } - Statement::If(node, block) => todo!(), + Statement::If(expr, block) => { + let (instr, regs) = expr.kind.compile(state, scope, Some(1)); + instructions.extend(instr); + + let local = scope.register_counter.next(); + instructions.push(Instruction::Test(local, *regs.first().unwrap(), 0)); + + let block_instructions = block.compile(state, scope); + instructions.push(Instruction::Jmp(block_instructions.len() as i32)); + instructions.extend(block_instructions); + } Statement::Expression(expr) => { let (instr, _) = expr.kind.compile(state, scope, None); instructions.extend(instr); @@ -333,15 +340,17 @@ impl Expression { .insert(param.kind.clone(), inner_scope.register_counter.next()); } - inner_scope.highest_upvalue = - scope.highest_upvalue + inner_scope.register_counter.0; + inner_scope.highest_upvalue = scope.highest_upvalue + scope.register_counter.0; inner_scope.upvalues = scope.upvalues.clone(); for (name, reg) in &scope.locals { - let new_reg = *reg + inner_scope.highest_upvalue + 1; + let new_reg = *reg + inner_scope.highest_upvalue; inner_scope.upvalues.insert(name.clone(), new_reg); } + dbg!(&inner_scope.highest_upvalue); + dbg!(&inner_scope.upvalues); + let instructions = block.compile(state, &mut inner_scope); state.prototypes.push(instructions); diff --git a/src/vm.rs b/src/vm.rs index f135b18..edb2b3c 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -274,7 +274,7 @@ impl ClosureRunner { } Instruction::Test(a, b, c) => { let is_true = match self.stack.get(b).unwrap_or(&Value::Nil) { - Value::Number(val) => (*val as u16) == *c, + Value::Number(val) => (LuaNumber::from_bits(*val) as u16) == *c, _ => false, }; if is_true { @@ -355,6 +355,7 @@ impl ClosureRunner { .max() .unwrap_or(0); + dbg!(&self.stack); let mut upvalues = self.closure.upvalues.clone(); for (reg, value) in &self.stack { upvalues.insert( @@ -363,6 +364,7 @@ impl ClosureRunner { ); } + dbg!(&upvalues); self.stack.insert( *reg, Value::Function(Closure { @@ -388,7 +390,6 @@ impl ClosureRunner { for i in reg_start..=reg_end { ret_values.push(self.stack.get(&i).cloned().unwrap_or(Value::Nil)); } - // dbg!(&self.closure.upvalues); return Some(ret_values); } Instruction::Add(res, lhs, rhs) => {