Load .lua files with `dofile`

main
Zef Hemel 2025-01-19 16:23:08 +01:00
parent 6078452a6c
commit 41d5743673
5 changed files with 28 additions and 22 deletions

View File

@ -760,6 +760,8 @@ export function jsToLuaValue(value: any): any {
}
if (value instanceof LuaTable) {
return value;
} else if (value instanceof Uint8Array || value instanceof ArrayBuffer) {
return value;
} else if (Array.isArray(value)) {
const table = new LuaTable();
for (let i = 0; i < value.length; i++) {

View File

@ -18,6 +18,8 @@ import { jsApi } from "$common/space_lua/stdlib/js.ts";
import { spaceLuaApi } from "$common/space_lua/stdlib/space_lua.ts";
import { templateApi } from "$common/space_lua/stdlib/template.ts";
import { mathApi } from "$common/space_lua/stdlib/math.ts";
import { parse } from "$common/space_lua/parse.ts";
import { evalStatement } from "$common/space_lua/eval.ts";
const printFunction = new LuaBuiltinFunction(async (_sf, ...args) => {
console.log(
@ -139,6 +141,27 @@ const getmetatableFunction = new LuaBuiltinFunction((_sf, table: LuaTable) => {
return table.metatable;
});
const dofileFunction = new LuaBuiltinFunction(async (sf, filename: string) => {
const global = sf.threadLocal.get("_GLOBAL");
const file = await luaCall(
global.get("space").get("read_file"),
[filename],
sf.astCtx!,
sf,
) as Uint8Array;
const code = new TextDecoder().decode(file);
try {
const parsedExpr = parse(code);
const env = new LuaEnv(global);
await evalStatement(parsedExpr, env, sf.withCtx(parsedExpr.ctx));
} catch (e: any) {
throw new LuaRuntimeError(
`Error evaluating "${filename}": ${e.message}`,
sf,
);
}
});
export function luaBuildStandardEnv() {
const env = new LuaEnv();
// Top-level builtins
@ -155,6 +178,7 @@ export function luaBuildStandardEnv() {
env.set("setmetatable", setmetatableFunction);
env.set("getmetatable", getmetatableFunction);
env.set("rawset", rawsetFunction);
env.set("dofile", dofileFunction);
// Error handling
env.set("error", errorFunction);
env.set("pcall", pcallFunction);

View File

@ -63,11 +63,6 @@ functions:
events:
- attachment:index
indexSpaceLuaFile:
path: "./script.ts:indexSpaceLuaFile"
events:
- attachment:index
indexPage:
path: page.ts:indexPage
events:

View File

@ -63,20 +63,3 @@ export async function indexSpaceLua({ name, tree }: IndexTreeEvent) {
});
await indexObjects<ScriptObject>(name, allScripts);
}
export async function indexSpaceLuaFile(name: string) {
if (!name.endsWith(".lua")) {
return;
}
console.log("Indexing space lua file", name);
const data = await space.readFile(name);
const code = new TextDecoder().decode(data);
// Parse out "-- priority: <number>"
const priority = code.match(/--\s*priority:\s*(-?\d+)/)?.[1];
await indexObjects<ScriptObject>(name, [{
ref: `${name}`,
tag: "space-lua",
script: code,
priority: priority !== undefined ? +priority : undefined,
}]);
}

View File

@ -201,3 +201,5 @@ rawset(t, "foo", "bar") -- bypasses the metamethod
print(t.foo) -- prints: "bar"
```
## dofile(path)
Loads a Lua file from a path in your space, e.g. if you uploaded a `test.lua` file, you can load it with `dofile("test.lua")`.