Fixes #1253
More accurate type classification and eager evaluation of left "and" operand.pull/1258/head
parent
a268ea89f2
commit
105908204b
|
@ -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),
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -80,9 +80,11 @@ const unpackFunction = new LuaBuiltinFunction(async (sf, t: LuaTable) => {
|
|||
return new LuaMultiRes(values);
|
||||
});
|
||||
|
||||
const typeFunction = new LuaBuiltinFunction((_sf, value: LuaValue): string => {
|
||||
return luaTypeOf(value);
|
||||
});
|
||||
const typeFunction = new LuaBuiltinFunction(
|
||||
(_sf, value: LuaValue): string | Promise<string> => {
|
||||
return luaTypeOf(value);
|
||||
},
|
||||
);
|
||||
|
||||
const tostringFunction = new LuaBuiltinFunction((_sf, value: any) => {
|
||||
return luaToString(value);
|
||||
|
|
Loading…
Reference in New Issue