diff --git a/lslopt/lslfoldconst.py b/lslopt/lslfoldconst.py index 739ed8b..486e2a7 100644 --- a/lslopt/lslfoldconst.py +++ b/lslopt/lslfoldconst.py @@ -20,6 +20,7 @@ import lslfuncs import math from lslparse import warning +from lslfuncparams import OptimizeParams class foldconst(object): @@ -179,6 +180,9 @@ class foldconst(object): if (Invertible[0] or Invertible[1]) and ParentIsNegation: # !(!a|b) -> a&-!b or a&!b + # This deals with the part after the first !, transforming + # it into (!a|!!b) so that the outer node can optimize the + # negated version to a simple &. for a in (0, 1): if not Invertible[a]: child[a] = {'nt':'!', 't':'integer', @@ -344,7 +348,7 @@ class foldconst(object): if nt == '!': self.FoldTree(child, 0) self.FoldCond(child, 0, True) - # !! does *not* cancel out (unless in cond), but !!! can be simplified to ! + # !! does *not* cancel out (unless in cond) subexpr = child[0] snt = subexpr['nt'] if 'SEF' in subexpr: @@ -926,8 +930,7 @@ class foldconst(object): if child[idx]['nt'] != 'CONST': CONSTargs = False - # TODO: Find some way to convert keys to "" e.g. llListen("", NULL_KEY, "") - # TODO: Find some way to convert PI to 4 in llSensor[Repeat] + OptimizeParams(node, self.symtab[0][node['name']]) if 'Fn' in self.symtab[0][node['name']]: # Guaranteed to be side-effect free if the children are. if SEFargs: diff --git a/lslopt/lslfuncparams.py b/lslopt/lslfuncparams.py new file mode 100644 index 0000000..06872eb --- /dev/null +++ b/lslopt/lslfuncparams.py @@ -0,0 +1,43 @@ +# (C) Copyright 2015 Sei Lisa. All rights reserved. +# +# This file is part of LSL PyOptimizer. +# +# LSL PyOptimizer is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# LSL PyOptimizer is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LSL PyOptimizer. If not, see . + +# Transform function parameters to shorter equivalents where possible. +# This is dependent on the LSL function library. + +from lslcommon import Key#, Vector, Quaternion +import lslfuncs + +def OptimizeParams(node, sym): + assert node['nt'] == 'FNCALL' + params = node['ch'] + name = node['name'] + + if name in ('llSensor', 'llSensorRepeat'): + # The cutoff value is at a bit less than 3.1275 for some reason, + # but we use 3.14159. + if params[4]['nt'] == 'CONST' and params[4]['t'] == 'float' and params[4]['value'] > 3.14159: + params[4]['value'] = 4.0 + + types = sym['ParamTypes'] + if name != 'llMessageLinked': + # Transform invalid/null keys to "" e.g. llGetOwnerKey(NULL_KEY) -> llGetOwnerKey("") + # llMessageLinked is the exception. + for i in range(len(types)): + if types[i] == 'key': + if params[i]['nt'] == 'CONST': + if not lslfuncs.cond(Key(params[i]['value'])): + params[i]['value'] = u"" diff --git a/lslopt/lsloptimizer.py b/lslopt/lsloptimizer.py index b7c005e..bdcce54 100644 --- a/lslopt/lsloptimizer.py +++ b/lslopt/lsloptimizer.py @@ -18,7 +18,7 @@ # Optimizer class that wraps and calls the other parts. import lslfuncs -from lslfuncs import Key, Vector, Quaternion +from lslcommon import Key, Vector, Quaternion from lslfoldconst import foldconst from lslrenamer import renamer