diff --git a/examples/test.lua b/examples/test.lua index 24d29b3..b343c6c 100644 --- a/examples/test.lua +++ b/examples/test.lua @@ -4,5 +4,5 @@ function add(x) end end -global d = add(5) +local d = add(5) global c = print(d()) \ No newline at end of file diff --git a/src/compile.rs b/src/compile.rs index 434b329..ca6bda1 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -212,11 +212,21 @@ impl Expression { let function_register = registers.first().unwrap(); - let mut param_regs = Vec::new(); + let mut original_param_regs = Vec::new(); for param in params.kind.0.iter() { let (instr, registers) = param.kind.compile(state, scope, 1); instructions.extend(instr); - param_regs.extend(registers); + original_param_regs.extend(registers); + } + scope.register_counter.0 = *function_register + 1; + + let mut param_regs = Vec::new(); + for param_reg in original_param_regs { + let new_reg = scope.register_counter.next(); + if param_reg != new_reg { + instructions.push(Instruction::Move(new_reg, param_reg)); + } + param_regs.push(new_reg); } let last_param_reg = param_regs.last().unwrap_or(function_register); @@ -231,9 +241,6 @@ impl Expression { } } - let last_return_reg = return_regs.last().unwrap(); - scope.register_counter.0 = *last_return_reg + 1; - instructions.push(Instruction::Call( *function_register, param_regs.len() as u16, diff --git a/src/vm.rs b/src/vm.rs index cd828d2..a3658ae 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -203,7 +203,7 @@ impl ClosureRunner { Instruction::SetGlobal(reg, global) => { self.closure.environment.borrow_mut().globals.insert( constants.get(*global as usize).unwrap().clone(), - self.stack.get(reg).unwrap().clone(), + self.stack.get(reg).unwrap_or(&Value::Nil).clone(), ); } Instruction::GetGlobal(reg, global) => { @@ -222,7 +222,12 @@ impl ClosureRunner { Instruction::Call(func_reg, param_len, ret_len) => { let mut params = Vec::new(); for i in 0..*param_len { - params.push(self.stack.get(&(func_reg + i + 1)).unwrap().clone()); + params.push( + self.stack + .get(&(func_reg + i + 1)) + .unwrap_or(&Value::Nil) + .clone(), + ); } match self.stack.get(func_reg).unwrap_or(&Value::Nil) { Value::RustFunction(func) => {