In Lua, only the last expression in an argument list preserves multiple results and all earlier expressions yield exactly one value (their first). For example: ``` f(a(), b(), c()) ``` where ``` a -> (1,2) b -> (3,4) c -> (5,6) ``` becomes ``` f(1, 3, 5, 6) ``` which matches Lua behaviour (tested in version 5.4). Changes: * Function argument lists keep multiple results only from the last argument. * Fixes failing truthiness tests (`true and ret_one_two()`). Sidenote: the `truthiness_test.lua` was not called at all because of my obvious copy/paste typo (the `arithmetical_test.lua` was called twice instead; now fixed too and both test suites pass ok).
44 lines
1.2 KiB
TypeScript
44 lines
1.2 KiB
TypeScript
import {
|
|
LuaBuiltinFunction,
|
|
type LuaEnv,
|
|
LuaMultiRes,
|
|
type LuaStackFrame,
|
|
type LuaValue,
|
|
} from "../runtime.ts";
|
|
import { parse } from "../parse.ts";
|
|
import { evalStatement } from "../eval.ts";
|
|
|
|
// Returns a function (callable chunk) or (nil, "error message") pair.
|
|
export function luaLoad(code: LuaValue, sf: LuaStackFrame): LuaValue {
|
|
const s = typeof code === "string" ? code : String(code);
|
|
|
|
try {
|
|
const block = parse(s, sf.astCtx || {});
|
|
const globalEnvMaybe = sf.threadLocal.get("_GLOBAL");
|
|
|
|
// Be vocal when no _GLOBAL is set
|
|
if (!globalEnvMaybe) {
|
|
console.warn(
|
|
"load() called without _GLOBAL in thread-local environment",
|
|
);
|
|
return new LuaMultiRes([null, "Global environment not set"]);
|
|
}
|
|
|
|
const globalEnv: LuaEnv = globalEnvMaybe as LuaEnv;
|
|
|
|
const runner = new LuaBuiltinFunction(async (innerSf: LuaStackFrame) => {
|
|
const res = await evalStatement(block, globalEnv, innerSf, true);
|
|
if (res === undefined) {
|
|
return null;
|
|
} else {
|
|
return new LuaMultiRes(res);
|
|
}
|
|
});
|
|
|
|
return runner;
|
|
} catch (e: any) {
|
|
const msg = e && typeof e.message === "string" ? e.message : String(e);
|
|
return new LuaMultiRes([null, msg]);
|
|
}
|
|
}
|