From c5fd4932f197f6fd93f78bfb29b608983a91156a Mon Sep 17 00:00:00 2001 From: Sei Lisa Date: Sun, 6 Jan 2019 01:59:36 +0100 Subject: [PATCH] Finish inlining for all loop conditions --- lslopt/lslinliner.py | 45 +++++++++++++++++++++----- unit_tests/coverage.suite/inline-1.lsl | 10 ++++++ unit_tests/coverage.suite/inline-1.out | 34 +++++++++++++++++++ 3 files changed, 81 insertions(+), 8 deletions(-) diff --git a/lslopt/lslinliner.py b/lslopt/lslinliner.py index 482756f..1a27bae 100644 --- a/lslopt/lslinliner.py +++ b/lslopt/lslinliner.py @@ -293,7 +293,8 @@ class inliner(object): if len(child) > 2: self.RecurseSingleStatement(child, 2, scope) - # TODO: Handle loops properly + # Loop handling is tricky. + # # Consider this: # # integer f() @@ -388,19 +389,47 @@ class inliner(object): i += 1 elif nt == 'WHILE': + # Convert to if() + lbl = self.newId('whl', scope, {'Kind':'l','Scope':scope,'ref':1}) + parent.insert(index, nr(nt='@', t=None, name=lbl, scope=scope)) + index += 1 + node.nt = 'IF' + if child[1].nt != '{}': + # Needs wrapping now + child[1] = nr(nt='{}', t=None, ch=[child[1]], + scope=self.newSymtab()) + child[1].ch.append(nr(nt='JUMP', t=None, name=lbl, scope=scope)) fns = self.RecurseExpression(child, 0, scope) self.RecurseSingleStatement(child, 1, scope) elif nt == 'FOR': assert child[0].nt == 'EXPRLIST' assert child[2].nt == 'EXPRLIST' - fns = [] - for i in range(len(child[0].ch)): - fns.extend(self.RecurseExpression(child[0].ch, i, scope)) - fns.extend(self.RecurseExpression(child, 1, scope)) - for i in range(len(child[2].ch)): - fns.extend(self.RecurseExpression(child[2].ch, i, scope)) - self.RecurseSingleStatement(child, 3, scope) + for i in child[0].ch: + parent.insert(index, nr(nt='EXPR', t=i.t, ch=[i])) + fns = self.RecurseExpression(parent, index, scope) + parent[index:index] = fns + index += 1 + len(fns) + lbl = self.newId('for', scope, {'Kind':'l','Scope':scope,'ref':1}) + parent.insert(index, nr(nt='@', t=None, name=lbl, scope=scope)) + index += 1 + node.nt = 'IF' + if child[3].nt != '{}': + # Needs wrapping now + child[3] = nr(nt='{}', t=None, ch=[child[3]], + scope=self.newSymtab()) + # Needs another wrapping if iterator is not empty + if child[2].ch: + child[3] = nr(nt='{}', t=None, ch=[child[3]], + scope=self.newSymtab()) + for i in child[2].ch: + child[3].ch.append(nr(nt='EXPR', t=i.t, ch=[i])) + del child[2] + del child[0] + child[1].ch.append(nr(nt='JUMP', t=None, name=lbl, scope=scope)) + fns.extend(self.RecurseExpression(child, 0, scope)) + self.RecurseSingleStatement(child, 1, scope) + #assert False, parent[index] else: assert False, u"Unexpected node type: %s" % nt.decode('utf8') diff --git a/unit_tests/coverage.suite/inline-1.lsl b/unit_tests/coverage.suite/inline-1.lsl index cc5365a..a3059c7 100644 --- a/unit_tests/coverage.suite/inline-1.lsl +++ b/unit_tests/coverage.suite/inline-1.lsl @@ -18,7 +18,17 @@ vector f3(integer f3p1, string f3p2) inline } @x; if (f3p2 != "") return <1,1,1>; + do ; while (f4()); + + while (f4()) ; + + for (f3p1=0; f4(); f3p1++, llDie()) + { + integer f3p1 = llGetNumberOfPrims(); + llOwnerSay((string)f3p1); + } + return <0,0,0>; } diff --git a/unit_tests/coverage.suite/inline-1.out b/unit_tests/coverage.suite/inline-1.out index 0bb09a0..ea3f082 100644 --- a/unit_tests/coverage.suite/inline-1.out +++ b/unit_tests/coverage.suite/inline-1.out @@ -50,6 +50,40 @@ default @___rtl__00006; } while (___ret__00002); + @___whl__00001; + integer ___ret__00003; + { + { + ___ret__00003 = llGetLinkNumber(); + jump ___rtl__00007; + } + } + @___rtl__00007; + if (___ret__00003) + { + ; + jump ___whl__00001; + } + f3p1 = 0; + @___for__00001; + integer ___ret__00004; + { + { + ___ret__00004 = llGetLinkNumber(); + jump ___rtl__00008; + } + } + @___rtl__00008; + if (___ret__00004) + { + { + integer f3p1 = llGetNumberOfPrims(); + llOwnerSay((string)f3p1); + } + f3p1++; + llDie(); + jump ___for__00001; + } { ___ret__00001 = <0, 0, 0>; jump ___rtl__00004;