diff --git a/lslopt/lsloptimizer.py b/lslopt/lsloptimizer.py index 1b20b1e..6faff03 100644 --- a/lslopt/lsloptimizer.py +++ b/lslopt/lsloptimizer.py @@ -160,6 +160,7 @@ class optimizer(object): if code0 in self.assign_ops: # TODO: Eliminate redundant operations, e.g. a += 0; etc. + # Consider also e.g. x -= 1 or x -= a transforming it into +=. self.FoldTree(code[3]) return @@ -344,12 +345,6 @@ class optimizer(object): raise Exception('Internal error: This should not happen, node = ' + code0) # pragma: no cover - def Fold(self, code, IsGlobal = True): - assert type(code) == tuple - self.globalmode = IsGlobal and len(code) == 3 - self.FoldTree(code) - del self.globalmode - def optimize(self, symtab, functions): """Optimize the symbolic table symtab in place. Requires a table of predefined functions for folding constants. @@ -357,6 +352,8 @@ class optimizer(object): self.functions = functions self.symtab = symtab + self.globalmode = False + # Fold constants etc. for name in symtab[0]: if name == -1: @@ -364,13 +361,15 @@ class optimizer(object): entry = symtab[0][name] if entry[1] == 'State': for event in entry[2]: - self.Fold(entry[2][event][2], False) + self.FoldTree(entry[2][event][2]) elif type(entry[2]) == tuple: - self.Fold(entry[2]) # global - if len(entry) == 3: + self.globalmode = len(entry) == 3 + self.FoldTree(entry[2]) # global + if self.globalmode: val = entry[2] # Unfold constant if val[0] == 'EXPR' and val[2][0] == CONSTANT: symtab[0][name] = entry[:2] + (val[2][2],) + entry[3:] else: - warning(u'WARNING: Expression does not collapse to a single constant.') + warning('WARNING: Expression does not collapse to a single constant.') + self.globalmode = False diff --git a/lslopt/lsloutput.py b/lslopt/lsloutput.py index 2b89788..aff06ec 100644 --- a/lslopt/lsloutput.py +++ b/lslopt/lsloutput.py @@ -23,7 +23,7 @@ class outscript(object): # is lost. So we emit a warning instead, letting the compiler # report the error in the generated source. if self.globalmode and self.listmode: - warning(u'Illegal combo: Key type inside a global list') + warning('WARNING: Illegal combo: Key type inside a global list') if self.listmode or not self.globalmode: if self.globalmode: pfx = '(key)' @@ -52,6 +52,7 @@ class outscript(object): if '.' not in s: # I couldn't produce one but it's assumed that if it happens, # this code deals with it correctly + # FIXME: Not true, it should handle (float) conversion. return s + exp # pragma: no cover else: if '.' not in s: @@ -60,6 +61,7 @@ class outscript(object): exp = '' while s[-1] != '.' and lslfuncs.F32(float(s[:-1]+exp)) == value: s = s[:-1] + # TODO: Refine. if value >= 0 or self.globalmode or not self.optsigns: return s + exp return '((float)' + s + exp + ')' @@ -282,6 +284,9 @@ class outscript(object): for name in order[0]: sym = symtab[0][name] + #DEBUG + #print name, repr(sym) + ret += self.dent() if sym[1] == 'State': if name == 'default': @@ -299,10 +304,11 @@ class outscript(object): self.indentlevel -= 1 ret += self.dent() + '}\n' - elif len(sym) > 3: # function call + elif len(sym) > 3: # function definition ret += self.OutFunc(sym[1], name, sym[3], symtab[sym[4]], sym[2]) else: # global var + self.globalmode = True ret += sym[1] + ' ' + name if sym[2] is not None: diff --git a/lslopt/lslparse.py b/lslopt/lslparse.py index 73057c7..59a627c 100644 --- a/lslopt/lslparse.py +++ b/lslopt/lslparse.py @@ -6,8 +6,8 @@ import sys, re # reading it. def warning(txt): - assert type(txt) == unicode - sys.stderr.write(txt + u'\n') + assert type(txt) == str + sys.stderr.write(txt + '\n') def isdigit(c): return '0' <= c <= '9' @@ -1818,7 +1818,7 @@ class parser(object): if not line: break match = parse_lin_re.match(line) if not match: - warning(u'Syntax error in builtins.txt: ' + line.decode('utf8')) + warning('Syntax error in builtins.txt: ' + line) continue if match.group(1): # event or function @@ -1836,20 +1836,20 @@ class parser(object): name = match.group(2) if typ == 'event': if name in self.events: - warning(u'Event already defined in bultins.txt, overwriting: ' + name.decode('utf8')) + warning('Event already defined in bultins.txt, overwriting: ' + name) self.events[name] = tuple(args) else: # Library functions go to the functions table. If # they are implemented in lslfuncs.*, they get a # reference to the implementation; otherwise None. if name in self.functions: - warning(u'Function already defined in bultins.txt, overwriting: ' + name.decode('utf8')) + warning('Function already defined in bultins.txt, overwriting: ' + name) self.functions[name] = (typ, tuple(args), getattr(lslfuncs, name, None)) elif match.group(4): # constant name = match.group(5) if name in self.constants: - warning(u'Global already defined in bultins.txt, overwriting: ' + name.decode('utf8')) + warning('Global already defined in bultins.txt, overwriting: ' + name) try: typ = match.group(4) if typ == 'quaternion': @@ -1881,7 +1881,7 @@ class parser(object): #if typ == 'key': # val = Key(val) elif typ == 'key': - warning(u'Key constants not supported in builtins.txt: ' + line.decode('utf8')) + warning('Key constants not supported in builtins.txt: ' + line) val = None elif typ in ('vector', 'rotation'): if val[0:1] != '<' or val[-1:] != '>': @@ -1911,14 +1911,14 @@ class parser(object): val = Vector(val) else: assert typ == 'list' - warning(u'List constants not supported in builtins.txt: ' + line.decode('utf8')) + warning('List constants not supported in builtins.txt: ' + line) val = None if val is not None: self.constants[name] = val except EInternal: - warning(u'Invalid string in builtins.txt: ' + line.decode('utf8')) + warning('Invalid string in builtins.txt: ' + line) except ValueError: - warning(u'Invalid vector syntax in builtins.txt: ' + line.decode('utf8')) + warning('Invalid vector syntax in builtins.txt: ' + line) finally: f.close()