Implement library function parameter optimization.

So far only two kinds: angle in llSensor[Repeat] and null keys in functions that take a key parameter.

Closes two TODOs.
This commit is contained in:
Sei Lisa 2015-04-21 04:56:09 +02:00
parent 595286f22a
commit d58bc2d350
3 changed files with 50 additions and 4 deletions

View file

@ -20,6 +20,7 @@
import lslfuncs import lslfuncs
import math import math
from lslparse import warning from lslparse import warning
from lslfuncparams import OptimizeParams
class foldconst(object): class foldconst(object):
@ -179,6 +180,9 @@ class foldconst(object):
if (Invertible[0] or Invertible[1]) and ParentIsNegation: if (Invertible[0] or Invertible[1]) and ParentIsNegation:
# !(!a|b) -> a&-!b or a&!b # !(!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): for a in (0, 1):
if not Invertible[a]: if not Invertible[a]:
child[a] = {'nt':'!', 't':'integer', child[a] = {'nt':'!', 't':'integer',
@ -344,7 +348,7 @@ class foldconst(object):
if nt == '!': if nt == '!':
self.FoldTree(child, 0) self.FoldTree(child, 0)
self.FoldCond(child, 0, True) 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] subexpr = child[0]
snt = subexpr['nt'] snt = subexpr['nt']
if 'SEF' in subexpr: if 'SEF' in subexpr:
@ -926,8 +930,7 @@ class foldconst(object):
if child[idx]['nt'] != 'CONST': if child[idx]['nt'] != 'CONST':
CONSTargs = False CONSTargs = False
# TODO: Find some way to convert keys to "" e.g. llListen("", NULL_KEY, "") OptimizeParams(node, self.symtab[0][node['name']])
# TODO: Find some way to convert PI to 4 in llSensor[Repeat]
if 'Fn' in self.symtab[0][node['name']]: if 'Fn' in self.symtab[0][node['name']]:
# Guaranteed to be side-effect free if the children are. # Guaranteed to be side-effect free if the children are.
if SEFargs: if SEFargs:

43
lslopt/lslfuncparams.py Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
# 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""

View file

@ -18,7 +18,7 @@
# Optimizer class that wraps and calls the other parts. # Optimizer class that wraps and calls the other parts.
import lslfuncs import lslfuncs
from lslfuncs import Key, Vector, Quaternion from lslcommon import Key, Vector, Quaternion
from lslfoldconst import foldconst from lslfoldconst import foldconst
from lslrenamer import renamer from lslrenamer import renamer