Files
plainleaf/client/space_lua/stdlib/load.ts
T
Matouš Jan FialkaandGitHub e5b4c8feb2 Space Lua: Refactor control flow signals (#1794)
* Space Lua: Refactor control flow signals

Removes "return throws an exception" failure mode. @zef :)

Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>

* Remove unused function

Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>

* Remove another unused function

Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>

* Remove unused `LuaBreak`/`LuaReturn` exception control flow

Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>

---------

Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
2026-01-29 08:07:26 +01:00

53 lines
1.6 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 {
if (res && typeof res === "object" && (res as any).ctrl === "return") {
return new LuaMultiRes((res as any).values);
}
if (res && typeof res === "object" && (res as any).ctrl === "break") {
throw new Error("break outside loop");
}
if (res && typeof res === "object" && (res as any).ctrl === "goto") {
throw new Error("unexpected goto signal");
}
return null;
}
});
return runner;
} catch (e: any) {
const msg = e && typeof e.message === "string" ? e.message : String(e);
return new LuaMultiRes([null, msg]);
}
}