diff --git a/examples/test.lua b/examples/test.lua index b3aca55..5200a0e 100644 --- a/examples/test.lua +++ b/examples/test.lua @@ -1,6 +1,6 @@ function f(x, ...) - return x + 5 + return x + 5, ... end -print(123, f(10, 12, 13)) \ No newline at end of file +print(123, f(10, 11, 12)) \ No newline at end of file diff --git a/src/compile.rs b/src/compile.rs index 7317f9a..63258be 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -31,6 +31,7 @@ pub struct Scope { pub register_counter: LocalCounter, pub highest_upvalue: u16, pub upvalues: HashMap, + pub is_vararg: bool, } #[derive(Clone, Debug, Default)] @@ -543,7 +544,9 @@ impl Expression { .locals .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]) } - 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()) + } } } } diff --git a/src/vm.rs b/src/vm.rs index 5f576ed..f743aa2 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -161,6 +161,8 @@ pub enum Instruction { Close(u16), /// R(A) := closure(KPROTO[Bx], R(A), ..., R(A+n)) Closure(u16, u32), + /// R(A), ... := varargs + Vararg(u16), } impl Debug for Instruction { @@ -198,6 +200,7 @@ impl Debug for Instruction { Instruction::Len(arg0, arg1) => write!(f, "LEN {} {}", arg0, arg1), Instruction::Or(arg0, arg1, arg2) => write!(f, "OR {} {} {}", 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, return_registers: Vec::new(), top: 0, + parameters: params, } } @@ -597,6 +601,7 @@ pub struct ClosureRunner { function_register: u16, return_registers: Vec, top: u16, + parameters: Vec, } #[derive(Clone, Debug)] @@ -1083,6 +1088,14 @@ impl ClosureRunner { .unwrap_or(Value::Nil); 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;