Add returning varargs
This commit is contained in:
parent
17c7432b7b
commit
b0fc0a1dce
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
function f(x, ...)
|
function f(x, ...)
|
||||||
return x + 5
|
return x + 5, ...
|
||||||
end
|
end
|
||||||
|
|
||||||
print(123, f(10, 12, 13))
|
print(123, f(10, 11, 12))
|
||||||
@ -31,6 +31,7 @@ pub struct Scope {
|
|||||||
pub register_counter: LocalCounter,
|
pub register_counter: LocalCounter,
|
||||||
pub highest_upvalue: u16,
|
pub highest_upvalue: u16,
|
||||||
pub upvalues: HashMap<String, u16>,
|
pub upvalues: HashMap<String, u16>,
|
||||||
|
pub is_vararg: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
@ -543,7 +544,9 @@ impl Expression {
|
|||||||
.locals
|
.locals
|
||||||
.insert(name.clone(), inner_scope.register_counter.next());
|
.insert(name.clone(), inner_scope.register_counter.next());
|
||||||
}
|
}
|
||||||
IdentOrEllipsis::Ellipsis => todo!(),
|
IdentOrEllipsis::Ellipsis => {
|
||||||
|
inner_scope.is_vararg = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,7 +729,15 @@ impl Expression {
|
|||||||
|
|
||||||
(instructions, vec![local])
|
(instructions, vec![local])
|
||||||
}
|
}
|
||||||
Expression::Ellipsis => todo!(),
|
Expression::Ellipsis => {
|
||||||
|
if !scope.is_vararg {
|
||||||
|
panic!("Function is not vararg!");
|
||||||
|
}
|
||||||
|
let mut instructions = Vec::new();
|
||||||
|
let new_reg = scope.register_counter.new();
|
||||||
|
instructions.push(Instruction::Vararg(new_reg));
|
||||||
|
(instructions, Vec::new())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/vm.rs
13
src/vm.rs
@ -161,6 +161,8 @@ pub enum Instruction {
|
|||||||
Close(u16),
|
Close(u16),
|
||||||
/// R(A) := closure(KPROTO[Bx], R(A), ..., R(A+n))
|
/// R(A) := closure(KPROTO[Bx], R(A), ..., R(A+n))
|
||||||
Closure(u16, u32),
|
Closure(u16, u32),
|
||||||
|
/// R(A), ... := varargs
|
||||||
|
Vararg(u16),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Instruction {
|
impl Debug for Instruction {
|
||||||
@ -198,6 +200,7 @@ impl Debug for Instruction {
|
|||||||
Instruction::Len(arg0, arg1) => write!(f, "LEN {} {}", arg0, arg1),
|
Instruction::Len(arg0, arg1) => write!(f, "LEN {} {}", arg0, arg1),
|
||||||
Instruction::Or(arg0, arg1, arg2) => write!(f, "OR {} {} {}", arg0, arg1, arg2),
|
Instruction::Or(arg0, arg1, arg2) => write!(f, "OR {} {} {}", arg0, arg1, arg2),
|
||||||
Instruction::And(arg0, arg1, arg2) => write!(f, "AND {} {} {}", arg0, arg1, arg2),
|
Instruction::And(arg0, arg1, arg2) => write!(f, "AND {} {} {}", arg0, arg1, arg2),
|
||||||
|
Instruction::Vararg(arg0) => write!(f, "VARARG {}", arg0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -574,6 +577,7 @@ impl Closure {
|
|||||||
function_register: 0,
|
function_register: 0,
|
||||||
return_registers: Vec::new(),
|
return_registers: Vec::new(),
|
||||||
top: 0,
|
top: 0,
|
||||||
|
parameters: params,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -597,6 +601,7 @@ pub struct ClosureRunner {
|
|||||||
function_register: u16,
|
function_register: u16,
|
||||||
return_registers: Vec<u16>,
|
return_registers: Vec<u16>,
|
||||||
top: u16,
|
top: u16,
|
||||||
|
parameters: Vec<Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -1083,6 +1088,14 @@ impl ClosureRunner {
|
|||||||
.unwrap_or(Value::Nil);
|
.unwrap_or(Value::Nil);
|
||||||
self.set_stack(*res, StackValue::Value(lhs.and(&rhs)?));
|
self.set_stack(*res, StackValue::Value(lhs.and(&rhs)?));
|
||||||
}
|
}
|
||||||
|
Instruction::Vararg(reg) => {
|
||||||
|
self.function_register = reg - 1;
|
||||||
|
self.top = self.function_register + self.parameters.len() as u16;
|
||||||
|
|
||||||
|
for (i, param) in self.parameters.clone().iter().enumerate() {
|
||||||
|
self.set_stack(*reg + i as u16, StackValue::Value(param.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.program_counter += 1;
|
self.program_counter += 1;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user