Implement setupval

This commit is contained in:
Sofia 2026-03-15 19:07:43 +02:00
parent 88d09abcce
commit c244edb9bc
3 changed files with 30 additions and 23 deletions

View File

@ -1,15 +1,9 @@
function add(x) function add(x)
return function (y) return function (y)
x = x + 1
return x + y, 1, 2 return x + y, 1, 2
end end
end end
function test() pr = print(add(10)(15))
return add(10)(15) pr = print(add(10)(15))
end
local a, b, c = add(10)(15)
b = 10
local pr = print(a, b, c)

View File

@ -165,6 +165,14 @@ impl Statement {
.cloned() .cloned()
.unwrap_or(scope.register_counter.0 + i as u16), .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 { } else {
let global = let global =
state.get_constant(&Constant::String(name.kind.clone())); state.get_constant(&Constant::String(name.kind.clone()));

View File

@ -36,6 +36,8 @@ pub enum Instruction {
GetGlobal(u16, u32), GetGlobal(u16, u32),
/// R(A) := U[B] /// R(A) := U[B]
GetUpVal(u16, u16), GetUpVal(u16, u16),
/// U[B] := R(A)
SetUpVal(u16, u16),
/// R(A) := R(B) + R(C) /// R(A) := R(B) + R(C)
Add(u16, u16, u16), Add(u16, u16, u16),
/// R(A) := R(B) < R(C) /// R(A) := R(B) < R(C)
@ -59,6 +61,7 @@ impl Debug for Instruction {
Instruction::SetGlobal(arg0, arg1) => write!(f, "SETGLOBAL {} {}", arg0, arg1), Instruction::SetGlobal(arg0, arg1) => write!(f, "SETGLOBAL {} {}", arg0, arg1),
Instruction::GetGlobal(arg0, arg1) => write!(f, "GETGLOBAL {} {}", arg0, arg1), Instruction::GetGlobal(arg0, arg1) => write!(f, "GETGLOBAL {} {}", arg0, arg1),
Instruction::GetUpVal(arg0, arg1) => write!(f, "GETUPVAL {} {}", 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::Call(arg0, arg1, arg2) => write!(f, "CALL {} {} {}", arg0, arg1, arg2),
Instruction::Close(arg0) => write!(f, "CLOSE {}", arg0), Instruction::Close(arg0) => write!(f, "CLOSE {}", arg0),
Instruction::Closure(arg0, arg1) => write!(f, "CLOSURE {} {}", arg0, arg1), Instruction::Closure(arg0, arg1) => write!(f, "CLOSURE {} {}", arg0, arg1),
@ -245,6 +248,21 @@ impl ClosureRunner {
todo!("Global not found: {:?}", constants.get(*global as usize)) 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) => { Instruction::Call(func_reg, param_len, ret_len) => {
let param_start_func_reg = if *param_len == 0 { let param_start_func_reg = if *param_len == 0 {
self.function_register self.function_register
@ -317,8 +335,6 @@ impl ClosureRunner {
); );
} }
dbg!(&highest_upvalue, &upvalues);
self.stack.insert( self.stack.insert(
*reg, *reg,
Value::Function(Closure { Value::Function(Closure {
@ -344,20 +360,9 @@ impl ClosureRunner {
for i in reg_start..=reg_end { for i in reg_start..=reg_end {
ret_values.push(self.stack.get(&i).cloned().unwrap_or(Value::Nil)); ret_values.push(self.stack.get(&i).cloned().unwrap_or(Value::Nil));
} }
dbg!(&self.closure.upvalues); // dbg!(&self.closure.upvalues);
return Some(ret_values); 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) => { Instruction::Add(res, lhs, rhs) => {
let lhs = self.stack.get(lhs).unwrap_or(&Value::Nil); let lhs = self.stack.get(lhs).unwrap_or(&Value::Nil);
let rhs = self.stack.get(rhs).unwrap_or(&Value::Nil); let rhs = self.stack.get(rhs).unwrap_or(&Value::Nil);