From fb6158a1c0ab64a5cc53f16d98968eb040242a4e Mon Sep 17 00:00:00 2001 From: Sodium-Aluminate Date: Wed, 14 May 2025 19:58:32 +0800 Subject: [PATCH] fix logical expression short-circuit evaluation (#27) --- src/operators.ts | 11 +++++++++-- src/parser.ts | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/operators.ts b/src/operators.ts index 6556f00..5a91df4 100644 --- a/src/operators.ts +++ b/src/operators.ts @@ -37,8 +37,15 @@ const binaryBooleanArithmetic = ( const bool = (value: LuaType): boolean => coerceToBoolean(value) // logical -const and = (l: LuaType, r: LuaType): LuaType => coerceToBoolean(l) ? r : l -const or = (l: LuaType, r: LuaType): LuaType => coerceToBoolean(l) ? l : r +const and = (l: () => LuaType, r: () => LuaType): LuaType => { + const lv = l() + return coerceToBoolean(lv) ? r() : lv +} + +const or = (l: () => LuaType, r: () => LuaType): LuaType => { + const lv = l() + return coerceToBoolean(lv) ? lv : r() +} // unary const not = (value: LuaType): boolean => !bool(value) diff --git a/src/parser.ts b/src/parser.ts index c3d5caf..dca6690 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -303,10 +303,10 @@ const generate = (node: luaparse.Node): string | MemExpr => { const operator = node.operator if (operator === 'and') { - return `__lua.and(${left},${right})` + return `__lua.and(() => ${left}, () => ${right})` } if (operator === 'or') { - return `__lua.or(${left},${right})` + return `__lua.or(() => ${left}, () => ${right})` } throw new Error(`Unhandled logical operator: ${node.operator}`) }