From 65326115d81ad6124522541efd2ed30d7a052c48 Mon Sep 17 00:00:00 2001 From: Sei Lisa Date: Mon, 6 May 2024 23:55:55 +0200 Subject: [PATCH] Fix/extend the `<` operator; promote min/max from symbol to node - Fix case where CONST < FNCALL or FNCALL < CONST, when the function was marked as SEF but the args were not SEF, could result in the FNCALL being optimized out, thus failing to apply the side effects of the arguments. - Copy the function's `min` and `max` present in the symbol table, to the node; use the node's `min` and `max` properties in the `<` operator instead of looking up the symbol and using that. - Extend it to cover all cases where CONST < SEFexpr and SEFexpr < CONST where SEFexpr.min and SEFexpr.max are defined. --- lslopt/lslfoldconst.py | 76 +++++++++------------ unit_tests/expr.suite/operators-compare.lsl | 5 ++ unit_tests/expr.suite/operators-compare.out | 5 ++ 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/lslopt/lslfoldconst.py b/lslopt/lslfoldconst.py index 6b17a8a..ed7b32e 100644 --- a/lslopt/lslfoldconst.py +++ b/lslopt/lslfoldconst.py @@ -1318,51 +1318,37 @@ class foldconst(object): parent[index] = nr(nt='CONST', t='integer', value=0, SEF=True) return - if child[0].t == child[1].t in ('integer', 'float'): - if (child[0].nt == 'CONST' - and child[1].nt == 'FNCALL' - and self.FnSEF(child[1]) + + if child[0].nt == 'CONST' and child[1].SEF: + # when CONST >= second.max: always false + # when CONST < second.min: always true + if (hasattr(child[1], 'max') + and not lslfuncs.less(child[0].value, child[1].max) ): - # CONST < FNCALL aka FNCALL > CONST - # when FNCALL.max <= CONST: always false - # when CONST < FNCALL.min: always true - if ('max' in self.symtab[0][child[1].name] - and not lslfuncs.less(child[0].value, - self.symtab[0][child[1].name]['max']) - ): - parent[index] = nr(nt='CONST', t='integer', - value=0, SEF=True) - return - if ('min' in self.symtab[0][child[1].name] - and lslfuncs.less(child[0].value, - self.symtab[0][child[1].name]['min']) - ): - parent[index] = nr(nt='CONST', t='integer', - value=1, SEF=True) - return - if (child[1].nt == 'CONST' - and child[0].nt == 'FNCALL' - and self.FnSEF(child[0]) + parent[index] = nr(nt='CONST', t='integer', + value=0, SEF=True) + return + if (hasattr(child[1], 'min') + and lslfuncs.less(child[0].value, child[1].min) ): - # FNCALL < CONST - # when CONST > FNCALL.max: always true - # when CONST <= FNCALL.min: always false - if ('max' in self.symtab[0][child[0].name] - and lslfuncs.less( - self.symtab[0][child[0].name]['max'] - , child[1].value) - ): - parent[index] = nr(nt='CONST', t='integer', - value=1, SEF=True) - return - if ('min' in self.symtab[0][child[0].name] - and not lslfuncs.less( - self.symtab[0][child[0].name]['min'], - child[1].value) - ): - parent[index] = nr(nt='CONST', t='integer', - value=0, SEF=True) - return + parent[index] = nr(nt='CONST', t='integer', + value=1, SEF=True) + return + if child[1].nt == 'CONST' and child[0].SEF: + # when first.max < CONST: always true + # when first.min >= CONST: always false + if (hasattr(child[0], 'max') + and lslfuncs.less(child[0].max, child[1].value) + ): + parent[index] = nr(nt='CONST', t='integer', + value=1, SEF=True) + return + if (hasattr(child[0], 'min') + and not lslfuncs.less(child[0].min, child[1].value) + ): + parent[index] = nr(nt='CONST', t='integer', + value=0, SEF=True) + return # Convert 2147483647= 0 +, llAbs(llGetLinkNumber()-2) < 0 +, llAbs(llGetLinkNumber()-2) < -1 +, llAbs(llGetLinkNumber()-2) < 3 +, llFabs(llSetRegionPos(<1, 1, 1>) - 0.5) < 0 ] diff --git a/unit_tests/expr.suite/operators-compare.out b/unit_tests/expr.suite/operators-compare.out index 743d70f..87c62e4 100644 --- a/unit_tests/expr.suite/operators-compare.out +++ b/unit_tests/expr.suite/operators-compare.out @@ -38,4 +38,9 @@ , 0 , 0 , 1 +, 1 +, 0 +, 0 +, llAbs(~-~-llGetLinkNumber()) < 3 +, llFabs(-0.5 + llSetRegionPos(<1., 1., 1.>)) < 0 ] \ No newline at end of file