Implement setupval
This commit is contained in:
parent
88d09abcce
commit
c244edb9bc
@ -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))
|
||||
@ -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()));
|
||||
|
||||
33
src/vm.rs
33
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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user