mirror of
https://github.com/Sei-Lisa/LSL-PyOptimizer
synced 2025-07-01 15:48:21 +00:00
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:
parent
7f6351c5e6
commit
8907a59d5f
3 changed files with 27 additions and 22 deletions
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue