New constants and functions; some refactoring of lslfuncopt

TODO: unit tests
This commit is contained in:
Sei Lisa 2022-05-13 14:41:36 +02:00
parent be479771aa
commit c29475d072
4 changed files with 310 additions and 176 deletions

View file

@ -1,4 +1,4 @@
// Generated by LSL2 Derived Files Generator. Database version: 0.0.20220306000; output module version: 0.0.20140731000 // Generated by LSL2 Derived Files Generator. Database version: 0.0.20220513000; output module version: 0.0.20140731000
integer llAbs( integer val ) integer llAbs( integer val )
float llAcos( float val ) float llAcos( float val )
void llAddToLandBanList( key avatar, float hours ) void llAddToLandBanList( key avatar, float hours )
@ -204,6 +204,7 @@ integer llGetUnixTime( )
integer llGetUsedMemory( ) integer llGetUsedMemory( )
string llGetUsername( key id ) string llGetUsername( key id )
vector llGetVel( ) vector llGetVel( )
list llGetVisualParams( key id, list params )
float llGetWallclock( ) float llGetWallclock( )
void llGiveInventory( key destination, string inventory ) void llGiveInventory( key destination, string inventory )
void llGiveInventoryList( key target, string folder, list inventory ) void llGiveInventoryList( key target, string folder, list inventory )
@ -762,6 +763,9 @@ const integer OBJECT_GROUP = 7
const integer OBJECT_GROUP_TAG = 33 const integer OBJECT_GROUP_TAG = 33
const integer OBJECT_HOVER_HEIGHT = 25 const integer OBJECT_HOVER_HEIGHT = 25
const integer OBJECT_LAST_OWNER_ID = 27 const integer OBJECT_LAST_OWNER_ID = 27
const integer OBJECT_LINK_NUMBER = 46
const integer OBJECT_MASS = 43
const integer OBJECT_MATERIAL = 42
const integer OBJECT_NAME = 1 const integer OBJECT_NAME = 1
const integer OBJECT_OMEGA = 29 const integer OBJECT_OMEGA = 29
const integer OBJECT_OWNER = 6 const integer OBJECT_OWNER = 6
@ -777,9 +781,11 @@ const integer OBJECT_RETURN_PARCEL = 0x1
const integer OBJECT_RETURN_PARCEL_OWNER = 0x2 const integer OBJECT_RETURN_PARCEL_OWNER = 0x2
const integer OBJECT_RETURN_REGION = 0x4 const integer OBJECT_RETURN_REGION = 0x4
const integer OBJECT_REZZER_KEY = 32 const integer OBJECT_REZZER_KEY = 32
const integer OBJECT_REZ_TIME = 45
const integer OBJECT_ROOT = 18 const integer OBJECT_ROOT = 18
const integer OBJECT_ROT = 4 const integer OBJECT_ROT = 4
const integer OBJECT_RUNNING_SCRIPT_COUNT = 9 const integer OBJECT_RUNNING_SCRIPT_COUNT = 9
const integer OBJECT_SCALE = 47
const integer OBJECT_SCRIPT_MEMORY = 11 const integer OBJECT_SCRIPT_MEMORY = 11
const integer OBJECT_SCRIPT_TIME = 12 const integer OBJECT_SCRIPT_TIME = 12
const integer OBJECT_SELECT_COUNT = 37 const integer OBJECT_SELECT_COUNT = 37
@ -788,6 +794,9 @@ const integer OBJECT_SIT_COUNT = 38
const integer OBJECT_STREAMING_COST = 15 const integer OBJECT_STREAMING_COST = 15
const integer OBJECT_TEMP_ATTACHED = 34 const integer OBJECT_TEMP_ATTACHED = 34
const integer OBJECT_TEMP_ON_REZ = 23 const integer OBJECT_TEMP_ON_REZ = 23
const integer OBJECT_TEXT = 44
const integer OBJECT_TEXT_ALPHA = 49
const integer OBJECT_TEXT_COLOR = 48
const integer OBJECT_TOTAL_INVENTORY_COUNT = 31 const integer OBJECT_TOTAL_INVENTORY_COUNT = 31
const integer OBJECT_TOTAL_SCRIPT_COUNT = 10 const integer OBJECT_TOTAL_SCRIPT_COUNT = 10
const integer OBJECT_UNKNOWN_DETAIL = -1 const integer OBJECT_UNKNOWN_DETAIL = -1
@ -808,11 +817,18 @@ const integer PARCEL_COUNT_TEMP = 5
const integer PARCEL_COUNT_TOTAL = 0 const integer PARCEL_COUNT_TOTAL = 0
const integer PARCEL_DETAILS_AREA = 4 const integer PARCEL_DETAILS_AREA = 4
const integer PARCEL_DETAILS_DESC = 1 const integer PARCEL_DETAILS_DESC = 1
const integer PARCEL_DETAILS_FLAGS = 12
const integer PARCEL_DETAILS_GROUP = 3 const integer PARCEL_DETAILS_GROUP = 3
const integer PARCEL_DETAILS_ID = 5 const integer PARCEL_DETAILS_ID = 5
const integer PARCEL_DETAILS_LANDING_LOOKAT = 10
const integer PARCEL_DETAILS_LANDING_POINT = 9
const integer PARCEL_DETAILS_NAME = 0 const integer PARCEL_DETAILS_NAME = 0
const integer PARCEL_DETAILS_OWNER = 2 const integer PARCEL_DETAILS_OWNER = 2
const integer PARCEL_DETAILS_PRIM_CAPACITY = 7
const integer PARCEL_DETAILS_PRIM_USED = 8
const integer PARCEL_DETAILS_SCRIPT_DANGER = 13
const integer PARCEL_DETAILS_SEE_AVATARS = 6 const integer PARCEL_DETAILS_SEE_AVATARS = 6
const integer PARCEL_DETAILS_TP_ROUTING = 11
const integer PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY = 0x08000000 const integer PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY = 0x08000000
const integer PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS = 0x04000000 const integer PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS = 0x04000000
const integer PARCEL_FLAG_ALLOW_CREATE_OBJECTS = 0x00000040 const integer PARCEL_FLAG_ALLOW_CREATE_OBJECTS = 0x00000040
@ -1162,6 +1178,9 @@ const string TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"
const integer TOUCH_INVALID_FACE = -1 const integer TOUCH_INVALID_FACE = -1
const vector TOUCH_INVALID_TEXCOORD = <-1.0, -1.0, 0.0> const vector TOUCH_INVALID_TEXCOORD = <-1.0, -1.0, 0.0>
const vector TOUCH_INVALID_VECTOR = <0.0, 0.0, 0.0> const vector TOUCH_INVALID_VECTOR = <0.0, 0.0, 0.0>
const integer TP_ROUTING_BLOCKED = 0
const integer TP_ROUTING_FREE = 2
const integer TP_ROUTING_LANDINGP = 1
const integer TRAVERSAL_TYPE = 7 const integer TRAVERSAL_TYPE = 7
const integer TRAVERSAL_TYPE_FAST = 1 const integer TRAVERSAL_TYPE_FAST = 1
const integer TRAVERSAL_TYPE_NONE = 2 const integer TRAVERSAL_TYPE_NONE = 2

View file

@ -863,6 +863,9 @@ vector llGetVel()
#- unstable #- unstable
- SEF - SEF
list llGetVisualParams(key id, list params)
- SEF
float llGetWallclock() float llGetWallclock()
- SEF - SEF
- min 0 - min 0

View file

@ -21,6 +21,7 @@ from lslopt.lslcommon import Key, Vector #, Quaternion
from lslopt.lslbasefuncs import ELSLCantCompute, fi,ff,fs,fk,v2f,q2f,fl, \ from lslopt.lslbasefuncs import ELSLCantCompute, fi,ff,fs,fk,v2f,q2f,fl, \
NULL_KEY, ZERO_VECTOR, ZERO_ROTATION, \ NULL_KEY, ZERO_VECTOR, ZERO_ROTATION, \
TOUCH_INVALID_TEXCOORD, cond TOUCH_INVALID_TEXCOORD, cond
#from strutil import unicode
ff, q2f # keep pyflakes happy as these are not used ff, q2f # keep pyflakes happy as these are not used
GetEnvSettings = frozenset({'agent_limit', 'dynamic_pathfinding', 'estate_id' GetEnvSettings = frozenset({'agent_limit', 'dynamic_pathfinding', 'estate_id'
@ -29,9 +30,26 @@ GetEnvSettings = frozenset({'agent_limit', 'dynamic_pathfinding', 'estate_id'
, 'sim_channel', 'sim_version', 'simulator_hostname' , 'sim_channel', 'sim_version', 'simulator_hostname'
, 'region_max_prims' # <http://wiki.secondlife.com/wiki/Release_Notes/Second_Life_RC_Magnum/16#16.11.02.321369> , 'region_max_prims' # <http://wiki.secondlife.com/wiki/Release_Notes/Second_Life_RC_Magnum/16#16.11.02.321369>
, 'region_object_bonus' # <http://wiki.secondlife.com/wiki/Release_Notes/Second_Life_RC_Magnum/16#16.12.03.322072> , 'region_object_bonus' # <http://wiki.secondlife.com/wiki/Release_Notes/Second_Life_RC_Magnum/16#16.12.03.322072>
, 'whisper_range', 'chat_range', 'shout_range' , 'whisper_range', 'chat_range', 'shout_range' #? (jun 2020)
, 'agent_limit_max', 'agent_reserved', 'agent_underserved' # <https://releasenotes.secondlife.com/simulator/2022-04-21.571166.html>
}) })
# Values valid for llGetVisualDetails parameters
GVD_ValidValues = \
{ 33, "height"
, 38, "torso_length"
, 80, "male"
, 198, "heel_height"
, 503, "platform_height"
, 616, "shoe_height"
, 692, "leg_length"
, 693, "arm_length"
, 756, "neck_length"
, 814, "waist_height"
, 842, "hip_length"
, 11001, "hover"
}
xp_error_messages = { xp_error_messages = {
-1:u'unknown error id', -1:u'unknown error id',
0:u'no error', 1:u'exceeded throttle', 2:u'experiences are disabled', 0:u'no error', 1:u'exceeded throttle', 2:u'experiences are disabled',
@ -319,4 +337,18 @@ def llGetStatus(mask):
return 0 return 0
raise ELSLCantCompute raise ELSLCantCompute
def llGetVisualParams(id, params):
id = fk(id)
params = fl(params)
if not cond(id) or params.nt == 'CONST' and not params.ch:
return []
# TODO: This needs to check whether the list is a literal, and whether the
# elements are constant.
# if params.nt == 'LIST':
# for i in params:
# if (i.lower() if type(i) == unicode else i) in GVD_ValidValues:
# raise ELSLCantCompute
# return [u""] * len(params)
raise ELSLCantCompute
# TODO: Add more predictable functions. # TODO: Add more predictable functions.

View file

@ -56,50 +56,64 @@ def OptimizeArgs(node, sym):
params[i].type = 'string' params[i].type = 'string'
# Type of each entry in llGetObjectDetails. # llGetObjectDetails return types
# Last: 41 (OBJECT_ACCOUNT_LEVEL). # Last: 49 (OBJECT_TEXT_ALPHA).
objDetailsTypes = 'issvrvkkkiiififfffkiiiiiiffkiviiksiisiiiii' objDetailsTypes = 'issvrvkkkiiififfffkiiiiiiffkiviiksiisiiiiiifssivvf'
# llGetParcelDetails return types
# Last: 13 (PARCEL_DETAILS_SCRIPT_DANGER)
parcelDetailsTypes = 'sskkikiiivviii'
parcelMediaQTypes = \
{ 4: 'k' # PARCEL_MEDIA_COMMAND_TEXTURE
, 5: 's' # PARCEL_MEDIA_COMMAND_URL
, 10: 's' # PARCEL_MEDIA_COMMAND_TYPE
, 11: 'ii' # PARCEL_MEDIA_COMMAND_SIZE
, 12: 's' # PARCEL_MEDIA_COMMAND_DESC
, 13: 'f' # PARCEL_MEDIA_COMMAND_LOOP
}
# llGetPrimitiveParams and llGetLinkPrimitiveParams return types
primParamsTypes = \ primParamsTypes = \
( False # 0 (unassigned) { # 0 (unassigned)
, 'i*' # 1=PRIM_TYPE_LEGACY 1: 'i*' # 1=PRIM_TYPE_LEGACY
, 'i' # 2=PRIM_MATERIAL , 2: 'i' # 2=PRIM_MATERIAL
, 'i' # 3=PRIM_PHYSICS , 3: 'i' # 3=PRIM_PHYSICS
, 'i' # 4=PRIM_TEMP_ON_REZ , 4: 'i' # 4=PRIM_TEMP_ON_REZ
, 'i' # 5=PRIM_PHANTOM , 5: 'i' # 5=PRIM_PHANTOM
, 'v' # 6=PRIM_POSITION , 6: 'v' # 6=PRIM_POSITION
, 'v' # 7=PRIM_SIZE , 7: 'v' # 7=PRIM_SIZE
, 'r' # 8=PRIM_ROTATION , 8: 'r' # 8=PRIM_ROTATION
, 'i*' # 9=PRIM_TYPE , 9: 'i*' # 9=PRIM_TYPE
, False, False, False, False # 10, 11, 12, 13 (unassigned) # 10 to 16: unassigned
, False, False, False # 14, 15, 16 (unassigned) , 17: 'svvf' # 17=PRIM_TEXTURE
, 'svvf' # 17=PRIM_TEXTURE , 18: 'vf' # 18=PRIM_COLOR
, 'vf' # 18=PRIM_COLOR , 19: 'ii' # 19=PRIM_BUMP_SHINY
, 'ii' # 19=PRIM_BUMP_SHINY , 20: 'i' # 20=PRIM_FULLBRIGHT
, 'i' # 20=PRIM_FULLBRIGHT , 21: 'iiffffv' # 21=PRIM_FLEXIBLE
, 'iiffffv' # 21=PRIM_FLEXIBLE , 22: 'i' # 22=PRIM_TEXGEN
, 'i' # 22=PRIM_TEXGEN , 23: 'ivfff' # 23=PRIM_POINT_LIGHT
, 'ivfff' # 23=PRIM_POINT_LIGHT # 24 :unassigned
, False # 24 (unassigned) , 25: 'f' # 25=PRIM_GLOW
, 'f' # 25=PRIM_GLOW , 26: 'svf' # 26=PRIM_TEXT
, 'svf' # 26=PRIM_TEXT , 27: 's' # 27=PRIM_NAME
, 's' # 27=PRIM_NAME , 28: 's' # 28=PRIM_DESC
, 's' # 28=PRIM_DESC , 29: 'r' # 29=PRIM_ROT_LOCAL
, 'r' # 29=PRIM_ROT_LOCAL , 30: 'i' # 30=PRIM_PHYSICS_SHAPE_TYPE
, 'i' # 30=PRIM_PHYSICS_SHAPE_TYPE # 31: unassigned
, False # 31 (unassigned) , 32: 'vff' # 32=PRIM_OMEGA
, 'vff' # 32=PRIM_OMEGA , 33: 'v' # 33=PRIM_POS_LOCAL
, 'v' # 33=PRIM_POS_LOCAL , 34: '' # 34=PRIM_LINK_TARGET
, '' # 34=PRIM_LINK_TARGET , 35: 'v' # 35=PRIM_SLICE
, 'v' # 35=PRIM_SLICE , 36: 'svvfvii' # 36=PRIM_SPECULAR
, 'svvfvii' # 36=PRIM_SPECULAR , 37: 'svvf' # 37=PRIM_NORMAL
, 'svvf' # 37=PRIM_NORMAL , 38: 'ii' # 38=PRIM_ALPHA_MODE
, 'ii' # 38=PRIM_ALPHA_MODE , 39: 'i' # 39=PRIM_ALLOW_UNSIT
, 'i' # 39=PRIM_ALLOW_UNSIT , 40: 'i' # 40=PRIM_SCRIPTED_SIT_ONLY
, 'i' # 40=PRIM_SCRIPTED_SIT_ONLY , 41: 'ivv' # 41=PRIM_SIT_TARGET
, 'ivv' # 41=PRIM_SIT_TARGET , 42: 'sfff' # 42=PRIM_PROJECTOR
, 'sfff' # 42=PRIM_PROJECTOR }
)
# GetPrimitiveParams parameters with arguments. F=face, L=link. # llGetPrimitiveParams parameters with arguments. F=face, L=link.
primParamsArgs = \ primParamsArgs = \
{ 17: 'F' # 17=PRIM_TEXTURE { 17: 'F' # 17=PRIM_TEXTURE
, 18: 'F' # 18=PRIM_COLOR , 18: 'F' # 18=PRIM_COLOR
@ -113,10 +127,56 @@ primParamsArgs = \
, 38: 'F' # PRIM_ALPHA_MODE , 38: 'F' # PRIM_ALPHA_MODE
} }
# Compatibility: list extraction function / input type (by type's first # llGetPrimMediaParams and llGetLinkMedia return types
# letter), e.g. 'si' means llList2String can extract an integer. # Last: 14 (PRIM_MEDIA_PERMS_CONTROL)
listCompat = frozenset({'ss', 'sk', 'si', 'sf', 'sv', 'sr', 'ks', 'kk', primMediaTypes = 'iissiiiiiiiisii'
'is', 'ii', 'if', 'fs', 'fi', 'ff', 'vv', 'rr'})
# llGetEnvironment return types (not to be confused with llGetEnv)
getEnvTypes = \
{ 15: 'fff'
, 0: 'v'
, 1: 'iii'
, 2: 'vfffvvvi'
, 4: 'fff'
, 5: 'f'
, 6: 'ff'
, 9: 'rffivvv'
, 13: 'f'
, 14: 'rfvivvv'
, 10: 'fff'
, 11: 'fff'
, 8: 'vvv'
, 100: 'f'
, 101: 'vff'
, 102: 'ff'
, 103: 'ii'
, 104: 'v'
, 105: 'ff'
, 106: 'vv'
, 200: 'iif'
}
# Types for llGetVisualDetails parameters (anything not in this list is
# returned as an empty string)
visualDetailsTypes = \
{ 33: 'f', 'height': 'f'
, 38: 'f', 'torso_length': 'f'
, 80: 'f', 'male': 'f'
, 198: 'f', 'heel_height': 'f'
, 503: 'f', 'platform_height': 'f'
, 616: 'f', 'shoe_height': 'f'
, 692: 'f', 'leg_length': 'f'
, 693: 'f', 'arm_length': 'f'
, 756: 'f', 'neck_length': 'f'
, 814: 'f', 'waist_height': 'f'
, 842: 'f', 'hip_length': 'f'
, 11001: 'f', 'hover': 'f'
}
# Compatibility: list extraction function / input type (by type's initial),
# e.g. 'si' means llList2String can extract an integer.
listCompat = {'ss', 'sk', 'si', 'sf', 'sv', 'sr', 'ks', 'kk',
'is', 'ii', 'if', 'fs', 'fi', 'ff', 'vv', 'rr'}
defaultListVals = {'llList2Integer':0, 'llList2Float':0.0, defaultListVals = {'llList2Integer':0, 'llList2Float':0.0,
'llList2String':u'', 'llList2String':u'',
@ -135,7 +195,7 @@ def CastDL2S(self, node, index):
if type(elem) != nr: if type(elem) != nr:
elem = nr(nt='CONST', t=lslcommon.PythonType2LSL[type(elem)], SEF=True, elem = nr(nt='CONST', t=lslcommon.PythonType2LSL[type(elem)], SEF=True,
value=elem) value=elem)
if elem.t in ('vector', 'rotation'): if elem.t in {'vector', 'rotation'}:
return self.Cast(self.Cast(elem, 'list'), 'string') return self.Cast(self.Cast(elem, 'list'), 'string')
return self.Cast(elem, 'string') return self.Cast(elem, 'string')
@ -143,7 +203,7 @@ def CastDL2S(self, node, index):
def FnFree(self, node): def FnFree(self, node):
if node.nt == 'FNCALL': if node.nt == 'FNCALL':
return False return False
if node.nt in ('CONST', 'IDENT', 'FLD'): if node.nt in {'CONST', 'IDENT', 'FLD'}:
return True return True
return all(FnFree(self, node.ch[i]) for i in range(len(node.ch))) return all(FnFree(self, node.ch[i]) for i in range(len(node.ch)))
@ -165,7 +225,7 @@ def OptimizeFunc(self, parent, index):
if name == 'llDumpList2String': if name == 'llDumpList2String':
assert child[0].t == 'list' assert child[0].t == 'list'
if (child[1].nt == 'CONST' if (child[1].nt == 'CONST'
and child[1].t in ('string', 'key') and child[1].t in {'string', 'key'}
and child[1].value == u"" and child[1].value == u""
): ):
# Convert llDumpList2String(expr, "") to (string)(expr) # Convert llDumpList2String(expr, "") to (string)(expr)
@ -197,7 +257,7 @@ def OptimizeFunc(self, parent, index):
# Only optimize if the second param is a very simple expression, # Only optimize if the second param is a very simple expression,
# otherwise the sums can get large. # otherwise the sums can get large.
if child[1].nt in ('CONST', 'IDENT'): if child[1].nt in {'CONST', 'IDENT'}:
threshold = 10 threshold = 10
else: else:
return return
@ -253,8 +313,8 @@ def OptimizeFunc(self, parent, index):
self.FoldTree(parent, index) self.FoldTree(parent, index)
return return
if (name in ('llList2String', 'llList2Key', 'llList2Integer', if (name in {'llList2String', 'llList2Key', 'llList2Integer',
'llList2Float', 'llList2Vector', 'llList2Rot') 'llList2Float', 'llList2Vector', 'llList2Rot'}
and child[1].nt == 'CONST' and child[1].nt == 'CONST'
): ):
# 2nd arg to llList2XXXX must be integer # 2nd arg to llList2XXXX must be integer
@ -278,8 +338,8 @@ def OptimizeFunc(self, parent, index):
parent[index] = nr(nt='CONST', t=node.t, value=const, SEF=True) parent[index] = nr(nt='CONST', t=node.t, value=const, SEF=True)
return return
if listarg.nt == 'FNCALL' \ if listarg.nt == 'FNCALL':
and listarg.name == 'llGetObjectDetails': if listarg.name == 'llGetObjectDetails':
# make it the list argument of llGetObjectDetails # make it the list argument of llGetObjectDetails
listarg = listarg.ch[1] listarg = listarg.ch[1]
@ -300,9 +360,9 @@ def OptimizeFunc(self, parent, index):
finaltype = objDetailsTypes[const:const+1] finaltype = objDetailsTypes[const:const+1]
if (name == 'llList2Key' # checked via listCompat if (name == 'llList2Key' # checked via listCompat
or (name == 'llList2Integer' or (name == 'llList2Integer'
and finaltype in ('s', 'i')) # won't work for floats and finaltype in {'s', 'i'}) # won't work for floats
or (name == 'llList2Float' or (name == 'llList2Float'
and finaltype in ('s', 'i')) # won't work for floats and finaltype in {'s', 'i'}) # won't work for floats
) and (node.t[0] + finaltype) in listCompat: ) and (node.t[0] + finaltype) in listCompat:
# -> (key)((string)llGetObjectDetails...) # -> (key)((string)llGetObjectDetails...)
# or (integer)((string)llGetObjectDetails...) # or (integer)((string)llGetObjectDetails...)
@ -322,8 +382,8 @@ def OptimizeFunc(self, parent, index):
parent[index] = nr(nt='CONST', t=node.t, parent[index] = nr(nt='CONST', t=node.t,
value=defaultListVals[name], SEF=True) value=defaultListVals[name], SEF=True)
elif listarg.nt == 'FNCALL' and listarg.name in ( elif listarg.name in {'llGetPrimitiveParams',
'llGetPrimitiveParams', 'llGetLinkPrimitiveParams'): 'llGetLinkPrimitiveParams'}:
# We're going to work with the primitive params list. # We're going to work with the primitive params list.
listarg = listarg.ch[ listarg = listarg.ch[
0 if listarg.name == 'llGetPrimitiveParams' 0 if listarg.name == 'llGetPrimitiveParams'
@ -347,9 +407,7 @@ def OptimizeFunc(self, parent, index):
# guaranteed to exist, but it's not worth # guaranteed to exist, but it's not worth
# the effort. # the effort.
or param in primParamsArgs or param in primParamsArgs
or param < 0 or param not in primParamsTypes
or param >= len(primParamsTypes)
or primParamsTypes[param] is False
): ):
# Can't process this list. # Can't process this list.
returntypes = '!' returntypes = '!'
@ -359,7 +417,7 @@ def OptimizeFunc(self, parent, index):
if returntypes != '!': if returntypes != '!':
if (len(returntypes) == 1 if (len(returntypes) == 1
and returntypes != '*' and returntypes != '*'
and idx in (0, -1) and idx in {0, -1}
): ):
if name == 'llList2String': if name == 'llList2String':
node.nt = 'CAST' node.nt = 'CAST'
@ -368,9 +426,9 @@ def OptimizeFunc(self, parent, index):
return return
if ((name == 'llList2Key' if ((name == 'llList2Key'
or name == 'llList2Integer' or name == 'llList2Integer'
and returntypes in ('s', 'i') and returntypes in {'s', 'i'}
or name == 'llList2Float' or name == 'llList2Float'
and returntypes in ('s', 'i') and returntypes in {'s', 'i'}
) )
and (node.t[0] + returntypes) and (node.t[0] + returntypes)
in listCompat in listCompat
@ -404,6 +462,28 @@ def OptimizeFunc(self, parent, index):
del returntypes del returntypes
elif listarg.name == 'llGetParcelDetails':
listarg = listarg.ch[1] # 0 is vector pos
# TODO: llList2XXX(llGetParcelDetails)
elif listarg.name == 'llParcelMediaQuery':
listarg = listarg.ch[0]
# TODO: llList2XXX(llParcelMediaQuery)
elif listarg.name in {'llGetPrimMediaParams', 'llGetLinkMedia'}:
listarg = listarg.ch[
1 if listarg.name == 'llGetPrimMediaParams'
else 2]
# TODO: llList2XXX(llGetPrimMediaXXX)
elif listarg.name == 'llGetEnvironment':
listarg = listarg.ch[1] # 0 is vector pos
# TODO: llList2XXX(llGetEnvironment)
elif listarg.name == 'llGetVisualParams':
listarg = listarg.ch[1] # 0 is id
# TODO: llList2XXX(llGetVisualParams)
del listarg, idx, value, tvalue, const del listarg, idx, value, tvalue, const
return return