Fix: lazy evaluation for logical expressions (#27) (#28)

* fix logical expression short-circuit evaluation (#27)

* test logical short-circuit cases (#27)
pull/31/head
铝箔 6 months ago committed by GitHub
parent be4f0fa982
commit d121e74c6f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -37,8 +37,15 @@ const binaryBooleanArithmetic = (
const bool = (value: LuaType): boolean => coerceToBoolean(value) const bool = (value: LuaType): boolean => coerceToBoolean(value)
// logical // logical
const and = (l: LuaType, r: LuaType): LuaType => coerceToBoolean(l) ? r : l const and = (l: () => LuaType, r: () => LuaType): LuaType => {
const or = (l: LuaType, r: LuaType): LuaType => coerceToBoolean(l) ? l : r const lv = l()
return coerceToBoolean(lv) ? r() : lv
}
const or = (l: () => LuaType, r: () => LuaType): LuaType => {
const lv = l()
return coerceToBoolean(lv) ? lv : r()
}
// unary // unary
const not = (value: LuaType): boolean => !bool(value) const not = (value: LuaType): boolean => !bool(value)

@ -303,10 +303,10 @@ const generate = (node: luaparse.Node): string | MemExpr => {
const operator = node.operator const operator = node.operator
if (operator === 'and') { if (operator === 'and') {
return `__lua.and(${left},${right})` return `__lua.and(() => ${left}, () => ${right})`
} }
if (operator === 'or') { if (operator === 'or') {
return `__lua.or(${left},${right})` return `__lua.or(() => ${left}, () => ${right})`
} }
throw new Error(`Unhandled logical operator: ${node.operator}`) throw new Error(`Unhandled logical operator: ${node.operator}`)
} }

@ -0,0 +1,6 @@
local x = nil
local x_ = (x and x.k or "fallback")
assert(x_ == "fallback")
local y = "ok"
local y_ = (y or error("should not raise"))
assert(y == y_)

@ -24,6 +24,7 @@ let exitCode = 0
}) })
luaEnv.parseFile('goto.lua').exec() luaEnv.parseFile('goto.lua').exec()
luaEnv.parseFile('bwcoercion.lua').exec() luaEnv.parseFile('bwcoercion.lua').exec()
luaEnv.parseFile('logical_operations.lua').exec()
} }
{ {

Loading…
Cancel
Save