diff --git a/builtins.txt b/builtins.txt index a019e91..434eeba 100644 --- a/builtins.txt +++ b/builtins.txt @@ -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 ) float llAcos( float val ) void llAddToLandBanList( key avatar, float hours ) @@ -204,6 +204,7 @@ integer llGetUnixTime( ) integer llGetUsedMemory( ) string llGetUsername( key id ) vector llGetVel( ) +list llGetVisualParams( key id, list params ) float llGetWallclock( ) void llGiveInventory( key destination, string 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_HOVER_HEIGHT = 25 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_OMEGA = 29 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_REGION = 0x4 const integer OBJECT_REZZER_KEY = 32 +const integer OBJECT_REZ_TIME = 45 const integer OBJECT_ROOT = 18 const integer OBJECT_ROT = 4 const integer OBJECT_RUNNING_SCRIPT_COUNT = 9 +const integer OBJECT_SCALE = 47 const integer OBJECT_SCRIPT_MEMORY = 11 const integer OBJECT_SCRIPT_TIME = 12 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_TEMP_ATTACHED = 34 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_SCRIPT_COUNT = 10 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_DETAILS_AREA = 4 const integer PARCEL_DETAILS_DESC = 1 +const integer PARCEL_DETAILS_FLAGS = 12 const integer PARCEL_DETAILS_GROUP = 3 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_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_TP_ROUTING = 11 const integer PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY = 0x08000000 const integer PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS = 0x04000000 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 vector TOUCH_INVALID_TEXCOORD = <-1.0, -1.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_FAST = 1 const integer TRAVERSAL_TYPE_NONE = 2 diff --git a/fndata.txt b/fndata.txt index c54c53e..461cdd7 100644 --- a/fndata.txt +++ b/fndata.txt @@ -863,6 +863,9 @@ vector llGetVel() #- unstable - SEF +list llGetVisualParams(key id, list params) +- SEF + float llGetWallclock() - SEF - min 0 diff --git a/lslopt/lslextrafuncs.py b/lslopt/lslextrafuncs.py index 1728fac..1d02467 100644 --- a/lslopt/lslextrafuncs.py +++ b/lslopt/lslextrafuncs.py @@ -21,17 +21,35 @@ from lslopt.lslcommon import Key, Vector #, Quaternion from lslopt.lslbasefuncs import ELSLCantCompute, fi,ff,fs,fk,v2f,q2f,fl, \ NULL_KEY, ZERO_VECTOR, ZERO_ROTATION, \ TOUCH_INVALID_TEXCOORD, cond +#from strutil import unicode ff, q2f # keep pyflakes happy as these are not used GetEnvSettings = frozenset({'agent_limit', 'dynamic_pathfinding', 'estate_id' , 'estate_name', 'frame_number', 'region_cpu_ratio', 'region_idle' , 'region_product_name', 'region_product_sku', 'region_start_time' , 'sim_channel', 'sim_version', 'simulator_hostname' - , 'region_max_prims' # - , 'region_object_bonus' # - , 'whisper_range', 'chat_range', 'shout_range' + , 'region_max_prims' # + , 'region_object_bonus' # + , 'whisper_range', 'chat_range', 'shout_range' #? (jun 2020) + , 'agent_limit_max', 'agent_reserved', 'agent_underserved' # }) +# 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 = { -1:u'unknown error id', 0:u'no error', 1:u'exceeded throttle', 2:u'experiences are disabled', @@ -319,4 +337,18 @@ def llGetStatus(mask): return 0 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. diff --git a/lslopt/lslfuncopt.py b/lslopt/lslfuncopt.py index a38dc75..aaaedf6 100644 --- a/lslopt/lslfuncopt.py +++ b/lslopt/lslfuncopt.py @@ -56,50 +56,64 @@ def OptimizeArgs(node, sym): params[i].type = 'string' -# Type of each entry in llGetObjectDetails. -# Last: 41 (OBJECT_ACCOUNT_LEVEL). -objDetailsTypes = 'issvrvkkkiiififfffkiiiiiiffkiviiksiisiiiii' +# llGetObjectDetails return types +# Last: 49 (OBJECT_TEXT_ALPHA). +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 = \ - ( False # 0 (unassigned) - , 'i*' # 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 - , 'sfff' # 42=PRIM_PROJECTOR - ) -# GetPrimitiveParams parameters with arguments. F=face, L=link. + { # 0 (unassigned) + 1: 'i*' # 1=PRIM_TYPE_LEGACY + , 2: 'i' # 2=PRIM_MATERIAL + , 3: 'i' # 3=PRIM_PHYSICS + , 4: 'i' # 4=PRIM_TEMP_ON_REZ + , 5: 'i' # 5=PRIM_PHANTOM + , 6: 'v' # 6=PRIM_POSITION + , 7: 'v' # 7=PRIM_SIZE + , 8: 'r' # 8=PRIM_ROTATION + , 9: 'i*' # 9=PRIM_TYPE + # 10 to 16: unassigned + , 17: 'svvf' # 17=PRIM_TEXTURE + , 18: 'vf' # 18=PRIM_COLOR + , 19: 'ii' # 19=PRIM_BUMP_SHINY + , 20: 'i' # 20=PRIM_FULLBRIGHT + , 21: 'iiffffv' # 21=PRIM_FLEXIBLE + , 22: 'i' # 22=PRIM_TEXGEN + , 23: 'ivfff' # 23=PRIM_POINT_LIGHT + # 24 :unassigned + , 25: 'f' # 25=PRIM_GLOW + , 26: 'svf' # 26=PRIM_TEXT + , 27: 's' # 27=PRIM_NAME + , 28: 's' # 28=PRIM_DESC + , 29: 'r' # 29=PRIM_ROT_LOCAL + , 30: 'i' # 30=PRIM_PHYSICS_SHAPE_TYPE + # 31: unassigned + , 32: 'vff' # 32=PRIM_OMEGA + , 33: 'v' # 33=PRIM_POS_LOCAL + , 34: '' # 34=PRIM_LINK_TARGET + , 35: 'v' # 35=PRIM_SLICE + , 36: 'svvfvii' # 36=PRIM_SPECULAR + , 37: 'svvf' # 37=PRIM_NORMAL + , 38: 'ii' # 38=PRIM_ALPHA_MODE + , 39: 'i' # 39=PRIM_ALLOW_UNSIT + , 40: 'i' # 40=PRIM_SCRIPTED_SIT_ONLY + , 41: 'ivv' # 41=PRIM_SIT_TARGET + , 42: 'sfff' # 42=PRIM_PROJECTOR + } + +# llGetPrimitiveParams parameters with arguments. F=face, L=link. primParamsArgs = \ { 17: 'F' # 17=PRIM_TEXTURE , 18: 'F' # 18=PRIM_COLOR @@ -113,10 +127,56 @@ primParamsArgs = \ , 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'}) +# llGetPrimMediaParams and llGetLinkMedia return types +# Last: 14 (PRIM_MEDIA_PERMS_CONTROL) +primMediaTypes = 'iissiiiiiiiisii' + +# 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, 'llList2String':u'', @@ -135,7 +195,7 @@ def CastDL2S(self, node, index): if type(elem) != nr: elem = nr(nt='CONST', t=lslcommon.PythonType2LSL[type(elem)], SEF=True, 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(elem, 'string') @@ -143,7 +203,7 @@ def CastDL2S(self, node, index): def FnFree(self, node): if node.nt == 'FNCALL': return False - if node.nt in ('CONST', 'IDENT', 'FLD'): + if node.nt in {'CONST', 'IDENT', 'FLD'}: return True 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': assert child[0].t == 'list' if (child[1].nt == 'CONST' - and child[1].t in ('string', 'key') + and child[1].t in {'string', 'key'} and child[1].value == u"" ): # 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, # otherwise the sums can get large. - if child[1].nt in ('CONST', 'IDENT'): + if child[1].nt in {'CONST', 'IDENT'}: threshold = 10 else: return @@ -253,8 +313,8 @@ def OptimizeFunc(self, parent, index): self.FoldTree(parent, index) return - if (name in ('llList2String', 'llList2Key', 'llList2Integer', - 'llList2Float', 'llList2Vector', 'llList2Rot') + if (name in {'llList2String', 'llList2Key', 'llList2Integer', + 'llList2Float', 'llList2Vector', 'llList2Rot'} and child[1].nt == 'CONST' ): # 2nd arg to llList2XXXX must be integer @@ -278,131 +338,151 @@ def OptimizeFunc(self, parent, index): parent[index] = nr(nt='CONST', t=node.t, value=const, SEF=True) return - if listarg.nt == 'FNCALL' \ - and listarg.name == 'llGetObjectDetails': + if listarg.nt == 'FNCALL': + if listarg.name == 'llGetObjectDetails': - # make it the list argument of llGetObjectDetails - listarg = listarg.ch[1] - 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 - node.nt = 'CAST' - del child[1] - del node.name - 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 - ) and (node.t[0] + finaltype) in listCompat: - # -> (key)((string)llGetObjectDetails...) - # or (integer)((string)llGetObjectDetails...) - node.nt = 'CAST' - del child[1] - del node.name - child[0] = self.Cast(child[0], 'string') - return + # make it the list argument of llGetObjectDetails + listarg = listarg.ch[1] + 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 + node.nt = 'CAST' + del child[1] + del node.name + 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 + ) and (node.t[0] + finaltype) in listCompat: + # -> (key)((string)llGetObjectDetails...) + # or (integer)((string)llGetObjectDetails...) + node.nt = 'CAST' + del child[1] + del node.name + child[0] = self.Cast(child[0], 'string') + 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 - and (node.t[0] + objDetailsTypes[const]) - not in listCompat - ) and node.SEF: - parent[index] = nr(nt='CONST', t=node.t, - value=defaultListVals[name], SEF=True) + # 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 + and (node.t[0] + objDetailsTypes[const]) + not in listCompat + ) and node.SEF: + parent[index] = nr(nt='CONST', t=node.t, + value=defaultListVals[name], SEF=True) - elif listarg.nt == 'FNCALL' and listarg.name in ( - 'llGetPrimitiveParams', 'llGetLinkPrimitiveParams'): - # We're going to work with the primitive params list. - listarg = listarg.ch[ - 0 if listarg.name == 'llGetPrimitiveParams' - 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': - node.nt = 'CAST' - del child[1] - del node.name - return - if ((name == 'llList2Key' - or name == 'llList2Integer' - and returntypes in ('s', 'i') - or name == 'llList2Float' - and returntypes in ('s', 'i') - ) - and (node.t[0] + returntypes) - in listCompat + elif listarg.name in {'llGetPrimitiveParams', + 'llGetLinkPrimitiveParams'}: + # We're going to work with the primitive params list. + listarg = listarg.ch[ + 0 if listarg.name == 'llGetPrimitiveParams' + 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 not in primParamsTypes ): - node.nt = 'CAST' - del child[1] - del node.name - child[0] = nr(nt='CAST', t='string', - ch=[child[0]], SEF=child[0].SEF) - return + # 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': + node.nt = 'CAST' + del child[1] + del node.name + return + if ((name == 'llList2Key' + or name == 'llList2Integer' + and returntypes in {'s', 'i'} + or name == 'llList2Float' + and returntypes in {'s', 'i'} + ) + and (node.t[0] + returntypes) + in listCompat + ): + node.nt = 'CAST' + del child[1] + del node.name + child[0] = nr(nt='CAST', t='string', + ch=[child[0]], SEF=child[0].SEF) + return - # The position of parameters past the first asterisk can't - # be determined, so we only consider parameters before it. - asteriskPos = returntypes.find('*') - if (asteriskPos == -1 - or 0 <= idx < asteriskPos - or asteriskPos - len(returntypes) < idx < 0 - ): - # Check for type incompatibility or index - # out of range. - if idx < 0: - # s[-1:0] doesn't return the last char - # so we make it positive to ensure correctness - idx += len(returntypes) - 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) - return + # The position of parameters past the first asterisk can't + # be determined, so we only consider parameters before it. + asteriskPos = returntypes.find('*') + if (asteriskPos == -1 + or 0 <= idx < asteriskPos + or asteriskPos - len(returntypes) < idx < 0 + ): + # Check for type incompatibility or index + # out of range. + if idx < 0: + # s[-1:0] doesn't return the last char + # so we make it positive to ensure correctness + idx += len(returntypes) + 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) + return - 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 return