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)
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)
pr = print(add(10)(15))
pr = print(add(10)(15))

View File

@ -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()));

View File

@ -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);