From 28e1b43b81239b20a109c9fa45522af77b08333a Mon Sep 17 00:00:00 2001 From: Sofia Date: Wed, 18 Mar 2026 19:47:47 +0200 Subject: [PATCH] Fix varargs for single value returns --- examples/test.lua | 40 ++++++++++++++++++++++++++++++++++++---- src/compile.rs | 9 +++++++-- src/vm.rs | 46 ++++++++++++++++++++++++++++++++-------------- 3 files changed, 75 insertions(+), 20 deletions(-) diff --git a/examples/test.lua b/examples/test.lua index 4bf4084..3d02370 100644 --- a/examples/test.lua +++ b/examples/test.lua @@ -1,7 +1,39 @@ +global b = 5 -function f(x, ...) - local b, c = ... - return x + 5, b, c +function add(x) + return function (y) + x = x + 1 + b = b + 1 + return x + y, 1, 2, b + end end -print(123, f(10, 11, 12)) +function min(x, y) + local m = x + if y < x then + m = y + end + return m +end + + +function f(x, ...) + local b = {10, ..., add(10)(15)} + return x + 5, b +end + +global sometable = {} +sometable["hello"] = { 100, 150, add(10)(15) } +print(#sometable["hello"]) +sometable["hello"].there = "my dude" +print(sometable.hello.there) + +print(max(11.12345, 9)) +print(add(10)(15)) +print(add(10)(15)) +print(b) +print(min(11, 9)) +print(10 - 15) +print("hello there!") +print(true or 0) +print(123, f(10, 11, 12)) \ No newline at end of file diff --git a/src/compile.rs b/src/compile.rs index 7be1ede..90d07cb 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -750,8 +750,13 @@ impl Expression { } let mut instructions = Vec::new(); let new_reg = scope.register_counter.new(); - instructions.push(Instruction::Vararg(new_reg)); - (instructions, Vec::new()) + if expected_values == None { + instructions.push(Instruction::Vararg(new_reg, 0)); + (instructions, Vec::new()) + } else { + instructions.push(Instruction::Vararg(new_reg, 3)); + (instructions, vec![new_reg]) + } } } } diff --git a/src/vm.rs b/src/vm.rs index f44167f..48fa0f1 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -161,8 +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), + /// R(A), ... , R(A+B-2) := varargs + Vararg(u16, u16), } impl Debug for Instruction { @@ -200,7 +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), + Instruction::Vararg(arg0, arg1) => write!(f, "VARARG {} {}", arg0, arg1), } } } @@ -1097,19 +1097,37 @@ impl ClosureRunner { .unwrap_or(Value::Nil); self.set_stack(*res, StackValue::Value(lhs.and(&rhs)?)); } - Instruction::Vararg(reg) => { + Instruction::Vararg(reg, len) => { self.function_register = reg - 1; - self.top = self.function_register + self.parameters.len() as u16 - - prototype.parameters as u16; + if *len == 0 { + self.top = self.function_register + self.parameters.len() as u16 + - prototype.parameters as u16; - for (i, param) in self - .parameters - .clone() - .iter() - .skip(prototype.parameters) - .enumerate() - { - self.set_stack(*reg + i as u16, StackValue::Value(param.clone())); + for (i, param) in self + .parameters + .clone() + .iter() + .skip(prototype.parameters) + .enumerate() + { + self.set_stack(*reg + i as u16, StackValue::Value(param.clone())); + } + } else { + let len = len - 2; + self.top = self.function_register + len + 1; + for i in 0..len { + self.set_stack( + *reg + i as u16, + StackValue::Value( + self.parameters + .iter() + .skip(prototype.parameters) + .next() + .unwrap_or(&Value::Nil) + .clone(), + ), + ); + } } } };