Lua runtime fixes
parent
821dddff5e
commit
b6f1977cec
|
@ -160,7 +160,8 @@ Deno.test("Test directive parser", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test("Test lua directive parser", () => {
|
Deno.test("Test lua directive parser", () => {
|
||||||
const simpleExample = `Simple \${{a=}}`;
|
const simpleExample = `Simple \${query_coll("page limit 3", template[==[
|
||||||
|
* Hello there {name}]==])}`;
|
||||||
console.log(JSON.stringify(parseMarkdown(simpleExample), null, 2));
|
console.log(JSON.stringify(parseMarkdown(simpleExample), null, 2));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -312,63 +312,70 @@ function evalPrefixExpression(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special handling for f(...) - propagate varargs
|
const handleFunctionCall = (prefixValue: LuaValue) => {
|
||||||
if (
|
// Special handling for f(...) - propagate varargs
|
||||||
e.args.length === 1 && e.args[0].type === "Variable" &&
|
if (
|
||||||
e.args[0].name === "..."
|
e.args.length === 1 && e.args[0].type === "Variable" &&
|
||||||
) {
|
e.args[0].name === "..."
|
||||||
const varargs = env.get("...");
|
) {
|
||||||
const resolveVarargs = async () => {
|
const varargs = env.get("...");
|
||||||
const resolvedVarargs = await Promise.resolve(varargs);
|
const resolveVarargs = async () => {
|
||||||
if (resolvedVarargs instanceof LuaTable) {
|
const resolvedVarargs = await Promise.resolve(varargs);
|
||||||
const args = [];
|
if (resolvedVarargs instanceof LuaTable) {
|
||||||
for (let i = 1; i <= resolvedVarargs.length; i++) {
|
const args = [];
|
||||||
const val = await Promise.resolve(resolvedVarargs.get(i));
|
for (let i = 1; i <= resolvedVarargs.length; i++) {
|
||||||
args.push(val);
|
const val = await Promise.resolve(resolvedVarargs.get(i));
|
||||||
|
args.push(val);
|
||||||
|
}
|
||||||
|
return args;
|
||||||
}
|
}
|
||||||
return args;
|
return [];
|
||||||
}
|
};
|
||||||
return [];
|
|
||||||
};
|
|
||||||
|
|
||||||
if (prefixValue instanceof Promise) {
|
if (prefixValue instanceof Promise) {
|
||||||
return prefixValue.then(async (resolvedPrefix) => {
|
return prefixValue.then(async (resolvedPrefix) => {
|
||||||
const args = await resolveVarargs();
|
const args = await resolveVarargs();
|
||||||
return luaCall(resolvedPrefix, args, e.ctx, sf.withCtx(e.ctx));
|
return luaCall(resolvedPrefix, args, e.ctx, sf.withCtx(e.ctx));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return resolveVarargs().then((args) =>
|
return resolveVarargs().then((args) =>
|
||||||
luaCall(prefixValue, args, e.ctx, sf.withCtx(e.ctx))
|
luaCall(prefixValue, args, e.ctx, sf.withCtx(e.ctx))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal argument handling
|
||||||
|
let selfArgs: LuaValue[] = [];
|
||||||
|
if (e.name && !prefixValue.get) {
|
||||||
|
throw new LuaRuntimeError(
|
||||||
|
`Attempting to index a non-table: ${prefixValue}`,
|
||||||
|
sf.withCtx(e.prefix.ctx),
|
||||||
|
);
|
||||||
|
} else if (e.name) {
|
||||||
|
selfArgs = [prefixValue];
|
||||||
|
prefixValue = prefixValue.get(e.name);
|
||||||
|
}
|
||||||
|
if (!prefixValue.call) {
|
||||||
|
throw new LuaRuntimeError(
|
||||||
|
`Attempting to call ${prefixValue} as a function`,
|
||||||
|
sf.withCtx(e.prefix.ctx),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
const args = evalPromiseValues(
|
||||||
|
e.args.map((arg) => evalExpression(arg, env, sf)),
|
||||||
// Normal argument handling
|
|
||||||
let selfArgs: LuaValue[] = [];
|
|
||||||
if (e.name && !prefixValue.get) {
|
|
||||||
throw new LuaRuntimeError(
|
|
||||||
`Attempting to index a non-table: ${prefixValue}`,
|
|
||||||
sf.withCtx(e.prefix.ctx),
|
|
||||||
);
|
|
||||||
} else if (e.name) {
|
|
||||||
selfArgs = [prefixValue];
|
|
||||||
prefixValue = prefixValue.get(e.name);
|
|
||||||
}
|
|
||||||
if (!prefixValue.call) {
|
|
||||||
throw new LuaRuntimeError(
|
|
||||||
`Attempting to call ${prefixValue} as a function`,
|
|
||||||
sf.withCtx(e.prefix.ctx),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const args = evalPromiseValues(
|
|
||||||
e.args.map((arg) => evalExpression(arg, env, sf)),
|
|
||||||
);
|
|
||||||
if (args instanceof Promise) {
|
|
||||||
return args.then((args) =>
|
|
||||||
luaCall(prefixValue, [...selfArgs, ...args], e.ctx, sf)
|
|
||||||
);
|
);
|
||||||
|
if (args instanceof Promise) {
|
||||||
|
return args.then((args) =>
|
||||||
|
luaCall(prefixValue, [...selfArgs, ...args], e.ctx, sf)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return luaCall(prefixValue, [...selfArgs, ...args], e.ctx, sf);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (prefixValue instanceof Promise) {
|
||||||
|
return prefixValue.then(handleFunctionCall);
|
||||||
} else {
|
} else {
|
||||||
return luaCall(prefixValue, [...selfArgs, ...args], e.ctx, sf);
|
return handleFunctionCall(prefixValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -3,9 +3,10 @@ import {
|
||||||
LuaBuiltinFunction,
|
LuaBuiltinFunction,
|
||||||
luaCall,
|
luaCall,
|
||||||
LuaEnv,
|
LuaEnv,
|
||||||
|
luaGet,
|
||||||
LuaMultiRes,
|
LuaMultiRes,
|
||||||
LuaRuntimeError,
|
LuaRuntimeError,
|
||||||
type LuaTable,
|
LuaTable,
|
||||||
luaToString,
|
luaToString,
|
||||||
luaTypeOf,
|
luaTypeOf,
|
||||||
type LuaValue,
|
type LuaValue,
|
||||||
|
@ -15,8 +16,8 @@ import { tableApi } from "$common/space_lua/stdlib/table.ts";
|
||||||
import { osApi } from "$common/space_lua/stdlib/os.ts";
|
import { osApi } from "$common/space_lua/stdlib/os.ts";
|
||||||
import { jsApi } from "$common/space_lua/stdlib/js.ts";
|
import { jsApi } from "$common/space_lua/stdlib/js.ts";
|
||||||
|
|
||||||
const printFunction = new LuaBuiltinFunction((_sf, ...args) => {
|
const printFunction = new LuaBuiltinFunction(async (_sf, ...args) => {
|
||||||
console.log("[Lua]", ...args.map(luaToString));
|
console.log("[Lua]", ...(await Promise.all(args.map(luaToString))));
|
||||||
});
|
});
|
||||||
|
|
||||||
const assertFunction = new LuaBuiltinFunction(
|
const assertFunction = new LuaBuiltinFunction(
|
||||||
|
@ -27,35 +28,35 @@ const assertFunction = new LuaBuiltinFunction(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const ipairsFunction = new LuaBuiltinFunction((_sf, ar: LuaTable) => {
|
const ipairsFunction = new LuaBuiltinFunction((sf, ar: LuaTable) => {
|
||||||
let i = 1;
|
let i = 1;
|
||||||
return () => {
|
return async () => {
|
||||||
if (i > ar.length) {
|
if (i > ar.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const result = new LuaMultiRes([i, ar.get(i)]);
|
const result = new LuaMultiRes([i, await luaGet(ar, i, sf)]);
|
||||||
i++;
|
i++;
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const pairsFunction = new LuaBuiltinFunction((_sf, t: LuaTable) => {
|
const pairsFunction = new LuaBuiltinFunction((sf, t: LuaTable) => {
|
||||||
const keys = t.keys();
|
const keys = t.keys();
|
||||||
let i = 0;
|
let i = 0;
|
||||||
return () => {
|
return async () => {
|
||||||
if (i >= keys.length) {
|
if (i >= keys.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const key = keys[i];
|
const key = keys[i];
|
||||||
i++;
|
i++;
|
||||||
return new LuaMultiRes([key, t.get(key)]);
|
return new LuaMultiRes([key, await luaGet(t, key, sf)]);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const unpackFunction = new LuaBuiltinFunction((_sf, t: LuaTable) => {
|
const unpackFunction = new LuaBuiltinFunction(async (sf, t: LuaTable) => {
|
||||||
const values: LuaValue[] = [];
|
const values: LuaValue[] = [];
|
||||||
for (let i = 1; i <= t.length; i++) {
|
for (let i = 1; i <= t.length; i++) {
|
||||||
values.push(t.get(i));
|
values.push(await luaGet(t, i, sf));
|
||||||
}
|
}
|
||||||
return new LuaMultiRes(values);
|
return new LuaMultiRes(values);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue