2018-03-23 16:36:45 +01:00
|
|
|
# (C) Copyright 2015-2018 Sei Lisa. All rights reserved.
|
2015-04-21 04:56:09 +02:00
|
|
|
#
|
|
|
|
|
# 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/>.
|
|
|
|
|
|
2017-08-25 20:11:16 +02:00
|
|
|
# Optimize calls to LSL library functions and parameters where possible
|
2015-04-21 04:56:09 +02:00
|
|
|
# This is dependent on the LSL function library.
|
|
|
|
|
|
2017-08-25 20:11:16 +02:00
|
|
|
import lslcommon
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
from lslcommon import Key, Vector, Quaternion, nr
|
2015-04-21 04:56:09 +02:00
|
|
|
import lslfuncs
|
|
|
|
|
|
2017-08-25 20:11:16 +02:00
|
|
|
def OptimizeArgs(node, sym):
|
|
|
|
|
"""Transform function arguments to shorter equivalents where possible."""
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
assert node.nt == 'FNCALL'
|
|
|
|
|
params = node.ch
|
|
|
|
|
name = node.name
|
2015-04-21 04:56:09 +02:00
|
|
|
|
|
|
|
|
if name in ('llSensor', 'llSensorRepeat'):
|
|
|
|
|
# The cutoff value is at a bit less than 3.1275 for some reason,
|
|
|
|
|
# but we use 3.14159.
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
if (params[4].nt == 'CONST' and params[4].t == 'float'
|
|
|
|
|
and params[4].value > 3.14159):
|
|
|
|
|
params[4].value = 4.0
|
2015-04-21 04:56:09 +02:00
|
|
|
|
|
|
|
|
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':
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
if params[i].nt == 'CONST':
|
|
|
|
|
if not lslfuncs.cond(Key(params[i].value)):
|
|
|
|
|
params[i].value = u""
|
|
|
|
|
params[i].type = 'string'
|
2017-08-25 20:11:16 +02:00
|
|
|
|
|
|
|
|
|
2017-10-20 10:18:44 +02:00
|
|
|
# Type of each entry in llGetObjectDetails. Last: 38 (OBJECT_SIT_COUNT).
|
2017-08-25 20:11:16 +02:00
|
|
|
objDetailsTypes = 'issvrvkkkiiififfffkiiiiiiffkiviiksiisii'
|
|
|
|
|
primParamsTypes = \
|
|
|
|
|
( False, False # 0 (unassigned) and 1=PRIM_TYPE_LEGACY
|
|
|
|
|
, 'i' # 2=PRIM_MATERIAL
|
|
|
|
|
, 'i' # 3=PRIM_PHYSICS
|
|
|
|
|
, 'i' # 4=PRIM_TEMP_ON_REZ
|
|
|
|
|
, 'i' # 5=PRIM_PHANTOM
|
|
|
|
|
, 'v' # 6=PRIM_POSITION
|
|
|
|
|
, 'v' # 7=PRIM_SIZE
|
|
|
|
|
, 'r' # 8=PRIM_ROTATION
|
|
|
|
|
, 'i*' # 9=PRIM_TYPE
|
|
|
|
|
, False, False, False, False # 10, 11, 12, 13 (unassigned)
|
|
|
|
|
, False, False, False # 14, 15, 16 (unassigned)
|
|
|
|
|
, 'svvf' # 17=PRIM_TEXTURE
|
|
|
|
|
, 'vf' # 18=PRIM_COLOR
|
|
|
|
|
, 'ii' # 19=PRIM_BUMP_SHINY
|
|
|
|
|
, 'i' # 20=PRIM_FULLBRIGHT
|
|
|
|
|
, 'iiffffv' # 21=PRIM_FLEXIBLE
|
|
|
|
|
, 'i' # 22=PRIM_TEXGEN
|
|
|
|
|
, 'ivfff' # 23=PRIM_POINT_LIGHT
|
|
|
|
|
, False # 24 (unassigned)
|
|
|
|
|
, 'f' # 25=PRIM_GLOW
|
|
|
|
|
, 'svf' # 26=PRIM_TEXT
|
|
|
|
|
, 's' # 27=PRIM_NAME
|
|
|
|
|
, 's' # 28=PRIM_DESC
|
|
|
|
|
, 'r' # 29=PRIM_ROT_LOCAL
|
|
|
|
|
, 'i' # 30=PRIM_PHYSICS_SHAPE_TYPE
|
|
|
|
|
, False # 31 (unassigned)
|
|
|
|
|
, 'vff' # 32=PRIM_OMEGA
|
|
|
|
|
, 'v' # 33=PRIM_POS_LOCAL
|
|
|
|
|
, '' # 34=PRIM_LINK_TARGET
|
|
|
|
|
, 'v' # 35=PRIM_SLICE
|
|
|
|
|
, 'svvfvii' # 36=PRIM_SPECULAR
|
|
|
|
|
, 'svvf' # 37=PRIM_NORMAL
|
|
|
|
|
, 'ii' # 38=PRIM_ALPHA_MODE
|
|
|
|
|
, 'i' # 39=PRIM_ALLOW_UNSIT
|
|
|
|
|
, 'i' # 40=PRIM_SCRIPTED_SIT_ONLY
|
|
|
|
|
, 'ivv' # 41=PRIM_SIT_TARGET
|
|
|
|
|
)
|
|
|
|
|
# Primitive Params with arguments. F=face, L=link.
|
|
|
|
|
primParamsArgs = \
|
|
|
|
|
{ 17: 'F' # 17=PRIM_TEXTURE
|
|
|
|
|
, 18: 'F' # 18=PRIM_COLOR
|
|
|
|
|
, 19: 'F' # 19=PRIM_BUMP_SHINY
|
|
|
|
|
, 20: 'F' # 20=PRIM_FULLBRIGHT
|
|
|
|
|
, 22: 'F' # PRIM_TEXGEN
|
|
|
|
|
, 25: 'F' # PRIM_GLOW
|
|
|
|
|
, 34: 'L' # PRIM_LINK_TARGET
|
|
|
|
|
, 36: 'F' # PRIM_SPECULAR
|
|
|
|
|
, 37: 'F' # PRIM_NORMAL
|
|
|
|
|
, 38: 'F' # PRIM_ALPHA_MODE
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Compatibility: list extraction function / input type (by type's first
|
|
|
|
|
# letter), e.g. 'si' means llList2String can extract an integer.
|
|
|
|
|
listCompat = frozenset({'ss', 'sk', 'si', 'sf', 'sv', 'sr', 'ks', 'kk',
|
|
|
|
|
'is', 'ii', 'if', 'fs', 'fi', 'ff', 'vv', 'rr'})
|
|
|
|
|
|
|
|
|
|
defaultListVals = {'llList2Integer':0, 'llList2Float':0.0,
|
|
|
|
|
'llList2String':u'',
|
2017-08-25 20:45:24 +02:00
|
|
|
# llList2Key is set programmatically in FuncOptSetup
|
2017-08-25 20:11:16 +02:00
|
|
|
#'llList2Key':Key(u''),
|
|
|
|
|
'llList2Vector':Vector((0.,0.,0.)),
|
|
|
|
|
'llList2Rot':Quaternion((0.,0.,0.,1.))}
|
|
|
|
|
|
2018-11-17 10:19:43 +01:00
|
|
|
# Auxiliary function for llDumpList2String optimization
|
|
|
|
|
def CastDL2S(self, node, index):
|
|
|
|
|
"""Cast a list element to string, wrapping it in a list if it's a vector or
|
|
|
|
|
rotation.
|
|
|
|
|
"""
|
|
|
|
|
elem = self.GetListNodeElement(node, index)
|
|
|
|
|
assert elem is not False
|
|
|
|
|
if type(elem) != nr:
|
|
|
|
|
elem = nr(nt='CONST', t=lslcommon.PythonType2LSL[type(elem)], SEF=True,
|
|
|
|
|
value=elem)
|
|
|
|
|
if elem.t in ('vector', 'rotation'):
|
|
|
|
|
return self.Cast(self.Cast(elem, 'list'), 'string')
|
|
|
|
|
return self.Cast(elem, 'string')
|
|
|
|
|
|
2018-11-19 14:13:10 +01:00
|
|
|
# Quick hack to work around lack of cached per-node ContainsFunctions info
|
|
|
|
|
def FnFree(self, node):
|
|
|
|
|
if node.nt == 'FNCALL':
|
|
|
|
|
return False
|
|
|
|
|
if node.nt in ('CONST', 'IDENT', 'FLD'):
|
|
|
|
|
return True
|
|
|
|
|
return all(FnFree(self, node.ch[i]) for i in range(len(node.ch)))
|
|
|
|
|
|
2017-08-25 20:11:16 +02:00
|
|
|
# The 'self' parameter here is the constant folding object.
|
|
|
|
|
def OptimizeFunc(self, parent, index):
|
|
|
|
|
"""Look for possible optimizations taking advantage of the specific LSL
|
|
|
|
|
library function semantics.
|
|
|
|
|
"""
|
|
|
|
|
node = parent[index]
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
assert node.nt == 'FNCALL'
|
|
|
|
|
name = node.name
|
|
|
|
|
child = node.ch
|
2017-08-25 20:11:16 +02:00
|
|
|
if self.optlistlength and name == 'llGetListLength':
|
|
|
|
|
# Convert llGetListLength(expr) to (expr != [])
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
node = nr(nt='CONST', t='list', value=[], SEF=True)
|
|
|
|
|
parent[index] = node = nr(nt='!=', t='integer',
|
|
|
|
|
ch=[child[0], node], SEF=child[0].SEF)
|
2018-11-17 10:19:43 +01:00
|
|
|
|
2017-08-25 20:11:16 +02:00
|
|
|
if name == 'llDumpList2String':
|
2018-11-17 10:19:43 +01:00
|
|
|
assert child[0].t == 'list'
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
if (child[1].nt == 'CONST'
|
|
|
|
|
and child[1].t in ('string', 'key')
|
|
|
|
|
and child[1].value == u""
|
2017-08-25 20:11:16 +02:00
|
|
|
):
|
|
|
|
|
# Convert llDumpList2String(expr, "") to (string)(expr)
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
node.nt = 'CAST'
|
2017-08-25 20:11:16 +02:00
|
|
|
del child[1]
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
del node.name
|
2017-08-25 20:11:16 +02:00
|
|
|
return
|
|
|
|
|
|
2018-11-17 10:19:43 +01:00
|
|
|
if node.SEF:
|
|
|
|
|
# Attempt to convert the function call into a sum of strings when
|
|
|
|
|
# possible and productive.
|
|
|
|
|
|
|
|
|
|
list_len = self.GetListNodeLength(child[0])
|
|
|
|
|
if list_len is False:
|
|
|
|
|
# Can't identify the length, which means we can't optimize.
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if list_len == 0:
|
|
|
|
|
# Empty list -> empty string, no matter the separator
|
|
|
|
|
# (remember we're SEF).
|
|
|
|
|
parent[index] = nr(nt='CONST', t='string', value=u'', SEF=True)
|
|
|
|
|
return
|
|
|
|
|
|
2018-11-19 02:23:23 +01:00
|
|
|
if list_len == 1:
|
|
|
|
|
# A single-element list can always be transformed regardless of
|
|
|
|
|
# the presence of function calls
|
|
|
|
|
parent[index] = CastDL2S(self, child[0], 0)
|
|
|
|
|
return
|
|
|
|
|
|
2018-11-17 10:19:43 +01:00
|
|
|
# Only optimize if the second param is a very simple expression,
|
|
|
|
|
# otherwise the sums can get large.
|
|
|
|
|
if child[1].nt in ('CONST', 'IDENT'):
|
|
|
|
|
threshold = 10
|
|
|
|
|
else:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Apply a threshold for optimizing as a sum.
|
|
|
|
|
if list_len > threshold:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
for i in range(list_len):
|
2018-11-19 14:13:10 +01:00
|
|
|
# Can't be optimized if the list has any function calls in any
|
|
|
|
|
# of the elements, or if they can't be extracted.
|
|
|
|
|
# If an element is a list, we can't optimize it either, as that
|
|
|
|
|
# will produce a side effect (namely an error).
|
2018-11-17 10:19:43 +01:00
|
|
|
val = self.GetListNodeElement(child[0], i)
|
|
|
|
|
if (val is False or type(val) == nr and (val.t == 'list'
|
2018-11-19 14:13:10 +01:00
|
|
|
or not FnFree(self, val))
|
2018-11-17 10:19:43 +01:00
|
|
|
):
|
|
|
|
|
# With our simple analysis, we can't guarantee that
|
|
|
|
|
# whatever the content is, there are no functions.
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
# Optimize to a sum of strings, right-to-left
|
|
|
|
|
i = list_len - 1
|
2018-11-19 02:23:23 +01:00
|
|
|
newnode = CastDL2S(self, child[0], i)
|
2018-11-17 10:19:43 +01:00
|
|
|
while i > 0:
|
|
|
|
|
i -= 1
|
|
|
|
|
newnode = nr(nt='+', t='string', SEF=True,
|
|
|
|
|
ch=[CastDL2S(self, child[0], i),
|
|
|
|
|
nr(nt='+', t='string', SEF=True,
|
2018-11-19 14:07:42 +01:00
|
|
|
ch=[self.Cast(child[1], 'string'), newnode]
|
2018-11-17 10:19:43 +01:00
|
|
|
)
|
|
|
|
|
])
|
|
|
|
|
parent[index] = newnode
|
|
|
|
|
# Re-fold
|
|
|
|
|
self.FoldTree(parent, index)
|
|
|
|
|
return
|
|
|
|
|
|
2017-08-25 20:11:16 +02:00
|
|
|
if (name in ('llList2String', 'llList2Key', 'llList2Integer',
|
|
|
|
|
'llList2Float', 'llList2Vector', 'llList2Rot')
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
and child[1].nt == 'CONST'
|
2017-08-25 20:11:16 +02:00
|
|
|
):
|
|
|
|
|
# 2nd arg to llList2XXXX must be integer
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
assert child[1].t == 'integer'
|
2017-08-25 20:11:16 +02:00
|
|
|
|
|
|
|
|
listarg = child[0]
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
idx = child[1].value
|
2017-08-25 20:11:16 +02:00
|
|
|
value = self.GetListNodeElement(listarg, idx)
|
|
|
|
|
tvalue = self.TypeFromNodeOrConst(value)
|
|
|
|
|
const = self.ConstFromNodeOrConst(value)
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
if const is not False and node.SEF:
|
2017-08-25 20:11:16 +02:00
|
|
|
# Managed to get a constant from a list, even if the
|
|
|
|
|
# list wasn't constant. Handle the type conversion.
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
if (node.t[0] + tvalue[0]) in listCompat:
|
2017-08-25 20:11:16 +02:00
|
|
|
const = lslfuncs.InternalTypecast(const,
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
lslcommon.LSLType2Python[node.t],
|
2017-08-25 20:11:16 +02:00
|
|
|
InList=True, f32=True)
|
|
|
|
|
else:
|
|
|
|
|
const = defaultListVals[name]
|
|
|
|
|
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
parent[index] = nr(nt='CONST', t=node.t, value=const, SEF=True)
|
2017-08-25 20:11:16 +02:00
|
|
|
return
|
|
|
|
|
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
if listarg.nt == 'FNCALL' \
|
|
|
|
|
and listarg.name == 'llGetObjectDetails':
|
2017-08-25 20:11:16 +02:00
|
|
|
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
listarg = listarg.ch[1] # make it the list argument of llGetObjectDetails
|
2017-08-25 20:11:16 +02:00
|
|
|
value = self.GetListNodeElement(listarg, idx)
|
|
|
|
|
tvalue = self.TypeFromNodeOrConst(value)
|
|
|
|
|
const = self.ConstFromNodeOrConst(value)
|
|
|
|
|
if type(const) == int and self.GetListNodeLength(listarg) == 1:
|
|
|
|
|
# Some of these can be handled with a typecast to string.
|
|
|
|
|
if name == 'llList2String':
|
|
|
|
|
# turn the node into a cast of arg 0 to string
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
node.nt = 'CAST'
|
2017-08-25 20:11:16 +02:00
|
|
|
del child[1]
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
del node.name
|
2017-08-25 20:11:16 +02:00
|
|
|
return
|
|
|
|
|
# The other ones that support cast to string then to
|
|
|
|
|
# the final type in some cases (depending on the
|
|
|
|
|
# list type, which we know) are key/int/float.
|
|
|
|
|
finaltype = objDetailsTypes[const:const+1]
|
|
|
|
|
if (name == 'llList2Key' # checked via listCompat
|
|
|
|
|
or (name == 'llList2Integer'
|
|
|
|
|
and finaltype in ('s', 'i')) # won't work for floats
|
|
|
|
|
or (name == 'llList2Float'
|
|
|
|
|
and finaltype in ('s', 'i')) # won't work for floats
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
) and (node.t[0] + finaltype) in listCompat:
|
2017-08-25 20:11:16 +02:00
|
|
|
# -> (key)((string)llGetObjectDetails...)
|
|
|
|
|
# or (integer)((string)llGetObjectDetails...)
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
node.nt = 'CAST'
|
2017-08-25 20:11:16 +02:00
|
|
|
del child[1]
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
del node.name
|
2017-09-22 14:17:56 +02:00
|
|
|
child[0] = self.Cast(child[0], 'string')
|
2017-08-25 20:11:16 +02:00
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Check for type incompatibility or index out of range
|
|
|
|
|
# and replace node with a constant if that's the case
|
|
|
|
|
if (value is False
|
|
|
|
|
or type(const) == int
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
and (node.t[0] + objDetailsTypes[const])
|
2017-08-25 20:11:16 +02:00
|
|
|
not in listCompat
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
) and node.SEF:
|
|
|
|
|
parent[index] = nr(nt='CONST', t=node.t,
|
|
|
|
|
value=defaultListVals[name], SEF=True)
|
2017-08-25 20:11:16 +02:00
|
|
|
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
elif listarg.nt == 'FNCALL' and listarg.name in (
|
2017-08-25 20:11:16 +02:00
|
|
|
'llGetPrimitiveParams', 'llGetLinkPrimitiveParams'):
|
|
|
|
|
# We're going to work with the primitive params list.
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
listarg = listarg.ch[
|
|
|
|
|
0 if listarg.name == 'llGetPrimitiveParams'
|
2017-08-25 20:11:16 +02:00
|
|
|
else 1]
|
|
|
|
|
length = self.GetListNodeLength(listarg)
|
|
|
|
|
if length is not False:
|
|
|
|
|
# Construct a list (string) of return types.
|
|
|
|
|
# A '*' in the list means the type can't be
|
|
|
|
|
# determined past this point (used with PRIM_TYPE).
|
|
|
|
|
i = 0
|
|
|
|
|
returntypes = ''
|
|
|
|
|
while i < length:
|
|
|
|
|
param = self.GetListNodeElement(listarg, i)
|
|
|
|
|
param = self.ConstFromNodeOrConst(param)
|
|
|
|
|
if (param is False
|
|
|
|
|
or type(param) != int
|
|
|
|
|
# Parameters with arguments have
|
|
|
|
|
# side effects (errors).
|
|
|
|
|
# We could check whether there's a face
|
|
|
|
|
# argument and the face is 0, which is
|
|
|
|
|
# guaranteed to exist, but it's not worth
|
|
|
|
|
# the effort.
|
|
|
|
|
or param in primParamsArgs
|
|
|
|
|
or param < 0
|
|
|
|
|
or param >= len(primParamsTypes)
|
|
|
|
|
or primParamsTypes[param] is False
|
|
|
|
|
):
|
|
|
|
|
# Can't process this list.
|
|
|
|
|
returntypes = '!'
|
|
|
|
|
break
|
|
|
|
|
returntypes += primParamsTypes[param]
|
|
|
|
|
i += 1
|
|
|
|
|
if returntypes != '!':
|
|
|
|
|
if (len(returntypes) == 1
|
|
|
|
|
and returntypes != '*'
|
|
|
|
|
and idx in (0, -1)
|
|
|
|
|
):
|
|
|
|
|
if name == 'llList2String':
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
node.nt = 'CAST'
|
2017-08-25 20:11:16 +02:00
|
|
|
del child[1]
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
del node.name
|
2017-08-25 20:11:16 +02:00
|
|
|
return
|
|
|
|
|
if ((name == 'llList2Key'
|
|
|
|
|
or name == 'llList2Integer'
|
|
|
|
|
and returntypes in ('s', 'i')
|
|
|
|
|
or name == 'llList2Float'
|
|
|
|
|
and returntypes in ('s', 'i')
|
|
|
|
|
)
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
and (node.t[0] + returntypes)
|
2017-08-25 20:11:16 +02:00
|
|
|
in listCompat
|
|
|
|
|
):
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
node.nt = 'CAST'
|
2017-08-25 20:11:16 +02:00
|
|
|
del child[1]
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
del node.name
|
|
|
|
|
child[0] = nr(nt='CAST', t='string',
|
|
|
|
|
ch=[child[0]], SEF=child[0].SEF)
|
2017-08-25 20:11:16 +02:00
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if (returntypes.find('*') == -1
|
|
|
|
|
or idx >= 0 and idx < returntypes.find('*')
|
|
|
|
|
or idx < 0 and idx > returntypes.rfind('*')
|
|
|
|
|
- len(returntypes)
|
|
|
|
|
):
|
|
|
|
|
# Check for type incompatibility or index
|
|
|
|
|
# out of range.
|
|
|
|
|
if idx < 0:
|
|
|
|
|
# s[-1:0] doesn't return the last char
|
|
|
|
|
# so we have to compensate
|
|
|
|
|
idx += len(returntypes)
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
if ((node.t[0] + returntypes[idx:idx+1])
|
|
|
|
|
not in listCompat
|
|
|
|
|
and node.SEF):
|
|
|
|
|
parent[index] = nr(nt='CONST', t=node.t,
|
|
|
|
|
value=defaultListVals[name], SEF=True)
|
2017-08-25 20:11:16 +02:00
|
|
|
return
|
|
|
|
|
|
|
|
|
|
del returntypes
|
|
|
|
|
|
|
|
|
|
del listarg, idx, value, tvalue, const
|
2017-08-25 20:22:22 +02:00
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if name == 'llDialog':
|
|
|
|
|
if self.GetListNodeLength(child[2]) == 1:
|
|
|
|
|
button = self.ConstFromNodeOrConst(self.GetListNodeElement(child[2],
|
|
|
|
|
0))
|
|
|
|
|
if type(button) == unicode and button == u'OK':
|
|
|
|
|
# remove the element, as 'OK' is the default button in SL
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
child[2] = nr(nt='CONST', t='list', value=[], SEF=True)
|
2017-08-25 20:22:22 +02:00
|
|
|
return
|
2017-08-25 20:11:16 +02:00
|
|
|
|
2017-09-15 23:13:59 +02:00
|
|
|
if (name == 'llDeleteSubList'
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
or name == 'llListReplaceList' and child[1].nt == 'CONST'
|
|
|
|
|
and not child[1].value
|
2017-09-15 23:13:59 +02:00
|
|
|
):
|
|
|
|
|
# llDeleteSubList(x, 0, -1) -> [] if x is SEF
|
|
|
|
|
# llListReplaceList(x, [], 0, -1) -> [] if x is SEF
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
if (child[0].SEF
|
|
|
|
|
and child[-2].nt == 'CONST' and child[-1].nt == 'CONST'
|
|
|
|
|
and child[-2].value == 0 and child[-1].value == -1
|
2017-09-15 23:13:59 +02:00
|
|
|
):
|
Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.
The new nr (node record) class has built-in dump capabilities, rather than using print_node().
SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).
Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.
A few minor bugfixes were applied while going through the code.
- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
- TODO: ~-~-~-expr -> expr + -3.
- FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
- TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
- FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-03-28 00:19:08 +02:00
|
|
|
parent[index] = nr(nt='CONST', t='list', value=[], SEF=True)
|
2017-09-15 23:13:59 +02:00
|
|
|
return
|
|
|
|
|
|
2017-08-25 20:11:16 +02:00
|
|
|
def FuncOptSetup():
|
|
|
|
|
# Patch the default values list for LSO
|
|
|
|
|
if lslcommon.LSO:
|
|
|
|
|
defaultListVals['llList2Key'] = Key(lslfuncs.NULL_KEY)
|
|
|
|
|
else:
|
|
|
|
|
defaultListVals['llList2Key'] = Key(u"")
|