More accurate type classification and eager evaluation of left "and" operand.
pull/1258/head
Zef Hemel 2025-02-22 21:28:00 +01:00
parent a268ea89f2
commit 105908204b
4 changed files with 34 additions and 4 deletions

View File

@ -154,6 +154,21 @@ export function evalExpression(
} else {
return evalExpression(e.right, env, sf);
}
} else if (e.operator === "and") {
// Special case: eagerly evaluate left before even attempting right
const left = evalExpression(e.left, env, sf);
if (left instanceof Promise) {
return left.then((left) => {
if (!luaTruthy(left)) {
return left;
}
return evalExpression(e.right, env, sf);
});
} else if (!luaTruthy(left)) {
return left;
} else {
return evalExpression(e.right, env, sf);
}
}
const values = evalPromiseValues([
evalExpression(e.left, env, sf),

View File

@ -433,3 +433,11 @@ end
assertEqual(sum(1, 2, 3), 6)
assertEqual(sum(1, 2, 3, 4, 5), 15)
local data = { { name = "John", favorite = { color = "blue" } }, { name = "Jane" } }
assertEqual(type(data[1].favorite), "table")
assertEqual(data[1].favorite.color, "blue")
local r = query [[from p = data where type(p.favorite) == "table" and p.favorite.color == "blue"]]
assertEqual(#r, 1)
assertEqual(r[1].name, "John")

View File

@ -657,9 +657,12 @@ export function luaKeys(val: any): any[] {
}
}
export function luaTypeOf(val: any): LuaType {
export function luaTypeOf(val: any): LuaType | Promise<LuaType> {
if (val === null || val === undefined) {
return "nil";
}
if (val instanceof Promise) {
return val.then((v) => luaTypeOf(v));
} else if (typeof val === "boolean") {
return "boolean";
} else if (typeof val === "number") {
@ -672,6 +675,8 @@ export function luaTypeOf(val: any): LuaType {
return "table";
} else if (typeof val === "function" || val.call) {
return "function";
} else if (typeof val === "object" && val.constructor === Object) {
return "table";
} else {
return "userdata";
}

View File

@ -80,9 +80,11 @@ const unpackFunction = new LuaBuiltinFunction(async (sf, t: LuaTable) => {
return new LuaMultiRes(values);
});
const typeFunction = new LuaBuiltinFunction((_sf, value: LuaValue): string => {
const typeFunction = new LuaBuiltinFunction(
(_sf, value: LuaValue): string | Promise<string> => {
return luaTypeOf(value);
});
},
);
const tostringFunction = new LuaBuiltinFunction((_sf, value: any) => {
return luaToString(value);