Add MoveRetValues instruction

This commit is contained in:
Sofia 2026-03-18 18:20:40 +02:00
parent 38e5b41644
commit b55c5eb070
3 changed files with 36 additions and 12 deletions

View File

@ -17,7 +17,7 @@ function min(x, y)
end
function f(x)
return x + 5
return x + 5, add(10)(15)
end
global sometable = {}
@ -34,3 +34,4 @@ print(min(11, 9))
print(10 - 15)
print("hello there!")
print(true or 0)
print(f(10))

View File

@ -566,18 +566,23 @@ impl Expression {
let mut param_scope = scope.clone();
let mut original_param_regs = Vec::new();
for param in params.kind.0.iter() {
let mut vararg = false;
for (i, param) in params.kind.0.iter().enumerate() {
let (instr, registers) = param.kind.compile(
state,
&mut param_scope,
if params.kind.0.len() == 1 {
if i == params.kind.0.len() - 1 {
None
} else {
Some(1)
},
);
instructions.extend(instr);
original_param_regs.extend(registers);
if registers.len() > 0 {
original_param_regs.push(*registers.first().unwrap());
} else {
vararg = true;
}
}
let mut registers = scope
@ -600,6 +605,11 @@ impl Expression {
instructions.push(Instruction::Move(function_reg, *old_function_reg));
}
if vararg {
let last_reg = param_regs.last().unwrap_or(&function_reg) + 1;
instructions.push(Instruction::MoveRetValues(last_reg));
}
let last_param_reg = param_regs.last().unwrap_or(&function_reg);
let mut return_regs = Vec::new();
@ -616,7 +626,7 @@ impl Expression {
instructions.push(Instruction::Call(
*&function_reg,
param_regs.len() as u16,
if vararg { 0 } else { param_regs.len() as u16 },
if return_regs.len() == 0 {
0
} else {

View File

@ -110,6 +110,8 @@ impl Debug for Constant {
pub enum Instruction {
/// R(A) := R(B)
Move(u16, u16),
/// R(A) ... R(A + func_register - top) := previous function return values
MoveRetValues(u16),
/// R(A) := K(Bx)
LoadK(u16, u32),
/// R(A), ..., R(B) := nil
@ -165,6 +167,7 @@ impl Debug for Instruction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Instruction::Move(arg0, arg1) => write!(f, "MOVE {} {}", arg0, arg1),
Instruction::MoveRetValues(arg0) => write!(f, "MOVERETVALS {}", arg0),
Instruction::LoadK(arg0, arg1) => write!(f, "LOADK {} {}", arg0, arg1),
Instruction::SetGlobal(arg0, arg1) => write!(f, "SETGLOBAL {} {}", arg0, arg1),
Instruction::GetGlobal(arg0, arg1) => write!(f, "GETGLOBAL {} {}", arg0, arg1),
@ -708,6 +711,20 @@ impl ClosureRunner {
let b = self.get_stack(*b);
self.set_stack(*a, b);
}
Instruction::MoveRetValues(res) => {
let length = self.top - self.function_register;
let mut values = Vec::new();
for i in 0..length {
let b = self.get_stack(self.function_register + i + 1);
values.push(b);
}
for (i, val) in values.into_iter().enumerate() {
self.set_stack(*res + i as u16, val);
}
self.top = *res + length;
}
Instruction::LoadK(reg, constant) => {
self.set_stack(
*reg,
@ -868,14 +885,10 @@ impl ClosureRunner {
}
}
Instruction::Call(func_reg, param_len, ret_len) => {
let param_start_func_reg = if *param_len == 0 {
self.function_register
} else {
*func_reg
};
let param_start_func_reg = *func_reg;
let param_len = if *param_len == 0 {
self.top - self.top.min(param_start_func_reg)
self.top - self.top.min(param_start_func_reg + 1)
} else {
*param_len
};