From c244edb9bc5eadccd68cdb401bb560f6b7e46f38 Mon Sep 17 00:00:00 2001 From: Sofia Date: Sun, 15 Mar 2026 19:07:43 +0200 Subject: [PATCH] Implement setupval --- examples/test.lua | 12 +++--------- src/compile.rs | 8 ++++++++ src/vm.rs | 33 +++++++++++++++++++-------------- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/examples/test.lua b/examples/test.lua index 9d705da..ada36c8 100644 --- a/examples/test.lua +++ b/examples/test.lua @@ -1,15 +1,9 @@ function add(x) return function (y) + x = x + 1 return x + y, 1, 2 end end -function test() - return add(10)(15) -end - -local a, b, c = add(10)(15) - -b = 10 - -local pr = print(a, b, c) \ No newline at end of file +pr = print(add(10)(15)) +pr = print(add(10)(15)) \ No newline at end of file diff --git a/src/compile.rs b/src/compile.rs index 3bf4895..af3fde8 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -165,6 +165,14 @@ impl Statement { .cloned() .unwrap_or(scope.register_counter.0 + i as u16), ); + } 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), + )); } else { let global = state.get_constant(&Constant::String(name.kind.clone())); diff --git a/src/vm.rs b/src/vm.rs index 7609804..c36630b 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -36,6 +36,8 @@ pub enum Instruction { GetGlobal(u16, u32), /// R(A) := U[B] GetUpVal(u16, u16), + /// U[B] := R(A) + SetUpVal(u16, u16), /// R(A) := R(B) + R(C) Add(u16, u16, u16), /// R(A) := R(B) < R(C) @@ -59,6 +61,7 @@ impl Debug for Instruction { Instruction::SetGlobal(arg0, arg1) => write!(f, "SETGLOBAL {} {}", arg0, arg1), Instruction::GetGlobal(arg0, arg1) => write!(f, "GETGLOBAL {} {}", arg0, arg1), Instruction::GetUpVal(arg0, arg1) => write!(f, "GETUPVAL {} {}", arg0, arg1), + Instruction::SetUpVal(arg0, arg1) => write!(f, "SETUPVAL {} {}", arg0, arg1), Instruction::Call(arg0, arg1, arg2) => write!(f, "CALL {} {} {}", arg0, arg1, arg2), Instruction::Close(arg0) => write!(f, "CLOSE {}", arg0), Instruction::Closure(arg0, arg1) => write!(f, "CLOSURE {} {}", arg0, arg1), @@ -245,6 +248,21 @@ impl ClosureRunner { todo!("Global not found: {:?}", constants.get(*global as usize)) } } + Instruction::GetUpVal(reg, upvalreg) => { + self.stack.insert( + *reg, + self.closure + .upvalues + .get(upvalreg) + .unwrap() + .borrow() + .clone(), + ); + } + Instruction::SetUpVal(upvalreg, reg) => { + *self.closure.upvalues.get(upvalreg).unwrap().borrow_mut() = + self.stack.get(reg).cloned().unwrap_or(Value::Nil); + } Instruction::Call(func_reg, param_len, ret_len) => { let param_start_func_reg = if *param_len == 0 { self.function_register @@ -317,8 +335,6 @@ impl ClosureRunner { ); } - dbg!(&highest_upvalue, &upvalues); - self.stack.insert( *reg, Value::Function(Closure { @@ -344,20 +360,9 @@ 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); + // dbg!(&self.closure.upvalues); return Some(ret_values); } - Instruction::GetUpVal(reg, upvalreg) => { - self.stack.insert( - *reg, - self.closure - .upvalues - .get(upvalreg) - .unwrap() - .borrow() - .clone(), - ); - } Instruction::Add(res, lhs, rhs) => { let lhs = self.stack.get(lhs).unwrap_or(&Value::Nil); let rhs = self.stack.get(rhs).unwrap_or(&Value::Nil);