diff --git a/lslopt/lsloptimizer.py b/lslopt/lsloptimizer.py index 5dc2ad5..851cbda 100644 --- a/lslopt/lsloptimizer.py +++ b/lslopt/lsloptimizer.py @@ -46,6 +46,16 @@ class optimizer(object): return value return {'nt':'CAST', 't':newtype, 'ch':[value]} + def CopyNode(self, node): + # This is mainly for simple_expr so not a big deal. + ret = node.copy() + if 'ch' in ret: + new = [] + for subnode in ret['ch']: + new.append(self.CopyNode(subnode)) + ret['ch'] = new + return ret + def FoldTree(self, parent, index): """Recursively traverse the tree to fold constants, changing it in place. @@ -512,10 +522,14 @@ class optimizer(object): if nt == 'DECL': if child: - # TODO: Decide if child is a simple_expr. - # If it is, then we should keep the original - # attached to the folded node and use it in the output. - self.FoldTree(child, 0) + # Check if child is a simple_expr. If it is, then we keep the + # original attached to the folded node and use it in the output. + if child[0].pop('Simple', False): + orig = self.CopyNode(child[0]) + self.FoldTree(child, 0) + child[0]['orig'] = orig + else: + self.FoldTree(child, 0) # Remove assignment if integer zero. if node['t'] == 'integer' and child[0]['nt'] == 'CONST' \ and not child[0]['value']: @@ -569,7 +583,7 @@ class optimizer(object): self.FoldTree(tree, idx) self.globalmode = False if not self.IsValidGlobalConstant(tree[idx]): - warning('WARNING: Expression does not collapse to a single constant.') + warning('WARNING: Expression does not resolve to a single constant.') else: self.FoldTree(tree, idx) diff --git a/lslopt/lsloutput.py b/lslopt/lsloutput.py index fc64377..1ca0774 100644 --- a/lslopt/lsloutput.py +++ b/lslopt/lsloutput.py @@ -265,7 +265,10 @@ class outscript(object): if nt == 'DECL': ret = self.dent() + node['t'] + ' ' + node['name'] if child: - ret += ' = ' + self.OutExpr(child[0]) + if 'orig' in child[0]: + ret += ' = ' + self.OutExpr(child[0]['orig']) + else: + ret += ' = ' + self.OutExpr(child[0]) return ret + ';\n' if nt == ';': return self.dent() + ';\n' diff --git a/lslopt/lslparse.py b/lslopt/lslparse.py index fb39cad..9522446 100644 --- a/lslopt/lslparse.py +++ b/lslopt/lslparse.py @@ -1465,7 +1465,7 @@ class parser(object): raise EParseAlreadyDefined(self) self.NextToken() - if self.tok[0] == '=' or self.tok[0] == ';': + if self.tok[0] in ('=', ';'): # This is a variable definition if typ is None: # Typeless variables are not allowed raise EParseSyntax(self) @@ -1474,11 +1474,27 @@ class parser(object): self.NextToken() if self.extendedglobalexpr: self.globalmode = True # Disallow forward globals. - value = self.Parse_expression() # Use advanced expression evaluation. + # Mark backtracking position + pos = self.pos + errorpos = self.errorpos + tok = self.tok + try: + value = self.Parse_simple_expr() + self.expect(';') + value['Simple'] = True # Success - mark it as simple + except EParse: + # Backtrack + self.pos = pos + self.errorpos = errorpos + self.tok = tok + # Use advanced expression evaluation. + value = self.Parse_expression() + self.expect(';') self.globalmode = False # Allow forward globals again. else: - value = self.Parse_simple_expr() # Use LSL's dull global expression. - self.expect(';') + # Use LSL's dull global expression. + value = self.Parse_simple_expr() + self.expect(';') self.NextToken() else: # must be semicolon self.NextToken()