mirror of
https://github.com/Sei-Lisa/LSL-PyOptimizer
synced 2025-07-01 07:38:21 +00:00
Fix bug with nested if's; fix missing EXPR wrap.
097c054
introduced a bug that we hadn't caught until now.
In some occasions, it could swap nested conditions in such a way that the 'else' of the outer statement was made to belong to the inner one, like this:
if (a)
if (b)
stuff;
else
stuff;
That is of course parsed with the 'else' belonging to if(b).
Fix implemented at output time, by detecting 'if(a) stmt; else y;' with stmt being an 'if' without 'else', and wrapping the stmt in {} like this: 'if(a){if(b) x;} else y;'. This has some similarity with parenthesis addition.
But the fix has the corner case that, since {} hides visibility of labels, when the inner 'if' has a label as direct child, it can't be swapped lest the label becomes out of scope. So these cases are detected and skipped in the constant folding module.
In the case of 'if(cond);', we transform it to 'cond;', but we forgot to wrap the cond in an EXPR node as required. Fixed too.
This commit is contained in:
parent
a4b3c1eadd
commit
e42479756b
2 changed files with 33 additions and 10 deletions
|
@ -1664,7 +1664,15 @@ class foldconst(object):
|
|||
if len(child) > 2:
|
||||
self.FoldTree(child, 2)
|
||||
self.FoldStmt(child, 2)
|
||||
if self.DoesSomething(child[2]):
|
||||
# Check if it makes sense to swap if and else branches
|
||||
# (but don't if the else branch is an elseless 'if'
|
||||
# with a label, as it will be wrapped in {} making it
|
||||
# become out of scope)
|
||||
if (self.DoesSomething(child[2])
|
||||
and (child[2]['nt'] != 'IF'
|
||||
or len(child[2]['ch']) == 3
|
||||
or child[2]['ch'][1]['nt'] != '@')
|
||||
):
|
||||
# Check if we can gain something by negating the
|
||||
# expression.
|
||||
# Swap 'if' and 'else' branch when the condition has
|
||||
|
@ -1674,27 +1682,34 @@ class foldconst(object):
|
|||
child[1], child[2] = child[2], child[1]
|
||||
# Swap them if condition is '==' with integer operands
|
||||
if (child[0]['nt'] == '=='
|
||||
and child[0]['ch'][0]['t']
|
||||
== child[0]['ch'][1]['t'] == 'integer'
|
||||
):
|
||||
and child[0]['ch'][0]['t']
|
||||
== child[0]['ch'][1]['t'] == 'integer'
|
||||
):
|
||||
child[0]['nt'] = '^'
|
||||
child[1], child[2] = child[2], child[1]
|
||||
# Re-test just in case we swapped in the previous check.
|
||||
if not self.DoesSomething(child[2]):
|
||||
if (not self.DoesSomething(child[2])
|
||||
and child[1]['nt'] != '@'):
|
||||
# no point in "... else ;" - remove else branch
|
||||
del child[2]
|
||||
if not self.DoesSomething(child[1]):
|
||||
# if (X) ; -> X;
|
||||
if len(child) == 2:
|
||||
parent[index] = child[0]
|
||||
# It has been promoted to statement. Fold it.
|
||||
parent[index] = {'nt':'EXPR', 't':child[0]['t'],
|
||||
'ch':[child[0]]}
|
||||
# It has been promoted to statement. Fold it as such.
|
||||
# (Will remove it if SEF)
|
||||
self.FoldStmt(child, 0)
|
||||
self.FoldStmt(parent, index)
|
||||
return
|
||||
|
||||
# If type(X) != Key, then:
|
||||
# if (X) ; else {stuff} -> if (!X) {stuff}
|
||||
if child[0]['t'] != 'key':
|
||||
# (being careful with labels again)
|
||||
if (child[0]['t'] != 'key'
|
||||
and (child[2]['nt'] != 'IF'
|
||||
or len(child[2]['ch']) == 3
|
||||
or child[2]['ch'][1]['nt'] != '@')
|
||||
):
|
||||
# We've already converted all other types to equivalent
|
||||
# comparisons
|
||||
assert child[0]['t'] == 'integer'
|
||||
|
|
|
@ -384,7 +384,15 @@ class outscript(object):
|
|||
if nt == 'IF':
|
||||
ret = self.dent()
|
||||
while True:
|
||||
ret += 'if (' + self.OutExpr(child[0]) + ')\n' + self.OutIndented(child[1])
|
||||
ret += 'if (' + self.OutExpr(child[0]) + ')\n'
|
||||
if (len(child) == 3
|
||||
and child[1]['nt'] == 'IF' and len(child[1]['ch']) < 3
|
||||
):
|
||||
ret += self.dent() + '{\n'
|
||||
ret += self.OutIndented(child[1])
|
||||
ret += self.dent() + '}\n'
|
||||
else:
|
||||
ret += self.OutIndented(child[1])
|
||||
if len(child) < 3:
|
||||
return ret
|
||||
if child[2]['nt'] != 'IF':
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue