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