Fix remaining bug in optimizer, and minor fixes.

- Get rid of Fold().

- Handle globalmode properly. It was sometimes active during function calls.

- Change all warning() calls to not use Unicode, just in case the output is redirected to file.

- Cosmetic fixes and TODO items.
This commit is contained in:
Sei Lisa 2014-07-27 23:33:20 +02:00
parent 7f6351c5e6
commit 8907a59d5f
3 changed files with 27 additions and 22 deletions

View file

@ -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

View file

@ -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:

View file

@ -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()