silverbullet/common/space_lua.ts

77 lines
2.3 KiB
TypeScript
Raw Normal View History

import type { System } from "../lib/plugos/system.ts";
import type { ScriptObject } from "../plugs/index/script.ts";
import {
LuaEnv,
2024-10-09 01:53:09 +08:00
LuaRuntimeError,
2024-10-20 21:06:23 +08:00
LuaStackFrame,
} from "$common/space_lua/runtime.ts";
import { parse as parseLua } from "$common/space_lua/parse.ts";
import { evalStatement } from "$common/space_lua/eval.ts";
2024-10-09 01:53:09 +08:00
import {
type PageRef,
parsePageRef,
} from "@silverbulletmd/silverbullet/lib/page_ref";
import type { ScriptEnvironment } from "$common/space_script.ts";
2024-10-09 01:53:09 +08:00
import type { ASTCtx } from "$common/space_lua/ast.ts";
2024-10-11 21:34:27 +08:00
import { buildLuaEnv } from "$common/space_lua_api.ts";
export class SpaceLuaEnvironment {
env: LuaEnv = new LuaEnv();
/**
* Loads all Lua scripts from the database and evaluates them in a new environment
* @param system
*/
async reload(
system: System<any>,
scriptEnv: ScriptEnvironment,
) {
const allScripts: ScriptObject[] = await system.invokeFunction(
"index.queryObjects",
["space-lua", {}],
);
2025-01-15 03:26:47 +08:00
try {
this.env = buildLuaEnv(system, scriptEnv);
const tl = new LuaEnv();
for (const script of allScripts) {
try {
console.log("Now evaluating", script.ref);
const ast = parseLua(script.script, { ref: script.ref });
// We create a local scope for each script
const scriptEnv = new LuaEnv(this.env);
const sf = new LuaStackFrame(tl, ast.ctx);
await evalStatement(ast, scriptEnv, sf);
} catch (e: any) {
if (e instanceof LuaRuntimeError) {
const origin = resolveASTReference(e.sf.astCtx!);
if (origin) {
console.error(
`Error evaluating script: ${e.message} at [[${origin.page}@${origin.pos}]]`,
);
continue;
}
2024-10-09 01:53:09 +08:00
}
2025-01-15 03:26:47 +08:00
console.error(
`Error evaluating script: ${e.message} for script: ${script.script}`,
);
2024-10-09 01:53:09 +08:00
}
}
2024-10-11 21:34:27 +08:00
2025-01-15 03:26:47 +08:00
console.log("[Lua] Loaded", allScripts.length, "scripts");
} catch (e: any) {
console.error("Error reloading Lua scripts:", e.message);
}
}
}
2024-10-09 01:53:09 +08:00
export function resolveASTReference(ctx?: ASTCtx): PageRef | null {
if (!ctx?.ref) {
return null;
}
const pageRef = parsePageRef(ctx.ref);
return {
page: pageRef.page,
pos: (pageRef.pos as number) + "```space-lua\n".length + ctx.from!,
};
}