summaryrefslogtreecommitdiff
path: root/indra/lscript/lscript_compile
diff options
context:
space:
mode:
authorJames Cook <james@lindenlab.com>2007-01-02 08:33:20 +0000
committerJames Cook <james@lindenlab.com>2007-01-02 08:33:20 +0000
commit420b91db29485df39fd6e724e782c449158811cb (patch)
treeb471a94563af914d3ed3edd3e856d21cb1b69945 /indra/lscript/lscript_compile
Print done when done.
Diffstat (limited to 'indra/lscript/lscript_compile')
-rw-r--r--indra/lscript/lscript_compile/indra.l834
-rw-r--r--indra/lscript/lscript_compile/indra.y1680
-rw-r--r--indra/lscript/lscript_compile/lscript_alloc.cpp8
-rw-r--r--indra/lscript/lscript_compile/lscript_bytecode.cpp299
-rw-r--r--indra/lscript/lscript_compile/lscript_bytecode.h71
-rw-r--r--indra/lscript/lscript_compile/lscript_error.cpp77
-rw-r--r--indra/lscript/lscript_compile/lscript_error.h132
-rw-r--r--indra/lscript/lscript_compile/lscript_heap.cpp49
-rw-r--r--indra/lscript/lscript_compile/lscript_heap.h40
-rw-r--r--indra/lscript/lscript_compile/lscript_resource.cpp18
-rw-r--r--indra/lscript/lscript_compile/lscript_resource.h21
-rw-r--r--indra/lscript/lscript_compile/lscript_scope.cpp13
-rw-r--r--indra/lscript/lscript_compile/lscript_scope.h388
-rw-r--r--indra/lscript/lscript_compile/lscript_tree.cpp9998
-rw-r--r--indra/lscript/lscript_compile/lscript_tree.h2279
-rw-r--r--indra/lscript/lscript_compile/lscript_typecheck.cpp562
-rw-r--r--indra/lscript/lscript_compile/lscript_typecheck.h100
17 files changed, 16569 insertions, 0 deletions
diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l
new file mode 100644
index 0000000000..2ee219a8ee
--- /dev/null
+++ b/indra/lscript/lscript_compile/indra.l
@@ -0,0 +1,834 @@
+D [-]?[0-9]
+N [0-9]
+L [a-zA-Z_]
+H [a-fA-F0-9]
+E [Ee][+-]?{D}+
+FS (f|F)
+%e 8000
+%n 4000
+%p 5000
+
+%{
+#include <stdio.h>
+#include "stdtypes.h"
+#include "llmath.h"
+#include "lscript_tree.h"
+#include "lscript_typecheck.h"
+#include "lscript_resource.h"
+#include "llfile.h"
+#if LL_WINDOWS
+#include "ytab.h"
+#else
+#include "indra.y.h"
+#endif
+#include "lltimer.h"
+#include "indra_constants.h"
+#include "llagentconstants.h"
+#include "lllslconstants.h"
+#include "lluuid.h"
+#include "llassetstorage.h"
+#include "llpartdata.h"
+#include "llvehicleparams.h"
+#include "llpermissionsflags.h"
+#include "llfollowcamparams.h"
+#include "llparcelflags.h"
+#include "llregionflags.h"
+#include "lscript_http.h"
+
+void count();
+void comment();
+void parse_string();
+
+#define YYLMAX 16384
+#define YY_NEVER_INTERACTIVE 1 /* stops flex from calling isatty() */
+
+#if defined(__cplusplus)
+extern "C" { int yylex( void ); }
+extern "C" { int yyparse( void ); }
+extern "C" { int yyerror(const char *fmt, ...); }
+#endif
+
+%}
+
+%%
+"//" { gInternalLine++; gInternalColumn = 0; comment(); }
+
+"integer" { count(); return(INTEGER); }
+"float" { count(); return(FLOAT_TYPE); }
+"string" { count(); return(STRING); }
+"key" { count(); return(LLKEY); }
+"vector" { count(); return(VECTOR); }
+"quaternion" { count(); return(QUATERNION); }
+"rotation" { count(); return(QUATERNION); }
+"list" { count(); return(LIST); }
+
+"default" { count(); yylval.sval = new char[strlen(yytext) + 1]; strcpy(yylval.sval, yytext); return(STATE_DEFAULT); }
+"state" { count(); return(STATE); }
+"event" { count(); return(EVENT); }
+"jump" { count(); return(JUMP); }
+"return" { count(); return(RETURN); }
+"if" { count(); return(IF); }
+"else" { count(); return(ELSE); }
+"for" { count(); return(FOR); }
+"do" { count(); return(DO); }
+"while" { count(); return(WHILE); }
+
+"state_entry" { count(); return(STATE_ENTRY); }
+"state_exit" { count(); return(STATE_EXIT); }
+"touch_start" { count(); return(TOUCH_START); }
+"touch" { count(); return(TOUCH); }
+"touch_end" { count(); return(TOUCH_END); }
+"collision_start" { count(); return(COLLISION_START); }
+"collision" { count(); return(COLLISION); }
+"collision_end" { count(); return(COLLISION_END); }
+"land_collision_start" { count(); return(LAND_COLLISION_START); }
+"land_collision" { count(); return(LAND_COLLISION); }
+"land_collision_end" { count(); return(LAND_COLLISION_END); }
+"timer" { count(); return(TIMER); }
+"listen" { count(); return(CHAT); }
+"sensor" { count(); return(SENSOR); }
+"no_sensor" { count(); return(NO_SENSOR); }
+"control" { count(); return(CONTROL); }
+"print" { count(); return(PRINT); }
+"at_target" { count(); return(AT_TARGET); }
+"not_at_target" { count(); return(NOT_AT_TARGET); }
+"at_rot_target" { count(); return(AT_ROT_TARGET); }
+"not_at_rot_target" { count(); return(NOT_AT_ROT_TARGET); }
+"money" { count(); return(MONEY); }
+"email" { count(); return(EMAIL); }
+"run_time_permissions" { count(); return(RUN_TIME_PERMISSIONS); }
+"changed" { count(); return(INVENTORY); }
+"attach" { count(); return(ATTACH); }
+"dataserver" { count(); return(DATASERVER); }
+"moving_start" { count(); return(MOVING_START); }
+"moving_end" { count(); return(MOVING_END); }
+"link_message" { count(); return(LINK_MESSAGE); }
+"on_rez" { count(); return(REZ); }
+"object_rez" { count(); return(OBJECT_REZ); }
+"remote_data" { count(); return(REMOTE_DATA); }
+"http_response" { count(); return(HTTP_RESPONSE); }
+"." { count(); return(PERIOD); }
+
+
+0[xX]{H}+ { count(); yylval.ival = strtoul(yytext, NULL, 0); return(INTEGER_CONSTANT); }
+{D}+ { count(); yylval.ival = strtoul(yytext, NULL, 10); return(INTEGER_CONSTANT); }
+"TRUE" { count(); yylval.ival = 1; return(INTEGER_TRUE); }
+"FALSE" { count(); yylval.ival = 0; return(INTEGER_FALSE); }
+"STATUS_PHYSICS" { count(); yylval.ival = 0x1; return(INTEGER_CONSTANT); }
+"STATUS_ROTATE_X" { count(); yylval.ival = 0x2; return(INTEGER_CONSTANT); }
+"STATUS_ROTATE_Y" { count(); yylval.ival = 0x4; return(INTEGER_CONSTANT); }
+"STATUS_ROTATE_Z" { count(); yylval.ival = 0x8; return(INTEGER_CONSTANT); }
+"STATUS_PHANTOM" { count(); yylval.ival = 0x10; return(INTEGER_CONSTANT); }
+"STATUS_SANDBOX" { count(); yylval.ival = 0x20; return(INTEGER_CONSTANT); }
+"STATUS_BLOCK_GRAB" { count(); yylval.ival = 0x40; return(INTEGER_CONSTANT); }
+"STATUS_DIE_AT_EDGE" { count(); yylval.ival = 0x80; return(INTEGER_CONSTANT); }
+"STATUS_RETURN_AT_EDGE" { count(); yylval.ival = 0x100; return(INTEGER_CONSTANT); }
+"STATUS_CAST_SHADOWS" { count(); yylval.ival = 0x200; return(INTEGER_CONSTANT); }
+
+"AGENT_FLYING" { count(); yylval.ival = AGENT_FLYING; return(INTEGER_CONSTANT); }
+"AGENT_ATTACHMENTS" { count(); yylval.ival = AGENT_ATTACHMENTS; return(INTEGER_CONSTANT); }
+"AGENT_SCRIPTED" { count(); yylval.ival = AGENT_SCRIPTED; return(INTEGER_CONSTANT); }
+"AGENT_MOUSELOOK" { count(); yylval.ival = AGENT_MOUSELOOK; return(INTEGER_CONSTANT); }
+"AGENT_SITTING" { count(); yylval.ival = AGENT_SITTING; return(INTEGER_CONSTANT); }
+"AGENT_ON_OBJECT" { count(); yylval.ival = AGENT_ON_OBJECT; return(INTEGER_CONSTANT); }
+"AGENT_AWAY" { count(); yylval.ival = AGENT_AWAY; return(INTEGER_CONSTANT); }
+"AGENT_WALKING" { count(); yylval.ival = AGENT_WALKING; return(INTEGER_CONSTANT); }
+"AGENT_IN_AIR" { count(); yylval.ival = AGENT_IN_AIR; return(INTEGER_CONSTANT); }
+"AGENT_TYPING" { count(); yylval.ival = AGENT_TYPING; return(INTEGER_CONSTANT); }
+"AGENT_CROUCHING" { count(); yylval.ival = AGENT_CROUCHING; return(INTEGER_CONSTANT); }
+"AGENT_BUSY" { count(); yylval.ival = AGENT_BUSY; return(INTEGER_CONSTANT); }
+"AGENT_ALWAYS_RUN" { count(); yylval.ival = AGENT_ALWAYS_RUN; return(INTEGER_CONSTANT); }
+
+"CAMERA_PITCH" { count(); yylval.ival = FOLLOWCAM_PITCH; return(INTEGER_CONSTANT); }
+"CAMERA_FOCUS_OFFSET" { count(); yylval.ival = FOLLOWCAM_FOCUS_OFFSET; return (INTEGER_CONSTANT); }
+"CAMERA_POSITION_LAG" { count(); yylval.ival = FOLLOWCAM_POSITION_LAG; return (INTEGER_CONSTANT); }
+"CAMERA_FOCUS_LAG" { count(); yylval.ival = FOLLOWCAM_FOCUS_LAG; return (INTEGER_CONSTANT); }
+"CAMERA_DISTANCE" { count(); yylval.ival = FOLLOWCAM_DISTANCE; return (INTEGER_CONSTANT); }
+"CAMERA_BEHINDNESS_ANGLE" { count(); yylval.ival = FOLLOWCAM_BEHINDNESS_ANGLE; return (INTEGER_CONSTANT); }
+"CAMERA_BEHINDNESS_LAG" { count(); yylval.ival = FOLLOWCAM_BEHINDNESS_LAG; return (INTEGER_CONSTANT); }
+"CAMERA_POSITION_THRESHOLD" { count(); yylval.ival = FOLLOWCAM_POSITION_THRESHOLD; return (INTEGER_CONSTANT); }
+"CAMERA_FOCUS_THRESHOLD" { count(); yylval.ival = FOLLOWCAM_FOCUS_THRESHOLD; return (INTEGER_CONSTANT); }
+"CAMERA_ACTIVE" { count(); yylval.ival = FOLLOWCAM_ACTIVE; return (INTEGER_CONSTANT); }
+"CAMERA_POSITION" { count(); yylval.ival = FOLLOWCAM_POSITION; return (INTEGER_CONSTANT); }
+"CAMERA_FOCUS" { count(); yylval.ival = FOLLOWCAM_FOCUS; return (INTEGER_CONSTANT); }
+"CAMERA_POSITION_LOCKED" { count(); yylval.ival = FOLLOWCAM_POSITION_LOCKED; return (INTEGER_CONSTANT); }
+"CAMERA_FOCUS_LOCKED" { count(); yylval.ival = FOLLOWCAM_FOCUS_LOCKED; return (INTEGER_CONSTANT); }
+
+"ANIM_ON" { count(); yylval.ival = 0x1; return(INTEGER_CONSTANT); }
+"LOOP" { count(); yylval.ival = 0x2; return(INTEGER_CONSTANT); }
+"REVERSE" { count(); yylval.ival = 0x4; return(INTEGER_CONSTANT); }
+"PING_PONG" { count(); yylval.ival = 0x8; return(INTEGER_CONSTANT); }
+"SMOOTH" { count(); yylval.ival = 0x10; return(INTEGER_CONSTANT); }
+"ROTATE" { count(); yylval.ival = 0x20; return(INTEGER_CONSTANT); }
+"SCALE" { count(); yylval.ival = 0x40; return(INTEGER_CONSTANT); }
+
+"ALL_SIDES" { count(); yylval.ival = LSL_ALL_SIDES; return(INTEGER_CONSTANT); }
+"LINK_ROOT" { count(); yylval.ival = LSL_LINK_ROOT; return(INTEGER_CONSTANT); }
+"LINK_SET" { count(); yylval.ival = LSL_LINK_SET; return(INTEGER_CONSTANT); }
+"LINK_ALL_OTHERS" { count(); yylval.ival = LSL_LINK_ALL_OTHERS; return(INTEGER_CONSTANT); }
+"LINK_ALL_CHILDREN" { count(); yylval.ival = LSL_LINK_ALL_CHILDREN; return(INTEGER_CONSTANT); }
+"LINK_THIS" { count(); yylval.ival = LSL_LINK_THIS; return(INTEGER_CONSTANT); }
+
+"AGENT" { count(); yylval.ival = 0x1; return(INTEGER_CONSTANT); }
+"ACTIVE" { count(); yylval.ival = 0x2; return(INTEGER_CONSTANT); }
+"PASSIVE" { count(); yylval.ival = 0x4; return(INTEGER_CONSTANT); }
+"SCRIPTED" { count(); yylval.ival = 0x8; return(INTEGER_CONSTANT); }
+
+"CONTROL_FWD" { count(); yylval.ival = AGENT_CONTROL_AT_POS; return(INTEGER_CONSTANT); }
+"CONTROL_BACK" { count(); yylval.ival = AGENT_CONTROL_AT_NEG; return(INTEGER_CONSTANT); }
+"CONTROL_LEFT" { count(); yylval.ival = AGENT_CONTROL_LEFT_POS; return(INTEGER_CONSTANT); }
+"CONTROL_RIGHT" { count(); yylval.ival = AGENT_CONTROL_LEFT_NEG; return(INTEGER_CONSTANT); }
+"CONTROL_ROT_LEFT" { count(); yylval.ival = AGENT_CONTROL_YAW_POS; return(INTEGER_CONSTANT); }
+"CONTROL_ROT_RIGHT" { count(); yylval.ival = AGENT_CONTROL_YAW_NEG; return(INTEGER_CONSTANT); }
+"CONTROL_UP" { count(); yylval.ival = AGENT_CONTROL_UP_POS; return(INTEGER_CONSTANT); }
+"CONTROL_DOWN" { count(); yylval.ival = AGENT_CONTROL_UP_NEG; return(INTEGER_CONSTANT); }
+"CONTROL_LBUTTON" { count(); yylval.ival = AGENT_CONTROL_LBUTTON_DOWN; return(INTEGER_CONSTANT); }
+"CONTROL_ML_LBUTTON" { count(); yylval.ival = AGENT_CONTROL_ML_LBUTTON_DOWN; return(INTEGER_CONSTANT); }
+
+"PERMISSION_DEBIT" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_DEBIT]; return(INTEGER_CONSTANT); }
+"PERMISSION_TAKE_CONTROLS" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TAKE_CONTROLS]; return(INTEGER_CONSTANT); }
+"PERMISSION_REMAP_CONTROLS" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_REMAP_CONTROLS]; return(INTEGER_CONSTANT); }
+"PERMISSION_TRIGGER_ANIMATION" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TRIGGER_ANIMATION]; return(INTEGER_CONSTANT); }
+"PERMISSION_ATTACH" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_ATTACH]; return(INTEGER_CONSTANT); }
+"PERMISSION_RELEASE_OWNERSHIP" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_RELEASE_OWNERSHIP]; return(INTEGER_CONSTANT); }
+"PERMISSION_CHANGE_LINKS" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_CHANGE_LINKS]; return(INTEGER_CONSTANT); }
+"PERMISSION_CHANGE_JOINTS" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_CHANGE_JOINTS]; return(INTEGER_CONSTANT); }
+"PERMISSION_CHANGE_PERMISSIONS" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_CHANGE_PERMISSIONS]; return(INTEGER_CONSTANT); }
+"PERMISSION_TRACK_CAMERA" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TRACK_CAMERA]; return(INTEGER_CONSTANT); }
+"PERMISSION_CONTROL_CAMERA" { count(); yylval.ival = LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_CONTROL_CAMERA]; return(INTEGER_CONSTANT); }
+
+"INVENTORY_TEXTURE" { count(); yylval.ival = LLAssetType::AT_TEXTURE; return(INTEGER_CONSTANT); }
+"INVENTORY_SOUND" { count(); yylval.ival = LLAssetType::AT_SOUND; return(INTEGER_CONSTANT); }
+"INVENTORY_OBJECT" { count(); yylval.ival = LLAssetType::AT_OBJECT; return(INTEGER_CONSTANT); }
+"INVENTORY_SCRIPT" { count(); yylval.ival = LLAssetType::AT_LSL_TEXT; return(INTEGER_CONSTANT); }
+"INVENTORY_LANDMARK" { count(); yylval.ival = LLAssetType::AT_LANDMARK; return(INTEGER_CONSTANT); }
+"INVENTORY_CLOTHING" { count(); yylval.ival = LLAssetType::AT_CLOTHING; return(INTEGER_CONSTANT); }
+"INVENTORY_NOTECARD" { count(); yylval.ival = LLAssetType::AT_NOTECARD; return(INTEGER_CONSTANT); }
+"INVENTORY_BODYPART" { count(); yylval.ival = LLAssetType::AT_BODYPART; return(INTEGER_CONSTANT); }
+"INVENTORY_ANIMATION" { count(); yylval.ival = LLAssetType::AT_ANIMATION; return(INTEGER_CONSTANT); }
+"INVENTORY_GESTURE" { count(); yylval.ival = LLAssetType::AT_GESTURE; return(INTEGER_CONSTANT); }
+"INVENTORY_ALL" { count(); yylval.ival = LLAssetType::AT_NONE; return(INTEGER_CONSTANT); }
+"INVENTORY_NONE" { count(); yylval.ival = LLAssetType::AT_NONE; return(INTEGER_CONSTANT); }
+
+"CHANGED_INVENTORY" { count(); yylval.ival = 0x1; return(INTEGER_CONSTANT); }
+"CHANGED_COLOR" { count(); yylval.ival = 0x2; return(INTEGER_CONSTANT); }
+"CHANGED_SHAPE" { count(); yylval.ival = 0x4; return(INTEGER_CONSTANT); }
+"CHANGED_SCALE" { count(); yylval.ival = 0x8; return(INTEGER_CONSTANT); }
+"CHANGED_TEXTURE" { count(); yylval.ival = 0x10; return(INTEGER_CONSTANT); }
+"CHANGED_LINK" { count(); yylval.ival = 0x20; return(INTEGER_CONSTANT); }
+"CHANGED_ALLOWED_DROP" { count(); yylval.ival = 0x40; return(INTEGER_CONSTANT); }
+"CHANGED_OWNER" { count(); yylval.ival = 0x80; return(INTEGER_CONSTANT); }
+"CHANGED_REGION" { count(); yylval.ival = 0x100; return(INTEGER_CONSTANT); }
+"CHANGED_TELEPORT" { count(); yylval.ival = 0x200; return(INTEGER_CONSTANT); }
+
+"TYPE_INTEGER" { count(); yylval.ival = LST_INTEGER; return(INTEGER_CONSTANT); }
+"TYPE_FLOAT" { count(); yylval.ival = LST_FLOATINGPOINT; return(INTEGER_CONSTANT); }
+"TYPE_STRING" { count(); yylval.ival = LST_STRING; return(INTEGER_CONSTANT); }
+"TYPE_KEY" { count(); yylval.ival = LST_KEY; return(INTEGER_CONSTANT); }
+"TYPE_VECTOR" { count(); yylval.ival = LST_VECTOR; return(INTEGER_CONSTANT); }
+"TYPE_ROTATION" { count(); yylval.ival = LST_QUATERNION; return(INTEGER_CONSTANT); }
+"TYPE_INVALID" { count(); yylval.ival = LST_NULL; return(INTEGER_CONSTANT); }
+
+"NULL_KEY" { yylval.sval = new char[UUID_STR_LENGTH]; strcpy(yylval.sval, "00000000-0000-0000-0000-000000000000"); return(STRING_CONSTANT); }
+"EOF" { yylval.sval = new char[UUID_STR_LENGTH]; strcpy(yylval.sval, "\n\n\n"); return(STRING_CONSTANT); }
+
+"PI" { count(); yylval.fval = F_PI; return(FP_CONSTANT); }
+"TWO_PI" { count(); yylval.fval = F_TWO_PI; return(FP_CONSTANT); }
+"PI_BY_TWO" { count(); yylval.fval = F_PI_BY_TWO; return(FP_CONSTANT); }
+"DEG_TO_RAD" { count(); yylval.fval = DEG_TO_RAD; return(FP_CONSTANT); }
+"RAD_TO_DEG" { count(); yylval.fval = RAD_TO_DEG; return(FP_CONSTANT); }
+"SQRT2" { count(); yylval.fval = F_SQRT2; return(FP_CONSTANT); }
+
+"DEBUG_CHANNEL" { count(); yylval.ival = CHAT_CHANNEL_DEBUG; return(INTEGER_CONSTANT); }
+"PUBLIC_CHANNEL" { count(); yylval.ival = 0; return(INTEGER_CONSTANT); }
+
+"ZERO_VECTOR" { count(); return(ZERO_VECTOR); }
+"ZERO_ROTATION" { count(); return(ZERO_ROTATION); }
+
+"ATTACH_CHEST" { count(); yylval.ival = 1; return(INTEGER_CONSTANT); }
+"ATTACH_HEAD" { count(); yylval.ival = 2; return(INTEGER_CONSTANT); }
+"ATTACH_LSHOULDER" { count(); yylval.ival = 3; return(INTEGER_CONSTANT); }
+"ATTACH_RSHOULDER" { count(); yylval.ival = 4; return(INTEGER_CONSTANT); }
+"ATTACH_LHAND" { count(); yylval.ival = 5; return(INTEGER_CONSTANT); }
+"ATTACH_RHAND" { count(); yylval.ival = 6; return(INTEGER_CONSTANT); }
+"ATTACH_LFOOT" { count(); yylval.ival = 7; return(INTEGER_CONSTANT); }
+"ATTACH_RFOOT" { count(); yylval.ival = 8; return(INTEGER_CONSTANT); }
+"ATTACH_BACK" { count(); yylval.ival = 9; return(INTEGER_CONSTANT); }
+"ATTACH_PELVIS" { count(); yylval.ival = 10; return(INTEGER_CONSTANT); }
+"ATTACH_MOUTH" { count(); yylval.ival = 11; return(INTEGER_CONSTANT); }
+"ATTACH_CHIN" { count(); yylval.ival = 12; return(INTEGER_CONSTANT); }
+"ATTACH_LEAR" { count(); yylval.ival = 13; return(INTEGER_CONSTANT); }
+"ATTACH_REAR" { count(); yylval.ival = 14; return(INTEGER_CONSTANT); }
+"ATTACH_LEYE" { count(); yylval.ival = 15; return(INTEGER_CONSTANT); }
+"ATTACH_REYE" { count(); yylval.ival = 16; return(INTEGER_CONSTANT); }
+"ATTACH_NOSE" { count(); yylval.ival = 17; return(INTEGER_CONSTANT); }
+"ATTACH_RUARM" { count(); yylval.ival = 18; return(INTEGER_CONSTANT); }
+"ATTACH_RLARM" { count(); yylval.ival = 19; return(INTEGER_CONSTANT); }
+"ATTACH_LUARM" { count(); yylval.ival = 20; return(INTEGER_CONSTANT); }
+"ATTACH_LLARM" { count(); yylval.ival = 21; return(INTEGER_CONSTANT); }
+"ATTACH_RHIP" { count(); yylval.ival = 22; return(INTEGER_CONSTANT); }
+"ATTACH_RULEG" { count(); yylval.ival = 23; return(INTEGER_CONSTANT); }
+"ATTACH_RLLEG" { count(); yylval.ival = 24; return(INTEGER_CONSTANT); }
+"ATTACH_LHIP" { count(); yylval.ival = 25; return(INTEGER_CONSTANT); }
+"ATTACH_LULEG" { count(); yylval.ival = 26; return(INTEGER_CONSTANT); }
+"ATTACH_LLLEG" { count(); yylval.ival = 27; return(INTEGER_CONSTANT); }
+"ATTACH_BELLY" { count(); yylval.ival = 28; return(INTEGER_CONSTANT); }
+"ATTACH_RPEC" { count(); yylval.ival = 29; return(INTEGER_CONSTANT); }
+"ATTACH_LPEC" { count(); yylval.ival = 30; return(INTEGER_CONSTANT); }
+"ATTACH_HUD_CENTER_2" { count(); yylval.ival = 31; return(INTEGER_CONSTANT); }
+"ATTACH_HUD_TOP_RIGHT" { count(); yylval.ival = 32; return(INTEGER_CONSTANT); }
+"ATTACH_HUD_TOP_CENTER" { count(); yylval.ival = 33; return(INTEGER_CONSTANT); }
+"ATTACH_HUD_TOP_LEFT" { count(); yylval.ival = 34; return(INTEGER_CONSTANT); }
+"ATTACH_HUD_CENTER_1" { count(); yylval.ival = 35; return(INTEGER_CONSTANT); }
+"ATTACH_HUD_BOTTOM_LEFT" { count(); yylval.ival = 36; return(INTEGER_CONSTANT); }
+"ATTACH_HUD_BOTTOM" { count(); yylval.ival = 37; return(INTEGER_CONSTANT); }
+"ATTACH_HUD_BOTTOM_RIGHT" { count(); yylval.ival = 38; return(INTEGER_CONSTANT); }
+
+"LAND_LEVEL" { count(); yylval.ival = E_LANDBRUSH_LEVEL; return(INTEGER_CONSTANT); }
+"LAND_RAISE" { count(); yylval.ival = E_LANDBRUSH_RAISE; return(INTEGER_CONSTANT); }
+"LAND_LOWER" { count(); yylval.ival = E_LANDBRUSH_LOWER; return(INTEGER_CONSTANT); }
+"LAND_SMOOTH" { count(); yylval.ival = E_LANDBRUSH_SMOOTH; return(INTEGER_CONSTANT); }
+"LAND_NOISE" { count(); yylval.ival = E_LANDBRUSH_NOISE; return(INTEGER_CONSTANT); }
+"LAND_REVERT" { count(); yylval.ival = E_LANDBRUSH_REVERT; return(INTEGER_CONSTANT); }
+
+"LAND_SMALL_BRUSH" { count(); yylval.ival = 1; return(INTEGER_CONSTANT); }
+"LAND_MEDIUM_BRUSH" { count(); yylval.ival = 2; return(INTEGER_CONSTANT); }
+"LAND_LARGE_BRUSH" { count(); yylval.ival = 3; return(INTEGER_CONSTANT); }
+
+"DATA_ONLINE" { count(); yylval.ival = 1; return(INTEGER_CONSTANT); }
+"DATA_NAME" { count(); yylval.ival = 2; return(INTEGER_CONSTANT); }
+"DATA_BORN" { count(); yylval.ival = 3; return(INTEGER_CONSTANT); }
+"DATA_RATING" { count(); yylval.ival = 4; return(INTEGER_CONSTANT); }
+"DATA_SIM_POS" { count(); yylval.ival = 5; return(INTEGER_CONSTANT); }
+"DATA_SIM_STATUS" { count(); yylval.ival = 6; return(INTEGER_CONSTANT); }
+"DATA_SIM_RATING" { count(); yylval.ival = 7; return(INTEGER_CONSTANT); }
+"DATA_PAYINFO" { count(); yylval.ival = 8; return(INTEGER_CONSTANT); }
+
+"PAYMENT_INFO_ON_FILE" { count(); yylval.ival = 1; return(INTEGER_CONSTANT); }
+"PAYMENT_INFO_USED" { count(); yylval.ival = 2; return(INTEGER_CONSTANT); }
+
+"REMOTE_DATA_CHANNEL" { count(); yylval.ival = LSL_REMOTE_DATA_CHANNEL; return(INTEGER_CONSTANT); }
+"REMOTE_DATA_REQUEST" { count(); yylval.ival = LSL_REMOTE_DATA_REQUEST; return(INTEGER_CONSTANT); }
+"REMOTE_DATA_REPLY" { count(); yylval.ival = LSL_REMOTE_DATA_REPLY; return(INTEGER_CONSTANT); }
+
+
+"PSYS_PART_FLAGS" { count(); yylval.ival = LLPS_PART_FLAGS; return(INTEGER_CONSTANT); }
+"PSYS_PART_START_COLOR" { count(); yylval.ival = LLPS_PART_START_COLOR; return (INTEGER_CONSTANT); }
+"PSYS_PART_START_ALPHA" { count(); yylval.ival = LLPS_PART_START_ALPHA; return (INTEGER_CONSTANT); }
+"PSYS_PART_START_SCALE" { count(); yylval.ival = LLPS_PART_START_SCALE; return (INTEGER_CONSTANT); }
+"PSYS_PART_END_COLOR" { count(); yylval.ival = LLPS_PART_END_COLOR; return (INTEGER_CONSTANT); }
+"PSYS_PART_END_ALPHA" { count(); yylval.ival = LLPS_PART_END_ALPHA; return (INTEGER_CONSTANT); }
+"PSYS_PART_END_SCALE" { count(); yylval.ival = LLPS_PART_END_SCALE; return (INTEGER_CONSTANT); }
+"PSYS_PART_MAX_AGE" { count(); yylval.ival = LLPS_PART_MAX_AGE; return (INTEGER_CONSTANT); }
+
+
+"PSYS_PART_WIND_MASK" { count(); yylval.ival = LLPartData::LL_PART_WIND_MASK; return(INTEGER_CONSTANT); }
+"PSYS_PART_INTERP_COLOR_MASK" { count(); yylval.ival = LLPartData::LL_PART_INTERP_COLOR_MASK; return(INTEGER_CONSTANT); }
+"PSYS_PART_INTERP_SCALE_MASK" { count(); yylval.ival = LLPartData::LL_PART_INTERP_SCALE_MASK; return(INTEGER_CONSTANT); }
+"PSYS_PART_BOUNCE_MASK" { count(); yylval.ival = LLPartData::LL_PART_BOUNCE_MASK; return(INTEGER_CONSTANT); }
+"PSYS_PART_FOLLOW_SRC_MASK" { count(); yylval.ival = LLPartData::LL_PART_FOLLOW_SRC_MASK; return(INTEGER_CONSTANT); }
+"PSYS_PART_FOLLOW_VELOCITY_MASK" { count(); yylval.ival = LLPartData::LL_PART_FOLLOW_VELOCITY_MASK; return(INTEGER_CONSTANT); }
+"PSYS_PART_TARGET_POS_MASK" { count(); yylval.ival = LLPartData::LL_PART_TARGET_POS_MASK; return(INTEGER_CONSTANT); }
+"PSYS_PART_EMISSIVE_MASK" { count(); yylval.ival = LLPartData::LL_PART_EMISSIVE_MASK; return(INTEGER_CONSTANT); }
+"PSYS_PART_TARGET_LINEAR_MASK" { count(); yylval.ival = LLPartData::LL_PART_TARGET_LINEAR_MASK; return(INTEGER_CONSTANT); }
+
+
+"PSYS_SRC_MAX_AGE" { count(); yylval.ival = LLPS_SRC_MAX_AGE; return(INTEGER_CONSTANT); }
+"PSYS_SRC_PATTERN" { count(); yylval.ival = LLPS_SRC_PATTERN; return(INTEGER_CONSTANT); }
+"PSYS_SRC_INNERANGLE" { count(); yylval.ival = LLPS_SRC_INNERANGLE; return(INTEGER_CONSTANT); }
+"PSYS_SRC_OUTERANGLE" { count(); yylval.ival = LLPS_SRC_OUTERANGLE; return(INTEGER_CONSTANT); }
+"PSYS_SRC_ANGLE_BEGIN" { count(); yylval.ival = LLPS_SRC_ANGLE_BEGIN; return(INTEGER_CONSTANT); }
+"PSYS_SRC_ANGLE_END" { count(); yylval.ival = LLPS_SRC_ANGLE_END; return(INTEGER_CONSTANT); }
+"PSYS_SRC_BURST_RATE" { count(); yylval.ival = LLPS_SRC_BURST_RATE; return(INTEGER_CONSTANT); }
+"PSYS_SRC_BURST_PART_COUNT" { count(); yylval.ival = LLPS_SRC_BURST_PART_COUNT; return(INTEGER_CONSTANT); }
+"PSYS_SRC_BURST_RADIUS" { count(); yylval.ival = LLPS_SRC_BURST_RADIUS; return(INTEGER_CONSTANT); }
+"PSYS_SRC_BURST_SPEED_MIN" { count(); yylval.ival = LLPS_SRC_BURST_SPEED_MIN; return(INTEGER_CONSTANT); }
+"PSYS_SRC_BURST_SPEED_MAX" { count(); yylval.ival = LLPS_SRC_BURST_SPEED_MAX; return(INTEGER_CONSTANT); }
+"PSYS_SRC_ACCEL" { count(); yylval.ival = LLPS_SRC_ACCEL; return(INTEGER_CONSTANT); }
+"PSYS_SRC_TEXTURE" { count(); yylval.ival = LLPS_SRC_TEXTURE; return(INTEGER_CONSTANT); }
+"PSYS_SRC_TARGET_KEY" { count(); yylval.ival = LLPS_SRC_TARGET_UUID; return(INTEGER_CONSTANT); }
+"PSYS_SRC_OMEGA" { count(); yylval.ival = LLPS_SRC_OMEGA; return(INTEGER_CONSTANT); }
+
+"PSYS_SRC_OBJ_REL_MASK" { count(); yylval.ival = LLPartSysData::LL_PART_SRC_OBJ_REL_MASK; return(INTEGER_CONSTANT); }
+
+"PSYS_SRC_PATTERN_DROP" { count(); yylval.ival = LLPartSysData::LL_PART_SRC_PATTERN_DROP; return(INTEGER_CONSTANT); }
+"PSYS_SRC_PATTERN_EXPLODE" { count(); yylval.ival = LLPartSysData::LL_PART_SRC_PATTERN_EXPLODE; return(INTEGER_CONSTANT); }
+"PSYS_SRC_PATTERN_ANGLE" { count(); yylval.ival = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE; return(INTEGER_CONSTANT); }
+"PSYS_SRC_PATTERN_ANGLE_CONE" { count(); yylval.ival = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE; return(INTEGER_CONSTANT); }
+"PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY" { count(); yylval.ival = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY; return(INTEGER_CONSTANT); }
+
+
+"VEHICLE_TYPE_NONE" { count(); yylval.ival = VEHICLE_TYPE_NONE; return(INTEGER_CONSTANT); }
+"VEHICLE_TYPE_SLED" { count(); yylval.ival = VEHICLE_TYPE_SLED; return(INTEGER_CONSTANT); }
+"VEHICLE_TYPE_CAR" { count(); yylval.ival = VEHICLE_TYPE_CAR; return(INTEGER_CONSTANT); }
+"VEHICLE_TYPE_BOAT" { count(); yylval.ival = VEHICLE_TYPE_BOAT; return(INTEGER_CONSTANT); }
+"VEHICLE_TYPE_AIRPLANE" { count(); yylval.ival = VEHICLE_TYPE_AIRPLANE; return(INTEGER_CONSTANT); }
+"VEHICLE_TYPE_BALLOON" { count(); yylval.ival = VEHICLE_TYPE_BALLOON; return(INTEGER_CONSTANT); }
+
+"VEHICLE_REFERENCE_FRAME" { count(); yylval.ival = VEHICLE_REFERENCE_FRAME; return(INTEGER_CONSTANT); }
+"VEHICLE_LINEAR_FRICTION_TIMESCALE" { count(); yylval.ival = VEHICLE_LINEAR_FRICTION_TIMESCALE; return(INTEGER_CONSTANT); }
+"VEHICLE_ANGULAR_FRICTION_TIMESCALE" { count(); yylval.ival = VEHICLE_ANGULAR_FRICTION_TIMESCALE; return(INTEGER_CONSTANT); }
+"VEHICLE_LINEAR_MOTOR_DIRECTION" { count(); yylval.ival = VEHICLE_LINEAR_MOTOR_DIRECTION; return(INTEGER_CONSTANT); }
+"VEHICLE_ANGULAR_MOTOR_DIRECTION" { count(); yylval.ival = VEHICLE_ANGULAR_MOTOR_DIRECTION; return(INTEGER_CONSTANT); }
+"VEHICLE_LINEAR_MOTOR_OFFSET" { count(); yylval.ival = VEHICLE_LINEAR_MOTOR_OFFSET; return(INTEGER_CONSTANT); }
+
+
+
+"VEHICLE_HOVER_HEIGHT" { count(); yylval.ival = VEHICLE_HOVER_HEIGHT; return(INTEGER_CONSTANT); }
+"VEHICLE_HOVER_EFFICIENCY" { count(); yylval.ival = VEHICLE_HOVER_EFFICIENCY; return(INTEGER_CONSTANT); }
+"VEHICLE_HOVER_TIMESCALE" { count(); yylval.ival = VEHICLE_HOVER_TIMESCALE; return(INTEGER_CONSTANT); }
+"VEHICLE_BUOYANCY" { count(); yylval.ival = VEHICLE_BUOYANCY; return(INTEGER_CONSTANT); }
+
+"VEHICLE_LINEAR_DEFLECTION_EFFICIENCY" { count(); yylval.ival = VEHICLE_LINEAR_DEFLECTION_EFFICIENCY; return(INTEGER_CONSTANT); }
+"VEHICLE_LINEAR_DEFLECTION_TIMESCALE" { count(); yylval.ival = VEHICLE_LINEAR_DEFLECTION_TIMESCALE; return(INTEGER_CONSTANT); }
+"VEHICLE_LINEAR_MOTOR_TIMESCALE" { count(); yylval.ival = VEHICLE_LINEAR_MOTOR_TIMESCALE; return(INTEGER_CONSTANT); }
+"VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE" { count(); yylval.ival = VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE; return(INTEGER_CONSTANT); }
+
+"VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY" { count(); yylval.ival = VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY; return(INTEGER_CONSTANT); }
+"VEHICLE_ANGULAR_DEFLECTION_TIMESCALE" { count(); yylval.ival = VEHICLE_ANGULAR_DEFLECTION_TIMESCALE; return(INTEGER_CONSTANT); }
+"VEHICLE_ANGULAR_MOTOR_TIMESCALE" { count(); yylval.ival = VEHICLE_ANGULAR_MOTOR_TIMESCALE; return(INTEGER_CONSTANT); }
+"VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE" { count(); yylval.ival = VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE; return(INTEGER_CONSTANT); }
+
+"VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY" { count(); yylval.ival = VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY; return(INTEGER_CONSTANT); }
+"VEHICLE_VERTICAL_ATTRACTION_TIMESCALE" { count(); yylval.ival = VEHICLE_VERTICAL_ATTRACTION_TIMESCALE; return(INTEGER_CONSTANT); }
+
+"VEHICLE_BANKING_EFFICIENCY" { count(); yylval.ival = VEHICLE_BANKING_EFFICIENCY; return(INTEGER_CONSTANT); }
+"VEHICLE_BANKING_MIX" { count(); yylval.ival = VEHICLE_BANKING_MIX; return(INTEGER_CONSTANT); }
+"VEHICLE_BANKING_TIMESCALE" { count(); yylval.ival = VEHICLE_BANKING_TIMESCALE; return(INTEGER_CONSTANT); }
+
+"VEHICLE_FLAG_NO_FLY_UP" { count(); yylval.ival = VEHICLE_FLAG_NO_DEFLECTION_UP; return(INTEGER_CONSTANT); }
+"VEHICLE_FLAG_NO_DEFLECTION_UP" { count(); yylval.ival = VEHICLE_FLAG_NO_DEFLECTION_UP; return(INTEGER_CONSTANT); }
+"VEHICLE_FLAG_LIMIT_ROLL_ONLY" { count(); yylval.ival = VEHICLE_FLAG_LIMIT_ROLL_ONLY; return(INTEGER_CONSTANT); }
+"VEHICLE_FLAG_HOVER_WATER_ONLY" { count(); yylval.ival = VEHICLE_FLAG_HOVER_WATER_ONLY; return(INTEGER_CONSTANT); }
+"VEHICLE_FLAG_HOVER_TERRAIN_ONLY" { count(); yylval.ival = VEHICLE_FLAG_HOVER_TERRAIN_ONLY; return(INTEGER_CONSTANT); }
+"VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT" { count(); yylval.ival = VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT; return(INTEGER_CONSTANT); }
+"VEHICLE_FLAG_HOVER_UP_ONLY" { count(); yylval.ival = VEHICLE_FLAG_HOVER_UP_ONLY; return(INTEGER_CONSTANT); }
+"VEHICLE_FLAG_LIMIT_MOTOR_UP" { count(); yylval.ival = VEHICLE_FLAG_LIMIT_MOTOR_UP; return(INTEGER_CONSTANT); }
+"VEHICLE_FLAG_MOUSELOOK_STEER" { count(); yylval.ival = VEHICLE_FLAG_MOUSELOOK_STEER; return(INTEGER_CONSTANT); }
+"VEHICLE_FLAG_MOUSELOOK_BANK" { count(); yylval.ival = VEHICLE_FLAG_MOUSELOOK_BANK; return(INTEGER_CONSTANT); }
+"VEHICLE_FLAG_CAMERA_DECOUPLED" { count(); yylval.ival = VEHICLE_FLAG_CAMERA_DECOUPLED; return(INTEGER_CONSTANT); }
+
+
+
+"PRIM_TYPE" { count(); yylval.ival = LSL_PRIM_TYPE; return(INTEGER_CONSTANT); }
+"PRIM_MATERIAL" { count(); yylval.ival = LSL_PRIM_MATERIAL; return(INTEGER_CONSTANT); }
+"PRIM_PHYSICS" { count(); yylval.ival = LSL_PRIM_PHYSICS; return(INTEGER_CONSTANT); }
+"PRIM_FLEXIBLE" { count(); yylval.ival = LSL_PRIM_FLEXIBLE; return(INTEGER_CONSTANT); }
+"PRIM_POINT_LIGHT" { count(); yylval.ival = LSL_PRIM_POINT_LIGHT; return(INTEGER_CONSTANT); }
+"PRIM_TEMP_ON_REZ" { count(); yylval.ival = LSL_PRIM_TEMP_ON_REZ; return(INTEGER_CONSTANT); }
+"PRIM_PHANTOM" { count(); yylval.ival = LSL_PRIM_PHANTOM; return(INTEGER_CONSTANT); }
+"PRIM_CAST_SHADOWS" { count(); yylval.ival = LSL_PRIM_CAST_SHADOWS; return(INTEGER_CONSTANT); }
+"PRIM_POSITION" { count(); yylval.ival = LSL_PRIM_POSITION; return(INTEGER_CONSTANT); }
+"PRIM_SIZE" { count(); yylval.ival = LSL_PRIM_SIZE; return(INTEGER_CONSTANT); }
+"PRIM_ROTATION" { count(); yylval.ival = LSL_PRIM_ROTATION; return(INTEGER_CONSTANT); }
+"PRIM_TEXTURE" { count(); yylval.ival = LSL_PRIM_TEXTURE; return(INTEGER_CONSTANT); }
+"PRIM_COLOR" { count(); yylval.ival = LSL_PRIM_COLOR; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_SHINY" { count(); yylval.ival = LSL_PRIM_BUMP_SHINY; return(INTEGER_CONSTANT); }
+"PRIM_FULLBRIGHT" { count(); yylval.ival = LSL_PRIM_FULLBRIGHT; return(INTEGER_CONSTANT); }
+"PRIM_TEXGEN" { count(); yylval.ival = LSL_PRIM_TEXGEN; return(INTEGER_CONSTANT); }
+
+"PRIM_TYPE_BOX" { count(); yylval.ival = LSL_PRIM_TYPE_BOX; return(INTEGER_CONSTANT); }
+"PRIM_TYPE_CYLINDER" { count(); yylval.ival = LSL_PRIM_TYPE_CYLINDER; return(INTEGER_CONSTANT); }
+"PRIM_TYPE_PRISM" { count(); yylval.ival = LSL_PRIM_TYPE_PRISM; return(INTEGER_CONSTANT); }
+"PRIM_TYPE_SPHERE" { count(); yylval.ival = LSL_PRIM_TYPE_SPHERE; return(INTEGER_CONSTANT); }
+"PRIM_TYPE_TORUS" { count(); yylval.ival = LSL_PRIM_TYPE_TORUS; return(INTEGER_CONSTANT); }
+"PRIM_TYPE_TUBE" { count(); yylval.ival = LSL_PRIM_TYPE_TUBE; return(INTEGER_CONSTANT); }
+"PRIM_TYPE_RING" { count(); yylval.ival = LSL_PRIM_TYPE_RING; return(INTEGER_CONSTANT); }
+
+"PRIM_HOLE_DEFAULT" { count(); yylval.ival = LSL_PRIM_HOLE_DEFAULT; return(INTEGER_CONSTANT); }
+"PRIM_HOLE_CIRCLE" { count(); yylval.ival = LSL_PRIM_HOLE_CIRCLE; return(INTEGER_CONSTANT); }
+"PRIM_HOLE_SQUARE" { count(); yylval.ival = LSL_PRIM_HOLE_SQUARE; return(INTEGER_CONSTANT); }
+"PRIM_HOLE_TRIANGLE" { count(); yylval.ival = LSL_PRIM_HOLE_TRIANGLE; return(INTEGER_CONSTANT); }
+
+"PRIM_MATERIAL_STONE" { count(); yylval.ival = LSL_PRIM_MATERIAL_STONE; return(INTEGER_CONSTANT); }
+"PRIM_MATERIAL_METAL" { count(); yylval.ival = LSL_PRIM_MATERIAL_METAL; return(INTEGER_CONSTANT); }
+"PRIM_MATERIAL_GLASS" { count(); yylval.ival = LSL_PRIM_MATERIAL_GLASS; return(INTEGER_CONSTANT); }
+"PRIM_MATERIAL_WOOD" { count(); yylval.ival = LSL_PRIM_MATERIAL_WOOD; return(INTEGER_CONSTANT); }
+"PRIM_MATERIAL_FLESH" { count(); yylval.ival = LSL_PRIM_MATERIAL_FLESH; return(INTEGER_CONSTANT); }
+"PRIM_MATERIAL_PLASTIC" { count(); yylval.ival = LSL_PRIM_MATERIAL_PLASTIC; return(INTEGER_CONSTANT); }
+"PRIM_MATERIAL_RUBBER" { count(); yylval.ival = LSL_PRIM_MATERIAL_RUBBER; return(INTEGER_CONSTANT); }
+"PRIM_MATERIAL_LIGHT" { count(); yylval.ival = LSL_PRIM_MATERIAL_LIGHT; return(INTEGER_CONSTANT); }
+
+"PRIM_SHINY_NONE" { count(); yylval.ival = LSL_PRIM_SHINY_NONE; return(INTEGER_CONSTANT); }
+"PRIM_SHINY_LOW" { count(); yylval.ival = LSL_PRIM_SHINY_LOW; return(INTEGER_CONSTANT); }
+"PRIM_SHINY_MEDIUM" { count(); yylval.ival = LSL_PRIM_SHINY_MEDIUM; return(INTEGER_CONSTANT); }
+"PRIM_SHINY_HIGH" { count(); yylval.ival = LSL_PRIM_SHINY_HIGH; return(INTEGER_CONSTANT); }
+
+"PRIM_BUMP_NONE" { count(); yylval.ival = LSL_PRIM_BUMP_NONE; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_BRIGHT" { count(); yylval.ival = LSL_PRIM_BUMP_BRIGHT; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_DARK" { count(); yylval.ival = LSL_PRIM_BUMP_DARK; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_WOOD" { count(); yylval.ival = LSL_PRIM_BUMP_WOOD; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_BARK" { count(); yylval.ival = LSL_PRIM_BUMP_BARK; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_BRICKS" { count(); yylval.ival = LSL_PRIM_BUMP_BRICKS; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_CHECKER" { count(); yylval.ival = LSL_PRIM_BUMP_CHECKER; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_CONCRETE" { count(); yylval.ival = LSL_PRIM_BUMP_CONCRETE; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_TILE" { count(); yylval.ival = LSL_PRIM_BUMP_TILE; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_STONE" { count(); yylval.ival = LSL_PRIM_BUMP_STONE; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_DISKS" { count(); yylval.ival = LSL_PRIM_BUMP_DISKS; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_GRAVEL" { count(); yylval.ival = LSL_PRIM_BUMP_GRAVEL; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_BLOBS" { count(); yylval.ival = LSL_PRIM_BUMP_BLOBS; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_SIDING" { count(); yylval.ival = LSL_PRIM_BUMP_SIDING; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_LARGETILE" { count(); yylval.ival = LSL_PRIM_BUMP_LARGETILE; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_STUCCO" { count(); yylval.ival = LSL_PRIM_BUMP_STUCCO; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_SUCTION" { count(); yylval.ival = LSL_PRIM_BUMP_SUCTION; return(INTEGER_CONSTANT); }
+"PRIM_BUMP_WEAVE" { count(); yylval.ival = LSL_PRIM_BUMP_WEAVE; return(INTEGER_CONSTANT); }
+
+"PRIM_TEXGEN_DEFAULT" { count(); yylval.ival = LSL_PRIM_TEXGEN_DEFAULT; return(INTEGER_CONSTANT); }
+"PRIM_TEXGEN_PLANAR" { count(); yylval.ival = LSL_PRIM_TEXGEN_PLANAR; return(INTEGER_CONSTANT); }
+
+"MASK_BASE" { count(); yylval.ival = 0; return(INTEGER_CONSTANT); }
+"MASK_OWNER" { count(); yylval.ival = 1; return(INTEGER_CONSTANT); }
+"MASK_GROUP" { count(); yylval.ival = 2; return(INTEGER_CONSTANT); }
+"MASK_EVERYONE" { count(); yylval.ival = 3; return(INTEGER_CONSTANT); }
+"MASK_NEXT" { count(); yylval.ival = 4; return(INTEGER_CONSTANT); }
+
+"PERM_TRANSFER" { count(); yylval.ival = PERM_TRANSFER; return(INTEGER_CONSTANT); }
+"PERM_MODIFY" { count(); yylval.ival = PERM_MODIFY; return(INTEGER_CONSTANT); }
+"PERM_COPY" { count(); yylval.ival = PERM_COPY; return(INTEGER_CONSTANT); }
+"PERM_MOVE" { count(); yylval.ival = PERM_MOVE; return(INTEGER_CONSTANT); }
+"PERM_ALL" { count(); yylval.ival = PERM_ALL; return(INTEGER_CONSTANT); }
+
+"PARCEL_MEDIA_COMMAND_STOP" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_STOP; return(INTEGER_CONSTANT); }
+"PARCEL_MEDIA_COMMAND_PAUSE" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_PAUSE; return(INTEGER_CONSTANT); }
+"PARCEL_MEDIA_COMMAND_PLAY" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_PLAY; return(INTEGER_CONSTANT); }
+"PARCEL_MEDIA_COMMAND_LOOP" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_LOOP; return(INTEGER_CONSTANT); }
+"PARCEL_MEDIA_COMMAND_TEXTURE" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_TEXTURE; return(INTEGER_CONSTANT); }
+"PARCEL_MEDIA_COMMAND_URL" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_URL; return(INTEGER_CONSTANT); }
+"PARCEL_MEDIA_COMMAND_TIME" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_TIME; return(INTEGER_CONSTANT); }
+"PARCEL_MEDIA_COMMAND_AGENT" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_AGENT; return(INTEGER_CONSTANT); }
+"PARCEL_MEDIA_COMMAND_UNLOAD" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_UNLOAD; return(INTEGER_CONSTANT); }
+"PARCEL_MEDIA_COMMAND_AUTO_ALIGN" { count(); yylval.ival = PARCEL_MEDIA_COMMAND_AUTO_ALIGN; return(INTEGER_CONSTANT); }
+
+"LIST_STAT_MAX" { count(); yylval.ival = LIST_STAT_MAX; return(INTEGER_CONSTANT); }
+"LIST_STAT_MIN" { count(); yylval.ival = LIST_STAT_MIN; return(INTEGER_CONSTANT); }
+"LIST_STAT_MEAN" { count(); yylval.ival = LIST_STAT_MEAN; return(INTEGER_CONSTANT); }
+"LIST_STAT_MEDIAN" { count(); yylval.ival = LIST_STAT_MEDIAN; return(INTEGER_CONSTANT); }
+"LIST_STAT_STD_DEV" { count(); yylval.ival = LIST_STAT_STD_DEV; return(INTEGER_CONSTANT); }
+"LIST_STAT_SUM" { count(); yylval.ival = LIST_STAT_SUM; return(INTEGER_CONSTANT); }
+"LIST_STAT_SUM_SQUARES" { count(); yylval.ival = LIST_STAT_SUM_SQUARES; return(INTEGER_CONSTANT); }
+"LIST_STAT_NUM_COUNT" { count(); yylval.ival = LIST_STAT_NUM_COUNT; return(INTEGER_CONSTANT); }
+"LIST_STAT_GEOMETRIC_MEAN" { count(); yylval.ival = LIST_STAT_GEO_MEAN; return(INTEGER_CONSTANT); }
+"LIST_STAT_RANGE" { count(); yylval.ival = LIST_STAT_RANGE; return(INTEGER_CONSTANT); }
+
+"PAY_HIDE" { count(); yylval.ival = PAY_PRICE_HIDE; return(INTEGER_CONSTANT); }
+"PAY_DEFAULT" { count(); yylval.ival = PAY_PRICE_DEFAULT; return(INTEGER_CONSTANT); }
+
+"PARCEL_FLAG_ALLOW_FLY" { count(); yylval.ival = PF_ALLOW_FLY; return(INTEGER_CONSTANT); }
+"PARCEL_FLAG_ALLOW_GROUP_SCRIPTS" { count(); yylval.ival = PF_ALLOW_GROUP_SCRIPTS; return(INTEGER_CONSTANT); }
+"PARCEL_FLAG_ALLOW_SCRIPTS" { count(); yylval.ival = PF_ALLOW_OTHER_SCRIPTS; return(INTEGER_CONSTANT); }
+"PARCEL_FLAG_ALLOW_LANDMARK" { count(); yylval.ival = PF_ALLOW_LANDMARK; return(INTEGER_CONSTANT); }
+"PARCEL_FLAG_ALLOW_TERRAFORM" { count(); yylval.ival = PF_ALLOW_TERRAFORM; return(INTEGER_CONSTANT); }
+"PARCEL_FLAG_ALLOW_DAMAGE" { count(); yylval.ival = PF_ALLOW_DAMAGE; return(INTEGER_CONSTANT); }
+"PARCEL_FLAG_ALLOW_CREATE_OBJECTS" { count(); yylval.ival = PF_CREATE_OBJECTS; return(INTEGER_CONSTANT); }
+"PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS" { count(); yylval.ival = PF_CREATE_GROUP_OBJECTS; return(INTEGER_CONSTANT); }
+"PARCEL_FLAG_USE_ACCESS_GROUP" { count(); yylval.ival = PF_USE_ACCESS_GROUP; return(INTEGER_CONSTANT); }
+"PARCEL_FLAG_USE_ACCESS_LIST" { count(); yylval.ival = PF_USE_ACCESS_LIST; return(INTEGER_CONSTANT); }
+"PARCEL_FLAG_USE_BAN_LIST" { count(); yylval.ival = PF_USE_BAN_LIST; return(INTEGER_CONSTANT); }
+"PARCEL_FLAG_USE_LAND_PASS_LIST" { count(); yylval.ival = PF_USE_PASS_LIST; return(INTEGER_CONSTANT); }
+"PARCEL_FLAG_LOCAL_SOUND_ONLY" { count(); yylval.ival = PF_SOUND_LOCAL; return(INTEGER_CONSTANT); }
+"PARCEL_FLAG_RESTRICT_PUSHOBJECT" { count(); yylval.ival = PF_RESTRICT_PUSHOBJECT; return(INTEGER_CONSTANT); }
+"PARCEL_FLAG_ALLOW_GROUP_OBJECT_ENTRY" { count(); yylval.ival = PF_ALLOW_GROUP_OBJECT_ENTRY; return(INTEGER_CONSTANT); }
+"PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY" { count(); yylval.ival = PF_ALLOW_ALL_OBJECT_ENTRY; return(INTEGER_CONSTANT); }
+
+"REGION_FLAG_ALLOW_DAMAGE" { count(); yylval.ival = REGION_FLAGS_ALLOW_DAMAGE; return(INTEGER_CONSTANT); }
+"REGION_FLAG_FIXED_SUN" { count(); yylval.ival = REGION_FLAGS_SUN_FIXED; return(INTEGER_CONSTANT); }
+"REGION_FLAG_BLOCK_TERRAFORM" { count(); yylval.ival = REGION_FLAGS_BLOCK_TERRAFORM; return(INTEGER_CONSTANT); }
+"REGION_FLAG_SANDBOX" { count(); yylval.ival = REGION_FLAGS_SANDBOX; return(INTEGER_CONSTANT); }
+"REGION_FLAG_DISABLE_COLLISIONS" { count(); yylval.ival = REGION_FLAGS_SKIP_COLLISIONS; return(INTEGER_CONSTANT); }
+"REGION_FLAG_DISABLE_PHYSICS" { count(); yylval.ival = REGION_FLAGS_SKIP_PHYSICS; return(INTEGER_CONSTANT); }
+"REGION_FLAG_BLOCK_FLY" { count(); yylval.ival = REGION_FLAGS_BLOCK_FLY; return(INTEGER_CONSTANT); }
+"REGION_FLAG_ALLOW_DIRECT_TELEPORT" { count(); yylval.ival = REGION_FLAGS_ALLOW_DIRECT_TELEPORT; return(INTEGER_CONSTANT); }
+"REGION_FLAG_RESTRICT_PUSHOBJECT" { count(); yylval.ival = REGION_FLAGS_RESTRICT_PUSHOBJECT; return(INTEGER_CONSTANT); }
+
+"HTTP_METHOD" { count(); yylval.ival = HTTP_METHOD; return(INTEGER_CONSTANT); }
+"HTTP_MIMETYPE" { count(); yylval.ival = HTTP_MIMETYPE; return(INTEGER_CONSTANT); }
+"HTTP_BODY_MAXLENGTH" { count(); yylval.ival = HTTP_BODY_MAXLENGTH; return(INTEGER_CONSTANT); }
+"HTTP_BODY_TRUNCATED" { count(); yylval.ival = HTTP_BODY_TRUNCATED; return(INTEGER_CONSTANT); }
+"HTTP_VERIFY_CERT" { count(); yylval.ival = HTTP_VERIFY_CERT; return(INTEGER_CONSTANT); }
+
+"PARCEL_COUNT_TOTAL" { count(); yylval.ival = OC_TOTAL; return(INTEGER_CONSTANT); }
+"PARCEL_COUNT_OWNER" { count(); yylval.ival = OC_OWNER; return(INTEGER_CONSTANT); }
+"PARCEL_COUNT_GROUP" { count(); yylval.ival = OC_GROUP; return(INTEGER_CONSTANT); }
+"PARCEL_COUNT_OTHER" { count(); yylval.ival = OC_OTHER; return(INTEGER_CONSTANT); }
+"PARCEL_COUNT_SELECTED" { count(); yylval.ival = OC_SELECTED; return(INTEGER_CONSTANT); }
+"PARCEL_COUNT_TEMP" { count(); yylval.ival = OC_TEMP; return(INTEGER_CONSTANT); }
+
+"PARCEL_DETAILS_NAME" { count(); yylval.ival = PARCEL_DETAILS_NAME; return(INTEGER_CONSTANT); }
+"PARCEL_DETAILS_DESC" { count(); yylval.ival = PARCEL_DETAILS_DESC; return(INTEGER_CONSTANT); }
+"PARCEL_DETAILS_OWNER" { count(); yylval.ival = PARCEL_DETAILS_OWNER; return(INTEGER_CONSTANT); }
+"PARCEL_DETAILS_GROUP" { count(); yylval.ival = PARCEL_DETAILS_GROUP; return(INTEGER_CONSTANT); }
+"PARCEL_DETAILS_AREA" { count(); yylval.ival = PARCEL_DETAILS_AREA; return(INTEGER_CONSTANT); }
+
+{L}({L}|{N})* { count(); yylval.sval = new char[strlen(yytext) + 1]; strcpy(yylval.sval, yytext); return(IDENTIFIER); }
+
+{D}+{E} { count(); yylval.fval = (F32)atof(yytext); return(FP_CONSTANT); }
+{D}*"."{D}+({E})?{FS}? { count(); yylval.fval = (F32)atof(yytext); return(FP_CONSTANT); }
+{D}+"."{D}*({E})?{FS}? { count(); yylval.fval = (F32)atof(yytext); return(FP_CONSTANT); }
+
+L?\"(\\.|[^\\"])*\" { parse_string(); count(); return(STRING_CONSTANT); }
+
+"++" { count(); return(INC_OP); }
+"--" { count(); return(DEC_OP); }
+"+=" { count(); return(ADD_ASSIGN); }
+"-=" { count(); return(SUB_ASSIGN); }
+"*=" { count(); return(MUL_ASSIGN); }
+"/=" { count(); return(DIV_ASSIGN); }
+"%=" { count(); return(MOD_ASSIGN); }
+";" { count(); return(';'); }
+"{" { count(); return('{'); }
+"}" { count(); return('}'); }
+"," { count(); return(','); }
+"=" { count(); return('='); }
+"(" { count(); return('('); }
+")" { count(); return(')'); }
+"-" { count(); return('-'); }
+"+" { count(); return('+'); }
+"*" { count(); return('*'); }
+"/" { count(); return('/'); }
+"%" { count(); return('%'); }
+"@" { count(); return('@'); }
+":" { count(); return(':'); }
+">" { count(); return('>'); }
+"<" { count(); return('<'); }
+"]" { count(); return(']'); }
+"[" { count(); return('['); }
+"==" { count(); return(EQ); }
+"!=" { count(); return(NEQ); }
+">=" { count(); return(GEQ); }
+"<=" { count(); return(LEQ); }
+"&" { count(); return('&'); }
+"|" { count(); return('|'); }
+"^" { count(); return('^'); }
+"~" { count(); return('~'); }
+"!" { count(); return('!'); }
+"&&" { count(); return(BOOLEAN_AND); }
+"||" { count(); return(BOOLEAN_OR); }
+"<<" { count(); return(SHIFT_LEFT); }
+">>" { count(); return(SHIFT_RIGHT); }
+
+[ \t\v\n\f] { count(); }
+. { /* ignore bad characters */ }
+
+%%
+
+LLScriptAllocationManager *gAllocationManager;
+LLScriptScript *gScriptp;
+
+// Prototype for the yacc parser entry point
+int yyparse(void);
+
+int yyerror(const char *fmt, ...)
+{
+ gErrorToText.writeError(yyout, gLine, gColumn, LSERROR_SYNTAX_ERROR);
+ return 0;
+}
+
+#define LL_MKS_YACC 1
+#if LL_WINDOWS && LL_MKS_YACC
+int yyinput(void)
+{
+ return input();
+}
+#endif
+
+//#define EMERGENCY_DEBUG_PRINTOUTS
+//#define EMIT_CIL_ASSEMBLER
+
+BOOL lscript_compile(const char* src_filename, const char* dst_filename,
+ const char* err_filename, BOOL is_god_like)
+{
+ BOOL b_parse_ok = FALSE;
+ BOOL b_dummy = FALSE;
+ U64 b_dummy_count = FALSE;
+ LSCRIPTType type = LST_NULL;
+
+ gInternalColumn = 0;
+ gInternalLine = 0;
+ gScriptp = NULL;
+
+ gErrorToText.init();
+ init_supported_expressions();
+ init_temp_jumps();
+ gAllocationManager = new LLScriptAllocationManager();
+
+ yyin = LLFile::fopen(src_filename, "r");
+ if (yyin)
+ {
+ yyout = LLFile::fopen(err_filename, "w");
+
+ // Reset the lexer's internal buffering.
+#if LL_DARWIN || LL_LINUX || !LL_MKS_YACC
+ yyrestart(yyin);
+#else
+ yy_reset();
+#endif
+ b_parse_ok = !yyparse();
+
+ if (b_parse_ok)
+ {
+#ifdef EMERGENCY_DEBUG_PRINTOUTS
+ char compiled[256];
+ sprintf(compiled, "%s.o", src_filename);
+ FILE* compfile;
+ compfile = LLFile::fopen(compiled, "w");
+#endif
+
+ if(dst_filename)
+ {
+ gScriptp->setBytecodeDest(dst_filename);
+ }
+
+ gScriptp->mGodLike = is_god_like;
+
+ gScopeStringTable = new LLStringTable(16384);
+#ifdef EMERGENCY_DEBUG_PRINTOUTS
+ gScriptp->recurse(compfile, 0, 4, LSCP_PRETTY_PRINT, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
+#endif
+ gScriptp->recurse(yyout, 0, 0, LSCP_PRUNE, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
+ gScriptp->recurse(yyout, 0, 0, LSCP_SCOPE_PASS1, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
+ gScriptp->recurse(yyout, 0, 0, LSCP_SCOPE_PASS2, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
+ gScriptp->recurse(yyout, 0, 0, LSCP_TYPE, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
+ if (!gErrorToText.getErrors())
+ {
+ gScriptp->recurse(yyout, 0, 0, LSCP_RESOURCE, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
+#ifdef EMERGENCY_DEBUG_PRINTOUTS
+ gScriptp->recurse(yyout, 0, 0, LSCP_EMIT_ASSEMBLY, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
+#endif
+#ifdef EMIT_CIL_ASSEMBLER
+ const char* cil_output_file_name = dst_filename? dst_filename : "lscript.cil";
+ FILE* cilout = LLFile::fopen(cil_output_file_name, "w");
+ if(NULL == cilout)
+ {
+ fprintf(yyout, "Error opening cil output file %s\n", cil_output_file_name);
+ }
+ else
+ {
+ gScriptp->recurse(cilout, 0, 0, LSCP_EMIT_CIL_ASSEMBLY, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
+ if(fclose(cilout) == EOF)
+ {
+ fprintf(yyout, "Error closing cil output file %s\n", cil_output_file_name);
+ }
+ }
+#endif
+ gScriptp->recurse(yyout, 0, 0, LSCP_EMIT_BYTE_CODE, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL);
+ }
+ delete gScopeStringTable;
+ gScopeStringTable = NULL;
+#ifdef EMERGENCY_DEBUG_PRINTOUTS
+ fclose(compfile);
+#endif
+ }
+ fclose(yyout);
+ }
+
+ fclose(yyin);
+ delete gAllocationManager;
+ delete gScopeStringTable;
+
+ return b_parse_ok && !gErrorToText.getErrors();
+}
+
+
+BOOL lscript_compile(char *filename, BOOL is_god_like = FALSE)
+{
+ char src_filename[MAX_STRING];
+ sprintf(src_filename, "%s.lsl", filename);
+ char err_filename[MAX_STRING];
+ sprintf(err_filename, "%s.out", filename);
+ return lscript_compile(src_filename, NULL, err_filename, is_god_like);
+}
+
+
+S32 yywrap()
+{
+ return(1);
+}
+
+void comment()
+{
+ char c;
+
+#if LL_DARWIN
+ while ((c = yyinput()) != '\n' && c != 0 && c != EOF)
+ ;
+#else
+ while ((c = yyinput()) != '\n' && c != 0)
+ ;
+#endif
+
+
+}
+
+void count()
+{
+ S32 i;
+
+ gColumn = gInternalColumn;
+ gLine = gInternalLine;
+
+ for (i = 0; yytext[i] != '\0'; i++)
+ if (yytext[i] == '\n')
+ {
+ gInternalLine++;
+ gInternalColumn = 0;
+ }
+ else if (yytext[i] == '\t')
+ gInternalColumn += 4 - (gInternalColumn % 8);
+ else
+ gInternalColumn++;
+}
+
+void parse_string()
+{
+ S32 length = (S32)strlen(yytext);
+ length = length - 2;
+ char *temp = yytext + 1;
+
+ S32 i;
+ S32 escapes = 0;
+ S32 tabs = 0;
+ for (i = 0; i < length; i++)
+ {
+ if (temp[i] == '\\')
+ {
+ escapes++;
+ i++;
+ if (temp[i] == 't')
+ tabs++;
+ }
+ }
+
+ S32 newlength = length - escapes + tabs*3;
+ yylval.sval = new char[newlength + 1];
+
+ char *dest = yylval.sval;
+
+ for (i = 0; i < length; i++)
+ {
+ if (temp[i] == '\\')
+ {
+ i++;
+ // linefeed
+ if (temp[i] == 'n')
+ {
+ *dest++ = 10;
+ }
+ else if (temp[i] == 't')
+ {
+ *dest++ = ' ';
+ *dest++ = ' ';
+ *dest++ = ' ';
+ *dest++ = ' ';
+ }
+ else
+ {
+ *dest++ = temp[i];
+ }
+ }
+ else
+ {
+ *dest++ = temp[i];
+ }
+ }
+ yylval.sval[newlength] = 0;
+}
diff --git a/indra/lscript/lscript_compile/indra.y b/indra/lscript/lscript_compile/indra.y
new file mode 100644
index 0000000000..7744649a92
--- /dev/null
+++ b/indra/lscript/lscript_compile/indra.y
@@ -0,0 +1,1680 @@
+%{
+ #include "stdtypes.h"
+ #include "lscript_tree.h"
+
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ int yylex(void);
+ int yyparse( void );
+ int yyerror(const char *fmt, ...);
+
+ #if LL_LINUX
+ // broken yacc codegen... --ryan.
+ #define getenv getenv_workaround
+ #endif
+
+ #ifdef __cplusplus
+ }
+ #endif
+%}
+
+%union
+{
+ S32 ival;
+ F32 fval;
+ char *sval;
+ class LLScriptType *type;
+ class LLScriptConstant *constant;
+ class LLScriptIdentifier *identifier;
+ class LLScriptSimpleAssignable *assignable;
+ class LLScriptGlobalVariable *global;
+ class LLScriptEvent *event;
+ class LLScriptEventHandler *handler;
+ class LLScriptExpression *expression;
+ class LLScriptStatement *statement;
+ class LLScriptGlobalFunctions *global_funcs;
+ class LLScriptFunctionDec *global_decl;
+ class LLScriptState *state;
+ class LLScritpGlobalStorage *global_store;
+ class LLScriptScript *script;
+};
+
+%token INTEGER
+%token FLOAT_TYPE
+%token STRING
+%token LLKEY
+%token VECTOR
+%token QUATERNION
+%token LIST
+
+%token STATE_DEFAULT
+%token STATE
+%token EVENT
+%token JUMP
+%token RETURN
+
+%token STATE_ENTRY
+%token STATE_EXIT
+%token TOUCH_START
+%token TOUCH
+%token TOUCH_END
+%token COLLISION_START
+%token COLLISION
+%token COLLISION_END
+%token LAND_COLLISION_START
+%token LAND_COLLISION
+%token LAND_COLLISION_END
+%token TIMER
+%token CHAT
+%token SENSOR
+%token NO_SENSOR
+%token CONTROL
+%token AT_TARGET
+%token NOT_AT_TARGET
+%token AT_ROT_TARGET
+%token NOT_AT_ROT_TARGET
+%token MONEY
+%token EMAIL
+%token RUN_TIME_PERMISSIONS
+%token INVENTORY
+%token ATTACH
+%token DATASERVER
+%token MOVING_START
+%token MOVING_END
+%token REZ
+%token OBJECT_REZ
+%token LINK_MESSAGE
+%token REMOTE_DATA
+%token HTTP_RESPONSE
+
+%token <sval> IDENTIFIER
+%token <sval> STATE_DEFAULT
+
+%token <ival> INTEGER_CONSTANT
+%token <ival> INTEGER_TRUE
+%token <ival> INTEGER_FALSE
+
+%token <fval> FP_CONSTANT
+
+%token <sval> STRING_CONSTANT
+
+%token INC_OP
+%token DEC_OP
+%token ADD_ASSIGN
+%token SUB_ASSIGN
+%token MUL_ASSIGN
+%token DIV_ASSIGN
+%token MOD_ASSIGN
+
+%token EQ
+%token NEQ
+%token GEQ
+%token LEQ
+
+%token BOOLEAN_AND
+%token BOOLEAN_OR
+
+%token SHIFT_LEFT
+%token SHIFT_RIGHT
+
+%token IF
+%token ELSE
+%token FOR
+%token DO
+%token WHILE
+
+%token PRINT
+
+%token PERIOD
+
+%token ZERO_VECTOR
+%token ZERO_ROTATION
+
+%nonassoc LOWER_THAN_ELSE
+%nonassoc ELSE
+
+
+%type <script> lscript_program
+%type <global_store> globals
+%type <global_store> global
+%type <global> global_variable
+%type <assignable> simple_assignable
+%type <assignable> simple_assignable_no_list
+%type <constant> constant
+%type <assignable> special_constant
+%type <assignable> vector_constant
+%type <assignable> quaternion_constant
+%type <assignable> list_constant
+%type <assignable> list_entries
+%type <assignable> list_entry
+%type <type> typename
+%type <global_funcs> global_function
+%type <global_decl> function_parameters
+%type <global_decl> function_parameter
+%type <state> states
+%type <state> other_states
+%type <state> default
+%type <state> state
+%type <handler> state_body
+%type <handler> event
+%type <event> state_entry
+%type <event> state_exit
+%type <event> touch_start
+%type <event> touch
+%type <event> touch_end
+%type <event> collision_start
+%type <event> collision
+%type <event> collision_end
+%type <event> land_collision_start
+%type <event> land_collision
+%type <event> land_collision_end
+%type <event> at_target
+%type <event> not_at_target
+%type <event> at_rot_target
+%type <event> not_at_rot_target
+%type <event> money
+%type <event> email
+%type <event> run_time_permissions
+%type <event> inventory
+%type <event> attach
+%type <event> dataserver
+%type <event> moving_start
+%type <event> moving_end
+%type <event> rez
+%type <event> object_rez
+%type <event> remote_data
+%type <event> http_response
+%type <event> link_message
+%type <event> timer
+%type <event> chat
+%type <event> sensor
+%type <event> no_sensor
+%type <event> control
+%type <statement> compound_statement
+%type <statement> statement
+%type <statement> statements
+%type <statement> declaration
+%type <statement> ';'
+%type <statement> '@'
+%type <expression> nextforexpressionlist
+%type <expression> forexpressionlist
+%type <expression> nextfuncexpressionlist
+%type <expression> funcexpressionlist
+%type <expression> nextlistexpressionlist
+%type <expression> listexpressionlist
+%type <expression> unarypostfixexpression
+%type <expression> vector_initializer
+%type <expression> quaternion_initializer
+%type <expression> list_initializer
+%type <expression> lvalue
+%type <expression> '-'
+%type <expression> '!'
+%type <expression> '~'
+%type <expression> '='
+%type <expression> '<'
+%type <expression> '>'
+%type <expression> '+'
+%type <expression> '*'
+%type <expression> '/'
+%type <expression> '%'
+%type <expression> '&'
+%type <expression> '|'
+%type <expression> '^'
+%type <expression> ADD_ASSIGN
+%type <expression> SUB_ASSIGN
+%type <expression> MUL_ASSIGN
+%type <expression> DIV_ASSIGN
+%type <expression> MOD_ASSIGN
+%type <expression> EQ
+%type <expression> NEQ
+%type <expression> LEQ
+%type <expression> GEQ
+%type <expression> BOOLEAN_AND
+%type <expression> BOOLEAN_OR
+%type <expression> SHIFT_LEFT
+%type <expression> SHIFT_RIGHT
+%type <expression> INC_OP
+%type <expression> DEC_OP
+%type <expression> '('
+%type <expression> ')'
+%type <expression> PRINT
+%type <identifier> name_type
+%type <expression> expression
+%type <expression> unaryexpression
+%type <expression> typecast
+
+%right '=' MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN SUB_ASSIGN
+%left BOOLEAN_AND BOOLEAN_OR
+%left '|'
+%left '^'
+%left '&'
+%left EQ NEQ
+%left '<' LEQ '>' GEQ
+%left SHIFT_LEFT SHIFT_RIGHT
+%left '+' '-'
+%left '*' '/' '%'
+%right '!' '~' INC_OP DEC_OP
+%nonassoc INITIALIZER
+
+%%
+
+lscript_program
+ : globals states
+ {
+ $$ = new LLScriptScript($1, $2);
+ gAllocationManager->addAllocation($$);
+ gScriptp = $$;
+ }
+ | states
+ {
+ $$ = new LLScriptScript(NULL, $1);
+ gAllocationManager->addAllocation($$);
+ gScriptp = $$;
+ }
+ ;
+
+globals
+ : global
+ {
+ $$ = $1;
+ }
+ | global globals
+ {
+ $$ = $1;
+ $1->addGlobal($2);
+ }
+ ;
+
+global
+ : global_variable
+ {
+ $$ = new LLScritpGlobalStorage($1);
+ gAllocationManager->addAllocation($$);
+ }
+ | global_function
+ {
+ $$ = new LLScritpGlobalStorage($1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+name_type
+ : typename IDENTIFIER
+ {
+ $$ = new LLScriptIdentifier(gLine, gColumn, $2, $1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+global_variable
+ : name_type ';'
+ {
+ $$ = new LLScriptGlobalVariable(gLine, gColumn, $1->mType, $1, NULL);
+ gAllocationManager->addAllocation($$);
+ }
+ | name_type '=' simple_assignable ';'
+ {
+ $$ = new LLScriptGlobalVariable(gLine, gColumn, $1->mType, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+simple_assignable
+ : simple_assignable_no_list
+ {
+ $$ = $1;
+ }
+ | list_constant
+ {
+ $$ = $1;
+ }
+ ;
+
+simple_assignable_no_list
+ : IDENTIFIER
+ {
+ LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1);
+ gAllocationManager->addAllocation(id);
+ $$ = new LLScriptSAIdentifier(gLine, gColumn, id);
+ gAllocationManager->addAllocation($$);
+ }
+ | constant
+ {
+ $$ = new LLScriptSAConstant(gLine, gColumn, $1);
+ gAllocationManager->addAllocation($$);
+ }
+ | special_constant
+ {
+ $$ = $1;
+ }
+ ;
+
+constant
+ : INTEGER_CONSTANT
+ {
+ $$ = new LLScriptConstantInteger(gLine, gColumn, $1);
+ gAllocationManager->addAllocation($$);
+ }
+ | INTEGER_TRUE
+ {
+ $$ = new LLScriptConstantInteger(gLine, gColumn, $1);
+ gAllocationManager->addAllocation($$);
+ }
+ | INTEGER_FALSE
+ {
+ $$ = new LLScriptConstantInteger(gLine, gColumn, $1);
+ gAllocationManager->addAllocation($$);
+ }
+ | FP_CONSTANT
+ {
+ $$ = new LLScriptConstantFloat(gLine, gColumn, $1);
+ gAllocationManager->addAllocation($$);
+ }
+ | STRING_CONSTANT
+ {
+ $$ = new LLScriptConstantString(gLine, gColumn, $1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+special_constant
+ : vector_constant
+ {
+ $$ = $1;
+ }
+ | quaternion_constant
+ {
+ $$ = $1;
+ }
+ ;
+
+vector_constant
+ : '<' simple_assignable ',' simple_assignable ',' simple_assignable '>'
+ {
+ $$ = new LLScriptSAVector(gLine, gColumn, $2, $4, $6);
+ gAllocationManager->addAllocation($$);
+ }
+ | ZERO_VECTOR
+ {
+ LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
+ gAllocationManager->addAllocation(cf0);
+ LLScriptSAConstant *sa0 = new LLScriptSAConstant(gLine, gColumn, cf0);
+ gAllocationManager->addAllocation(sa0);
+ LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
+ gAllocationManager->addAllocation(cf1);
+ LLScriptSAConstant *sa1 = new LLScriptSAConstant(gLine, gColumn, cf1);
+ gAllocationManager->addAllocation(sa1);
+ LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
+ gAllocationManager->addAllocation(cf2);
+ LLScriptSAConstant *sa2 = new LLScriptSAConstant(gLine, gColumn, cf2);
+ gAllocationManager->addAllocation(sa2);
+ $$ = new LLScriptSAVector(gLine, gColumn, sa0, sa1, sa2);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+quaternion_constant
+ : '<' simple_assignable ',' simple_assignable ',' simple_assignable ',' simple_assignable '>'
+ {
+ $$ = new LLScriptSAQuaternion(gLine, gColumn, $2, $4, $6, $8);
+ gAllocationManager->addAllocation($$);
+ }
+ | ZERO_ROTATION
+ {
+ LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
+ gAllocationManager->addAllocation(cf0);
+ LLScriptSAConstant *sa0 = new LLScriptSAConstant(gLine, gColumn, cf0);
+ gAllocationManager->addAllocation(sa0);
+ LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
+ gAllocationManager->addAllocation(cf1);
+ LLScriptSAConstant *sa1 = new LLScriptSAConstant(gLine, gColumn, cf1);
+ gAllocationManager->addAllocation(sa1);
+ LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
+ gAllocationManager->addAllocation(cf2);
+ LLScriptSAConstant *sa2 = new LLScriptSAConstant(gLine, gColumn, cf2);
+ gAllocationManager->addAllocation(sa2);
+ LLScriptConstantFloat *cf3 = new LLScriptConstantFloat(gLine, gColumn, 1.f);
+ gAllocationManager->addAllocation(cf3);
+ LLScriptSAConstant *sa3 = new LLScriptSAConstant(gLine, gColumn, cf3);
+ gAllocationManager->addAllocation(sa3);
+ $$ = new LLScriptSAQuaternion(gLine, gColumn, sa0, sa1, sa2, sa3);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+list_constant
+ : '[' list_entries ']'
+ {
+ $$ = new LLScriptSAList(gLine, gColumn, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | '[' ']'
+ {
+ $$ = new LLScriptSAList(gLine, gColumn, NULL);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+list_entries
+ : list_entry
+ {
+ $$ = $1;
+ }
+ | list_entry ',' list_entries
+ {
+ $$ = $1;
+ $1->addAssignable($3);
+ }
+ ;
+
+list_entry
+ : simple_assignable_no_list
+ {
+ $$ = $1;
+ }
+ ;
+
+typename
+ : INTEGER
+ {
+ $$ = new LLScriptType(gLine, gColumn, LST_INTEGER);
+ gAllocationManager->addAllocation($$);
+ }
+ | FLOAT_TYPE
+ {
+ $$ = new LLScriptType(gLine, gColumn, LST_FLOATINGPOINT);
+ gAllocationManager->addAllocation($$);
+ }
+ | STRING
+ {
+ $$ = new LLScriptType(gLine, gColumn, LST_STRING);
+ gAllocationManager->addAllocation($$);
+ }
+ | LLKEY
+ {
+ $$ = new LLScriptType(gLine, gColumn, LST_KEY);
+ gAllocationManager->addAllocation($$);
+ }
+ | VECTOR
+ {
+ $$ = new LLScriptType(gLine, gColumn, LST_VECTOR);
+ gAllocationManager->addAllocation($$);
+ }
+ | QUATERNION
+ {
+ $$ = new LLScriptType(gLine, gColumn, LST_QUATERNION);
+ gAllocationManager->addAllocation($$);
+ }
+ | LIST
+ {
+ $$ = new LLScriptType(gLine, gColumn, LST_LIST);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+global_function
+ : IDENTIFIER '(' ')' compound_statement
+ {
+ LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1);
+ gAllocationManager->addAllocation(id);
+ $$ = new LLScriptGlobalFunctions(gLine, gColumn, NULL, id, NULL, $4);
+ gAllocationManager->addAllocation($$);
+ }
+ | name_type '(' ')' compound_statement
+ {
+ $$ = new LLScriptGlobalFunctions(gLine, gColumn, $1->mType, $1, NULL, $4);
+ gAllocationManager->addAllocation($$);
+ }
+ | IDENTIFIER '(' function_parameters ')' compound_statement
+ {
+ LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1);
+ gAllocationManager->addAllocation(id);
+ $$ = new LLScriptGlobalFunctions(gLine, gColumn, NULL, id, $3, $5);
+ gAllocationManager->addAllocation($$);
+ }
+ | name_type '(' function_parameters ')' compound_statement
+ {
+ $$ = new LLScriptGlobalFunctions(gLine, gColumn, $1->mType, $1, $3, $5);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+function_parameters
+ : function_parameter
+ {
+ $$ = $1;
+ }
+ | function_parameter ',' function_parameters
+ {
+ $$ = $1;
+ $1->addFunctionParameter($3);
+ }
+ ;
+
+function_parameter
+ : typename IDENTIFIER
+ {
+ LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
+ gAllocationManager->addAllocation(id);
+ $$ = new LLScriptFunctionDec(gLine, gColumn, $1, id);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+states
+ : default
+ {
+ $$ = $1;
+ }
+ | default other_states
+ {
+ $$ = $1;
+ $1->mNextp = $2;
+ }
+ ;
+
+other_states
+ : state
+ {
+ $$ = $1;
+ }
+ | state other_states
+ {
+ $$ = $1;
+ $1->addState($2);
+ }
+ ;
+
+default
+ : STATE_DEFAULT '{' state_body '}'
+ {
+ LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1);
+ gAllocationManager->addAllocation(id);
+ $$ = new LLScriptState(gLine, gColumn, LSSTYPE_DEFAULT, id, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+state
+ : STATE IDENTIFIER '{' state_body '}'
+ {
+ LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
+ gAllocationManager->addAllocation(id);
+ $$ = new LLScriptState(gLine, gColumn, LSSTYPE_USER, id, $4);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+state_body
+ : event
+ {
+ $$ = $1;
+ }
+ | event state_body
+ {
+ $$ = $1;
+ $1->addEvent($2);
+ }
+ ;
+
+event
+ : state_entry compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | state_exit compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | touch_start compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | touch compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | touch_end compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | collision_start compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | collision compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | collision_end compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | land_collision_start compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | land_collision compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | land_collision_end compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | timer compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | chat compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | sensor compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | no_sensor compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | at_target compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | not_at_target compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | at_rot_target compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | not_at_rot_target compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | money compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | email compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | run_time_permissions compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | inventory compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | attach compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | dataserver compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | control compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | moving_start compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | moving_end compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | rez compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | object_rez compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | link_message compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | remote_data compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | http_response compound_statement
+ {
+ $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+state_entry
+ : STATE_ENTRY '(' ')'
+ {
+ $$ = new LLScriptStateEntryEvent(gLine, gColumn);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+state_exit
+ : STATE_EXIT '(' ')'
+ {
+ $$ = new LLScriptStateExitEvent(gLine, gColumn);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+touch_start
+ : TOUCH_START '(' INTEGER IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ $$ = new LLScriptTouchStartEvent(gLine, gColumn, id1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+touch
+ : TOUCH '(' INTEGER IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ $$ = new LLScriptTouchEvent(gLine, gColumn, id1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+touch_end
+ : TOUCH_END '(' INTEGER IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ $$ = new LLScriptTouchEndEvent(gLine, gColumn, id1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+collision_start
+ : COLLISION_START '(' INTEGER IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ $$ = new LLScriptCollisionStartEvent(gLine, gColumn, id1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+collision
+ : COLLISION '(' INTEGER IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ $$ = new LLScriptCollisionEvent(gLine, gColumn, id1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+collision_end
+ : COLLISION_END '(' INTEGER IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ $$ = new LLScriptCollisionEndEvent(gLine, gColumn, id1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+land_collision_start
+ : LAND_COLLISION_START '(' VECTOR IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ $$ = new LLScriptLandCollisionStartEvent(gLine, gColumn, id1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+land_collision
+ : LAND_COLLISION '(' VECTOR IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ $$ = new LLScriptLandCollisionEvent(gLine, gColumn, id1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+land_collision_end
+ : LAND_COLLISION_END '(' VECTOR IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ $$ = new LLScriptLandCollisionEndEvent(gLine, gColumn, id1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+at_target
+ : AT_TARGET '(' INTEGER IDENTIFIER ',' VECTOR IDENTIFIER ',' VECTOR IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
+ gAllocationManager->addAllocation(id2);
+ LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
+ gAllocationManager->addAllocation(id3);
+ $$ = new LLScriptAtTarget(gLine, gColumn, id1, id2, id3);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+not_at_target
+ : NOT_AT_TARGET '(' ')'
+ {
+ $$ = new LLScriptNotAtTarget(gLine, gColumn);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+at_rot_target
+ : AT_ROT_TARGET '(' INTEGER IDENTIFIER ',' QUATERNION IDENTIFIER ',' QUATERNION IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
+ gAllocationManager->addAllocation(id2);
+ LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
+ gAllocationManager->addAllocation(id3);
+ $$ = new LLScriptAtRotTarget(gLine, gColumn, id1, id2, id3);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+not_at_rot_target
+ : NOT_AT_ROT_TARGET '(' ')'
+ {
+ $$ = new LLScriptNotAtRotTarget(gLine, gColumn);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+money
+ : MONEY '(' LLKEY IDENTIFIER ',' INTEGER IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
+ gAllocationManager->addAllocation(id2);
+ $$ = new LLScriptMoneyEvent(gLine, gColumn, id1, id2);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+email
+ : EMAIL '(' STRING IDENTIFIER ',' STRING IDENTIFIER ',' STRING IDENTIFIER ',' STRING IDENTIFIER ',' INTEGER IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
+ gAllocationManager->addAllocation(id2);
+ LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
+ gAllocationManager->addAllocation(id3);
+ LLScriptIdentifier *id4 = new LLScriptIdentifier(gLine, gColumn, $13);
+ gAllocationManager->addAllocation(id4);
+ LLScriptIdentifier *id5 = new LLScriptIdentifier(gLine, gColumn, $16);
+ gAllocationManager->addAllocation(id5);
+ $$ = new LLScriptEmailEvent(gLine, gColumn, id1, id2, id3, id4, id5);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+run_time_permissions
+ : RUN_TIME_PERMISSIONS '(' INTEGER IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ $$ = new LLScriptRTPEvent(gLine, gColumn, id1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+inventory
+ : INVENTORY '(' INTEGER IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ $$ = new LLScriptInventoryEvent(gLine, gColumn, id1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+attach
+ : ATTACH '(' LLKEY IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ $$ = new LLScriptAttachEvent(gLine, gColumn, id1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+dataserver
+ : DATASERVER '(' LLKEY IDENTIFIER ',' STRING IDENTIFIER')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
+ gAllocationManager->addAllocation(id2);
+ $$ = new LLScriptDataserverEvent(gLine, gColumn, id1, id2);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+moving_start
+ : MOVING_START '(' ')'
+ {
+ $$ = new LLScriptMovingStartEvent(gLine, gColumn);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+moving_end
+ : MOVING_END '(' ')'
+ {
+ $$ = new LLScriptMovingEndEvent(gLine, gColumn);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+timer
+ : TIMER '(' ')'
+ {
+ $$ = new LLScriptTimerEvent(gLine, gColumn);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+chat
+ : CHAT '(' INTEGER IDENTIFIER ',' STRING IDENTIFIER ',' LLKEY IDENTIFIER ',' STRING IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
+ gAllocationManager->addAllocation(id2);
+ LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
+ gAllocationManager->addAllocation(id3);
+ LLScriptIdentifier *id4 = new LLScriptIdentifier(gLine, gColumn, $13);
+ gAllocationManager->addAllocation(id4);
+ $$ = new LLScriptChatEvent(gLine, gColumn, id1, id2, id3, id4);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+sensor
+ : SENSOR '(' INTEGER IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ $$ = new LLScriptSensorEvent(gLine, gColumn, id1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+no_sensor
+ : NO_SENSOR '(' ')'
+ {
+ $$ = new LLScriptNoSensorEvent(gLine, gColumn);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+control
+ : CONTROL '(' LLKEY IDENTIFIER ',' INTEGER IDENTIFIER ',' INTEGER IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
+ gAllocationManager->addAllocation(id2);
+ LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
+ gAllocationManager->addAllocation(id3);
+ $$ = new LLScriptControlEvent(gLine, gColumn, id1, id2, id3);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+rez
+ : REZ '(' INTEGER IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ $$ = new LLScriptRezEvent(gLine, gColumn, id1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+object_rez
+ : OBJECT_REZ '(' LLKEY IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ $$ = new LLScriptObjectRezEvent(gLine, gColumn, id1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+link_message
+ : LINK_MESSAGE '(' INTEGER IDENTIFIER ',' INTEGER IDENTIFIER ',' STRING IDENTIFIER ',' LLKEY IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
+ gAllocationManager->addAllocation(id2);
+ LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
+ gAllocationManager->addAllocation(id3);
+ LLScriptIdentifier *id4 = new LLScriptIdentifier(gLine, gColumn, $13);
+ gAllocationManager->addAllocation(id4);
+ $$ = new LLScriptLinkMessageEvent(gLine, gColumn, id1, id2, id3, id4);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+remote_data
+ : REMOTE_DATA '(' INTEGER IDENTIFIER ',' LLKEY IDENTIFIER ',' LLKEY IDENTIFIER ',' STRING IDENTIFIER ',' INTEGER IDENTIFIER ',' STRING IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
+ gAllocationManager->addAllocation(id2);
+ LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
+ gAllocationManager->addAllocation(id3);
+ LLScriptIdentifier *id4 = new LLScriptIdentifier(gLine, gColumn, $13);
+ gAllocationManager->addAllocation(id4);
+ LLScriptIdentifier *id5 = new LLScriptIdentifier(gLine, gColumn, $16);
+ gAllocationManager->addAllocation(id4);
+ LLScriptIdentifier *id6 = new LLScriptIdentifier(gLine, gColumn, $19);
+ gAllocationManager->addAllocation(id4);
+ $$ = new LLScriptRemoteEvent(gLine, gColumn, id1, id2, id3, id4, id5, id6);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+http_response
+ : HTTP_RESPONSE '(' LLKEY IDENTIFIER ',' INTEGER IDENTIFIER ',' LIST IDENTIFIER ',' STRING IDENTIFIER ')'
+ {
+ LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(id1);
+ LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
+ gAllocationManager->addAllocation(id2);
+ LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
+ gAllocationManager->addAllocation(id3);
+ LLScriptIdentifier *id4 = new LLScriptIdentifier(gLine, gColumn, $13);
+ gAllocationManager->addAllocation(id4);
+ $$ = new LLScriptHTTPResponseEvent(gLine, gColumn, id1, id2, id3, id4);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+compound_statement
+ : '{' '}'
+ {
+ $$ = new LLScriptCompoundStatement(gLine, gColumn, NULL);
+ gAllocationManager->addAllocation($$);
+ }
+ | '{' statements '}'
+ {
+ $$ = new LLScriptCompoundStatement(gLine, gColumn, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+statements
+ : statement
+ {
+ $$ = $1;
+ }
+ | statements statement
+ {
+ $$ = new LLScriptStatementSequence(gLine, gColumn, $1, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+statement
+ : ';'
+ {
+ $$ = new LLScriptNOOP(gLine, gColumn);
+ gAllocationManager->addAllocation($$);
+ }
+ | STATE IDENTIFIER ';'
+ {
+ LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
+ gAllocationManager->addAllocation(id);
+ $$ = new LLScriptStateChange(gLine, gColumn, id);
+ gAllocationManager->addAllocation($$);
+ }
+ | STATE STATE_DEFAULT ';'
+ {
+ LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
+ gAllocationManager->addAllocation(id);
+ $$ = new LLScriptStateChange(gLine, gColumn, id);
+ gAllocationManager->addAllocation($$);
+ }
+ | JUMP IDENTIFIER ';'
+ {
+ LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
+ gAllocationManager->addAllocation(id);
+ $$ = new LLScriptJump(gLine, gColumn, id);
+ gAllocationManager->addAllocation($$);
+ }
+ | '@' IDENTIFIER ';'
+ {
+ LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
+ gAllocationManager->addAllocation(id);
+ $$ = new LLScriptLabel(gLine, gColumn, id);
+ gAllocationManager->addAllocation($$);
+ }
+ | RETURN expression ';'
+ {
+ $$ = new LLScriptReturn(gLine, gColumn, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | RETURN ';'
+ {
+ $$ = new LLScriptReturn(gLine, gColumn, NULL);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression ';'
+ {
+ $$ = new LLScriptExpressionStatement(gLine, gColumn, $1);
+ gAllocationManager->addAllocation($$);
+ }
+ | declaration ';'
+ {
+ $$ = $1;
+ }
+ | compound_statement
+ {
+ $$ = $1;
+ }
+ | IF '(' expression ')' statement %prec LOWER_THAN_ELSE
+ {
+ $$ = new LLScriptIf(gLine, gColumn, $3, $5);
+ $5->mAllowDeclarations = FALSE;
+ gAllocationManager->addAllocation($$);
+ }
+ | IF '(' expression ')' statement ELSE statement
+ {
+ $$ = new LLScriptIfElse(gLine, gColumn, $3, $5, $7);
+ $5->mAllowDeclarations = FALSE;
+ $7->mAllowDeclarations = FALSE;
+ gAllocationManager->addAllocation($$);
+ }
+ | FOR '(' forexpressionlist ';' expression ';' forexpressionlist ')' statement
+ {
+ $$ = new LLScriptFor(gLine, gColumn, $3, $5, $7, $9);
+ $9->mAllowDeclarations = FALSE;
+ gAllocationManager->addAllocation($$);
+ }
+ | DO statement WHILE '(' expression ')' ';'
+ {
+ $$ = new LLScriptDoWhile(gLine, gColumn, $2, $5);
+ $2->mAllowDeclarations = FALSE;
+ gAllocationManager->addAllocation($$);
+ }
+ | WHILE '(' expression ')' statement
+ {
+ $$ = new LLScriptWhile(gLine, gColumn, $3, $5);
+ $5->mAllowDeclarations = FALSE;
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+declaration
+ : typename IDENTIFIER
+ {
+ LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
+ gAllocationManager->addAllocation(id);
+ $$ = new LLScriptDeclaration(gLine, gColumn, $1, id, NULL);
+ gAllocationManager->addAllocation($$);
+ }
+ | typename IDENTIFIER '=' expression
+ {
+ LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2);
+ gAllocationManager->addAllocation(id);
+ $$ = new LLScriptDeclaration(gLine, gColumn, $1, id, $4);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+forexpressionlist
+ : /* empty */
+ {
+ $$ = NULL;
+ }
+ | nextforexpressionlist
+ {
+ $$ = $1;
+ }
+ ;
+
+nextforexpressionlist
+ : expression
+ {
+ $$ = new LLScriptForExpressionList(gLine, gColumn, $1, NULL);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression ',' nextforexpressionlist
+ {
+ $$ = new LLScriptForExpressionList(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+funcexpressionlist
+ : /* empty */
+ {
+ $$ = NULL;
+ }
+ | nextfuncexpressionlist
+ {
+ $$ = $1;
+ }
+ ;
+
+nextfuncexpressionlist
+ : expression
+ {
+ $$ = new LLScriptFuncExpressionList(gLine, gColumn, $1, NULL);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression ',' nextfuncexpressionlist
+ {
+ $$ = new LLScriptFuncExpressionList(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+listexpressionlist
+ : /* empty */
+ {
+ $$ = NULL;
+ }
+ | nextlistexpressionlist
+ {
+ $$ = $1;
+ }
+ ;
+
+nextlistexpressionlist
+ : expression
+ {
+ $$ = new LLScriptListExpressionList(gLine, gColumn, $1, NULL);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression ',' nextlistexpressionlist
+ {
+ $$ = new LLScriptListExpressionList(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+expression
+ : unaryexpression
+ {
+ $$ = $1;
+ }
+ | lvalue '=' expression
+ {
+ $$ = new LLScriptAssignment(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | lvalue ADD_ASSIGN expression
+ {
+ $$ = new LLScriptAddAssignment(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | lvalue SUB_ASSIGN expression
+ {
+ $$ = new LLScriptSubAssignment(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | lvalue MUL_ASSIGN expression
+ {
+ $$ = new LLScriptMulAssignment(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | lvalue DIV_ASSIGN expression
+ {
+ $$ = new LLScriptDivAssignment(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | lvalue MOD_ASSIGN expression
+ {
+ $$ = new LLScriptModAssignment(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression EQ expression
+ {
+ $$ = new LLScriptEquality(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression NEQ expression
+ {
+ $$ = new LLScriptNotEquals(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression LEQ expression
+ {
+ $$ = new LLScriptLessEquals(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression GEQ expression
+ {
+ $$ = new LLScriptGreaterEquals(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression '<' expression
+ {
+ $$ = new LLScriptLessThan(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression '>' expression
+ {
+ $$ = new LLScriptGreaterThan(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression '+' expression
+ {
+ $$ = new LLScriptPlus(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression '-' expression
+ {
+ $$ = new LLScriptMinus(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression '*' expression
+ {
+ $$ = new LLScriptTimes(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression '/' expression
+ {
+ $$ = new LLScriptDivide(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression '%' expression
+ {
+ $$ = new LLScriptMod(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression '&' expression
+ {
+ $$ = new LLScriptBitAnd(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression '|' expression
+ {
+ $$ = new LLScriptBitOr(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression '^' expression
+ {
+ $$ = new LLScriptBitXor(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression BOOLEAN_AND expression
+ {
+ $$ = new LLScriptBooleanAnd(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression BOOLEAN_OR expression
+ {
+ $$ = new LLScriptBooleanOr(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression SHIFT_LEFT expression
+ {
+ $$ = new LLScriptShiftLeft(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | expression SHIFT_RIGHT expression
+ {
+ $$ = new LLScriptShiftRight(gLine, gColumn, $1, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+unaryexpression
+ : '-' expression
+ {
+ $$ = new LLScriptUnaryMinus(gLine, gColumn, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | '!' expression
+ {
+ $$ = new LLScriptBooleanNot(gLine, gColumn, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | '~' expression
+ {
+ $$ = new LLScriptBitNot(gLine, gColumn, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | INC_OP lvalue
+ {
+ $$ = new LLScriptPreIncrement(gLine, gColumn, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | DEC_OP lvalue
+ {
+ $$ = new LLScriptPreDecrement(gLine, gColumn, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ | typecast
+ {
+ $$ = $1;
+ }
+ | unarypostfixexpression
+ {
+ $$ = $1;
+ }
+ | '(' expression ')'
+ {
+ $$ = new LLScriptParenthesis(gLine, gColumn, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+typecast
+ : '(' typename ')' lvalue
+ {
+ $$ = new LLScriptTypeCast(gLine, gColumn, $2, $4);
+ gAllocationManager->addAllocation($$);
+ }
+ | '(' typename ')' constant
+ {
+ LLScriptConstantExpression *temp = new LLScriptConstantExpression(gLine, gColumn, $4);
+ gAllocationManager->addAllocation(temp);
+ $$ = new LLScriptTypeCast(gLine, gColumn, $2, temp);
+ gAllocationManager->addAllocation($$);
+ }
+ | '(' typename ')' unarypostfixexpression
+ {
+ $$ = new LLScriptTypeCast(gLine, gColumn, $2, $4);
+ gAllocationManager->addAllocation($$);
+ }
+ | '(' typename ')' '(' expression ')'
+ {
+ $$ = new LLScriptTypeCast(gLine, gColumn, $2, $5);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+unarypostfixexpression
+ : vector_initializer
+ {
+ $$ = $1;
+ }
+ | quaternion_initializer
+ {
+ $$ = $1;
+ }
+ | list_initializer
+ {
+ $$ = $1;
+ }
+ | lvalue
+ {
+ $$ = $1;
+ }
+ | lvalue INC_OP
+ {
+ $$ = new LLScriptPostIncrement(gLine, gColumn, $1);
+ gAllocationManager->addAllocation($$);
+ }
+ | lvalue DEC_OP
+ {
+ $$ = new LLScriptPostDecrement(gLine, gColumn, $1);
+ gAllocationManager->addAllocation($$);
+ }
+ | IDENTIFIER '(' funcexpressionlist ')'
+ {
+ LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1);
+ gAllocationManager->addAllocation(id);
+ $$ = new LLScriptFunctionCall(gLine, gColumn, id, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | PRINT '(' expression ')'
+ {
+ $$ = new LLScriptPrint(gLine, gColumn, $3);
+ gAllocationManager->addAllocation($$);
+ }
+ | constant
+ {
+ $$ = new LLScriptConstantExpression(gLine, gColumn, $1);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+vector_initializer
+ : '<' expression ',' expression ',' expression '>' %prec INITIALIZER
+ {
+ $$ = new LLScriptVectorInitializer(gLine, gColumn, $2, $4, $6);
+ gAllocationManager->addAllocation($$);
+ }
+ | ZERO_VECTOR
+ {
+ LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
+ gAllocationManager->addAllocation(cf0);
+ LLScriptConstantExpression *sa0 = new LLScriptConstantExpression(gLine, gColumn, cf0);
+ gAllocationManager->addAllocation(sa0);
+ LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
+ gAllocationManager->addAllocation(cf1);
+ LLScriptConstantExpression *sa1 = new LLScriptConstantExpression(gLine, gColumn, cf1);
+ gAllocationManager->addAllocation(sa1);
+ LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
+ gAllocationManager->addAllocation(cf2);
+ LLScriptConstantExpression *sa2 = new LLScriptConstantExpression(gLine, gColumn, cf2);
+ gAllocationManager->addAllocation(sa2);
+ $$ = new LLScriptVectorInitializer(gLine, gColumn, sa0, sa1, sa2);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+quaternion_initializer
+ : '<' expression ',' expression ',' expression ',' expression '>' %prec INITIALIZER
+ {
+ $$ = new LLScriptQuaternionInitializer(gLine, gColumn, $2, $4, $6, $8);
+ gAllocationManager->addAllocation($$);
+ }
+ | ZERO_ROTATION
+ {
+ LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
+ gAllocationManager->addAllocation(cf0);
+ LLScriptConstantExpression *sa0 = new LLScriptConstantExpression(gLine, gColumn, cf0);
+ gAllocationManager->addAllocation(sa0);
+ LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
+ gAllocationManager->addAllocation(cf1);
+ LLScriptConstantExpression *sa1 = new LLScriptConstantExpression(gLine, gColumn, cf1);
+ gAllocationManager->addAllocation(sa1);
+ LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f);
+ gAllocationManager->addAllocation(cf2);
+ LLScriptConstantExpression *sa2 = new LLScriptConstantExpression(gLine, gColumn, cf2);
+ gAllocationManager->addAllocation(sa2);
+ LLScriptConstantFloat *cf3 = new LLScriptConstantFloat(gLine, gColumn, 1.f);
+ gAllocationManager->addAllocation(cf3);
+ LLScriptConstantExpression *sa3 = new LLScriptConstantExpression(gLine, gColumn, cf3);
+ gAllocationManager->addAllocation(sa3);
+ $$ = new LLScriptQuaternionInitializer(gLine, gColumn, sa0, sa1, sa2, sa3);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+list_initializer
+ : '[' listexpressionlist ']' %prec INITIALIZER
+ {
+ $$ = new LLScriptListInitializer(gLine, gColumn, $2);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+lvalue
+ : IDENTIFIER
+ {
+ LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1);
+ gAllocationManager->addAllocation(id);
+ $$ = new LLScriptLValue(gLine, gColumn, id, NULL);
+ gAllocationManager->addAllocation($$);
+ }
+ | IDENTIFIER PERIOD IDENTIFIER
+ {
+ LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1);
+ gAllocationManager->addAllocation(id);
+ LLScriptIdentifier *ac = new LLScriptIdentifier(gLine, gColumn, $3);
+ gAllocationManager->addAllocation(id);
+ $$ = new LLScriptLValue(gLine, gColumn, id, ac);
+ gAllocationManager->addAllocation($$);
+ }
+ ;
+
+%%
diff --git a/indra/lscript/lscript_compile/lscript_alloc.cpp b/indra/lscript/lscript_compile/lscript_alloc.cpp
new file mode 100644
index 0000000000..3df68c0bd4
--- /dev/null
+++ b/indra/lscript/lscript_compile/lscript_alloc.cpp
@@ -0,0 +1,8 @@
+/**
+ * @file lscript_alloc.cpp
+ * @brief Allocation tracking
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
diff --git a/indra/lscript/lscript_compile/lscript_bytecode.cpp b/indra/lscript/lscript_compile/lscript_bytecode.cpp
new file mode 100644
index 0000000000..1cf8cd7f28
--- /dev/null
+++ b/indra/lscript/lscript_compile/lscript_bytecode.cpp
@@ -0,0 +1,299 @@
+/**
+ * @file lscript_bytecode.cpp
+ * @brief classes to build actual bytecode
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "linden_common.h"
+
+#include "lscript_bytecode.h"
+#include "lscript_error.h"
+
+#if defined(_MSC_VER)
+# pragma warning(disable: 4102) // 'yy_more' : unreferenced label
+# pragma warning(disable: 4702) // unreachable code
+#endif
+
+LLScriptJumpTable::LLScriptJumpTable()
+{
+}
+
+LLScriptJumpTable::~LLScriptJumpTable()
+{
+ mLabelMap.deleteAllData();
+ mJumpMap.deleteAllData();
+}
+
+void LLScriptJumpTable::addLabel(char *name, S32 offset)
+{
+ char *temp = gScopeStringTable->addString(name);
+ mLabelMap[temp] = new S32(offset);
+}
+
+void LLScriptJumpTable::addJump(char *name, S32 offset)
+{
+ char *temp = gScopeStringTable->addString(name);
+ mJumpMap[temp] = new S32(offset);
+}
+
+
+LLScriptByteCodeChunk::LLScriptByteCodeChunk(BOOL b_need_jumps)
+: mCodeChunk(NULL), mCurrentOffset(0), mJumpTable(NULL)
+{
+ if (b_need_jumps)
+ {
+ mJumpTable = new LLScriptJumpTable();
+ }
+}
+
+LLScriptByteCodeChunk::~LLScriptByteCodeChunk()
+{
+ delete [] mCodeChunk;
+ delete mJumpTable;
+}
+
+void LLScriptByteCodeChunk::addByte(U8 byte)
+{
+ if (mCodeChunk)
+ {
+ U8 *temp = new U8[mCurrentOffset + 1];
+ memcpy(temp, mCodeChunk, mCurrentOffset);
+ delete [] mCodeChunk;
+ mCodeChunk = temp;
+ }
+ else
+ {
+ mCodeChunk = new U8[1];
+ }
+ *(mCodeChunk + mCurrentOffset++) = byte;
+}
+
+void LLScriptByteCodeChunk::addU16(U16 data)
+{
+ U8 temp[2];
+ S32 offset = 0;
+ u162bytestream(temp, offset, data);
+ addBytes(temp, 2);
+}
+
+void LLScriptByteCodeChunk::addBytes(U8 *bytes, S32 size)
+{
+ if (mCodeChunk)
+ {
+ U8 *temp = new U8[mCurrentOffset + size];
+ memcpy(temp, mCodeChunk, mCurrentOffset);
+ delete [] mCodeChunk;
+ mCodeChunk = temp;
+ }
+ else
+ {
+ mCodeChunk = new U8[size];
+ }
+ memcpy(mCodeChunk + mCurrentOffset, bytes, size);
+ mCurrentOffset += size;
+}
+
+void LLScriptByteCodeChunk::addBytes(char *bytes, S32 size)
+{
+ if (mCodeChunk)
+ {
+ U8 *temp = new U8[mCurrentOffset + size];
+ memcpy(temp, mCodeChunk, mCurrentOffset);
+ delete [] mCodeChunk;
+ mCodeChunk = temp;
+ }
+ else
+ {
+ mCodeChunk = new U8[size];
+ }
+ memcpy(mCodeChunk + mCurrentOffset, bytes, size);
+ mCurrentOffset += size;
+}
+
+void LLScriptByteCodeChunk::addBytes(S32 size)
+{
+ if (mCodeChunk)
+ {
+ U8 *temp = new U8[mCurrentOffset + size];
+ memcpy(temp, mCodeChunk, mCurrentOffset);
+ delete [] mCodeChunk;
+ mCodeChunk = temp;
+ }
+ else
+ {
+ mCodeChunk = new U8[size];
+ }
+ memset(mCodeChunk + mCurrentOffset, 0, size);
+ mCurrentOffset += size;
+}
+
+void LLScriptByteCodeChunk::addBytesDontInc(S32 size)
+{
+ if (mCodeChunk)
+ {
+ U8 *temp = new U8[mCurrentOffset + size];
+ memcpy(temp, mCodeChunk, mCurrentOffset);
+ delete [] mCodeChunk;
+ mCodeChunk = temp;
+ }
+ else
+ {
+ mCodeChunk = new U8[size];
+ }
+ memset(mCodeChunk + mCurrentOffset, 0, size);
+}
+
+void LLScriptByteCodeChunk::addInteger(S32 value)
+{
+ U8 temp[4];
+ S32 offset = 0;
+ integer2bytestream(temp, offset, value);
+ addBytes(temp, 4);
+}
+
+void LLScriptByteCodeChunk::addFloat(F32 value)
+{
+ U8 temp[4];
+ S32 offset = 0;
+ float2bytestream(temp, offset, value);
+ addBytes(temp, 4);
+}
+
+void LLScriptByteCodeChunk::addLabel(char *name)
+{
+ if (mJumpTable)
+ {
+ mJumpTable->addLabel(name, mCurrentOffset);
+ }
+}
+
+void LLScriptByteCodeChunk::addJump(char *name)
+{
+ if (mJumpTable)
+ {
+ mJumpTable->addJump(name, mCurrentOffset);
+ }
+}
+
+// format is Byte 0: jump op code Byte 1 - 4: offset
+// the jump position points to Byte 5, so we need to add the data at
+// offset - 4, offset - 3, offset - 2, and offset - 1
+
+// offset is label - jump
+
+void LLScriptByteCodeChunk::connectJumps()
+{
+ char *jump;
+ S32 offset, jumppos;
+
+ if (mJumpTable)
+ {
+ for (jump = mJumpTable->mJumpMap.getFirstKey();
+ jump;
+ jump = mJumpTable->mJumpMap.getNextKey())
+ {
+ jumppos = *mJumpTable->mJumpMap[jump];
+ offset = *mJumpTable->mLabelMap[jump] - jumppos;
+ jumppos = jumppos - 4;
+ integer2bytestream(mCodeChunk, jumppos, offset);
+ }
+ }
+}
+
+LLScriptScriptCodeChunk::LLScriptScriptCodeChunk(S32 total_size)
+: mTotalSize(total_size), mCompleteCode(NULL)
+{
+ mRegisters = new LLScriptByteCodeChunk(FALSE);
+ mGlobalVariables = new LLScriptByteCodeChunk(FALSE);
+ mGlobalFunctions = new LLScriptByteCodeChunk(FALSE);
+ mStates = new LLScriptByteCodeChunk(FALSE);
+ mHeap = new LLScriptByteCodeChunk(FALSE);
+}
+
+LLScriptScriptCodeChunk::~LLScriptScriptCodeChunk()
+{
+ delete mRegisters;
+ delete mGlobalVariables;
+ delete mGlobalFunctions;
+ delete mStates;
+ delete mHeap;
+ delete [] mCompleteCode;
+}
+
+void LLScriptScriptCodeChunk::build(FILE *efp, FILE *bcfp)
+{
+ S32 code_data_size = mRegisters->mCurrentOffset +
+ mGlobalVariables->mCurrentOffset +
+ mGlobalFunctions->mCurrentOffset +
+ mStates->mCurrentOffset +
+ mHeap->mCurrentOffset;
+
+ S32 offset = 0;
+
+ if (code_data_size < mTotalSize)
+ {
+ mCompleteCode = new U8[mTotalSize];
+ memset(mCompleteCode, 0, mTotalSize);
+
+ memcpy(mCompleteCode, mRegisters->mCodeChunk, mRegisters->mCurrentOffset);
+ offset += mRegisters->mCurrentOffset;
+
+ set_register(mCompleteCode, LREG_IP, 0);
+ set_register(mCompleteCode, LREG_VN, LSL2_VERSION_NUMBER);
+ set_event_register(mCompleteCode, LREG_IE, 0, LSL2_CURRENT_MAJOR_VERSION);
+ set_register(mCompleteCode, LREG_BP, mTotalSize - 1);
+ set_register(mCompleteCode, LREG_SP, mTotalSize - 1);
+
+ set_register(mCompleteCode, LREG_GVR, offset);
+
+ memcpy(mCompleteCode + offset, mGlobalVariables->mCodeChunk, mGlobalVariables->mCurrentOffset);
+ offset += mGlobalVariables->mCurrentOffset;
+
+ set_register(mCompleteCode, LREG_GFR, offset);
+
+ memcpy(mCompleteCode + offset, mGlobalFunctions->mCodeChunk, mGlobalFunctions->mCurrentOffset);
+ offset += mGlobalFunctions->mCurrentOffset;
+
+ set_register(mCompleteCode, LREG_SR, offset);
+ // zero is, by definition the default state
+ set_register(mCompleteCode, LREG_CS, 0);
+ set_register(mCompleteCode, LREG_NS, 0);
+ set_event_register(mCompleteCode, LREG_CE, LSCRIPTStateBitField[LSTT_STATE_ENTRY], LSL2_CURRENT_MAJOR_VERSION);
+ S32 default_state_offset = 0;
+ if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)
+ {
+ default_state_offset = 8;
+ }
+ else
+ {
+ default_state_offset = 4;
+ }
+ set_event_register(mCompleteCode, LREG_ER, bytestream2u64(mStates->mCodeChunk, default_state_offset), LSL2_CURRENT_MAJOR_VERSION);
+
+ memcpy(mCompleteCode + offset, mStates->mCodeChunk, mStates->mCurrentOffset);
+ offset += mStates->mCurrentOffset;
+
+ set_register(mCompleteCode, LREG_HR, offset);
+
+ memcpy(mCompleteCode + offset, mHeap->mCodeChunk, mHeap->mCurrentOffset);
+ offset += mHeap->mCurrentOffset;
+
+ set_register(mCompleteCode, LREG_HP, offset);
+ set_register(mCompleteCode, LREG_FR, 0);
+ set_register(mCompleteCode, LREG_SLR, 0);
+ set_register(mCompleteCode, LREG_ESR, 0);
+ set_register(mCompleteCode, LREG_PR, 0);
+ set_register(mCompleteCode, LREG_TM, mTotalSize);
+
+
+ fwrite(mCompleteCode, 1, mTotalSize, bcfp);
+ }
+ else
+ {
+ gErrorToText.writeError(efp, 0, 0, LSERROR_ASSEMBLE_OUT_OF_MEMORY);
+ }
+}
+
+LLScriptScriptCodeChunk *gScriptCodeChunk;
diff --git a/indra/lscript/lscript_compile/lscript_bytecode.h b/indra/lscript/lscript_compile/lscript_bytecode.h
new file mode 100644
index 0000000000..afe7f9411b
--- /dev/null
+++ b/indra/lscript/lscript_compile/lscript_bytecode.h
@@ -0,0 +1,71 @@
+/**
+ * @file lscript_bytecode.h
+ * @brief classes to build actual bytecode
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LL_LSCRIPT_BYTECODE_H
+#define LL_LSCRIPT_BYTECODE_H
+
+#include "lscript_byteconvert.h"
+#include "lscript_scope.h"
+
+class LLScriptJumpTable
+{
+public:
+ LLScriptJumpTable();
+ ~LLScriptJumpTable();
+
+ void addLabel(char *name, S32 offset);
+ void addJump(char *name, S32 offset);
+
+ LLMap<char *, S32 *> mLabelMap;
+ LLMap<char *, S32 *> mJumpMap;
+};
+
+class LLScriptByteCodeChunk
+{
+public:
+ LLScriptByteCodeChunk(BOOL b_need_jumps);
+ ~LLScriptByteCodeChunk();
+
+ void addByte(U8 byte);
+ void addU16(U16 data);
+ void addBytes(U8 *bytes, S32 size);
+ void addBytes(char *bytes, S32 size);
+ void addBytes(S32 size);
+ void addBytesDontInc(S32 size);
+ void addInteger(S32 value);
+ void addFloat(F32 value);
+ void addLabel(char *name);
+ void addJump(char *name);
+ void connectJumps();
+
+ U8 *mCodeChunk;
+ S32 mCurrentOffset;
+ LLScriptJumpTable *mJumpTable;
+};
+
+class LLScriptScriptCodeChunk
+{
+public:
+ LLScriptScriptCodeChunk(S32 total_size);
+ ~LLScriptScriptCodeChunk();
+
+ void build(FILE *efp, FILE *bcfp);
+
+ LLScriptByteCodeChunk *mRegisters;
+ LLScriptByteCodeChunk *mGlobalVariables;
+ LLScriptByteCodeChunk *mGlobalFunctions;
+ LLScriptByteCodeChunk *mStates;
+ LLScriptByteCodeChunk *mHeap;
+ S32 mTotalSize;
+ U8 *mCompleteCode;
+};
+
+extern LLScriptScriptCodeChunk *gScriptCodeChunk;
+
+#endif
+
diff --git a/indra/lscript/lscript_compile/lscript_error.cpp b/indra/lscript/lscript_compile/lscript_error.cpp
new file mode 100644
index 0000000000..0bc51a65ed
--- /dev/null
+++ b/indra/lscript/lscript_compile/lscript_error.cpp
@@ -0,0 +1,77 @@
+/**
+ * @file lscript_error.cpp
+ * @brief error reporting class and strings
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "linden_common.h"
+
+#include "lscript_error.h"
+
+S32 gColumn = 0;
+S32 gLine = 0;
+S32 gInternalColumn = 0;
+S32 gInternalLine = 0;
+
+LLScriptGenerateErrorText gErrorToText;
+
+void LLScriptFilePosition::fdotabs(FILE *fp, S32 tabs, S32 tabsize)
+{
+ S32 i;
+ for (i = 0; i < tabs * tabsize; i++)
+ {
+ fprintf(fp, " ");
+ }
+}
+
+char *gWarningText[LSWARN_EOF] =
+{
+ "INVALID",
+ "Dead code found beyond return statement"
+};
+
+char *gErrorText[LSERROR_EOF] =
+{
+ "INVALID",
+ "Syntax error",
+ "Not all code paths return a value",
+ "Function returns a value but return statement doesn't",
+ "Return statement type doesn't match function return type",
+ "Global functions can't change state",
+ "Name previously declared within scope",
+ "Name not defined within scope",
+ "Type mismatch",
+ "Expression must act on LValue",
+ "Byte code assembly failed -- out of memory",
+ "Function call mismatches type or number of arguments",
+ "Use of vector or quaternion method on incorrect type",
+ "Lists can't be included in lists",
+ "Unitialized variables can't be included in lists",
+ "Declaration requires a new scope -- use { and }"
+};
+
+void LLScriptGenerateErrorText::writeWarning(FILE *fp, LLScriptFilePosition *pos, LSCRIPTWarnings warning)
+{
+ fprintf(fp, "(%d, %d) : WARNING : %s\n", pos->mLineNumber, pos->mColumnNumber, gWarningText[warning]);
+ mTotalWarnings++;
+}
+
+void LLScriptGenerateErrorText::writeWarning(FILE *fp, S32 line, S32 col, LSCRIPTWarnings warning)
+{
+ fprintf(fp, "(%d, %d) : WARNING : %s\n", line, col, gWarningText[warning]);
+ mTotalWarnings++;
+}
+
+void LLScriptGenerateErrorText::writeError(FILE *fp, LLScriptFilePosition *pos, LSCRIPTErrors error)
+{
+ fprintf(fp, "(%d, %d) : ERROR : %s\n", pos->mLineNumber, pos->mColumnNumber, gErrorText[error]);
+ mTotalErrors++;
+}
+
+void LLScriptGenerateErrorText::writeError(FILE *fp, S32 line, S32 col, LSCRIPTErrors error)
+{
+ fprintf(fp, "(%d, %d) : ERROR : %s\n", line, col, gErrorText[error]);
+ mTotalErrors++;
+}
diff --git a/indra/lscript/lscript_compile/lscript_error.h b/indra/lscript/lscript_compile/lscript_error.h
new file mode 100644
index 0000000000..4ad7b60dd8
--- /dev/null
+++ b/indra/lscript/lscript_compile/lscript_error.h
@@ -0,0 +1,132 @@
+/**
+ * @file lscript_error.h
+ * @brief error reporting class and strings
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LL_LSCRIPT_ERROR_H
+#define LL_LSCRIPT_ERROR_H
+
+#include <stdio.h>
+#include "stdtypes.h"
+#include "lscript_scope.h"
+
+
+typedef enum e_lscript_compile_pass
+{
+ LSCP_INVALID,
+ LSCP_PRETTY_PRINT,
+ LSCP_PRUNE,
+ LSCP_SCOPE_PASS1,
+ LSCP_SCOPE_PASS2,
+ LSCP_TYPE,
+ LSCP_RESOURCE,
+ LSCP_EMIT_ASSEMBLY,
+ LSCP_EMIT_BYTE_CODE,
+ LSCP_DETERMINE_HANDLERS,
+ LSCP_LIST_BUILD_SIMPLE,
+ LSCP_TO_STACK,
+ LSCP_BUILD_FUNCTION_ARGS,
+ LSCP_EMIT_CIL_ASSEMBLY,
+ LSCP_EOF
+} LSCRIPTCompilePass;
+
+typedef enum e_lscript_prune_type
+{
+ LSPRUNE_INVALID,
+ LSPRUNE_GLOBAL_VOIDS,
+ LSPRUNE_GLOBAL_NON_VOIDS,
+ LSPRUNE_EVENTS,
+ LSPRUNE_DEAD_CODE,
+ LSPRUNE_EOF
+} LSCRIPTPruneType;
+
+extern S32 gColumn;
+extern S32 gLine;
+extern S32 gInternalColumn;
+extern S32 gInternalLine;
+
+
+// used to describe where in the file this piece is
+class LLScriptByteCodeChunk;
+
+class LLScriptLibData;
+
+class LLScriptFilePosition
+{
+public:
+ LLScriptFilePosition(S32 line, S32 col)
+ : mLineNumber(line), mColumnNumber(col), mByteOffset(0), mByteSize(0)
+ {
+ }
+
+ virtual ~LLScriptFilePosition() {}
+
+ virtual void recurse(FILE *fp, S32 tabs, S32 tabsize,
+ LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg,
+ LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count,
+ LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata) = 0;
+ virtual S32 getSize() = 0;
+
+ void fdotabs(FILE *fp, S32 tabs, S32 tabsize);
+
+ S32 mLineNumber;
+ S32 mColumnNumber;
+
+ S32 mByteOffset;
+ S32 mByteSize;
+};
+
+typedef enum e_lscript_warnings
+{
+ LSWARN_INVALID,
+ LSWARN_DEAD_CODE,
+ LSWARN_EOF
+} LSCRIPTWarnings;
+
+typedef enum e_lscript_errors
+{
+ LSERROR_INVALID,
+ LSERROR_SYNTAX_ERROR,
+ LSERROR_NO_RETURN,
+ LSERROR_INVALID_VOID_RETURN,
+ LSERROR_INVALID_RETURN,
+ LSERROR_STATE_CHANGE_IN_GLOBAL,
+ LSERROR_DUPLICATE_NAME,
+ LSERROR_UNDEFINED_NAME,
+ LSERROR_TYPE_MISMATCH,
+ LSERROR_EXPRESSION_ON_LVALUE,
+ LSERROR_ASSEMBLE_OUT_OF_MEMORY,
+ LSERROR_FUNCTION_TYPE_ERROR,
+ LSERROR_VECTOR_METHOD_ERROR,
+ LSERROR_NO_LISTS_IN_LISTS,
+ LSERROR_NO_UNITIALIZED_VARIABLES_IN_LISTS,
+ LSERROR_NEED_NEW_SCOPE,
+ LSERROR_EOF
+} LSCRIPTErrors;
+
+class LLScriptGenerateErrorText
+{
+public:
+ LLScriptGenerateErrorText() { init(); }
+ ~LLScriptGenerateErrorText() {}
+
+ void init() { mTotalErrors = 0; mTotalWarnings = 0; }
+
+ void writeWarning(FILE *fp, LLScriptFilePosition *pos, LSCRIPTWarnings warning);
+ void writeWarning(FILE *fp, S32 line, S32 col, LSCRIPTWarnings warning);
+ void writeError(FILE *fp, LLScriptFilePosition *pos, LSCRIPTErrors error);
+ void writeError(FILE *fp, S32 line, S32 col, LSCRIPTErrors error);
+
+ BOOL getErrors() { return mTotalErrors; }
+ BOOL getWarnings() { return mTotalWarnings; }
+
+ S32 mTotalErrors;
+ S32 mTotalWarnings;
+};
+
+extern LLScriptGenerateErrorText gErrorToText;
+
+#endif
diff --git a/indra/lscript/lscript_compile/lscript_heap.cpp b/indra/lscript/lscript_compile/lscript_heap.cpp
new file mode 100644
index 0000000000..98c5fe37be
--- /dev/null
+++ b/indra/lscript/lscript_compile/lscript_heap.cpp
@@ -0,0 +1,49 @@
+/**
+ * @file lscript_heap.cpp
+ * @brief classes to manage script heap
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#if 0
+
+#include "linden_common.h"
+
+#include "lscript_heap.h"
+
+LLScriptHeapEntry::LLScriptHeapEntry(U8 *entry)
+: mEntry(entry)
+{
+ S32 offset = 0;
+ mNext = bytestream2integer(entry, offset);
+ mRefCount = bytestream2integer(entry, offset);
+ mType = *(entry + offset);
+ mData = entry + offset;
+ mListOffset = offset;
+}
+
+LLScriptHeapEntry::LLScriptHeapEntry(U8 *heap, S32 offset)
+: mNext(0x9), mType(0), mRefCount(0), mEntry(heap + offset), mData(heap + offset + 0x9), mListOffset(0x9)
+{
+}
+
+LLScriptHeapEntry::~LLScriptHeapEntry()
+{
+}
+
+void LLScriptHeapEntry::addString(char *string)
+{
+ S32 size = strlen(string) + 1;
+ S32 offset = 0;
+ memcpy(mData, string, size);
+ mNext += size;
+ integer2bytestream(mEntry, offset, mNext);
+ mRefCount++;
+ integer2bytestream(mEntry, offset, mRefCount);
+ *(mEntry + offset) = LSCRIPTTypeByte[LST_STRING];
+}
+
+
+
+#endif
diff --git a/indra/lscript/lscript_compile/lscript_heap.h b/indra/lscript/lscript_compile/lscript_heap.h
new file mode 100644
index 0000000000..5b04ba768a
--- /dev/null
+++ b/indra/lscript/lscript_compile/lscript_heap.h
@@ -0,0 +1,40 @@
+/**
+ * @file lscript_heap.h
+ * @brief classes to manage script heap
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#if 0
+
+#ifndef LL_LSCRIPT_HEAP_H
+#define LL_LSCRIPT_HEAP_H
+
+#include "lscript_byteconvert.h"
+//#include "vmath.h"
+#include "v3math.h"
+#include "llquaternion.h"
+
+class LLScriptHeapEntry
+{
+public:
+ LLScriptHeapEntry(U8 *entry);
+ LLScriptHeapEntry(U8 *heap, S32 offset);
+ ~LLScriptHeapEntry();
+
+ void addString(char *string);
+
+ S32 mNext;
+ U8 mType;
+ S32 mRefCount;
+ S32 mListOffset;
+ U8 *mEntry;
+ U8 *mData;
+ U8 *mListEntry;
+};
+
+#endif
+
+#endif
+
diff --git a/indra/lscript/lscript_compile/lscript_resource.cpp b/indra/lscript/lscript_compile/lscript_resource.cpp
new file mode 100644
index 0000000000..147cb093b5
--- /dev/null
+++ b/indra/lscript/lscript_compile/lscript_resource.cpp
@@ -0,0 +1,18 @@
+/**
+ * @file lscript_resource.cpp
+ * @brief resource determination prior to assembly
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "linden_common.h"
+
+#include "lscript_resource.h"
+
+void init_temp_jumps()
+{
+ gTempJumpCount = 0;
+}
+
+S32 gTempJumpCount = 0;
diff --git a/indra/lscript/lscript_compile/lscript_resource.h b/indra/lscript/lscript_compile/lscript_resource.h
new file mode 100644
index 0000000000..b0a38b81fb
--- /dev/null
+++ b/indra/lscript/lscript_compile/lscript_resource.h
@@ -0,0 +1,21 @@
+/**
+ * @file lscript_resource.h
+ * @brief resource determination prior to assembly
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LL_LSCRIPT_RESOURCE_H
+#define LL_LSCRIPT_RESOURCE_H
+
+#include <stdio.h>
+#include "stdtypes.h"
+#include "lscript_scope.h"
+
+void init_temp_jumps();
+
+extern S32 gTempJumpCount;
+
+#endif
+
diff --git a/indra/lscript/lscript_compile/lscript_scope.cpp b/indra/lscript/lscript_compile/lscript_scope.cpp
new file mode 100644
index 0000000000..a2eeceb9c6
--- /dev/null
+++ b/indra/lscript/lscript_compile/lscript_scope.cpp
@@ -0,0 +1,13 @@
+/**
+ * @file lscript_scope.cpp
+ * @brief builds nametable and checks scope
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "linden_common.h"
+
+#include "lscript_tree.h"
+
+LLStringTable *gScopeStringTable;
diff --git a/indra/lscript/lscript_compile/lscript_scope.h b/indra/lscript/lscript_compile/lscript_scope.h
new file mode 100644
index 0000000000..18640441af
--- /dev/null
+++ b/indra/lscript/lscript_compile/lscript_scope.h
@@ -0,0 +1,388 @@
+/**
+ * @file lscript_scope.h
+ * @brief builds nametable and checks scope
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LL_LSCRIPT_SCOPE_H
+#define LL_LSCRIPT_SCOPE_H
+
+#include "string_table.h"
+#include "llmap.h"
+#include "lscript_byteformat.h"
+
+typedef enum e_lscript_identifier_type
+{
+ LIT_INVALID,
+ LIT_GLOBAL,
+ LIT_VARIABLE,
+ LIT_FUNCTION,
+ LIT_LABEL,
+ LIT_STATE,
+ LIT_HANDLER,
+ LIT_LIBRARY_FUNCTION,
+ LIT_EOF
+} LSCRIPTIdentifierType;
+
+const char LSCRIPTFunctionTypeStrings[LST_EOF] =
+{
+ '0',
+ 'i',
+ 'f',
+ 's',
+ 'k',
+ 'v',
+ 'q',
+ 'l',
+ '0'
+};
+
+const char * const LSCRIPTListDescription[LST_EOF] =
+{
+ "PUSHARGB 0",
+ "PUSHARGB 1",
+ "PUSHARGB 2",
+ "PUSHARGB 3",
+ "PUSHARGB 4",
+ "PUSHARGB 5",
+ "PUSHARGB 6",
+ "PUSHARGB 7",
+ "PUSHARGB 0"
+};
+
+const char * const LSCRIPTTypePush[LST_EOF] =
+{
+ "INVALID",
+ "PUSHE",
+ "PUSHE",
+ "PUSHE",
+ "PUSHE",
+ "PUSHEV",
+ "PUSHEQ",
+ "PUSHE",
+ "undefined"
+};
+
+const char * const LSCRIPTTypeReturn[LST_EOF] =
+{
+ "INVALID",
+ "LOADP -12",
+ "LOADP -12",
+ "STORES -12\nPOP",
+ "STORES -12\nPOP",
+ "LOADVP -20",
+ "LOADQP -24",
+ "LOADLP -12",
+ "undefined"
+};
+
+const char * const LSCRIPTTypePop[LST_EOF] =
+{
+ "INVALID",
+ "POP",
+ "POP",
+ "POPS",
+ "POPS",
+ "POPV",
+ "POPQ",
+ "POPL",
+ "undefined"
+};
+
+const char * const LSCRIPTTypeDuplicate[LST_EOF] =
+{
+ "INVALID",
+ "DUP",
+ "DUP",
+ "DUPS",
+ "DUPS",
+ "DUPV",
+ "DUPQ",
+ "DUPL",
+ "undefined"
+};
+
+const char * const LSCRIPTTypeLocalStore[LST_EOF] =
+{
+ "INVALID",
+ "STORE ",
+ "STORE ",
+ "STORES ",
+ "STORES ",
+ "STOREV ",
+ "STOREQ ",
+ "STOREL ",
+ "undefined"
+};
+
+const char * const LSCRIPTTypeLocalDeclaration[LST_EOF] =
+{
+ "INVALID",
+ "STOREP ",
+ "STOREP ",
+ "STORESP ",
+ "STORESP ",
+ "STOREVP ",
+ "STOREQP ",
+ "STORELP ",
+ "undefined"
+};
+
+const char * const LSCRIPTTypeGlobalStore[LST_EOF] =
+{
+ "INVALID",
+ "STOREG ",
+ "STOREG ",
+ "STORESG ",
+ "STORESG ",
+ "STOREGV ",
+ "STOREGQ ",
+ "STORELG ",
+ "undefined"
+};
+
+const char * const LSCRIPTTypeLocalPush[LST_EOF] =
+{
+ "INVALID",
+ "PUSH ",
+ "PUSH ",
+ "PUSHS ",
+ "PUSHS ",
+ "PUSHV ",
+ "PUSHQ ",
+ "PUSHL ",
+ "undefined"
+};
+
+const char * const LSCRIPTTypeLocalPush1[LST_EOF] =
+{
+ "INVALID",
+ "PUSHARGI 1",
+ "PUSHARGF 1",
+ "undefined",
+ "undefined",
+ "undefined",
+ "undefined",
+ "undefined",
+ "undefined"
+};
+
+const char * const LSCRIPTTypeGlobalPush[LST_EOF] =
+{
+ "INVALID",
+ "PUSHG ",
+ "PUSHG ",
+ "PUSHGS ",
+ "PUSHGS ",
+ "PUSHGV ",
+ "PUSHGQ ",
+ "PUSHGL ",
+ "undefined"
+};
+
+class LLScriptSimpleAssignable;
+
+class LLScriptArgString
+{
+public:
+ LLScriptArgString() : mString(NULL) {}
+ ~LLScriptArgString() { delete [] mString; }
+
+ LSCRIPTType getType(S32 count)
+ {
+ if (!mString)
+ return LST_NULL;
+ S32 length = (S32)strlen(mString);
+ if (count >= length)
+ {
+ return LST_NULL;
+ }
+ switch(mString[count])
+ {
+ case 'i':
+ return LST_INTEGER;
+ case 'f':
+ return LST_FLOATINGPOINT;
+ case 's':
+ return LST_STRING;
+ case 'k':
+ return LST_KEY;
+ case 'v':
+ return LST_VECTOR;
+ case 'q':
+ return LST_QUATERNION;
+ case 'l':
+ return LST_LIST;
+ default:
+ return LST_NULL;
+ }
+ }
+
+ void addType(LSCRIPTType type)
+ {
+ S32 count = 0;
+ if (mString)
+ {
+ count = (S32)strlen(mString);
+ char *temp = new char[count + 2];
+ memcpy(temp, mString, count);
+ delete [] mString;
+ mString = temp;
+ mString[count + 1] = 0;
+ }
+ else
+ {
+ mString = new char[count + 2];
+ mString[count + 1] = 0;
+ }
+ mString[count++] = LSCRIPTFunctionTypeStrings[type];
+ }
+
+ S32 getNumber()
+ {
+ if (mString)
+ return (S32)strlen(mString);
+ else
+ return 0;
+ }
+
+ char *mString;
+};
+
+class LLScriptScopeEntry
+{
+public:
+ LLScriptScopeEntry(char *identifier, LSCRIPTIdentifierType idtype, LSCRIPTType type, S32 count = 0)
+ : mIdentifier(identifier), mIDType(idtype), mType(type), mOffset(0), mSize(0), mAssignable(NULL), mCount(count), mLibraryNumber(0)
+ {
+ }
+
+ ~LLScriptScopeEntry() {}
+
+ char *mIdentifier;
+ LSCRIPTIdentifierType mIDType;
+ LSCRIPTType mType;
+ S32 mOffset;
+ S32 mSize;
+ LLScriptSimpleAssignable *mAssignable;
+ S32 mCount; // NOTE: Index for locals in CIL.
+ U16 mLibraryNumber;
+ LLScriptArgString mFunctionArgs;
+ LLScriptArgString mLocals;
+};
+
+class LLScriptScope
+{
+public:
+ LLScriptScope(LLStringTable *stable)
+ : mParentScope(NULL), mSTable(stable), mFunctionCount(0), mStateCount(0)
+ {
+ }
+
+ ~LLScriptScope()
+ {
+ mEntryMap.deleteAllData();
+ }
+
+ LLScriptScopeEntry *addEntry(char *identifier, LSCRIPTIdentifierType idtype, LSCRIPTType type)
+ {
+ char *name = mSTable->addString(identifier);
+ if (!mEntryMap.checkData(name))
+ {
+ if (idtype == LIT_FUNCTION)
+ mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type, mFunctionCount++);
+ else if (idtype == LIT_STATE)
+ mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type, mStateCount++);
+ else
+ mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type);
+ return mEntryMap[name];
+ }
+ else
+ {
+ // identifier already exists at this scope
+ return NULL;
+ }
+ }
+
+ BOOL checkEntry(char *identifier)
+ {
+ char *name = mSTable->addString(identifier);
+ if (mEntryMap.checkData(name))
+ {
+ return TRUE;
+ }
+ else
+ {
+ // identifier already exists at this scope
+ return FALSE;
+ }
+ }
+
+ LLScriptScopeEntry *findEntry(char *identifier)
+ {
+ char *name = mSTable->addString(identifier);
+ LLScriptScope *scope = this;
+
+ while (scope)
+ {
+ if (scope->mEntryMap.checkData(name))
+ {
+ // cool, we found it at this scope
+ return scope->mEntryMap[name];
+ }
+ scope = scope->mParentScope;
+ }
+ return NULL;
+ }
+
+ LLScriptScopeEntry *findEntryTyped(char *identifier, LSCRIPTIdentifierType idtype)
+ {
+ char *name = mSTable->addString(identifier);
+ LLScriptScope *scope = this;
+
+ while (scope)
+ {
+ if (scope->mEntryMap.checkData(name))
+ {
+ // need to check type, and if type is function we need to check both types
+ if (idtype == LIT_FUNCTION)
+ {
+ if (scope->mEntryMap[name]->mIDType == LIT_FUNCTION)
+ {
+ return scope->mEntryMap[name];
+ }
+ else if (scope->mEntryMap[name]->mIDType == LIT_LIBRARY_FUNCTION)
+ {
+ return scope->mEntryMap[name];
+ }
+ }
+ else if (scope->mEntryMap[name]->mIDType == idtype)
+ {
+ // cool, we found it at this scope
+ return scope->mEntryMap[name];
+ }
+ }
+ scope = scope->mParentScope;
+ }
+ return NULL;
+ }
+
+ void addParentScope(LLScriptScope *scope)
+ {
+ mParentScope = scope;
+ }
+
+ LLMap<char *, LLScriptScopeEntry *> mEntryMap;
+ LLScriptScope *mParentScope;
+ LLStringTable *mSTable;
+ S32 mFunctionCount;
+ S32 mStateCount;
+};
+
+extern LLStringTable *gScopeStringTable;
+
+
+
+#endif
diff --git a/indra/lscript/lscript_compile/lscript_tree.cpp b/indra/lscript/lscript_compile/lscript_tree.cpp
new file mode 100644
index 0000000000..4b4a7f13f4
--- /dev/null
+++ b/indra/lscript/lscript_compile/lscript_tree.cpp
@@ -0,0 +1,9998 @@
+/**
+ * @file lscript_tree.cpp
+ * @brief implements methods for lscript_tree.h classes
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+// TO DO: Move print functionality from .h file to here
+
+#include "linden_common.h"
+
+#include "lscript_tree.h"
+#include "lscript_typecheck.h"
+#include "lscript_resource.h"
+#include "lscript_bytecode.h"
+#include "lscript_heap.h"
+#include "lscript_library.h"
+#include "lscript_alloc.h"
+
+//#define LSL_INCLUDE_DEBUG_INFO
+
+void print_cil_box(FILE* fp, LSCRIPTType type)
+{
+ switch(type)
+ {
+ case LST_INTEGER:
+ fprintf(fp, "box [mscorlib]System.Int32\n");
+ break;
+ case LST_FLOATINGPOINT:
+ fprintf(fp, "box [mscorlib]System.Double\n");
+ break;
+ case LST_STRING:
+ case LST_KEY:
+ fprintf(fp, "box [mscorlib]System.String\n");
+ break;
+ case LST_VECTOR:
+ fprintf(fp, "box [LScriptLibrary]LLVector\n");
+ break;
+ case LST_QUATERNION:
+ fprintf(fp, "box [LScriptLibrary]LLQuaternion\n");
+ break;
+ default:
+ break;
+ }
+}
+
+void print_cil_type(FILE* fp, LSCRIPTType type)
+{
+ switch(type)
+ {
+ case LST_INTEGER:
+ fprintf(fp, "int32");
+ break;
+ case LST_FLOATINGPOINT:
+ fprintf(fp, "float32");
+ break;
+ case LST_STRING:
+ case LST_KEY:
+ fprintf(fp, "string");
+ break;
+ case LST_VECTOR:
+ fprintf(fp, "valuetype [LScriptLibrary]LLVector");
+ break;
+ case LST_QUATERNION:
+ fprintf(fp, "valuetype [LScriptLibrary]LLQuaternion");
+ break;
+ case LST_LIST:
+ fprintf(fp, "class [mscorlib]System.Collections.ArrayList");
+ break;
+ case LST_NULL:
+ fprintf(fp, "void");
+ break;
+ default:
+ break;
+ }
+}
+
+void LLScriptType::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp,"%s",LSCRIPTTypeNames[mType]);
+ break;
+ case LSCP_TYPE:
+ type = mType;
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ print_cil_type(fp, mType);
+ break;
+ default:
+ break;
+ }
+}
+
+S32 LLScriptType::getSize()
+{
+ return LSCRIPTDataSize[mType];
+}
+
+void LLScriptConstant::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp,"Script Constant Base class -- should never get here!\n");
+ break;
+ default:
+ break;
+ }
+}
+
+S32 LLScriptConstant::getSize()
+{
+ printf("Script Constant Base class -- should never get here!\n");
+ return 0;
+}
+
+
+
+void LLScriptConstantInteger::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fprintf(fp, "%d", mValue);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp, "PUSHARGI %d\n", mValue);
+ break;
+ case LSCP_TYPE:
+ type = mType;
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ chunk->addInteger(mValue);
+ type = mType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
+ chunk->addInteger(mValue);
+ type = mType;
+ }
+ break;
+ case LSCP_LIST_BUILD_SIMPLE:
+ {
+ *ldata = new LLScriptLibData(mValue);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fprintf(fp, "ldc.i4 %d\n", mValue);
+ break;
+ default:
+ break;
+ }
+}
+
+S32 LLScriptConstantInteger::getSize()
+{
+ return LSCRIPTDataSize[LST_INTEGER];
+}
+
+void LLScriptConstantFloat::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fprintf(fp, "%5.5f", mValue);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp, "PUSHARGF %5.5f\n", mValue);
+ break;
+ case LSCP_TYPE:
+ type = mType;
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ chunk->addFloat(mValue);
+ type = mType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
+ chunk->addFloat(mValue);
+ type = mType;
+ }
+ break;
+ case LSCP_LIST_BUILD_SIMPLE:
+ {
+ *ldata = new LLScriptLibData(mValue);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fprintf(fp, "ldc.r8 %5.5f\n", mValue); // NOTE: Precision?
+ default:
+ break;
+ }
+}
+
+S32 LLScriptConstantFloat::getSize()
+{
+ return LSCRIPTDataSize[LST_FLOATINGPOINT];
+}
+
+void print_escape_quotes(FILE* fp, const char* str)
+{
+ putc('"', fp);
+ for(const char* c = str; *c != '\0'; ++c)
+ {
+ if(*c == '"')
+ {
+ putc('\\', fp);
+ }
+ putc(*c, fp);
+ }
+ putc('"', fp);
+}
+
+void LLScriptConstantString::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fprintf(fp, "\"%s\"", mValue);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp, "PUSHARGS \"%s\"\n", mValue);
+ fprintf(fp, "STACKTOS %lu\n", strlen(mValue) + 1);
+ break;
+ case LSCP_TYPE:
+ type = mType;
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ chunk->addInteger(heap->mCurrentOffset + 1);
+ LLScriptLibData *data = new LLScriptLibData(mValue);
+ U8 *temp;
+ S32 size = lsa_create_data_block(&temp, data, heap->mCurrentOffset);
+
+ heap->addBytes(temp, size);
+ delete [] temp;
+ delete data;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGS]);
+ chunk->addBytes(mValue, (S32)strlen(mValue) + 1);
+ type = mType;
+ }
+ break;
+ case LSCP_LIST_BUILD_SIMPLE:
+ {
+ *ldata = new LLScriptLibData(mValue);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fprintf(fp, "ldstr ");
+ print_escape_quotes(fp, mValue);
+ fprintf(fp, "\n");
+ default:
+ break;
+ }
+}
+
+S32 LLScriptConstantString::getSize()
+{
+ return (S32)strlen(mValue) + 1;
+}
+
+
+void LLScriptIdentifier::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fprintf(fp, "%s", mName);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ if (mScopeEntry)
+ {
+ if (mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ fprintf(fp, "$BP + %d [%s]", mScopeEntry->mOffset, mName);
+ }
+ else if (mScopeEntry->mIDType == LIT_GLOBAL)
+ {
+ fprintf(fp, "$GVR + %d [%s]", mScopeEntry->mOffset, mName);
+ }
+ else
+ {
+ fprintf(fp, "%s", mName);
+ }
+ }
+ break;
+ case LSCP_TYPE:
+ if (mScopeEntry)
+ type = mScopeEntry->mType;
+ else
+ type = LST_NULL;
+ break;
+ case LSCP_RESOURCE:
+ if (mScopeEntry)
+ {
+ if (mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+// fprintf(fp, "LOCAL : %d : %d : %s\n", mScopeEntry->mOffset, mScopeEntry->mSize, mName);
+ }
+ else if (mScopeEntry->mIDType == LIT_GLOBAL)
+ {
+// fprintf(fp, "GLOBAL: %d : %d : %s\n", mScopeEntry->mOffset, mScopeEntry->mSize, mName);
+ }
+ }
+ break;
+ case LSCP_LIST_BUILD_SIMPLE:
+ {
+ if (mScopeEntry)
+ {
+ if (mScopeEntry->mType == LST_LIST)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_NO_LISTS_IN_LISTS);
+ }
+ else if (mScopeEntry->mAssignable)
+ {
+ mScopeEntry->mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
+ }
+ else
+ {
+ gErrorToText.writeError(fp, this, LSERROR_NO_UNITIALIZED_VARIABLES_IN_LISTS);
+ }
+ }
+ else
+ {
+ gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
+ }
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fprintf(fp, "%s", mName);
+ break;
+ default:
+ break;
+ }
+}
+
+S32 LLScriptIdentifier::getSize()
+{
+
+ return 0;
+}
+
+
+
+void LLScriptSimpleAssignable::addAssignable(LLScriptSimpleAssignable *assign)
+{
+ if (mNextp)
+ {
+ assign->mNextp = mNextp;
+ }
+ mNextp = assign;
+}
+
+void LLScriptSimpleAssignable::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ fprintf(fp, "Simple Assignable Base Class -- should never get here!\n");
+}
+
+S32 LLScriptSimpleAssignable::getSize()
+{
+
+ printf("Simple Assignable Base Class -- should never get here!\n");
+ return 0;
+}
+
+void LLScriptSAIdentifier::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mNextp)
+ {
+ fprintf(fp, ", ");
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_SCOPE_PASS1:
+ {
+ LLScriptScopeEntry *entry = scope->findEntry(mIdentifier->mName);
+ if (!entry)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
+ }
+ else
+ {
+ // if we did find it, make sure this identifier is associated with the correct scope entry
+ mIdentifier->mScopeEntry = entry;
+ }
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ if (mIdentifier->mScopeEntry)
+ {
+ if(mIdentifier->mScopeEntry->mAssignable)
+ {
+ mIdentifier->mScopeEntry->mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ else
+ {
+ // Babbage: 29/8/06: If the scope entry has no mAssignable,
+ // set the default type and add the default 0 value to the
+ // chunk. Without this SAVectors and SAQuaternions will
+ // assume the arbitrary current type is the assignable type
+ // and may attempt to access a null chunk. (SL-20156)
+ type = mIdentifier->mScopeEntry->mType;
+ chunk->addBytes(LSCRIPTDataSize[type]);
+ }
+ }
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ }
+ break;
+ case LSCP_LIST_BUILD_SIMPLE:
+ {
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
+ }
+ }
+ break;
+ default:
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+}
+
+S32 LLScriptSAIdentifier::getSize()
+{
+ return mIdentifier->getSize();
+}
+
+void LLScriptSAConstant::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mNextp)
+ {
+ fprintf(fp, ", ");
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_LIST_BUILD_SIMPLE:
+ {
+ mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
+ }
+ }
+ break;
+ default:
+ mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+}
+
+S32 LLScriptSAConstant::getSize()
+{
+ return mConstant->getSize();
+}
+
+void print_cil_cast(FILE* fp, LSCRIPTType srcType, LSCRIPTType targetType)
+{
+ switch(srcType)
+ {
+ case LST_INTEGER:
+ switch(targetType)
+ {
+ case LST_FLOATINGPOINT:
+ fprintf(fp, "conv.r8\n");
+ break;
+ case LST_STRING:
+ fprintf(fp, "call string class [mscorlib]System.Convert::ToString(int32)\n");
+ break;
+ case LST_LIST:
+ fprintf(fp, "box [mscorlib]System.Int32\n");
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::CreateList()\n");
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::AddReturnList(object, class [mscorlib]System.Collections.ArrayList)\n");
+ break;
+ default:
+ break;
+ }
+ break;
+ case LST_FLOATINGPOINT:
+ switch(targetType)
+ {
+ case LST_INTEGER:
+ fprintf(fp, "conv.i4\n");
+ break;
+ case LST_STRING:
+ fprintf(fp, "call string class [mscorlib]System.Convert::ToString(float32)\n");
+ break;
+ case LST_LIST:
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
+ break;
+ default:
+ break;
+ }
+ break;
+ case LST_STRING:
+ switch(targetType)
+ {
+ case LST_INTEGER:
+ fprintf(fp, "call int32 valuetype [mscorlib]System.Int32::Parse(string)\n");
+ break;
+ case LST_FLOATINGPOINT:
+ fprintf(fp, "call float64 valuetype [mscorlib]System.Double::Parse(string)\n");
+ break;
+ case LST_LIST:
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
+ break;
+ case LST_VECTOR:
+ fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'Parse'(string)\n");
+ break;
+ case LST_QUATERNION:
+ fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'Parse'(string)\n");
+ break;
+ default:
+ break;
+ }
+ break;
+ case LST_KEY:
+ switch(targetType)
+ {
+ case LST_KEY:
+ break;
+ case LST_STRING:
+ break;
+ case LST_LIST:
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
+ break;
+ default:
+ break;
+ }
+ break;
+ case LST_VECTOR:
+ switch(targetType)
+ {
+ case LST_VECTOR:
+ break;
+ case LST_STRING:
+ fprintf(fp, "call string valuetype [LScriptLibrary]LLVector::'ToString'(valuetype [LScriptLibrary]LLVector)\n");
+ break;
+ case LST_LIST:
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
+ break;
+ default:
+ break;
+ }
+ break;
+ case LST_QUATERNION:
+ switch(targetType)
+ {
+ case LST_QUATERNION:
+ break;
+ case LST_STRING:
+ fprintf(fp, "call string valuetype [LScriptLibrary]LLQuaternion::'ToString'(valuetype [LScriptLibrary]LLQuaternion)\n");
+ break;
+ case LST_LIST:
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
+ break;
+ default:
+ break;
+ }
+ break;
+ case LST_LIST:
+ switch(targetType)
+ {
+ case LST_LIST:
+ break;
+ case LST_STRING:
+ fprintf(fp, "call string [LScriptLibrary]LScriptInternal::ListToString(class [mscorlib]System.Collections.ArrayList)\n");
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+bool is_SA_constant_integer(LLScriptSimpleAssignable* sa)
+{
+ // HACK: Downcast based on type.
+ return (sa->mType == LSSAT_CONSTANT && ((LLScriptSAConstant*) sa)->mConstant->mType == LST_INTEGER);
+}
+
+void LLScriptSAVector::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp, "< ");
+ mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", ");
+ mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", ");
+ mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " >");
+ if (mNextp)
+ {
+ fprintf(fp, ", ");
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_TYPE:
+ // vector's take floats
+ mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(LST_FLOATINGPOINT, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(LST_FLOATINGPOINT, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(LST_FLOATINGPOINT, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = LST_VECTOR;
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_INTEGER)
+ {
+ S32 offset = chunk->mCurrentOffset - 4;
+ bytestream_int2float(chunk->mCodeChunk, offset);
+ }
+ mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_INTEGER)
+ {
+ S32 offset = chunk->mCurrentOffset - 4;
+ bytestream_int2float(chunk->mCodeChunk, offset);
+ }
+ mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_INTEGER)
+ {
+ S32 offset = chunk->mCurrentOffset - 4;
+ bytestream_int2float(chunk->mCodeChunk, offset);
+ }
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_LIST_BUILD_SIMPLE:
+ {
+ LLScriptByteCodeChunk *list = new LLScriptByteCodeChunk(FALSE);
+ mEntry3->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_INTEGER)
+ {
+ S32 offset = list->mCurrentOffset - 4;
+ bytestream_int2float(list->mCodeChunk, offset);
+ }
+ mEntry2->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_INTEGER)
+ {
+ S32 offset = list->mCurrentOffset - 4;
+ bytestream_int2float(list->mCodeChunk, offset);
+ }
+ mEntry1->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_INTEGER)
+ {
+ S32 offset = list->mCurrentOffset - 4;
+ bytestream_int2float(list->mCodeChunk, offset);
+ }
+ LLVector3 vec;
+ S32 offset = 0;
+ bytestream2vector(vec, list->mCodeChunk, offset);
+ *ldata = new LLScriptLibData(vec);
+ delete list;
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
+ }
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+
+ // Load arguments.
+ mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if(is_SA_constant_integer(mEntry1))
+ {
+ print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
+ }
+ mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if(is_SA_constant_integer(mEntry3))
+ {
+ print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
+ }
+ mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if(is_SA_constant_integer(mEntry3))
+ {
+ print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
+ }
+
+ // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
+ fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'create'(float32, float32, float32)\n");
+
+ // Next.
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ default:
+ mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+}
+
+S32 LLScriptSAVector::getSize()
+{
+ return mEntry1->getSize() + mEntry2->getSize() + mEntry3->getSize();
+}
+
+void LLScriptSAQuaternion::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp, "< ");
+ mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", ");
+ mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", ");
+ mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", ");
+ mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " >");
+ if (mNextp)
+ {
+ fprintf(fp, ", ");
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_TYPE:
+ // vector's take floats
+ mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(LST_FLOATINGPOINT, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(LST_FLOATINGPOINT, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(LST_FLOATINGPOINT, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(LST_FLOATINGPOINT, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = LST_QUATERNION;
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_INTEGER)
+ {
+ S32 offset = chunk->mCurrentOffset - 4;
+ bytestream_int2float(chunk->mCodeChunk, offset);
+ }
+ mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_INTEGER)
+ {
+ S32 offset = chunk->mCurrentOffset - 4;
+ bytestream_int2float(chunk->mCodeChunk, offset);
+ }
+ mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_INTEGER)
+ {
+ S32 offset = chunk->mCurrentOffset - 4;
+ bytestream_int2float(chunk->mCodeChunk, offset);
+ }
+ mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_INTEGER)
+ {
+ S32 offset = chunk->mCurrentOffset - 4;
+ bytestream_int2float(chunk->mCodeChunk, offset);
+ }
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_LIST_BUILD_SIMPLE:
+ {
+ LLScriptByteCodeChunk *list = new LLScriptByteCodeChunk(FALSE);
+ mEntry4->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_INTEGER)
+ {
+ S32 offset = list->mCurrentOffset - 4;
+ bytestream_int2float(list->mCodeChunk, offset);
+ }
+ mEntry3->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_INTEGER)
+ {
+ S32 offset = list->mCurrentOffset - 4;
+ bytestream_int2float(list->mCodeChunk, offset);
+ }
+ mEntry2->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_INTEGER)
+ {
+ S32 offset = list->mCurrentOffset - 4;
+ bytestream_int2float(list->mCodeChunk, offset);
+ }
+ mEntry1->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
+ if (type == LST_INTEGER)
+ {
+ S32 offset = list->mCurrentOffset - 4;
+ bytestream_int2float(list->mCodeChunk, offset);
+ }
+ LLQuaternion quat;
+ S32 offset = 0;
+ bytestream2quaternion(quat, list->mCodeChunk, offset);
+ *ldata = new LLScriptLibData(quat);
+ delete list;
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
+ }
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+
+ // Load arguments.
+ mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if(is_SA_constant_integer(mEntry1))
+ {
+ print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
+ }
+ mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if(is_SA_constant_integer(mEntry2))
+ {
+ print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
+ }
+ mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if(is_SA_constant_integer(mEntry3))
+ {
+ print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
+ }
+ mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if(is_SA_constant_integer(mEntry4))
+ {
+ print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
+ }
+
+ // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
+ fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'create'(float32, float32, float32, float32)\n");
+
+ // Next.
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ default:
+ mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+}
+
+S32 LLScriptSAQuaternion::getSize()
+{
+ return mEntry1->getSize() + mEntry2->getSize() + mEntry3->getSize() + mEntry4->getSize();
+}
+
+void LLScriptSAList::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp, "[ ");
+ if (mEntryList)
+ mEntryList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " ]");
+ if (mNextp)
+ {
+ fprintf(fp, ", ");
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_TYPE:
+ if (mEntryList)
+ mEntryList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ type = LST_LIST;
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ LLScriptLibData *list_data = new LLScriptLibData;
+
+ list_data->mType = LST_LIST;
+ if (mEntryList)
+ mEntryList->recurse(fp, tabs, tabsize, LSCP_LIST_BUILD_SIMPLE, ptype, prunearg, scope, type, basetype, count, chunk, NULL, stacksize, entry, entrycount, &(list_data->mListp));
+
+ U8 *temp;
+ chunk->addInteger(heap->mCurrentOffset + 1);
+ S32 size = lsa_create_data_block(&temp, list_data, heap->mCurrentOffset);
+ heap->addBytes(temp, size);
+ delete list_data;
+ delete [] temp;
+
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, chunk, NULL, stacksize, entry, entrycount, NULL);
+ }
+ }
+ break;
+ default:
+ if (mEntryList)
+ mEntryList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
+ }
+ break;
+ }
+}
+
+S32 LLScriptSAList::getSize()
+{
+ return mEntryList->getSize();
+}
+
+void LLScriptGlobalVariable::addGlobal(LLScriptGlobalVariable *global)
+{
+ if (mNextp)
+ {
+ global->mNextp = mNextp;
+ }
+ mNextp = global;
+}
+
+void LLScriptGlobalVariable::gonext(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ default:
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+}
+
+void LLScriptGlobalVariable::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp,"\t");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mAssignable)
+ {
+ fprintf(fp, " = ");
+ mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ fprintf(fp, ";\n");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp,"\t");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mAssignable)
+ {
+ fprintf(fp, " = ");
+ mAssignable->recurse(fp, tabs, tabsize, LSCP_PRETTY_PRINT, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ fprintf(fp, "Offset: %d Type: %d\n", mIdentifier->mScopeEntry->mOffset, (S32)LSCRIPTTypeByte[mType->mType]);
+ }
+ else
+ {
+ fprintf(fp, "\n");
+ fprintf(fp, "Offset: %d Type: %d\n", mIdentifier->mScopeEntry->mOffset, (S32)LSCRIPTTypeByte[mType->mType]);
+ }
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mIdentifier->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ if (mAssignable)
+ {
+ mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ // this needs to go after expression decent to make sure that we don't add ourselves or something silly
+ mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_GLOBAL, mType->mType);
+ if (mIdentifier->mScopeEntry && mAssignable)
+ mIdentifier->mScopeEntry->mAssignable = mAssignable;
+ }
+ break;
+ case LSCP_TYPE:
+ // if the variable has an assignable, it must assignable to the variable's type
+ if (mAssignable)
+ {
+ mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mAssignableType = type;
+ if (!legal_assignment(mType->mType, mAssignableType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ // it also includes the name of the variable as well as the type
+ // plus 4 bytes of offset from it's apparent address to the actual data
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ count += strlen(mIdentifier->mName) + 1 + 1 + 4;
+#else
+ count += 1 + 1 + 4;
+#endif
+ mIdentifier->mScopeEntry->mOffset = (S32)count;
+ mIdentifier->mScopeEntry->mSize = mType->getSize();
+ count += mIdentifier->mScopeEntry->mSize;
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ // order for global variables
+ // 0 - 4: offset to actual data
+ S32 offsetoffset = chunk->mCurrentOffset;
+ S32 offsetdelta = 0;
+ chunk->addBytes(4);
+ // type
+ char vtype;
+ vtype = LSCRIPTTypeByte[mType->mType];
+ chunk->addBytes(&vtype, 1);
+ // null terminated name
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);
+#else
+ chunk->addBytes(1);
+#endif
+ // put correct offset delta in
+ offsetdelta = chunk->mCurrentOffset - offsetoffset;
+ integer2bytestream(chunk->mCodeChunk, offsetoffset, offsetdelta);
+
+ // now we need space for the variable itself
+ LLScriptByteCodeChunk *value = new LLScriptByteCodeChunk(FALSE);
+ if (mAssignable)
+ {
+ mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, value, heap, stacksize, entry, entrycount, NULL);
+ // need to put sneaky type conversion here
+ if (mAssignableType != mType->mType)
+ {
+ // the only legal case that is a problem is int->float
+ if (mType->mType == LST_FLOATINGPOINT && mAssignableType == LST_INTEGER)
+ {
+ S32 offset = value->mCurrentOffset - 4;
+ bytestream_int2float(value->mCodeChunk, offset);
+ }
+ }
+ }
+ else
+ {
+ if ( (mType->mType == LST_STRING)
+ ||(mType->mType == LST_KEY))
+ {
+ // string and keys (even empty ones) need heap entries
+ chunk->addInteger(heap->mCurrentOffset + 1);
+ LLScriptLibData *data = new LLScriptLibData("");
+ U8 *temp;
+ S32 size = lsa_create_data_block(&temp, data, heap->mCurrentOffset);
+
+ heap->addBytes(temp, size);
+ delete [] temp;
+ delete data;
+ }
+ else if (mType->mType == LST_LIST)
+ {
+ chunk->addInteger(heap->mCurrentOffset + 1);
+ LLScriptLibData *data = new LLScriptLibData;
+ data->mType = LST_LIST;
+ U8 *temp;
+ S32 size = lsa_create_data_block(&temp, data, heap->mCurrentOffset);
+
+ heap->addBytes(temp, size);
+ delete [] temp;
+ delete data;
+ }
+ else if (mType->mType == LST_QUATERNION)
+ {
+ chunk->addFloat(1.f);
+ chunk->addFloat(0.f);
+ chunk->addFloat(0.f);
+ chunk->addFloat(0.f);
+ }
+ else
+ {
+ value->addBytes(LSCRIPTDataSize[mType->mType]);
+ }
+ }
+ chunk->addBytes(value->mCodeChunk, value->mCurrentOffset);
+ delete value;
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+
+ // Initialisation inside ctor.
+ if (mAssignable)
+ {
+ fprintf(fp, "ldarg.0\n");
+ mAssignable->recurse(fp, tabs, tabsize, LSCP_EMIT_CIL_ASSEMBLY, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "stfld ");
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp," LSL::");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ }
+ break;
+ default:
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mAssignable)
+ {
+ mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptGlobalVariable::getSize()
+{
+ S32 return_size;
+
+ return_size = mType->getSize();
+ return return_size;
+}
+
+void LLScriptEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ fprintf(fp, "Event Base Class -- should never get here!\n");
+}
+
+S32 LLScriptEvent::getSize()
+{
+ printf("Event Base Class -- should never get here!\n");
+ return 0;
+}
+
+void LLScriptStateEntryEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "state_entry()\n");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp, "state_entry()\n");
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "state_entry";
+ chunk->addBytes(name, strlen(name) + 1);
+#endif
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fprintf(fp, "state_entry()");
+ break;
+ default:
+ break;
+ }
+}
+
+S32 LLScriptStateEntryEvent::getSize()
+{
+ return 0;
+}
+
+void LLScriptStateExitEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "state_exit()\n");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp, "state_exit()\n");
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "state_exit";
+ chunk->addBytes(name, strlen(name) + 1);
+#endif
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fprintf(fp, "state_exit()");
+ break;
+ default:
+ break;
+ }
+}
+
+S32 LLScriptStateExitEvent::getSize()
+{
+ return 0;
+}
+
+void LLScriptTouchStartEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "touch_start( integer ");
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mCount->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mCount->mScopeEntry)
+ {
+ mCount->mScopeEntry->mOffset = (S32)count;
+ mCount->mScopeEntry->mSize = 4;
+ count += mCount->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "touch_start";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptTouchStartEvent::getSize()
+{
+ // integer = 4
+ return 4;
+}
+
+void LLScriptTouchEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "touch( integer ");
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mCount->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mCount->mScopeEntry)
+ {
+ mCount->mScopeEntry->mOffset = (S32)count;
+ mCount->mScopeEntry->mSize = 4;
+ count += mCount->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "touch";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptTouchEvent::getSize()
+{
+ // integer = 4
+ return 4;
+}
+
+void LLScriptTouchEndEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "touch_end( integer ");
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mCount->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mCount->mScopeEntry)
+ {
+ mCount->mScopeEntry->mOffset = (S32)count;
+ mCount->mScopeEntry->mSize = 4;
+ count += mCount->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "touch_end";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptTouchEndEvent::getSize()
+{
+ // integer = 4
+ return 4;
+}
+
+void LLScriptCollisionStartEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "collision_start( integer ");
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mCount->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mCount->mScopeEntry)
+ {
+ mCount->mScopeEntry->mOffset = (S32)count;
+ mCount->mScopeEntry->mSize = 4;
+ count += mCount->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "collision_start";
+ chunk->addBytes(name, (S32)strlen(name) + 1);
+ chunk->addBytes(mCount->mName, (S32)strlen(mCount->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptCollisionStartEvent::getSize()
+{
+ // integer = 4
+ return 4;
+}
+
+void LLScriptCollisionEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "collision( integer ");
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mCount->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mCount->mScopeEntry)
+ {
+ mCount->mScopeEntry->mOffset = (S32)count;
+ mCount->mScopeEntry->mSize = 4;
+ count += mCount->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "collision";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptCollisionEvent::getSize()
+{
+ // integer = 4
+ return 4;
+}
+
+void LLScriptCollisionEndEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "collision_end( integer ");
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mCount->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mCount->mScopeEntry)
+ {
+ mCount->mScopeEntry->mOffset = (S32)count;
+ mCount->mScopeEntry->mSize = 4;
+ count += mCount->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "collision_end";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptCollisionEndEvent::getSize()
+{
+ // integer = 4
+ return 4;
+}
+
+void LLScriptLandCollisionStartEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "land_collision_start( vector ");
+ mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mPosition->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mPosition->mScopeEntry = scope->addEntry(mPosition->mName, LIT_VARIABLE, LST_VECTOR);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mPosition->mScopeEntry)
+ {
+ mPosition->mScopeEntry->mOffset = (S32)count;
+ mPosition->mScopeEntry->mSize = 12;
+ count += mPosition->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "land_collision_start";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mPosition->mName, strlen(mPosition->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptLandCollisionStartEvent::getSize()
+{
+ // vector = 12
+ return 12;
+}
+
+
+
+void LLScriptLandCollisionEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "land_collision( vector ");
+ mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mPosition->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mPosition->mScopeEntry = scope->addEntry(mPosition->mName, LIT_VARIABLE, LST_VECTOR);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mPosition->mScopeEntry)
+ {
+ mPosition->mScopeEntry->mOffset = (S32)count;
+ mPosition->mScopeEntry->mSize = 12;
+ count += mPosition->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "land_collision";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mPosition->mName, strlen(mPosition->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptLandCollisionEvent::getSize()
+{
+ // vector = 12
+ return 12;
+}
+
+
+void LLScriptLandCollisionEndEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "land_collision_end( vector ");
+ mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mPosition->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mPosition->mScopeEntry = scope->addEntry(mPosition->mName, LIT_VARIABLE, LST_VECTOR);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mPosition->mScopeEntry)
+ {
+ mPosition->mScopeEntry->mOffset = (S32)count;
+ mPosition->mScopeEntry->mSize = 12;
+ count += mPosition->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "land_collision_end";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mPosition->mName, strlen(mPosition->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptLandCollisionEndEvent::getSize()
+{
+ // vector = 12
+ return 12;
+}
+
+
+void LLScriptInventoryEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "changed( integer ");
+ mChange->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mChange->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mChange->mScopeEntry = scope->addEntry(mChange->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mChange->mScopeEntry)
+ {
+ mChange->mScopeEntry->mOffset = (S32)count;
+ mChange->mScopeEntry->mSize = 4;
+ count += mChange->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "changed";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mChange->mName, strlen(mChange->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mChange->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptInventoryEvent::getSize()
+{
+ // integer = 4
+ return 4;
+}
+
+void LLScriptAttachEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "attach( key ");
+ mAttach->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mAttach->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mAttach->mScopeEntry = scope->addEntry(mAttach->mName, LIT_VARIABLE, LST_KEY);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mAttach->mScopeEntry)
+ {
+ mAttach->mScopeEntry->mOffset = (S32)count;
+ mAttach->mScopeEntry->mSize = 4;
+ count += mAttach->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "attach";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mAttach->mName, strlen(mAttach->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mAttach->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptAttachEvent::getSize()
+{
+ // key = 4
+ return 4;
+}
+
+void LLScriptDataserverEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "dataserver( key ");
+ mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mData->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mID->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mID->mScopeEntry = scope->addEntry(mID->mName, LIT_VARIABLE, LST_KEY);
+ }
+ if (scope->checkEntry(mData->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mData->mScopeEntry = scope->addEntry(mData->mName, LIT_VARIABLE, LST_STRING);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mID->mScopeEntry)
+ {
+ mID->mScopeEntry->mOffset = (S32)count;
+ mID->mScopeEntry->mSize = 4;
+ count += mID->mScopeEntry->mSize;
+ mData->mScopeEntry->mOffset = (S32)count;
+ mData->mScopeEntry->mSize = 4;
+ count += mData->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "dataserver";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mID->mName, strlen(mID->mName) + 1);
+ chunk->addBytes(mData->mName, strlen(mData->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mData->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptDataserverEvent::getSize()
+{
+ // key + string = 8
+ return 8;
+}
+
+void LLScriptTimerEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "timer()\n");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp, "timer()\n");
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "timer";
+ chunk->addBytes(name, strlen(name) + 1);
+#endif
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+S32 LLScriptTimerEvent::getSize()
+{
+ return 0;
+}
+
+void LLScriptMovingStartEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "moving_start()\n");
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "moving_start";
+ chunk->addBytes(name, strlen(name) + 1);
+#endif
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+S32 LLScriptMovingStartEvent::getSize()
+{
+ return 0;
+}
+
+void LLScriptMovingEndEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "moving_end()\n");
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "moving_end";
+ chunk->addBytes(name, strlen(name) + 1);
+#endif
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+S32 LLScriptMovingEndEvent::getSize()
+{
+ return 0;
+}
+
+void LLScriptRTPEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "chat( integer ");
+ mRTPermissions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mRTPermissions->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mRTPermissions->mScopeEntry = scope->addEntry(mRTPermissions->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mRTPermissions->mScopeEntry)
+ {
+ mRTPermissions->mScopeEntry->mOffset = (S32)count;
+ mRTPermissions->mScopeEntry->mSize = 4;
+ count += mRTPermissions->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "chat";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mRTPermissions->mName, strlen(mRTPermissions->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mRTPermissions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptRTPEvent::getSize()
+{
+ // integer = 4
+ return 4;
+}
+
+void LLScriptChatEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "chat( integer ");
+ mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", key ");
+ mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mMessage->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mChannel->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mChannel->mScopeEntry = scope->addEntry(mChannel->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ if (scope->checkEntry(mName->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mName->mScopeEntry = scope->addEntry(mName->mName, LIT_VARIABLE, LST_STRING);
+ }
+ if (scope->checkEntry(mID->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mID->mScopeEntry = scope->addEntry(mID->mName, LIT_VARIABLE, LST_KEY);
+ }
+ if (scope->checkEntry(mMessage->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mMessage->mScopeEntry = scope->addEntry(mMessage->mName, LIT_VARIABLE, LST_STRING);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mName->mScopeEntry)
+ {
+ mChannel->mScopeEntry->mOffset = (S32)count;
+ mChannel->mScopeEntry->mSize = 4;
+ count += mChannel->mScopeEntry->mSize;
+ mName->mScopeEntry->mOffset = (S32)count;
+ mName->mScopeEntry->mSize = 4;
+ count += mName->mScopeEntry->mSize;
+ mID->mScopeEntry->mOffset = (S32)count;
+ mID->mScopeEntry->mSize = 4;
+ count += mID->mScopeEntry->mSize;
+ mMessage->mScopeEntry->mOffset = (S32)count;
+ mMessage->mScopeEntry->mSize = 4;
+ count += mMessage->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "chat";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mChannel->mName, strlen(mChannel->mName) + 1);
+ chunk->addBytes(mName->mName, strlen(mName->mName) + 1);
+ chunk->addBytes(mID->mName, strlen(mID->mName) + 1);
+ chunk->addBytes(mMessage->mName, strlen(mMessage->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mMessage->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptChatEvent::getSize()
+{
+ // integer + key + string + string = 16
+ return 16;
+}
+
+void LLScriptSensorEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "sensor( integer ");
+ mNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mNumber->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mNumber->mScopeEntry = scope->addEntry(mNumber->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mNumber->mScopeEntry)
+ {
+ mNumber->mScopeEntry->mOffset = (S32)count;
+ mNumber->mScopeEntry->mSize = 4;
+ count += mNumber->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "sensor";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mNumber->mName, strlen(mNumber->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptSensorEvent::getSize()
+{
+ // integer = 4
+ return 4;
+}
+
+void LLScriptObjectRezEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "object_rez( key ");
+ mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mID->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mID->mScopeEntry = scope->addEntry(mID->mName, LIT_VARIABLE, LST_KEY);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mID->mScopeEntry)
+ {
+ mID->mScopeEntry->mOffset = (S32)count;
+ mID->mScopeEntry->mSize = 4;
+ count += mID->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "sensor";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mID->mName, strlen(mID->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptObjectRezEvent::getSize()
+{
+ // key = 4
+ return 4;
+}
+
+void LLScriptControlEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "control( key ");
+ mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", integer ");
+ mLevels->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", integer ");
+ mEdges->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mName->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mName->mScopeEntry = scope->addEntry(mName->mName, LIT_VARIABLE, LST_KEY);
+ }
+ if (scope->checkEntry(mLevels->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mLevels->mScopeEntry = scope->addEntry(mLevels->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ if (scope->checkEntry(mEdges->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mEdges->mScopeEntry = scope->addEntry(mEdges->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mName->mScopeEntry)
+ {
+ mName->mScopeEntry->mOffset = (S32)count;
+ mName->mScopeEntry->mSize = 4;
+ count += mName->mScopeEntry->mSize;
+ mLevels->mScopeEntry->mOffset = (S32)count;
+ mLevels->mScopeEntry->mSize = 4;
+ count += mLevels->mScopeEntry->mSize;
+ mEdges->mScopeEntry->mOffset = (S32)count;
+ mEdges->mScopeEntry->mSize = 4;
+ count += mEdges->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "control";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mName->mName, strlen(mName->mName) + 1);
+ chunk->addBytes(mLevels->mName, strlen(mLevels->mName) + 1);
+ chunk->addBytes(mEdges->mName, strlen(mEdges->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLevels->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mEdges->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptControlEvent::getSize()
+{
+ // key + integer + integer = 12
+ return 12;
+}
+
+void LLScriptLinkMessageEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "link_message( integer ");
+ mSender->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", integer ");
+ mNum->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mStr->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", key ");
+ mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mSender->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mSender->mScopeEntry = scope->addEntry(mSender->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ if (scope->checkEntry(mNum->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mNum->mScopeEntry = scope->addEntry(mNum->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ if (scope->checkEntry(mStr->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mStr->mScopeEntry = scope->addEntry(mStr->mName, LIT_VARIABLE, LST_STRING);
+ }
+ if (scope->checkEntry(mID->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mID->mScopeEntry = scope->addEntry(mID->mName, LIT_VARIABLE, LST_KEY);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mSender->mScopeEntry)
+ {
+ mSender->mScopeEntry->mOffset = (S32)count;
+ mSender->mScopeEntry->mSize = 4;
+ count += mSender->mScopeEntry->mSize;
+ mNum->mScopeEntry->mOffset = (S32)count;
+ mNum->mScopeEntry->mSize = 4;
+ count += mNum->mScopeEntry->mSize;
+ mStr->mScopeEntry->mOffset = (S32)count;
+ mStr->mScopeEntry->mSize = 4;
+ count += mStr->mScopeEntry->mSize;
+ mID->mScopeEntry->mOffset = (S32)count;
+ mID->mScopeEntry->mSize = 4;
+ count += mID->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "link_message";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mSender->mName, strlen(mSender->mName) + 1);
+ chunk->addBytes(mNum->mName, strlen(mNum->mName) + 1);
+ chunk->addBytes(mStr->mName, strlen(mStr->mName) + 1);
+ chunk->addBytes(mID->mName, strlen(mID->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mSender->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mNum->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mStr->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptLinkMessageEvent::getSize()
+{
+ // integer + key + integer + string = 16
+ return 16;
+}
+
+void LLScriptRemoteEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "remote_event( integer ");
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", key ");
+ mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", key ");
+ mMessageID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mSender->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", integer ");
+ mIntVal->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mStrVal->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mType->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mType->mScopeEntry = scope->addEntry(mType->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ if (scope->checkEntry(mChannel->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mChannel->mScopeEntry = scope->addEntry(mChannel->mName, LIT_VARIABLE, LST_KEY);
+ }
+ if (scope->checkEntry(mMessageID->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mMessageID->mScopeEntry = scope->addEntry(mMessageID->mName, LIT_VARIABLE, LST_KEY);
+ }
+ if (scope->checkEntry(mSender->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mSender->mScopeEntry = scope->addEntry(mSender->mName, LIT_VARIABLE, LST_STRING);
+ }
+ if (scope->checkEntry(mIntVal->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mIntVal->mScopeEntry = scope->addEntry(mIntVal->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ if (scope->checkEntry(mStrVal->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mStrVal->mScopeEntry = scope->addEntry(mStrVal->mName, LIT_VARIABLE, LST_STRING);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mType->mScopeEntry)
+ {
+ mType->mScopeEntry->mOffset = (S32)count;
+ mType->mScopeEntry->mSize = 4;
+ count += mType->mScopeEntry->mSize;
+ mChannel->mScopeEntry->mOffset = (S32)count;
+ mChannel->mScopeEntry->mSize = 4;
+ count += mChannel->mScopeEntry->mSize;
+ mMessageID->mScopeEntry->mOffset = (S32)count;
+ mMessageID->mScopeEntry->mSize = 4;
+ count += mMessageID->mScopeEntry->mSize;
+ mSender->mScopeEntry->mOffset = (S32)count;
+ mSender->mScopeEntry->mSize = 4;
+ count += mSender->mScopeEntry->mSize;
+ mIntVal->mScopeEntry->mOffset = (S32)count;
+ mIntVal->mScopeEntry->mSize = 4;
+ count += mIntVal->mScopeEntry->mSize;
+ mStrVal->mScopeEntry->mOffset = (S32)count;
+ mStrVal->mScopeEntry->mSize = 4;
+ count += mStrVal->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "remote_event";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mType->mName, strlen(mType->mName) + 1);
+ chunk->addBytes(mChannel->mName, strlen(mChannel->mName) + 1);
+ chunk->addBytes(mMessageID->mName, strlen(mMessageID->mName) + 1);
+ chunk->addBytes(mSender->mName, strlen(mSender->mName) + 1);
+ chunk->addBytes(mIntVal->mName, strlen(mIntVal->mName) + 1);
+ chunk->addBytes(mStrVal->mName, strlen(mStrVal->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mMessageID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mSender->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mIntVal->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mStrVal->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptRemoteEvent::getSize()
+{
+ // integer + key + key + string + integer + string = 24
+ return 24;
+}
+
+void LLScriptHTTPResponseEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "http_response( key ");
+ mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", integer ");
+ mStatus->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", list ");
+ mMetadata->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mRequestId->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mRequestId->mScopeEntry = scope->addEntry(mRequestId->mName, LIT_VARIABLE, LST_KEY);
+ }
+
+ if (scope->checkEntry(mStatus->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mStatus->mScopeEntry = scope->addEntry(mStatus->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+
+ if (scope->checkEntry(mMetadata->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mMetadata->mScopeEntry = scope->addEntry(mMetadata->mName, LIT_VARIABLE, LST_LIST);
+ }
+
+ if (scope->checkEntry(mBody->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mBody->mScopeEntry = scope->addEntry(mBody->mName, LIT_VARIABLE, LST_STRING);
+ }
+ break;
+
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mRequestId->mScopeEntry)
+ {
+ mRequestId->mScopeEntry->mOffset = (S32)count;
+ mRequestId->mScopeEntry->mSize = 4;
+ count += mRequestId->mScopeEntry->mSize;
+
+ mStatus->mScopeEntry->mOffset = (S32)count;
+ mStatus->mScopeEntry->mSize = 4;
+ count += mStatus->mScopeEntry->mSize;
+
+ mMetadata->mScopeEntry->mOffset = (S32)count;
+ mMetadata->mScopeEntry->mSize = 4;
+ count += mMetadata->mScopeEntry->mSize;
+
+ mBody->mScopeEntry->mOffset = (S32)count;
+ mBody->mScopeEntry->mSize = 4;
+ count += mBody->mScopeEntry->mSize;
+ }
+ }
+ break;
+
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "http_response";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mRequestId->mName, strlen(mRequestId->mName) + 1);
+ chunk->addBytes(mStatus->mName, strlen(mStatus->mName) + 1);
+ chunk->addBytes(mMetadata->mName, strlen(mMetadata->mName) + 1);
+ chunk->addBytes(mBody->mName, strlen(mBody->mName) + 1);
+#endif
+ }
+ break;
+
+ default:
+ mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mStatus->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mMetadata->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptHTTPResponseEvent::getSize()
+{
+ // key + integer + list + string = 16
+ return 16;
+}
+
+
+void LLScriptMoneyEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "money( key ");
+ mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", integer ");
+ mAmount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mName->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mName->mScopeEntry = scope->addEntry(mName->mName, LIT_VARIABLE, LST_KEY);
+ }
+ if (scope->checkEntry(mAmount->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mAmount->mScopeEntry = scope->addEntry(mAmount->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mName->mScopeEntry)
+ {
+ mName->mScopeEntry->mOffset = (S32)count;
+ mName->mScopeEntry->mSize = 4;
+ count += mName->mScopeEntry->mSize;
+ mAmount->mScopeEntry->mOffset = (S32)count;
+ mAmount->mScopeEntry->mSize = 4;
+ count += mAmount->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "money";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mName->mName, strlen(mName->mName) + 1);
+ chunk->addBytes(mAmount->mName, strlen(mAmount->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mAmount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptMoneyEvent::getSize()
+{
+ // key + integer = 8
+ return 8;
+}
+
+void LLScriptEmailEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "email( string ");
+ mTime->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mAddress->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mSubject->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", string ");
+ mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", integer ");
+ mNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mTime->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mTime->mScopeEntry = scope->addEntry(mTime->mName, LIT_VARIABLE, LST_STRING);
+ }
+ if (scope->checkEntry(mAddress->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mAddress->mScopeEntry = scope->addEntry(mAddress->mName, LIT_VARIABLE, LST_STRING);
+ }
+ if (scope->checkEntry(mSubject->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mSubject->mScopeEntry = scope->addEntry(mSubject->mName, LIT_VARIABLE, LST_STRING);
+ }
+ if (scope->checkEntry(mBody->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mBody->mScopeEntry = scope->addEntry(mBody->mName, LIT_VARIABLE, LST_STRING);
+ }
+ if (scope->checkEntry(mNumber->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mNumber->mScopeEntry = scope->addEntry(mNumber->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mAddress->mScopeEntry)
+ {
+ mTime->mScopeEntry->mOffset = (S32)count;
+ mTime->mScopeEntry->mSize = 4;
+ count += mTime->mScopeEntry->mSize;
+ mAddress->mScopeEntry->mOffset = (S32)count;
+ mAddress->mScopeEntry->mSize = 4;
+ count += mAddress->mScopeEntry->mSize;
+ mSubject->mScopeEntry->mOffset = (S32)count;
+ mSubject->mScopeEntry->mSize = 4;
+ count += mSubject->mScopeEntry->mSize;
+ mBody->mScopeEntry->mOffset = (S32)count;
+ mBody->mScopeEntry->mSize = 4;
+ count += mBody->mScopeEntry->mSize;
+ mNumber->mScopeEntry->mOffset = (S32)count;
+ mNumber->mScopeEntry->mSize = 4;
+ count += mNumber->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "email";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mTime->mName, strlen(mTime->mName) + 1);
+ chunk->addBytes(mAddress->mName, strlen(mAddress->mName) + 1);
+ chunk->addBytes(mSubject->mName, strlen(mSubject->mName) + 1);
+ chunk->addBytes(mBody->mName, strlen(mBody->mName) + 1);
+ chunk->addBytes(mNumber->mName, strlen(mNumber->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mTime->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mAddress->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mSubject->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptEmailEvent::getSize()
+{
+ // string + string + string + string + integer = 16
+ return 20;
+}
+
+void LLScriptRezEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "rez( integer ");
+ mStartParam->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mStartParam->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mStartParam->mScopeEntry = scope->addEntry(mStartParam->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mStartParam->mScopeEntry)
+ {
+ mStartParam->mScopeEntry->mOffset = (S32)count;
+ mStartParam->mScopeEntry->mSize = 4;
+ count += mStartParam->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "rez";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mStartParam->mName, strlen(mStartParam->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mStartParam->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptRezEvent::getSize()
+{
+ // integer = 4
+ return 4;
+}
+
+void LLScriptNoSensorEvent::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "no_sensor()\n");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp, "no_sensor()\n");
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "no_sensor";
+ chunk->addBytes(name, strlen(name) + 1);
+#endif
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+S32 LLScriptNoSensorEvent::getSize()
+{
+ return 0;
+}
+
+void LLScriptAtTarget::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "at_target( integer ");
+ mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", vector ");
+ mTargetPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", vector ");
+ mOurPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mTargetNumber->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mTargetNumber->mScopeEntry = scope->addEntry(mTargetNumber->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ if (scope->checkEntry(mTargetPosition->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mTargetPosition->mScopeEntry = scope->addEntry(mTargetPosition->mName, LIT_VARIABLE, LST_VECTOR);
+ }
+ if (scope->checkEntry(mOurPosition->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mOurPosition->mScopeEntry = scope->addEntry(mOurPosition->mName, LIT_VARIABLE, LST_VECTOR);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mTargetNumber->mScopeEntry)
+ {
+ mTargetNumber->mScopeEntry->mOffset = (S32)count;
+ mTargetNumber->mScopeEntry->mSize = 4;
+ count += mTargetNumber->mScopeEntry->mSize;
+ mTargetPosition->mScopeEntry->mOffset = (S32)count;
+ mTargetPosition->mScopeEntry->mSize = 12;
+ count += mTargetPosition->mScopeEntry->mSize;
+ mOurPosition->mScopeEntry->mOffset = (S32)count;
+ mOurPosition->mScopeEntry->mSize = 12;
+ count += mOurPosition->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "at_target";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mTargetNumber->mName, strlen(mTargetNumber->mName) + 1);
+ chunk->addBytes(mTargetPosition->mName, strlen(mTargetPosition->mName) + 1);
+ chunk->addBytes(mOurPosition->mName, strlen(mOurPosition->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mTargetPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mOurPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptAtTarget::getSize()
+{
+ // integer + vector + vector = 28
+ return 28;
+}
+
+
+
+void LLScriptNotAtTarget::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "not_at_target()\n");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp, "not_at_target()\n");
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "not_at_target";
+ chunk->addBytes(name, strlen(name) + 1);
+#endif
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+S32 LLScriptNotAtTarget::getSize()
+{
+ return 0;
+}
+
+void LLScriptAtRotTarget::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ case LSCP_EMIT_ASSEMBLY:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "at_target( integer ");
+ mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", quaternion ");
+ mTargetRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", quaternion ");
+ mOurRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (scope->checkEntry(mTargetNumber->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mTargetNumber->mScopeEntry = scope->addEntry(mTargetNumber->mName, LIT_VARIABLE, LST_INTEGER);
+ }
+ if (scope->checkEntry(mTargetRotation->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mTargetRotation->mScopeEntry = scope->addEntry(mTargetRotation->mName, LIT_VARIABLE, LST_QUATERNION);
+ }
+ if (scope->checkEntry(mOurRotation->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mOurRotation->mScopeEntry = scope->addEntry(mOurRotation->mName, LIT_VARIABLE, LST_QUATERNION);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ if (mTargetNumber->mScopeEntry)
+ {
+ mTargetNumber->mScopeEntry->mOffset = (S32)count;
+ mTargetNumber->mScopeEntry->mSize = 4;
+ count += mTargetNumber->mScopeEntry->mSize;
+ mTargetRotation->mScopeEntry->mOffset = (S32)count;
+ mTargetRotation->mScopeEntry->mSize = 16;
+ count += mTargetRotation->mScopeEntry->mSize;
+ mOurRotation->mScopeEntry->mOffset = (S32)count;
+ mOurRotation->mScopeEntry->mSize = 16;
+ count += mOurRotation->mScopeEntry->mSize;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "at_rot_target";
+ chunk->addBytes(name, strlen(name) + 1);
+ chunk->addBytes(mTargetNumber->mName, strlen(mTargetNumber->mName) + 1);
+ chunk->addBytes(mTargetRotation->mName, strlen(mTargetRotation->mName) + 1);
+ chunk->addBytes(mOurRotation->mName, strlen(mOurRotation->mName) + 1);
+#endif
+ }
+ break;
+ default:
+ mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mTargetRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mOurRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
+
+S32 LLScriptAtRotTarget::getSize()
+{
+ // integer + quaternion + quaternion = 36
+ return 36;
+}
+
+
+
+void LLScriptNotAtRotTarget::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "not_at_rot_target()\n");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp, "not_at_rot_target()\n");
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ char name[] = "not_at_rot_target";
+ chunk->addBytes(name, strlen(name) + 1);
+#endif
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+S32 LLScriptNotAtRotTarget::getSize()
+{
+ return 0;
+}
+
+
+
+void LLScriptExpression::addExpression(LLScriptExpression *expression)
+{
+ if (mNextp)
+ {
+ expression->mNextp = mNextp;
+ }
+ mNextp = expression;
+}
+
+void LLScriptExpression::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ fprintf(fp, "Expression Base Class -- should never get here!\n");
+}
+
+S32 LLScriptExpression::getSize()
+{
+ printf("Expression Base Class -- should never get here!\n");
+ return 0;
+}
+
+void LLScriptExpression::gonext(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ if (mNextp)
+ {
+ fprintf(fp, ", ");
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ default:
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+}
+
+void LLScriptForExpressionList::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mSecondp)
+ {
+ fprintf(fp, ", ");
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mFirstp->mReturnType)
+ {
+ fprintf(fp, "%s\n", LSCRIPTTypePop[mFirstp->mReturnType]);
+ }
+ if (mSecondp)
+ {
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mSecondp->mReturnType)
+ {
+ fprintf(fp, "%s\n", LSCRIPTTypePop[mSecondp->mReturnType]);
+ }
+ }
+ break;
+ case LSCP_TO_STACK:
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ switch(mFirstp->mReturnType)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
+ break;
+ case LST_STRING:
+ case LST_KEY:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
+ break;
+ case LST_LIST:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
+ break;
+ case LST_VECTOR:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
+ break;
+ case LST_QUATERNION:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
+ break;
+ default:
+ break;
+ }
+ if (mSecondp)
+ {
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ switch(mSecondp->mReturnType)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
+ break;
+ case LST_STRING:
+ case LST_KEY:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
+ break;
+ case LST_LIST:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
+ break;
+ case LST_VECTOR:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
+ break;
+ case LST_QUATERNION:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mFirstp->mReturnType)
+ {
+ fprintf(fp, "pop\n");
+ }
+ if (mSecondp)
+ {
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mSecondp->mReturnType)
+ {
+ fprintf(fp, "pop\n");
+ }
+ }
+ break;
+ default:
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mSecondp)
+ {
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+}
+
+S32 LLScriptForExpressionList::getSize()
+{
+ return 0;
+}
+
+void LLScriptFuncExpressionList::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mSecondp)
+ {
+ fprintf(fp, ", ");
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_TYPE:
+ {
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!entry->mFunctionArgs.getType(entrycount))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
+ }
+ if (!legal_assignment(entry->mFunctionArgs.getType(entrycount), mFirstp->mReturnType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
+ }
+ count++;
+ entrycount++;
+ if (mSecondp)
+ {
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mSecondp->mReturnType)
+ {
+ count++;
+ if (!entry->mFunctionArgs.getType(entrycount))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
+ }
+ if (!legal_assignment(entry->mFunctionArgs.getType(entrycount), mSecondp->mReturnType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
+ }
+ }
+ }
+ }
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ LSCRIPTType argtype = entry->mFunctionArgs.getType(entrycount);
+ if (argtype != mFirstp->mReturnType)
+ {
+ fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mFirstp->mReturnType], LSCRIPTTypeNames[argtype]);
+ }
+ entrycount++;
+ if (mSecondp)
+ {
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mSecondp->mReturnType)
+ {
+ argtype = entry->mFunctionArgs.getType(entrycount);
+ if (argtype != mSecondp->mReturnType)
+ {
+ fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mSecondp->mReturnType], LSCRIPTTypeNames[argtype]);
+ }
+ }
+ }
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ LSCRIPTType argtype = entry->mFunctionArgs.getType(entrycount);
+ if (argtype != mFirstp->mReturnType)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
+ U8 castbyte = LSCRIPTTypeByte[argtype] | LSCRIPTTypeHi4Bits[mFirstp->mReturnType];
+ chunk->addByte(castbyte);
+ }
+ entrycount++;
+ if (mSecondp)
+ {
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mSecondp->mReturnType)
+ {
+ argtype = entry->mFunctionArgs.getType(entrycount);
+ if (argtype != mSecondp->mReturnType)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
+ U8 castbyte = LSCRIPTTypeByte[argtype] | LSCRIPTTypeHi4Bits[mSecondp->mReturnType];
+ chunk->addByte(castbyte);
+ }
+ }
+ }
+ }
+ break;
+ /* TODO: Fix conflict between global/local variable determination needing caller scope and cast determination here needs callee scope...
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ LSCRIPTType argtype = entry->mFunctionArgs.getType(entrycount);
+ if (argtype != mFirstp->mReturnType)
+ {
+ print_cil_cast(fp, mFirstp->mReturnType, argtype);
+ }
+ entrycount++;
+ if (mSecondp)
+ {
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mSecondp->mReturnType)
+ {
+ argtype = entry->mFunctionArgs.getType(entrycount);
+ if (argtype != mSecondp->mReturnType)
+ {
+ print_cil_cast(fp, mFirstp->mReturnType, argtype);
+ }
+ }
+ }
+ }
+ break;
+ */
+ default:
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mSecondp)
+ {
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+}
+
+S32 LLScriptFuncExpressionList::getSize()
+{
+ return 0;
+}
+
+void LLScriptListExpressionList::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mSecondp)
+ {
+ fprintf(fp, ", ");
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mFirstp->mType != LET_LIST_EXPRESSION_LIST)
+ {
+ fprintf(fp, "%s\n", LSCRIPTListDescription[mFirstp->mReturnType]);
+ count++;
+ }
+ if (mSecondp)
+ {
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mSecondp->mType != LET_LIST_EXPRESSION_LIST)
+ {
+ fprintf(fp, "%s\n", LSCRIPTListDescription[mSecondp->mReturnType]);
+ count++;
+ }
+ }
+ break;
+ case LSCP_TO_STACK:
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mFirstp->mType != LET_LIST_EXPRESSION_LIST)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGB]);
+ chunk->addByte(LSCRIPTTypeByte[mFirstp->mReturnType]);
+ count++;
+ }
+ if (mSecondp)
+ {
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mSecondp->mType != LET_LIST_EXPRESSION_LIST)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGB]);
+ chunk->addByte(LSCRIPTTypeByte[mSecondp->mReturnType]);
+ count++;
+ }
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ // Evaluate expressions in reverse order so first expression is on top of stack.
+ // Results can then be popped and appended to list to result in list with correct order.
+ if (mSecondp)
+ {
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mSecondp->mType != LET_LIST_EXPRESSION_LIST)
+ {
+ // Box value.
+ print_cil_box(fp, mSecondp->mReturnType);
+
+ ++count;
+ }
+ }
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mFirstp->mType != LET_LIST_EXPRESSION_LIST)
+ {
+ // Box value.
+ print_cil_box(fp, mFirstp->mReturnType);
+
+ ++count;
+ }
+ break;
+ default:
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mSecondp)
+ {
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+}
+
+S32 LLScriptListExpressionList::getSize()
+{
+ return 0;
+}
+
+// Returns true if identifier is a parameter and false if identifier is a local variable within function_scope.
+bool is_parameter(LLScriptIdentifier* identifier, LLScriptScopeEntry* function_scope)
+{
+ // Function offset stores offset of first local.
+ // Compare variable offset with function offset to
+ // determine whether variable is local or parameter.
+ return (identifier->mScopeEntry->mOffset < function_scope->mOffset);
+}
+
+// If assignment is to global variable, pushes this pointer on to stack.
+void print_cil_load_address(FILE* fp, LLScriptExpression* exp, LLScriptScopeEntry* function_scope)
+{
+ LLScriptLValue *lvalue = (LLScriptLValue *) exp;
+ LLScriptIdentifier *ident = lvalue->mIdentifier;
+
+ // If global (member), load this pointer.
+ if(ident->mScopeEntry->mIDType == LIT_GLOBAL)
+ {
+ fprintf(fp, "ldarg.0\n");
+ }
+
+ // If accessor, load address of object.
+ if(lvalue->mAccessor)
+ {
+ if(ident->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ if(is_parameter(ident, function_scope))
+ {
+ // Parameter, load by name.
+ fprintf(fp, "ldarga.s %s\n", ident->mScopeEntry->mIdentifier);
+ }
+ else
+ {
+ // Local, load by index.
+ fprintf(fp, "ldloca.s %d\n", ident->mScopeEntry->mCount);
+ }
+ }
+ else if (ident->mScopeEntry->mIDType == LIT_GLOBAL)
+ {
+ fprintf(fp, "ldflda ");
+ print_cil_type(fp, ident->mScopeEntry->mType);
+ fprintf(fp, " LSL::%s\n", ident->mScopeEntry->mIdentifier);
+ }
+ }
+}
+
+void print_cil_accessor(FILE* fp, LLScriptLValue *lvalue)
+{
+ LLScriptIdentifier *ident = lvalue->mIdentifier;
+ print_cil_type(fp, lvalue->mReturnType);
+ fprintf(fp, " ");
+ print_cil_type(fp, ident->mScopeEntry->mType);
+ fprintf(fp, "::%s\n", lvalue->mAccessor->mName);
+}
+
+void print_cil_member(FILE* fp, LLScriptIdentifier *ident)
+{
+ print_cil_type(fp, ident->mScopeEntry->mType);
+ fprintf(fp, " LSL::%s\n", ident->mScopeEntry->mIdentifier);
+}
+
+void LLScriptLValue::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mAccessor)
+ {
+ fprintf(fp, ".");
+ mAccessor->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ if (mAccessor)
+ {
+ fprintf(fp, "%s%d [%s.%s]\n", LSCRIPTTypeLocalPush[mReturnType], mIdentifier->mScopeEntry->mOffset + mOffset, mIdentifier->mName, mAccessor->mName);
+ }
+ else
+ {
+ fprintf(fp, "%s%d [%s]\n", LSCRIPTTypeLocalPush[mIdentifier->mScopeEntry->mType], mIdentifier->mScopeEntry->mOffset, mIdentifier->mName);
+ }
+ }
+ else if (mIdentifier->mScopeEntry->mIDType == LIT_GLOBAL)
+ {
+ if (mAccessor)
+ {
+ fprintf(fp, "%s%d [%s.%s]\n", LSCRIPTTypeGlobalPush[mReturnType], mIdentifier->mScopeEntry->mOffset + mOffset, mIdentifier->mName, mAccessor->mName);
+ }
+ else
+ {
+ fprintf(fp, "%s%d [%s]\n", LSCRIPTTypeGlobalPush[mIdentifier->mScopeEntry->mType], mIdentifier->mScopeEntry->mOffset, mIdentifier->mName);
+ }
+ }
+ else
+ {
+ fprintf(fp, "Unexpected LValue!\n");
+ }
+ break;
+ case LSCP_SCOPE_PASS1:
+ {
+ LLScriptScopeEntry *entry = scope->findEntry(mIdentifier->mName);
+ if (!entry || ( (entry->mIDType != LIT_GLOBAL) && (entry->mIDType != LIT_VARIABLE)))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
+ }
+ else
+ {
+ // if we did find it, make sure this identifier is associated with the correct scope entry
+ mIdentifier->mScopeEntry = entry;
+ }
+ }
+ break;
+ case LSCP_TYPE:
+ // if we have an accessor, we need to change what type our identifier returns and set our offset value
+ if (mIdentifier->mScopeEntry)
+ {
+ if (mAccessor)
+ {
+ BOOL b_ok = FALSE;
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ if (mIdentifier->mScopeEntry->mType == LST_VECTOR)
+ {
+ if (!strcmp("x", mAccessor->mName))
+ {
+ mOffset = 0;
+ b_ok = TRUE;
+ }
+ else if (!strcmp("y", mAccessor->mName))
+ {
+ mOffset = 4;
+ b_ok = TRUE;
+ }
+ else if (!strcmp("z", mAccessor->mName))
+ {
+ mOffset = 8;
+ b_ok = TRUE;
+ }
+ }
+ else if (mIdentifier->mScopeEntry->mType == LST_QUATERNION)
+ {
+ if (!strcmp("x", mAccessor->mName))
+ {
+ mOffset = 0;
+ b_ok = TRUE;
+ }
+ else if (!strcmp("y", mAccessor->mName))
+ {
+ mOffset = 4;
+ b_ok = TRUE;
+ }
+ else if (!strcmp("z", mAccessor->mName))
+ {
+ mOffset = 8;
+ b_ok = TRUE;
+ }
+ else if (!strcmp("s", mAccessor->mName))
+ {
+ mOffset = 12;
+ b_ok = TRUE;
+ }
+ }
+ }
+ else
+ {
+ if (mIdentifier->mScopeEntry->mType == LST_VECTOR)
+ {
+ if (!strcmp("x", mAccessor->mName))
+ {
+ mOffset = 8;
+ b_ok = TRUE;
+ }
+ else if (!strcmp("y", mAccessor->mName))
+ {
+ mOffset = 4;
+ b_ok = TRUE;
+ }
+ else if (!strcmp("z", mAccessor->mName))
+ {
+ mOffset = 0;
+ b_ok = TRUE;
+ }
+ }
+ else if (mIdentifier->mScopeEntry->mType == LST_QUATERNION)
+ {
+ if (!strcmp("x", mAccessor->mName))
+ {
+ mOffset = 12;
+ b_ok = TRUE;
+ }
+ else if (!strcmp("y", mAccessor->mName))
+ {
+ mOffset = 8;
+ b_ok = TRUE;
+ }
+ else if (!strcmp("z", mAccessor->mName))
+ {
+ mOffset = 4;
+ b_ok = TRUE;
+ }
+ else if (!strcmp("s", mAccessor->mName))
+ {
+ mOffset = 0;
+ b_ok = TRUE;
+ }
+ }
+ }
+ if (b_ok)
+ {
+ mReturnType = type = LST_FLOATINGPOINT;
+ }
+ else
+ {
+ gErrorToText.writeError(fp, this, LSERROR_VECTOR_METHOD_ERROR);
+ }
+ }
+ else
+ {
+ mReturnType = type = mIdentifier->mScopeEntry->mType;
+ }
+ }
+ else
+ {
+ mReturnType = type = LST_UNDEFINED;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ switch(mReturnType)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSH]);
+ }
+ else
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHG]);
+ }
+ break;
+ case LST_KEY:
+ case LST_STRING:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHS]);
+ }
+ else
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHGS]);
+ }
+ break;
+ case LST_LIST:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHL]);
+ }
+ else
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHGL]);
+ }
+ break;
+ case LST_VECTOR:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHV]);
+ }
+ else
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHGV]);
+ }
+ break;
+ case LST_QUATERNION:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHQ]);
+ }
+ else
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHGQ]);
+ }
+ break;
+ default:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSH]);
+ }
+ else
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHG]);
+ }
+ break;
+ }
+ S32 address = mIdentifier->mScopeEntry->mOffset + mOffset;
+ chunk->addInteger(address);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ print_cil_load_address(fp, this, entry);
+ if(mAccessor)
+ {
+ fprintf(fp, "ldfld ");
+ print_cil_accessor(fp, this);
+ }
+ else if(mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ if(is_parameter(mIdentifier, entry))
+ {
+ // Parameter, load by name.
+ fprintf(fp, "ldarg.s %s\n", mIdentifier->mScopeEntry->mIdentifier);
+ }
+ else
+ {
+ // Local, load by index.
+ fprintf(fp, "ldloc.s %d\n", mIdentifier->mScopeEntry->mCount);
+ }
+ }
+ else if (mIdentifier->mScopeEntry->mIDType == LIT_GLOBAL)
+ {
+ fprintf(fp, "ldfld ");
+ print_cil_member(fp, mIdentifier);
+ }
+ else
+ {
+ fprintf(fp, "Unexpected LValue!\n");
+ }
+ break;
+ default:
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptLValue::getSize()
+{
+ return 0;
+}
+
+void print_asignment(FILE *fp, LLScriptExpression *exp)
+{
+ LLScriptLValue *lvalue = (LLScriptLValue *)exp;
+ LLScriptIdentifier *ident = lvalue->mIdentifier;
+ if (lvalue->mAccessor)
+ {
+ if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ fprintf(fp, "%s%d [%s.%s]\n", LSCRIPTTypeLocalStore[ident->mScopeEntry->mType], ident->mScopeEntry->mOffset + lvalue->mOffset, ident->mName, lvalue->mAccessor->mName);
+ }
+ else if (ident->mScopeEntry->mIDType == LIT_GLOBAL)
+ {
+ fprintf(fp, "%s%d [%s.%s]\n", LSCRIPTTypeGlobalStore[ident->mScopeEntry->mType], ident->mScopeEntry->mOffset + lvalue->mOffset, ident->mName, lvalue->mAccessor->mName);
+ }
+ }
+ else
+ {
+ if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ fprintf(fp, "%s%d [%s]\n", LSCRIPTTypeLocalStore[ident->mScopeEntry->mType], ident->mScopeEntry->mOffset, ident->mName);
+ }
+ else if (ident->mScopeEntry->mIDType == LIT_GLOBAL)
+ {
+ fprintf(fp, "%s%d [%s]\n", LSCRIPTTypeGlobalStore[ident->mScopeEntry->mType], ident->mScopeEntry->mOffset, ident->mName);
+ }
+ }
+}
+
+void print_cil_asignment(FILE *fp, LLScriptExpression *exp, LLScriptScopeEntry* function_scope)
+{
+ LLScriptLValue *lvalue = (LLScriptLValue *) exp;
+ LLScriptIdentifier *ident = lvalue->mIdentifier;
+ if (lvalue->mAccessor)
+ {
+ // Object address loaded, store in to field.
+ fprintf(fp, "stfld ");
+ print_cil_accessor(fp, lvalue);
+
+ // Load object address.
+ print_cil_load_address(fp, exp, function_scope);
+
+ // Load field.
+ fprintf(fp, "ldfld ");
+ print_cil_accessor(fp, lvalue);
+ }
+ else
+ {
+ if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ // Language semantics require value of assignment to be left on stack.
+ // TODO: Optimise away redundant dup/pop pairs.
+ fprintf(fp, "dup\n");
+ if(is_parameter(ident, function_scope))
+ {
+ // Parameter, store by name.
+ fprintf(fp, "starg.s %s\n", ident->mScopeEntry->mIdentifier);
+ }
+ else
+ {
+ // Local, store by index.
+ fprintf(fp, "stloc.s %d\n", ident->mScopeEntry->mCount);
+ }
+ }
+ else if (ident->mScopeEntry->mIDType == LIT_GLOBAL)
+ {
+ // Object address loaded, store in to field.
+ fprintf(fp, "stfld ");
+ print_cil_member(fp, ident);
+
+ // Load object address.
+ print_cil_load_address(fp, exp, function_scope);
+
+ // Load field.
+ fprintf(fp, "ldfld ");
+ print_cil_member(fp, ident);
+ }
+ }
+}
+
+void print_cast(FILE *fp, LSCRIPTType ret_type, LSCRIPTType right_type)
+{
+ if (right_type != ret_type)
+ {
+ fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[right_type], LSCRIPTTypeNames[ret_type]);
+ }
+}
+
+void cast2stack(LLScriptByteCodeChunk *chunk, LSCRIPTType ret_type, LSCRIPTType right_type)
+{
+ if (right_type != ret_type)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
+ U8 castbyte = LSCRIPTTypeByte[right_type] | LSCRIPTTypeHi4Bits[ret_type];
+ chunk->addByte(castbyte);
+ }
+}
+
+void operation2stack(LLScriptByteCodeChunk *chunk, LSCRIPTType ret_type, LSCRIPTType right_type)
+{
+ U8 typebyte = LSCRIPTTypeByte[right_type] | LSCRIPTTypeHi4Bits[ret_type];
+ chunk->addByte(typebyte);
+}
+
+void store2stack(LLScriptExpression *exp, LLScriptExpression *lv, LLScriptByteCodeChunk *chunk, LSCRIPTType right_type)
+{
+ LLScriptLValue *lvalue = (LLScriptLValue *)lv;
+ LLScriptIdentifier *ident = lvalue->mIdentifier;
+ LSCRIPTType rettype = exp->mReturnType;
+
+ if (exp->mRightType != LST_NULL)
+ {
+ if (legal_binary_expression(rettype, exp->mLeftType, exp->mRightType, exp->mType))
+ cast2stack(chunk, right_type, exp->mReturnType);
+ }
+ switch(exp->mReturnType)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+ if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STORE]);
+ }
+ else
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STOREG]);
+ }
+ break;
+ case LST_KEY:
+ case LST_STRING:
+ if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STORES]);
+ }
+ else
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STOREGS]);
+ }
+ break;
+ case LST_LIST:
+ if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STOREL]);
+ }
+ else
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STOREGL]);
+ }
+ break;
+ case LST_VECTOR:
+ if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STOREV]);
+ }
+ else
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STOREGV]);
+ }
+ break;
+ case LST_QUATERNION:
+ if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STOREQ]);
+ }
+ else
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STOREGQ]);
+ }
+ break;
+ default:
+ if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STORE]);
+ }
+ else
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STOREG]);
+ }
+ break;
+ }
+ S32 address = ident->mScopeEntry->mOffset + lvalue->mOffset;
+ chunk->addInteger(address);
+}
+
+void print_cil_numeric_cast(FILE* fp, LSCRIPTType currentArg, LSCRIPTType otherArg)
+{
+ if((currentArg == LST_INTEGER) && (otherArg == LST_FLOATINGPOINT))
+ {
+ print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
+ }
+}
+
+void LLScriptAssignment::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " = ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cast(fp, mReturnType, mRightType);
+ print_asignment(fp, mLValue);
+ }
+ break;
+ case LSCP_TYPE:
+ {
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_assignment(mLeftType, mRightType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType = mLeftType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ store2stack(this, mLValue, chunk, mRightType);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ print_cil_load_address(fp, mLValue, entry);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mRightType, mReturnType);
+ print_cil_asignment(fp, mLValue, entry);
+ }
+ break;
+ default:
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptAssignment::getSize()
+{
+ return 0;
+}
+
+void print_cil_add(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
+{
+ switch(left_type)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+
+ // Numeric addition.
+ fprintf(fp, "add\n");
+ break;
+
+ case LST_STRING:
+ case LST_KEY:
+
+ // String concatenation.
+ fprintf(fp, "call string valuetype [mscorlib]System.String::Concat(string, string)");
+ break;
+
+ case LST_VECTOR:
+
+ // Vector addition.
+ // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
+ fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'add_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
+ break;
+
+ case LST_QUATERNION:
+
+ // Rotation addition.
+ // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
+ fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'add_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
+ break;
+
+ case LST_LIST:
+ print_cil_box(fp, right_type);
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::AddReturnList(class [mscorlib]System.Collections.ArrayList, object)\n");
+ break;
+
+ default:
+ break;
+ }
+}
+
+void LLScriptAddAssignment::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " += ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "ADD %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ print_asignment(fp, mLValue);
+ }
+ break;
+ case LSCP_TYPE:
+ {
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
+ operation2stack(chunk, mReturnType, mRightType);
+ store2stack(this, mLValue, chunk, mReturnType);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ print_cil_load_address(fp, mLValue, entry);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
+ print_cil_add(fp, mLValue->mReturnType, mRightSide->mReturnType);
+ print_cil_asignment(fp, mLValue, entry);
+ }
+ break;
+ default:
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptAddAssignment::getSize()
+{
+ return 0;
+}
+
+void print_cil_sub(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
+{
+ switch(left_type)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+
+ // Numeric subtraction.
+ fprintf(fp, "sub\n");
+ break;
+
+ case LST_VECTOR:
+
+ // Vector subtraction.
+ // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
+ fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'subtract_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
+ break;
+
+ case LST_QUATERNION:
+
+ // Rotation subtraction.
+ // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
+ fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'subtract_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
+ break;
+
+ default:
+
+ // Error.
+ break;
+ }
+}
+
+void LLScriptSubAssignment::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " -= ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "SUB %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ print_asignment(fp, mLValue);
+ }
+ break;
+ case LSCP_TYPE:
+ {
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
+ operation2stack(chunk, mReturnType, mRightType);
+ store2stack(this, mLValue, chunk, mReturnType);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ print_cil_load_address(fp, mLValue, entry);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
+ print_cil_sub(fp, mLValue->mReturnType, mRightSide->mReturnType);
+ print_cil_asignment(fp, mLValue, entry);
+ }
+ break;
+ default:
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptSubAssignment::getSize()
+{
+ return 0;
+}
+
+void print_cil_mul(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
+{
+ switch(left_type)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+
+ // Numeric multiplication.
+ fprintf(fp, "mul\n");
+ break;
+
+ case LST_VECTOR:
+
+ switch(right_type)
+ {
+ case LST_INTEGER:
+
+ print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
+
+ case LST_FLOATINGPOINT:
+
+ // Vector scaling.
+ fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'multiply_float'(valuetype [LScriptLibrary]LLVector, float32)\n");
+ break;
+
+ case LST_VECTOR:
+
+ // Dot product.
+ fprintf(fp, "call float32 valuetype [LScriptLibrary]LLVector::'multiply_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
+ break;
+
+ case LST_QUATERNION:
+
+ // Vector rotation.
+ fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'multiply_quat'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLQuaternion)\n");
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case LST_QUATERNION:
+
+ // Rotation multiplication.
+ fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'multiply_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
+ break;
+
+ default:
+
+ // Error.
+ break;
+ }
+}
+
+void LLScriptMulAssignment::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " *= ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "MUL %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ print_asignment(fp, mLValue);
+ }
+ break;
+ case LSCP_TYPE:
+ {
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_MUL]);
+ operation2stack(chunk, mReturnType, mRightType);
+ store2stack(this, mLValue, chunk, mReturnType);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ print_cil_load_address(fp, mLValue, entry);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
+ print_cil_mul(fp, mLValue->mReturnType, mRightSide->mReturnType);
+ print_cil_asignment(fp, mLValue, entry);
+ }
+ break;
+ default:
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptMulAssignment::getSize()
+{
+ return 0;
+}
+
+void print_cil_div(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
+{
+ switch(left_type)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+
+ // Numeric addition.
+ fprintf(fp, "div\n");
+ break;
+
+ case LST_VECTOR:
+
+ switch(right_type)
+ {
+ case LST_INTEGER:
+
+ print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
+
+ case LST_FLOATINGPOINT:
+
+ // Scale.
+ fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'divide_float'(valuetype [LScriptLibrary]LLVector, float32)\n");
+ break;
+
+ case LST_QUATERNION:
+
+ // Inverse rotation.
+ fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'divide_quat'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLQuaternion)\n");
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case LST_QUATERNION:
+
+ fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'divide_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
+ break;
+
+ default:
+
+ // Error.
+ break;
+ }
+}
+
+void LLScriptDivAssignment::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " /= ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "DIV %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ print_asignment(fp, mLValue);
+ }
+ break;
+ case LSCP_TYPE:
+ {
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_DIV]);
+ operation2stack(chunk, mReturnType, mRightType);
+ store2stack(this, mLValue, chunk, mReturnType);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ print_cil_load_address(fp, mLValue, entry);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
+ print_cil_div(fp, mLValue->mReturnType, mRightSide->mReturnType);
+ print_cil_asignment(fp, mLValue, entry);
+ }
+ break;
+ default:
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptDivAssignment::getSize()
+{
+ return 0;
+}
+
+void print_cil_mod(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
+{
+ switch(left_type)
+ {
+ case LST_INTEGER:
+
+ // Numeric remainder.
+ fprintf(fp, "rem\n");
+ break;
+
+ case LST_VECTOR:
+
+ // Vector cross product.
+ fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'mod_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
+ break;
+
+ default:
+
+ // Error.
+ break;
+ }
+}
+
+void LLScriptModAssignment::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " %%= ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "MOD %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ print_asignment(fp, mLValue);
+ }
+ break;
+ case LSCP_TYPE:
+ {
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_MOD]);
+ operation2stack(chunk, mReturnType, mRightType);
+ store2stack(this, mLValue, chunk, mReturnType);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ print_cil_load_address(fp, mLValue, entry);
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_mod(fp, mLValue->mReturnType, mRightSide->mReturnType);
+ print_cil_asignment(fp, mLValue, entry);
+ }
+ break;
+ default:
+ mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptModAssignment::getSize()
+{
+ return 0;
+}
+
+void print_cil_eq(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
+{
+ switch(left_type)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+
+ // Numeric equality.
+ fprintf(fp, "ceq\n");
+ break;
+
+ case LST_STRING:
+ case LST_KEY:
+
+ // String equality.
+ fprintf(fp, "call bool valuetype [mscorlib]System.String::op_Equality(string, string)\n");
+ break;
+
+ case LST_VECTOR:
+
+ // Vector equality.
+ fprintf(fp, "call bool [LScriptLibrary]LLVector::'equals_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
+ break;
+
+ case LST_QUATERNION:
+
+ // Rotation equality.
+ fprintf(fp, "call bool [LScriptLibrary]LLQuaternion::'equals_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
+ break;
+
+ case LST_LIST:
+ fprintf(fp, "call bool [LScriptLibrary]LScriptInternal::EqualsList(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)\n");
+ break;
+
+ default:
+
+ // Error.
+ break;
+ }
+}
+
+void LLScriptEquality::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " == ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "EQ %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
+ chunk->addByte(LSCRIPTOpCodes[LOPC_EQ]);
+ chunk->addByte(typebyte);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
+ print_cil_eq(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptEquality::getSize()
+{
+ return 0;
+}
+
+void LLScriptNotEquals::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " != ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "NEQ %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
+ chunk->addByte(LSCRIPTOpCodes[LOPC_NEQ]);
+ chunk->addByte(typebyte);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "ceq\n");
+ fprintf(fp, "ldc.i4.0\n");
+ fprintf(fp, "ceq\n"); // Compare result of first compare equal with 0 to get compare not equal.
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptNotEquals::getSize()
+{
+ return 0;
+}
+
+void LLScriptLessEquals::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " <= ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "LEQ %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LEQ]);
+ chunk->addByte(typebyte);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "cgt\n"); // Test greater than.
+ fprintf(fp, "ldc.i4.0\n"); // Use (b == 0) implementation of boolean not.
+ fprintf(fp, "ceq\n"); // Apply boolean not to greater than. If not greater than, then less or equal.
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptLessEquals::getSize()
+{
+ return 0;
+}
+
+void LLScriptGreaterEquals::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " >= ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "GEQ %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
+ chunk->addByte(LSCRIPTOpCodes[LOPC_GEQ]);
+ chunk->addByte(typebyte);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "clt\n"); // Test less than.
+ fprintf(fp, "ldc.i4.0\n"); // Use (b == 0) implementation of boolean not.
+ fprintf(fp, "ceq\n"); // Apply boolean not to less than. If not less than, then greater or equal.
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptGreaterEquals::getSize()
+{
+ return 0;
+}
+
+void LLScriptLessThan::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " < ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "LESS %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LESS]);
+ chunk->addByte(typebyte);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "clt\n");
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptLessThan::getSize()
+{
+ return 0;
+}
+
+void LLScriptGreaterThan::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " > ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "GREATER %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
+ chunk->addByte(LSCRIPTOpCodes[LOPC_GREATER]);
+ chunk->addByte(typebyte);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "cgt\n");
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptGreaterThan::getSize()
+{
+ return 0;
+}
+
+void LLScriptPlus::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " + ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "ADD %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
+ chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
+ chunk->addByte(typebyte);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
+ print_cil_add(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptPlus::getSize()
+{
+ return 0;
+}
+
+void LLScriptMinus::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " - ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "SUB %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
+ chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
+ chunk->addByte(typebyte);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
+ print_cil_sub(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptMinus::getSize()
+{
+ return 0;
+}
+
+void LLScriptTimes::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " * ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "MUL %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
+ chunk->addByte(LSCRIPTOpCodes[LOPC_MUL]);
+ chunk->addByte(typebyte);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
+ print_cil_mul(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptTimes::getSize()
+{
+ return 0;
+}
+
+void LLScriptDivide::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " / ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "DIV %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
+ chunk->addByte(LSCRIPTOpCodes[LOPC_DIV]);
+ chunk->addByte(typebyte);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
+ print_cil_div(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptDivide::getSize()
+{
+ return 0;
+}
+
+void LLScriptMod::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " %% ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "MOD %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
+ chunk->addByte(LSCRIPTOpCodes[LOPC_MOD]);
+ chunk->addByte(typebyte);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_mod(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptMod::getSize()
+{
+ return 0;
+}
+
+void LLScriptBitAnd::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " & ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "BITAND\n");
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_BITAND]);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "and\n");
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptBitAnd::getSize()
+{
+ return 0;
+}
+
+void LLScriptBitOr::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " | ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "BITOR\n");
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_BITOR]);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "or\n");
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptBitOr::getSize()
+{
+ return 0;
+}
+
+void LLScriptBitXor::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " ^ ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "BITXOR\n");
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_BITXOR]);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "xor\n");
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptBitXor::getSize()
+{
+ return 0;
+}
+
+void LLScriptBooleanAnd::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " && ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "BOOLAND\n");
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_BOOLAND]);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "and\n");
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptBooleanAnd::getSize()
+{
+ return 0;
+}
+
+void LLScriptBooleanOr::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " || ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "BOOLOR\n");
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_BOOLOR]);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "or\n");
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptBooleanOr::getSize()
+{
+ return 0;
+}
+
+void LLScriptShiftLeft::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " << ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "SHL\n");
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_SHL]);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "shl\n");
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptShiftLeft::getSize()
+{
+ return 0;
+}
+
+
+void LLScriptShiftRight::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " >> ");
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "SHR\n");
+ break;
+ case LSCP_TYPE:
+ {
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mReturnType;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_SHR]);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "shr\n");
+ break;
+ default:
+ mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptShiftRight::getSize()
+{
+ return 0;
+}
+
+void LLScriptParenthesis::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fprintf(fp, "( ");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
+ case LSCP_TYPE:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mReturnType = mLeftType = type;
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mReturnType = mLeftType = type;
+ break;
+ default:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptParenthesis::getSize()
+{
+ return 0;
+}
+
+void LLScriptUnaryMinus::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fprintf(fp, "-");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "NEG %s\n", LSCRIPTTypeNames[mLeftType]);
+ break;
+ case LSCP_TYPE:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_unary_expression(type, type, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ else
+ {
+ mReturnType = mLeftType = type;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ U8 typebyte = LSCRIPTTypeByte[mLeftType];
+ chunk->addByte(LSCRIPTOpCodes[LOPC_NEG]);
+ chunk->addByte(typebyte);
+ }
+ break;
+ default:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptUnaryMinus::getSize()
+{
+ return 0;
+}
+
+void LLScriptBooleanNot::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fprintf(fp, "!");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "BOOLNOT\n");
+ break;
+ case LSCP_TYPE:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_unary_expression(type, type, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ else
+ {
+ mReturnType = mLeftType = type;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_BOOLNOT]);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "ldc.i4.0\n");
+ fprintf(fp, "ceq\n"); // If f(e) is (e == 0), f(e) returns 1 if e is 0 and 0 otherwise, therefore f(e) implements boolean not.
+ break;
+ default:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptBooleanNot::getSize()
+{
+ return 0;
+}
+
+void LLScriptBitNot::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fprintf(fp, "~");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "BITNOT\n");
+ break;
+ case LSCP_TYPE:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_unary_expression(type, type, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ else
+ {
+ mReturnType = mLeftType = type;
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_BITNOT]);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "not\n");
+ break;
+ default:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptBitNot::getSize()
+{
+ return 0;
+}
+
+void LLScriptPreIncrement::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fprintf(fp, "++");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ if (mReturnType == LST_INTEGER)
+ {
+ fprintf(fp, "PUSHARGI 1\n");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ fprintf(fp, "ADD integer, integer\n");
+ }
+ else if (mReturnType == LST_FLOATINGPOINT)
+ {
+ fprintf(fp, "PUSHARGF 1\n");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ fprintf(fp, "ADD float, float\n");
+ }
+ else
+ {
+ fprintf(fp, "Unexpected Type\n");
+ }
+ print_asignment(fp, mExpression);
+ }
+ break;
+ case LSCP_TYPE:
+ if (mExpression->mType != LET_LVALUE)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
+ }
+ else
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_unary_expression(type, type, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ else
+ {
+ mReturnType = mLeftType = type;
+ }
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ if (mReturnType == LST_INTEGER)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
+ chunk->addInteger(1);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
+ chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
+ }
+ else if (mReturnType == LST_FLOATINGPOINT)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
+ chunk->addFloat(1.f);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
+ chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
+ }
+ store2stack(this, mExpression, chunk, mReturnType);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ print_cil_load_address(fp, mExpression, entry);
+ if (mReturnType == LST_INTEGER)
+ {
+ fprintf(fp, "ldc.i4.1\n");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "add\n");
+ }
+ else if (mReturnType == LST_FLOATINGPOINT)
+ {
+ fprintf(fp, "ldc.r8.1\n");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "add\n");
+ }
+ else
+ {
+ fprintf(fp, "Unexpected Type\n");
+ }
+ print_cil_asignment(fp, mExpression, entry);
+ }
+ break;
+ default:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptPreIncrement::getSize()
+{
+ return 0;
+}
+
+void LLScriptPreDecrement::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fprintf(fp, "--");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ if (mReturnType == LST_INTEGER)
+ {
+ fprintf(fp, "PUSHARGI 1\n");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ fprintf(fp, "SUB integer, integer\n");
+ }
+ else if (mReturnType == LST_FLOATINGPOINT)
+ {
+ fprintf(fp, "PUSHARGF 1\n");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ fprintf(fp, "SUB float, float\n");
+ }
+ else
+ {
+ fprintf(fp, "Unexpected Type\n");
+ }
+ print_asignment(fp, mExpression);
+ }
+ break;
+ case LSCP_TYPE:
+ if (mExpression->mType != LET_LVALUE)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
+ }
+ else
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_unary_expression(type, type, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ else
+ {
+ mReturnType = mLeftType = type;
+ }
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ if (mReturnType == LST_INTEGER)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
+ chunk->addInteger(1);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
+ chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
+ }
+ else if (mReturnType == LST_FLOATINGPOINT)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
+ chunk->addFloat(1.f);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
+ chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
+ }
+ store2stack(this, mExpression, chunk, mReturnType);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ print_cil_load_address(fp, mExpression, entry);
+ if (mReturnType == LST_INTEGER)
+ {
+ fprintf(fp, "ldc.i4.1\n");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "sub\n");
+ }
+ else if (mReturnType == LST_FLOATINGPOINT)
+ {
+ fprintf(fp, "ldc.r8.1\n");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "sub\n");
+ }
+ else
+ {
+ fprintf(fp, "Unexpected Type\n");
+ }
+ print_cil_asignment(fp, mExpression, entry);
+ }
+ break;
+ default:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptPreDecrement::getSize()
+{
+ return 0;
+}
+
+void LLScriptTypeCast::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fprintf(fp, "( ");
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ") ");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mType->mType]);
+ break;
+ case LSCP_TYPE:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mRightType = type;
+ if (!legal_casts(mType->mType, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ type = mType->mType;
+ mReturnType = mLeftType = type;
+ break;
+ case LSCP_TO_STACK:
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
+ U8 castbyte = LSCRIPTTypeByte[mType->mType] | LSCRIPTTypeHi4Bits[mRightType];
+ chunk->addByte(castbyte);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ print_cil_cast(fp, mRightType, mType->mType);
+ break;
+ default:
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptTypeCast::getSize()
+{
+ return 0;
+}
+
+void LLScriptVectorInitializer::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fprintf(fp, "< ");
+ mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", ");
+ mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", ");
+ mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " >");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression1->mReturnType != LST_FLOATINGPOINT)
+ {
+ fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression1->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
+ }
+ mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression2->mReturnType != LST_FLOATINGPOINT)
+ {
+ fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression2->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
+ }
+ mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression3->mReturnType != LST_FLOATINGPOINT)
+ {
+ fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression3->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
+ }
+ break;
+ case LSCP_TYPE:
+ // vector's take floats
+ mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(LST_FLOATINGPOINT, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(LST_FLOATINGPOINT, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(LST_FLOATINGPOINT, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ mReturnType = type = LST_VECTOR;
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_TO_STACK:
+ pass = LSCP_TO_STACK;
+ mExpression1->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression1->mReturnType != LST_FLOATINGPOINT)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
+ U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression1->mReturnType];
+ chunk->addByte(castbyte);
+ }
+ mExpression2->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression2->mReturnType != LST_FLOATINGPOINT)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
+ U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression2->mReturnType];
+ chunk->addByte(castbyte);
+ }
+ mExpression3->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression3->mReturnType != LST_FLOATINGPOINT)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
+ U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression3->mReturnType];
+ chunk->addByte(castbyte);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+
+ // Load arguments.
+ mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression1->mReturnType != LST_FLOATINGPOINT)
+ {
+ print_cil_cast(fp, mExpression1->mReturnType, LST_FLOATINGPOINT);
+ }
+ mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression2->mReturnType != LST_FLOATINGPOINT)
+ {
+ print_cil_cast(fp, mExpression2->mReturnType, LST_FLOATINGPOINT);
+ }
+ mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression3->mReturnType != LST_FLOATINGPOINT)
+ {
+ print_cil_cast(fp, mExpression3->mReturnType, LST_FLOATINGPOINT);
+ }
+ // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
+ fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'create'(float32, float32, float32)\n");
+ break;
+ default:
+ mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptVectorInitializer::getSize()
+{
+ return 0;
+}
+
+void LLScriptQuaternionInitializer::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fprintf(fp, "< ");
+ mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", ");
+ mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", ");
+ mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", ");
+ mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " >");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression1->mReturnType != LST_FLOATINGPOINT)
+ {
+ fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression1->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
+ }
+ mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression2->mReturnType != LST_FLOATINGPOINT)
+ {
+ fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression2->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
+ }
+ mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression3->mReturnType != LST_FLOATINGPOINT)
+ {
+ fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression3->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
+ }
+ mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression4->mReturnType != LST_FLOATINGPOINT)
+ {
+ fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression4->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
+ }
+ break;
+ case LSCP_TYPE:
+ // vector's take floats
+ mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(LST_FLOATINGPOINT, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(LST_FLOATINGPOINT, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(LST_FLOATINGPOINT, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(LST_FLOATINGPOINT, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ mReturnType = type = LST_QUATERNION;
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_TO_STACK:
+ pass = LSCP_TO_STACK;
+ mExpression1->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression1->mReturnType != LST_FLOATINGPOINT)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
+ U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression1->mReturnType];
+ chunk->addByte(castbyte);
+ }
+ mExpression2->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression2->mReturnType != LST_FLOATINGPOINT)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
+ U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression2->mReturnType];
+ chunk->addByte(castbyte);
+ }
+ mExpression3->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression3->mReturnType != LST_FLOATINGPOINT)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
+ U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression3->mReturnType];
+ chunk->addByte(castbyte);
+ }
+ mExpression4->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression4->mReturnType != LST_FLOATINGPOINT)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
+ U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression4->mReturnType];
+ chunk->addByte(castbyte);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+
+ // Load arguments.
+ mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression1->mReturnType != LST_FLOATINGPOINT)
+ {
+ print_cil_cast(fp, mExpression1->mReturnType, LST_FLOATINGPOINT);
+ }
+ mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression2->mReturnType != LST_FLOATINGPOINT)
+ {
+ print_cil_cast(fp, mExpression2->mReturnType, LST_FLOATINGPOINT);
+ }
+ mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression3->mReturnType != LST_FLOATINGPOINT)
+ {
+ print_cil_cast(fp, mExpression3->mReturnType, LST_FLOATINGPOINT);
+ }
+ mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression4->mReturnType != LST_FLOATINGPOINT)
+ {
+ print_cil_cast(fp, mExpression4->mReturnType, LST_FLOATINGPOINT);
+ }
+
+ // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
+ fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'create'(float32, float32, float32, float32)\n");
+ break;
+ default:
+ mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptQuaternionInitializer::getSize()
+{
+ return 0;
+}
+
+void LLScriptListInitializer::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fprintf(fp, "[ ");
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " ]");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ count = 0;
+ if (mExpressionList)
+ {
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "STACKTOL %llu\n", count);
+ }
+ break;
+ case LSCP_TYPE:
+ if (mExpressionList)
+ {
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mReturnType = type = LST_LIST;
+ }
+ mReturnType = type = LST_LIST;
+ break;
+ case LSCP_TO_STACK:
+ if (mExpressionList)
+ {
+ pass = LSCP_TO_STACK;
+ count = 0;
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STACKTOL]);
+ chunk->addInteger((S32)count);
+ count = 0;
+ }
+ else
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STACKTOL]);
+ chunk->addInteger(0);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+
+ // Push boxed elements on stack.
+ count = 0;
+ if (mExpressionList)
+ {
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+
+ // Create list on stack, consuming first boxed element.
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::CreateList()\n");
+
+ // Call AddReturnList to add remaining boxed expressions.
+ for(U64 i = 0; i < count; i++)
+ {
+ fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::AddReturnList(object, class [mscorlib]System.Collections.ArrayList)\n");
+ }
+ count = 0;
+
+ break;
+ default:
+ if (mExpressionList)
+ {
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptListInitializer::getSize()
+{
+ return 0;
+}
+
+void LLScriptPostIncrement::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "++");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mReturnType == LST_INTEGER)
+ {
+ fprintf(fp, "PUSHARGI 1\n");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "ADD integer, integer\n");
+ }
+ else if (mReturnType == LST_FLOATINGPOINT)
+ {
+ fprintf(fp, "PUSHARGF 1\n");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "ADD float, float\n");
+ }
+ else
+ {
+ fprintf(fp, "Unexpected Type\n");
+ }
+ print_asignment(fp, mExpression);
+ fprintf(fp, "%s\n", LSCRIPTTypePop[mReturnType]);
+ }
+ break;
+ case LSCP_TYPE:
+ if (mExpression->mType != LET_LVALUE)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
+ }
+ else
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_unary_expression(type, type, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ else
+ {
+ mReturnType = mLeftType = type;
+ }
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mReturnType == LST_INTEGER)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
+ chunk->addInteger(1);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
+ chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
+ }
+ else if (mReturnType == LST_FLOATINGPOINT)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
+ chunk->addFloat(1.f);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
+ chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
+ }
+ store2stack(this, mExpression, chunk, mReturnType);
+ switch(mReturnType)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
+ break;
+ case LST_KEY:
+ case LST_STRING:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
+ break;
+ case LST_LIST:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
+ break;
+ case LST_VECTOR:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
+ break;
+ case LST_QUATERNION:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
+ break;
+ default:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
+ break;
+ }
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ print_cil_load_address(fp, mExpression, entry);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp,"dup\n"); // Copy expression result to use as increment operand.
+ if (mReturnType == LST_INTEGER)
+ {
+ fprintf(fp, "ldc.i4.1\n");
+ }
+ else if (mReturnType == LST_FLOATINGPOINT)
+ {
+ fprintf(fp, "ldc.r8.1\n");
+ }
+ else
+ {
+ fprintf(fp, "Unexpected Type\n");
+ }
+ fprintf(fp, "add\n");
+ print_cil_asignment(fp, mExpression, entry);
+ fprintf(fp, "pop\n"); // Pop assignment result to leave original expression result on stack. TODO: Optimise away redundant pop/dup pairs.
+ }
+ break;
+ default:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptPostIncrement::getSize()
+{
+ return 0;
+}
+
+void LLScriptPostDecrement::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "--");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mReturnType == LST_INTEGER)
+ {
+ fprintf(fp, "PUSHARGI 1\n");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "SUB integer, integer\n");
+ }
+ else if (mReturnType == LST_FLOATINGPOINT)
+ {
+ fprintf(fp, "PUSHARGF 1\n");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "SUB float, float\n");
+ }
+ else
+ {
+ fprintf(fp, "Unexpected Type\n");
+ }
+ print_asignment(fp, mExpression);
+ fprintf(fp, "%s\n", LSCRIPTTypePop[mReturnType]);
+ }
+ break;
+ case LSCP_TYPE:
+ if (mExpression->mType != LET_LVALUE)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
+ }
+ else
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_unary_expression(type, type, mType))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ else
+ {
+ mReturnType = mLeftType = type;
+ }
+ }
+ break;
+ case LSCP_TO_STACK:
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mReturnType == LST_INTEGER)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
+ chunk->addInteger(1);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
+ chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
+ }
+ else if (mReturnType == LST_FLOATINGPOINT)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
+ chunk->addFloat(1.f);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
+ chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
+ }
+ store2stack(this, mExpression, chunk, mReturnType);
+ switch(mReturnType)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
+ break;
+ case LST_KEY:
+ case LST_STRING:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
+ break;
+ case LST_LIST:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
+ break;
+ case LST_VECTOR:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
+ break;
+ case LST_QUATERNION:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
+ break;
+ default:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
+ break;
+ }
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ print_cil_load_address(fp, mExpression, entry);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp,"dup\n"); // Copy expression result to use as decrement operand.
+ if (mReturnType == LST_INTEGER)
+ {
+ fprintf(fp, "ldc.i4.1\n");
+ }
+ else if (mReturnType == LST_FLOATINGPOINT)
+ {
+ fprintf(fp, "ldc.r8.1\n");
+ }
+ else
+ {
+ fprintf(fp, "Unexpected Type\n");
+ }
+ fprintf(fp, "sub\n");
+ print_cil_asignment(fp, mExpression, entry);
+ fprintf(fp, "pop\n"); // Pop assignment result to leave original expression result on stack. TODO: Optimise away redundant pop/dup pairs.
+ }
+ break;
+ default:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptPostDecrement::getSize()
+{
+ return 0;
+}
+
+// Generate arg list.
+void print_cil_arg_list(FILE *fp, LLScriptFuncExpressionList* exp_list)
+{
+ // Print first argument.
+ print_cil_type(fp, exp_list->mFirstp->mReturnType);
+
+ // Recursively print next arguments.
+ if(exp_list->mSecondp != NULL)
+ {
+ fprintf(fp, ", ");
+ print_cil_arg_list(fp, (LLScriptFuncExpressionList*) exp_list->mSecondp);
+ }
+}
+
+void LLScriptFunctionCall::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "( ");
+ if (mExpressionList)
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ if (mIdentifier->mScopeEntry->mType)
+ fprintf(fp, "%s\n", LSCRIPTTypePush[mIdentifier->mScopeEntry->mType]);
+ fprintf(fp,"PUSHE\n");
+ fprintf(fp, "PUSHBP\n");
+ if (mExpressionList)
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
+ fprintf(fp, "PUSHARGE %d\n", mIdentifier->mScopeEntry->mSize - mIdentifier->mScopeEntry->mOffset);
+ fprintf(fp, "PUSHSP\n");
+ fprintf(fp, "PUSHARGI %d\n", mIdentifier->mScopeEntry->mSize);
+ fprintf(fp, "ADD integer, integer\n");
+ fprintf(fp, "POPBP\n");
+ if (mIdentifier->mScopeEntry->mIDType != LIT_LIBRARY_FUNCTION)
+ {
+ fprintf(fp, "CALL ");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ else
+ {
+ fprintf(fp, "CALLLID ");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ", %d", (U32)mIdentifier->mScopeEntry->mLibraryNumber);
+ }
+ fprintf(fp, "\n");
+ fprintf(fp, "POPBP\n");
+ break;
+ case LSCP_SCOPE_PASS1:
+ if (mExpressionList)
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_SCOPE_PASS2:
+ {
+ LLScriptScopeEntry *entry = scope->findEntryTyped(mIdentifier->mName, LIT_FUNCTION);
+ if (!entry)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
+ }
+ else
+ {
+ // if we did find it, make sure this identifier is associated with the correct scope entry
+ mIdentifier->mScopeEntry = entry;
+ }
+ if (mExpressionList)
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_TYPE:
+ if (mIdentifier->mScopeEntry)
+ {
+ U64 argcount = 0;
+ if (mExpressionList)
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, argcount, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
+
+ if (!mIdentifier->mScopeEntry->mFunctionArgs.mString)
+ {
+ if (argcount)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
+ }
+ }
+ else if (argcount != strlen(mIdentifier->mScopeEntry->mFunctionArgs.mString))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
+ }
+ }
+
+ if (mIdentifier->mScopeEntry)
+ type = mIdentifier->mScopeEntry->mType;
+ else
+ type = LST_NULL;
+ mReturnType = type;
+ break;
+ case LSCP_TO_STACK:
+ switch(mIdentifier->mScopeEntry->mType)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+ case LST_STRING:
+ case LST_KEY:
+ case LST_LIST:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHE]);
+ break;
+ case LST_VECTOR:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHEV]);
+ break;
+ case LST_QUATERNION:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHEQ]);
+ break;
+ default:
+ break;
+ }
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHE]);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHBP]);
+ if (mExpressionList)
+ {
+ // Don't let this change the count.
+ U64 dummy_count = 0;
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, dummy_count, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
+ //mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
+ }
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGE]);
+ chunk->addInteger(mIdentifier->mScopeEntry->mSize - mIdentifier->mScopeEntry->mOffset);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHSP]);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
+ chunk->addInteger(mIdentifier->mScopeEntry->mSize);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
+ chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPBP]);
+ if (mIdentifier->mScopeEntry->mIDType != LIT_LIBRARY_FUNCTION)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_CALL]);
+ chunk->addInteger(mIdentifier->mScopeEntry->mCount);
+ }
+ else
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_CALLLIB_TWO_BYTE]);
+ chunk->addU16(mIdentifier->mScopeEntry->mLibraryNumber);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ bool library_call = (mIdentifier->mScopeEntry->mIDType == LIT_LIBRARY_FUNCTION);
+ if(! library_call)
+ {
+ // Load this pointer.
+ fprintf(fp, "ldarg.0\n");
+ }
+
+ // Load args on to stack.
+ if (mExpressionList)
+ {
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry /* Needed for is_parameter calls */, 0, NULL);
+ }
+
+ // Make call.
+ if (! library_call)
+ {
+ fprintf(fp, "callvirt instance ");
+ }
+ else
+ {
+ fprintf(fp, "call ");
+ }
+ print_cil_type(fp, mIdentifier->mScopeEntry->mType);
+ fprintf(fp, " class ");
+ if (library_call)
+ {
+ fprintf(fp, "[LScriptLibrary]LScriptLibrary");
+ }
+ else
+ {
+ fprintf(fp, "LSL");
+ }
+ fprintf(fp, "::");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "(");
+ if (mExpressionList) {print_cil_arg_list(fp, (LLScriptFuncExpressionList*) mExpressionList);}
+ fprintf(fp, ")\n");
+ }
+ break;
+ default:
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpressionList)
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptFunctionCall::getSize()
+{
+ return 0;
+}
+
+void LLScriptPrint::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fprintf(fp, " PRINT ( ");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "PRINT %s\n", LSCRIPTTypeNames[mLeftType]);
+ break;
+ case LSCP_TYPE:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mLeftType = type;
+ mReturnType = LST_NULL;
+ break;
+ case LSCP_TO_STACK:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PRINT]);
+ chunk->addByte(LSCRIPTTypeByte[mLeftType]);
+ break;
+ default:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptPrint::getSize()
+{
+ return 0;
+}
+
+void LLScriptConstantExpression::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_TYPE:
+ mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mReturnType = type;
+ break;
+ case LSCP_TO_STACK:
+ mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ default:
+ mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptConstantExpression::getSize()
+{
+ return 0;
+}
+
+void LLScriptStatement::addStatement(LLScriptStatement *event)
+{
+ if (mNextp)
+ {
+ event->mNextp = mNextp;
+ }
+ mNextp = event;
+}
+
+void LLScriptStatement::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ fprintf(fp, "Statement Base Class -- should never get here!\n");
+}
+
+S32 LLScriptStatement::getSize()
+{
+ printf("Statement Base Class -- should never get here!\n");
+ return 0;
+}
+
+void LLScriptStatement::gonext(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ if (mNextp)
+ {
+ fprintf(fp, ", ");
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ default:
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+}
+
+S32 LLScriptStatementSequence::getSize()
+{
+ return 0;
+}
+
+void LLScriptStatementSequence::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_PRUNE:
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (prunearg)
+ {
+ ptype = LSPRUNE_DEAD_CODE;
+ gErrorToText.writeWarning(fp, this, LSWARN_DEAD_CODE);
+ }
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_TYPE:
+ // pass the return type into all statements so we can check returns
+ {
+ LSCRIPTType return_type = type;
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, return_type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ return_type = type;
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, return_type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ default:
+ mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptNOOP::getSize()
+{
+ return 0;
+}
+
+void LLScriptNOOP::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, ";\n");
+ break;
+ case LSCP_PRUNE:
+ if (ptype == LSPRUNE_DEAD_CODE)
+ prunearg = TRUE;
+ else
+ prunearg = FALSE;
+ break;
+ default:
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+void add_exit_pops(LLScriptByteCodeChunk *chunk, LLScriptScopeEntry *entry)
+{
+ // remember that we need to pop in reverse order
+ S32 number, i;
+
+ if (entry->mLocals.mString)
+ {
+ number = (S32)strlen(entry->mLocals.mString);
+ for (i = number - 1; i >= 0; i--)
+ {
+ switch(entry->mLocals.getType(i))
+ {
+ case LST_INTEGER:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
+ break;
+ case LST_FLOATINGPOINT:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
+ break;
+ case LST_STRING:
+ case LST_KEY:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
+ break;
+ case LST_VECTOR:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
+ break;
+ case LST_QUATERNION:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
+ break;
+ case LST_LIST:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if (entry->mFunctionArgs.mString)
+ {
+ number = (S32)strlen(entry->mFunctionArgs.mString);
+ for (i = number - 1; i >= 0; i--)
+ {
+ switch(entry->mFunctionArgs.getType(i))
+ {
+ case LST_INTEGER:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
+ break;
+ case LST_FLOATINGPOINT:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
+ break;
+ case LST_STRING:
+ case LST_KEY:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
+ break;
+ case LST_VECTOR:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
+ break;
+ case LST_QUATERNION:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
+ break;
+ case LST_LIST:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+}
+
+void print_exit_pops(FILE *fp, LLScriptScopeEntry *entry)
+{
+ // remember that we need to pop in reverse order
+ S32 number, i;
+
+ if (entry->mLocals.mString)
+ {
+ number = (S32)strlen(entry->mLocals.mString);
+ for (i = number - 1; i >= 0; i--)
+ {
+ fprintf(fp, "%s", LSCRIPTTypePop[entry->mLocals.getType(i)]);
+ }
+ }
+
+ if (entry->mFunctionArgs.mString)
+ {
+ number = (S32)strlen(entry->mFunctionArgs.mString);
+ for (i = number - 1; i >= 0; i--)
+ {
+ fprintf(fp, "%s", LSCRIPTTypePop[entry->mFunctionArgs.getType(i)]);
+ }
+ }
+}
+
+
+S32 LLScriptStateChange::getSize()
+{
+ return 0;
+}
+
+void LLScriptStateChange::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "state ");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ";\n");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ print_exit_pops(fp, entry);
+ fprintf(fp, "STATE ");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ break;
+ case LSCP_PRUNE:
+ if ( (ptype == LSPRUNE_GLOBAL_VOIDS)
+ ||(ptype == LSPRUNE_GLOBAL_NON_VOIDS))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_STATE_CHANGE_IN_GLOBAL);
+ }
+ if (ptype == LSPRUNE_DEAD_CODE)
+ prunearg = TRUE;
+ else
+ prunearg = FALSE;
+ break;
+ case LSCP_SCOPE_PASS2:
+ {
+ LLScriptScopeEntry *entry = scope->findEntryTyped(mIdentifier->mName, LIT_STATE);
+ if (!entry)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
+ }
+ else
+ {
+ // if we did find it, make sure this identifier is associated with the correct scope entry
+ mIdentifier->mScopeEntry = entry;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ add_exit_pops(chunk, entry);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STATE]);
+ chunk->addInteger(mIdentifier->mScopeEntry->mCount);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fprintf(fp, "ldstr \"");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\"\n");
+ fprintf(fp, "call void class [LScriptLibrary]LScriptInternal::change_state(string)\n");
+ break;
+ default:
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptJump::getSize()
+{
+ return 0;
+}
+
+void LLScriptJump::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "jump ");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ";\n");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp, "JUMP ");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ break;
+ case LSCP_PRUNE:
+ if (ptype == LSPRUNE_DEAD_CODE)
+ prunearg = TRUE;
+ else
+ prunearg = FALSE;
+ break;
+ case LSCP_SCOPE_PASS2:
+ {
+ LLScriptScopeEntry *entry = scope->findEntryTyped(mIdentifier->mName, LIT_LABEL);
+ if (!entry)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
+ }
+ else
+ {
+ // if we did find it, make sure this identifier is associated with the correct scope entry
+ mIdentifier->mScopeEntry = entry;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_JUMP]);
+ chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
+ chunk->addJump(mIdentifier->mName);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ fprintf(fp, "br ");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ break;
+ default:
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptLabel::getSize()
+{
+ return 0;
+}
+
+void LLScriptLabel::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "@");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ";\n");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ fprintf(fp, "LABEL ");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ break;
+ case LSCP_PRUNE:
+ // Always clear this flag, to stop pruning after return statements. A jump
+ // might start up code at this label, so we need to stop pruning.
+ prunearg = FALSE;
+ break;
+ case LSCP_SCOPE_PASS1:
+ // add labels to scope
+ if (scope->checkEntry(mIdentifier->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_LABEL, LST_NULL);
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ chunk->addLabel(mIdentifier->mName);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ":\n");
+ break;
+ default:
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+void add_return(LLScriptByteCodeChunk *chunk, LLScriptScopeEntry *entry)
+{
+ add_exit_pops(chunk, entry);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_RETURN]);
+}
+
+void print_return(FILE *fp, LLScriptScopeEntry *entry)
+{
+ print_exit_pops(fp, entry);
+ fprintf(fp, "RETURN\n");
+}
+
+
+S32 LLScriptReturn::getSize()
+{
+ return 0;
+}
+
+void LLScriptReturn::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ if (mExpression)
+ {
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "return ");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ";\n");
+ }
+ else
+ {
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "return;\n");
+ }
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ if (mExpression)
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "%s\n", LSCRIPTTypeReturn[mType]);
+ }
+ print_return(fp, entry);
+ break;
+ case LSCP_PRUNE:
+ if ( (ptype == LSPRUNE_GLOBAL_VOIDS)
+ ||(ptype == LSPRUNE_EVENTS))
+ {
+ if (mExpression)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_INVALID_RETURN);
+ }
+ }
+ else if (ptype == LSPRUNE_GLOBAL_NON_VOIDS)
+ {
+ if (!mExpression)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_INVALID_VOID_RETURN);
+ }
+ }
+ prunearg = TRUE;
+ case LSCP_TYPE:
+ // if there is a return expression, it must be promotable to the return type of the function
+ if (mExpression)
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(basetype, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ else
+ {
+ mType = basetype;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ if (mExpression)
+ {
+ mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ switch(mType)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
+ chunk->addInteger(-12);
+ break;
+ case LST_STRING:
+ case LST_KEY:
+ // use normal store for reference counted types
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADSP]);
+ chunk->addInteger(-12);
+ break;
+ case LST_LIST:
+ // use normal store for reference counted types
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADLP]);
+ chunk->addInteger(-12);
+ break;
+ case LST_VECTOR:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADVP]);
+ chunk->addInteger(-20);
+ break;
+ case LST_QUATERNION:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADQP]);
+ chunk->addInteger(-24);
+ break;
+ default:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
+ chunk->addInteger(-12);
+ break;
+ }
+ }
+ add_return(chunk, entry);
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ if (mExpression)
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ fprintf(fp, "ret\n");
+ break;
+ default:
+ if (mExpression)
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptExpressionStatement::getSize()
+{
+ return 0;
+}
+
+void LLScriptExpressionStatement::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ";\n");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression->mReturnType)
+ {
+ fprintf(fp, "%s\n", LSCRIPTTypePop[mExpression->mReturnType]);
+ }
+ break;
+ case LSCP_PRUNE:
+ if (ptype == LSPRUNE_DEAD_CODE)
+ prunearg = TRUE;
+ else
+ prunearg = FALSE;
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ switch(mExpression->mReturnType)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
+ break;
+ case LST_STRING:
+ case LST_KEY:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
+ break;
+ case LST_LIST:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
+ break;
+ case LST_VECTOR:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
+ break;
+ case LST_QUATERNION:
+ chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
+ break;
+ default:
+ break;
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if(mExpression->mReturnType)
+ {
+ fprintf(fp, "pop\n");
+ }
+ break;
+ default:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptIf::getSize()
+{
+ return 0;
+}
+
+void LLScriptIf::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "if ( ");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ S32 tjump = gTempJumpCount++;
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "JUMPNIF ##Temp Jump %d##\n", tjump);
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump);
+ }
+ break;
+ case LSCP_PRUNE:
+ if (ptype == LSPRUNE_DEAD_CODE)
+ prunearg = TRUE;
+ else
+ prunearg = FALSE;
+ break;
+ case LSCP_TYPE:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mType = type;
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ char jumpname[32];
+ sprintf(jumpname, "##Temp Jump %d##", gTempJumpCount++);
+
+ mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPNIF]);
+ chunk->addByte(LSCRIPTTypeByte[mType]);
+ chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
+ chunk->addJump(jumpname);
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addLabel(jumpname);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ S32 tjump = gTempJumpCount++;
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "brfalse LabelTempJump%d\n", tjump);
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "LabelTempJump%d:\n", tjump);
+ }
+ break;
+ default:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptIfElse::getSize()
+{
+ return 0;
+}
+
+void LLScriptIfElse::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "if ( ");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "else\n");
+ mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ S32 tjump1 = gTempJumpCount++;
+ S32 tjump2 = gTempJumpCount++;
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "JUMPNIF ##Temp Jump %d##\n", tjump1);
+ mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "JUMP ##Temp Jump %d##\n", tjump2);
+ fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump1);
+ mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump2);
+ }
+ break;
+ case LSCP_PRUNE:
+ {
+ BOOL arg1 = TRUE, arg2 = TRUE;
+ mStatement1->recurse(fp, tabs, tabsize, pass, ptype, arg1, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mStatement2->recurse(fp, tabs, tabsize, pass, ptype, arg2, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ prunearg = arg1 && arg2;
+ }
+ break;
+ case LSCP_TYPE:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mType = type;
+ mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ char jumpname1[32];
+ sprintf(jumpname1, "##Temp Jump %d##", gTempJumpCount++);
+ char jumpname2[32];
+ sprintf(jumpname2, "##Temp Jump %d##", gTempJumpCount++);
+
+ mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPNIF]);
+ chunk->addByte(LSCRIPTTypeByte[mType]);
+ chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
+ chunk->addJump(jumpname1);
+ mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_JUMP]);
+ chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
+ chunk->addJump(jumpname2);
+ chunk->addLabel(jumpname1);
+ mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addLabel(jumpname2);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ S32 tjump1 = gTempJumpCount++;
+ S32 tjump2 = gTempJumpCount++;
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "brfalse LabelTempJump%d\n", tjump1);
+ mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "br LabelTempJump%d\n", tjump2);
+ fprintf(fp, "LabelTempJump%d:\n", tjump1);
+ mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "LabelTempJump%d:\n", tjump2);
+ }
+ break;
+ default:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ };
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptFor::getSize()
+{
+ return 0;
+}
+
+void LLScriptFor::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "for ( ");
+ if(mSequence)
+ mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " ; ");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " ; ");
+ if(mExpressionList)
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ if(mStatement)
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ S32 tjump1 = gTempJumpCount++;
+ S32 tjump2 = gTempJumpCount++;
+ if(mSequence)
+ mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump1);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "JUMPNIF ##Temp Jump %d##\n", tjump2);
+ if(mStatement)
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if(mExpressionList)
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "JUMP ##Temp Jump %d##\n", tjump1);
+ fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump2);
+ }
+ break;
+ case LSCP_PRUNE:
+ if (ptype == LSPRUNE_DEAD_CODE)
+ prunearg = TRUE;
+ else
+ prunearg = FALSE;
+ break;
+ case LSCP_TYPE:
+ if(mSequence)
+ mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mType = type;
+ if(mExpressionList)
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if(mStatement)
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ char jumpname1[32];
+ sprintf(jumpname1, "##Temp Jump %d##", gTempJumpCount++);
+ char jumpname2[32];
+ sprintf(jumpname2, "##Temp Jump %d##", gTempJumpCount++);
+
+ if(mSequence)
+ mSequence->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addLabel(jumpname1);
+ mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPNIF]);
+ chunk->addByte(LSCRIPTTypeByte[mType]);
+ chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
+ chunk->addJump(jumpname2);
+ if(mStatement)
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if(mExpressionList)
+ mExpressionList->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_JUMP]);
+ chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
+ chunk->addJump(jumpname1);
+ chunk->addLabel(jumpname2);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ S32 tjump1 = gTempJumpCount++;
+ S32 tjump2 = gTempJumpCount++;
+ if(mSequence)
+ mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "LabelTempJump%d:\n", tjump1);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "brfalse LabelTempJump%d\n", tjump2);
+ if(mStatement)
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if(mExpressionList)
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "br LabelTempJump%d\n", tjump1);
+ fprintf(fp, "LabelTempJump%d:\n", tjump2);
+ }
+ break;
+ default:
+ if(mSequence)
+ mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if(mExpressionList)
+ mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if(mStatement)
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptDoWhile::getSize()
+{
+ return 0;
+}
+
+void LLScriptDoWhile::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "do\n");
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "while( ");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " );\n");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ S32 tjump1 = gTempJumpCount++;
+ fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump1);
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "JUMPIF ##Temp Jump %d##\n", tjump1);
+ }
+ break;
+ case LSCP_PRUNE:
+ if (ptype == LSPRUNE_DEAD_CODE)
+ prunearg = TRUE;
+ else
+ prunearg = FALSE;
+ break;
+ case LSCP_TYPE:
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mType = type;
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ char jumpname1[32];
+ sprintf(jumpname1, "##Temp Jump %d##", gTempJumpCount++);
+
+ chunk->addLabel(jumpname1);
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPIF]);
+ chunk->addByte(LSCRIPTTypeByte[mType]);
+ chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
+ chunk->addJump(jumpname1);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ S32 tjump1 = gTempJumpCount++;
+ fprintf(fp, "LabelTempJump%d:\n", tjump1);
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "brtrue LabelTempJump%d\n", tjump1);
+ }
+ break;
+ default:
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptWhile::getSize()
+{
+ return 0;
+}
+
+void LLScriptWhile::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "while( ");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ {
+ S32 tjump1 = gTempJumpCount++;
+ S32 tjump2 = gTempJumpCount++;
+ fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump1);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "JUMPNIF ##Temp Jump %d##\n", tjump2);
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "JUMP ##Temp Jump %d##\n", tjump1);
+ fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump2);
+ }
+ break;
+ case LSCP_PRUNE:
+ if (ptype == LSPRUNE_DEAD_CODE)
+ prunearg = TRUE;
+ else
+ prunearg = FALSE;
+ break;
+ case LSCP_TYPE:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mType = type;
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ char jumpname1[32];
+ sprintf(jumpname1, "##Temp Jump %d##", gTempJumpCount++);
+ char jumpname2[32];
+ sprintf(jumpname2, "##Temp Jump %d##", gTempJumpCount++);
+
+ chunk->addLabel(jumpname1);
+ mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPNIF]);
+ chunk->addByte(LSCRIPTTypeByte[mType]);
+ chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
+ chunk->addJump(jumpname2);
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_JUMP]);
+ chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
+ chunk->addJump(jumpname1);
+ chunk->addLabel(jumpname2);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ S32 tjump1 = gTempJumpCount++;
+ S32 tjump2 = gTempJumpCount++;
+ fprintf(fp, "LabelTempJump%d:\n", tjump1);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "brfalse LabelTempJump%d\n", tjump2);
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "br LabelTempJump%d\n", tjump1);
+ fprintf(fp, "LabelTempJump%d:\n", tjump2);
+ }
+ break;
+ default:
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptDeclaration::getSize()
+{
+ return mType->getSize();
+}
+
+void LLScriptDeclaration::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ if (mExpression)
+ {
+ fdotabs(fp, tabs, tabsize);
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\t");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " = ");
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ";\n");
+ }
+ else
+ {
+ fdotabs(fp, tabs, tabsize);
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\t");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ";\n");
+ }
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ if (mExpression)
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ fprintf(fp, "%s%d [%s]\n", LSCRIPTTypeLocalDeclaration[mIdentifier->mScopeEntry->mType], mIdentifier->mScopeEntry->mOffset, mIdentifier->mName);
+ }
+ else if (mIdentifier->mScopeEntry->mIDType == LIT_GLOBAL)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
+ }
+ }
+ break;
+ case LSCP_PRUNE:
+ if (ptype == LSPRUNE_DEAD_CODE)
+ prunearg = TRUE;
+ else
+ prunearg = FALSE;
+ break;
+ case LSCP_SCOPE_PASS1:
+ // Check to see if a declaration is valid here.
+ if (!mAllowDeclarations)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_NEED_NEW_SCOPE);
+ }
+ // add labels to scope
+ else if (scope->checkEntry(mIdentifier->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ if (mExpression)
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ // this needs to go after expression decent to make sure that we don't add ourselves or something silly
+ // check expression if it exists
+ mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_VARIABLE, mType->mType);
+ }
+ break;
+ case LSCP_TYPE:
+ // if there is an expression, it must be promotable to variable type
+ if (mExpression && mIdentifier->mScopeEntry)
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!legal_assignment(mIdentifier->mScopeEntry->mType, type))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
+ }
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ mIdentifier->mScopeEntry->mOffset = (S32)count;
+ mIdentifier->mScopeEntry->mSize = mType->getSize();
+ count += mIdentifier->mScopeEntry->mSize;
+ // Index into locals is current number of locals. Stored in mCount member of mScopeEntry.
+ mIdentifier->mScopeEntry->mCount = entry->mLocals.getNumber();
+ entry->mLocals.addType(mType->mType);
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ if (mExpression)
+ {
+ mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mExpression->mReturnType != mIdentifier->mScopeEntry->mType)
+ {
+ cast2stack(chunk, mExpression->mReturnType, mIdentifier->mScopeEntry->mType);
+ }
+ switch(mExpression->mReturnType)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
+ }
+ break;
+ case LST_STRING:
+ case LST_KEY:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADSP]);
+ }
+ break;
+ case LST_LIST:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADLP]);
+ }
+ break;
+ case LST_VECTOR:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADVP]);
+ }
+ break;
+ case LST_QUATERNION:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADQP]);
+ }
+ break;
+ default:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
+ }
+ break;
+ }
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ S32 address = mIdentifier->mScopeEntry->mOffset;
+ chunk->addInteger(address);
+ }
+ }
+ else
+ {
+ switch(mIdentifier->mScopeEntry->mType)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
+ chunk->addInteger(0);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
+ }
+ break;
+ case LST_STRING:
+ case LST_KEY:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGS]);
+ chunk->addBytes("", 1);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADSP]);
+ }
+ break;
+ case LST_LIST:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_STACKTOL]);
+ chunk->addInteger(0);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADLP]);
+ }
+ break;
+ case LST_VECTOR:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGV]);
+ chunk->addFloat(0);
+ chunk->addFloat(0);
+ chunk->addFloat(0);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADVP]);
+ }
+ break;
+ case LST_QUATERNION:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGQ]);
+ chunk->addFloat(1);
+ chunk->addFloat(0);
+ chunk->addFloat(0);
+ chunk->addFloat(0);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADQP]);
+ }
+ break;
+ default:
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
+ chunk->addInteger(0);
+ chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
+ }
+ break;
+ }
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ S32 address = mIdentifier->mScopeEntry->mOffset;
+ chunk->addInteger(address);
+ }
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ if (mExpression)
+ {
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
+ {
+ if(is_parameter(mIdentifier, entry))
+ {
+ // Parameter, store by name.
+ fprintf(fp, "starg.s %s\n", mIdentifier->mScopeEntry->mIdentifier);
+ }
+ else
+ {
+ // Local, store by index.
+ fprintf(fp, "stloc.s %d\n", mIdentifier->mScopeEntry->mCount);
+ }
+ }
+ else if (mIdentifier->mScopeEntry->mIDType == LIT_GLOBAL)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
+ }
+ }
+ break;
+ default:
+ if (mExpression)
+ {
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ else
+ {
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptCompoundStatement::getSize()
+{
+ return 0;
+}
+
+void LLScriptCompoundStatement::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ if (mStatement)
+ {
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "{\n");
+ mStatement->recurse(fp, tabs + 1, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "}\n");
+ }
+ else
+ {
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "{\n");
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "}\n");
+ }
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ if (mStatement)
+ {
+ mStatement->recurse(fp, tabs + 1, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_PRUNE:
+ if (mStatement)
+ {
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ else
+ {
+ prunearg = FALSE;
+ }
+ break;
+ case LSCP_SCOPE_PASS1:
+ // compound statements create a new scope
+ if (mStatement)
+ {
+ mStatementScope = new LLScriptScope(gScopeStringTable);
+ mStatementScope->addParentScope(scope);
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mStatementScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_SCOPE_PASS2:
+ // compound statements create a new scope
+ if (mStatement)
+ {
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mStatementScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ default:
+ if (mStatement)
+ {
+ mStatement->recurse(fp, tabs + 1, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+void LLScriptEventHandler::addEvent(LLScriptEventHandler *event)
+{
+ if (mNextp)
+ {
+ event->mNextp = mNextp;
+ }
+ mNextp = event;
+}
+
+void LLScriptEventHandler::gonext(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ default:
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+}
+
+S32 LLScriptEventHandler::getSize()
+{
+ return mStackSpace;
+}
+
+U64 gCurrentHandler = 0;
+
+void print_cil_local_init(FILE* fp, LLScriptScopeEntry* scopeEntry)
+{
+ if(scopeEntry->mLocals.getNumber() > 0)
+ {
+ fprintf(fp, ".locals init (");
+ for(int local = 0; local < scopeEntry->mLocals.getNumber(); ++local)
+ {
+ if(local > 0)
+ {
+ fprintf(fp, ", ");
+ }
+ print_cil_type(fp, scopeEntry->mLocals.getType(local));
+ }
+ fprintf(fp, ")\n");
+ }
+}
+
+void LLScriptEventHandler::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mStatement)
+ {
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ else
+ {
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "{\n");
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "}\n");
+ }
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mStatement)
+ {
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, getSize(), mScopeEntry, entrycount, NULL);
+ }
+ if (mbNeedTrailingReturn)
+ {
+ print_return(fp, mScopeEntry);
+ }
+ fprintf(fp, "\n");
+ break;
+ case LSCP_PRUNE:
+ mbNeedTrailingReturn = FALSE;
+ prunearg = TRUE;
+ mStatement->recurse(fp, tabs, tabsize, pass, LSPRUNE_EVENTS, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!prunearg)
+ {
+ // this means that we didn't end with a return statement, need to add one
+ mbNeedTrailingReturn = TRUE;
+ }
+ break;
+ case LSCP_SCOPE_PASS1:
+ // create event level scope
+ mEventScope = new LLScriptScope(gScopeStringTable);
+ mEventScope->addParentScope(scope);
+
+ // add event parameters
+ mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mEventScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mEventScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_SCOPE_PASS2:
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mEventScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_TYPE:
+ mScopeEntry = new LLScriptScopeEntry("Event", LIT_HANDLER, LST_NULL);
+ switch(mEventp->mType)
+ {
+ case LSTT_STATE_ENTRY:
+ break;
+ case LSTT_STATE_EXIT:
+ break;
+ case LSTT_TOUCH_START:
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ break;
+ case LSTT_TOUCH:
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ break;
+ case LSTT_TOUCH_END:
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ break;
+ case LSTT_COLLISION_START:
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ break;
+ case LSTT_COLLISION:
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ break;
+ case LSTT_COLLISION_END:
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ break;
+ case LSTT_LAND_COLLISION_START:
+ mScopeEntry->mFunctionArgs.addType(LST_VECTOR);
+ break;
+ case LSTT_LAND_COLLISION:
+ mScopeEntry->mFunctionArgs.addType(LST_VECTOR);
+ break;
+ case LSTT_LAND_COLLISION_END:
+ mScopeEntry->mFunctionArgs.addType(LST_VECTOR);
+ break;
+ case LSTT_INVENTORY:
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ break;
+ case LSTT_ATTACH:
+ mScopeEntry->mFunctionArgs.addType(LST_KEY);
+ break;
+ case LSTT_DATASERVER:
+ mScopeEntry->mFunctionArgs.addType(LST_KEY);
+ mScopeEntry->mFunctionArgs.addType(LST_STRING);
+ break;
+ case LSTT_TIMER:
+ break;
+ case LSTT_MOVING_START:
+ break;
+ case LSTT_MOVING_END:
+ break;
+ case LSTT_OBJECT_REZ:
+ mScopeEntry->mFunctionArgs.addType(LST_KEY);
+ break;
+ case LSTT_REMOTE_DATA:
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ mScopeEntry->mFunctionArgs.addType(LST_KEY);
+ mScopeEntry->mFunctionArgs.addType(LST_KEY);
+ mScopeEntry->mFunctionArgs.addType(LST_STRING);
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ mScopeEntry->mFunctionArgs.addType(LST_STRING);
+ break;
+ case LSTT_CHAT:
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ mScopeEntry->mFunctionArgs.addType(LST_STRING);
+ mScopeEntry->mFunctionArgs.addType(LST_KEY);
+ mScopeEntry->mFunctionArgs.addType(LST_STRING);
+ break;
+ case LSTT_SENSOR:
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ break;
+ case LSTT_CONTROL:
+ mScopeEntry->mFunctionArgs.addType(LST_KEY);
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ break;
+ case LSTT_LINK_MESSAGE:
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ mScopeEntry->mFunctionArgs.addType(LST_STRING);
+ mScopeEntry->mFunctionArgs.addType(LST_KEY);
+ break;
+ case LSTT_MONEY:
+ mScopeEntry->mFunctionArgs.addType(LST_KEY);
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ break;
+ case LSTT_EMAIL:
+ mScopeEntry->mFunctionArgs.addType(LST_STRING);
+ mScopeEntry->mFunctionArgs.addType(LST_STRING);
+ mScopeEntry->mFunctionArgs.addType(LST_STRING);
+ mScopeEntry->mFunctionArgs.addType(LST_STRING);
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ break;
+ case LSTT_REZ:
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ break;
+ case LSTT_NO_SENSOR:
+ break;
+ case LSTT_AT_TARGET:
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ mScopeEntry->mFunctionArgs.addType(LST_VECTOR);
+ mScopeEntry->mFunctionArgs.addType(LST_VECTOR);
+ break;
+ case LSTT_NOT_AT_TARGET:
+ break;
+ case LSTT_AT_ROT_TARGET:
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ mScopeEntry->mFunctionArgs.addType(LST_QUATERNION);
+ mScopeEntry->mFunctionArgs.addType(LST_QUATERNION);
+ break;
+ case LSTT_NOT_AT_ROT_TARGET:
+ break;
+ case LSTT_RTPERMISSIONS:
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ break;
+ case LSTT_HTTP_RESPONSE:
+ mScopeEntry->mFunctionArgs.addType(LST_KEY);
+ mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
+ mScopeEntry->mFunctionArgs.addType(LST_LIST);
+ mScopeEntry->mFunctionArgs.addType(LST_STRING);
+ break;
+
+ default:
+ break;
+ }
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_RESOURCE:
+ // first determine resource counts for globals
+ count = 0;
+ mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mStatement)
+ {
+ entrycount = 0;
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mScopeEntry, entrycount, NULL);
+ fprintf(fp, "Function Args: %s\n", mScopeEntry->mFunctionArgs.mString);
+ fprintf(fp, "Local List: %s\n", mScopeEntry->mLocals.mString);
+ }
+ mStackSpace = (S32)count;
+ break;
+ case LSCP_DETERMINE_HANDLERS:
+ count |= LSCRIPTStateBitField[mEventp->mType];
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ // order for event handler
+ // set jump table value
+ S32 jumpoffset;
+ jumpoffset = LSCRIPTDataSize[LST_INTEGER]*get_event_handler_jump_position(gCurrentHandler, mEventp->mType)*2;
+
+ integer2bytestream(chunk->mCodeChunk, jumpoffset, chunk->mCurrentOffset);
+
+ // 0 - 3: offset to actual data
+ S32 offsetoffset = chunk->mCurrentOffset;
+ S32 offsetdelta = 0;
+ chunk->addBytes(4);
+
+ // null terminated event name and null terminated parameters
+ if (mEventp)
+ {
+ LLScriptByteCodeChunk *event = new LLScriptByteCodeChunk(FALSE);
+ mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, event, heap, stacksize, entry, entrycount, NULL);
+ chunk->addBytes(event->mCodeChunk, event->mCurrentOffset);
+ delete event;
+ }
+ chunk->addBytes(1);
+
+ // now we're at the first opcode
+ offsetdelta = chunk->mCurrentOffset - offsetoffset;
+ integer2bytestream(chunk->mCodeChunk, offsetoffset, offsetdelta);
+
+ // get ready to compute the number of bytes of opcode
+ offsetdelta = chunk->mCurrentOffset;
+
+ if (mStatement)
+ {
+ LLScriptByteCodeChunk *statements = new LLScriptByteCodeChunk(TRUE);
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, statements, heap, getSize(), mScopeEntry, entrycount, NULL);
+ statements->connectJumps();
+ chunk->addBytes(statements->mCodeChunk, statements->mCurrentOffset);
+ delete statements;
+ }
+ if (mbNeedTrailingReturn)
+ {
+ add_return(chunk, mScopeEntry);
+ }
+ // now stuff in the number of bytes of stack space that this routine needs
+ integer2bytestream(chunk->mCodeChunk, jumpoffset, getSize());
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+
+ // Method signature prefix.
+ fprintf(fp, ".method public hidebysig instance default void ");
+
+ // Mangle event handler name by prefixing it with state name. Allows state changing by finding handlers prefixed with new state name.
+ fprintf(fp, entry->mIdentifier);
+
+ // Handler name and arguments.
+ mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+
+ // Method signature postfix.
+ fprintf(fp, " cil managed\n");
+
+ // Function header.
+ fprintf(fp,"{\n");
+ fprintf(fp, ".maxstack 500\n"); // TODO: Calculated stack size...
+
+ // Allocate space for locals.
+ print_cil_local_init(fp, mScopeEntry);
+
+ if (mStatement)
+ {
+ // Pass scope so identifiers can determine parameter or local.
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mScopeEntry, entrycount, NULL);
+ }
+
+ // Function footer.
+ fprintf(fp, "\nret\n"); // TODO: Check whether return needed?
+ fprintf(fp, "}\n");
+
+ break;
+ default:
+ mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mStatement)
+ {
+ mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+void LLScriptFunctionDec::addFunctionParameter(LLScriptFunctionDec *dec)
+{
+ if (mNextp)
+ {
+ dec->mNextp = mNextp;
+ }
+ mNextp = dec;
+}
+
+void LLScriptFunctionDec::gonext(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ if (mNextp)
+ {
+ fprintf(fp, ", ");
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ if (mNextp)
+ {
+ fprintf(fp, ", ");
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ default:
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+
+}
+
+S32 LLScriptFunctionDec::getSize()
+{
+ return 0;
+}
+
+void LLScriptFunctionDec::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " ");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " ");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_SCOPE_PASS1:
+ // add function names into global scope
+ if (scope->checkEntry(mIdentifier->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_VARIABLE, mType->mType);
+ }
+ break;
+ case LSCP_RESOURCE:
+ {
+ // we're just tryng to determine how much space the variable needs
+ mIdentifier->mScopeEntry->mOffset = (S32)count;
+ mIdentifier->mScopeEntry->mSize = mType->getSize();
+ count += mIdentifier->mScopeEntry->mSize;
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ // return type
+ char typereturn;
+ if (mType)
+ {
+ typereturn = LSCRIPTTypeByte[mType->mType];
+ }
+ else
+ {
+ typereturn = LSCRIPTTypeByte[LST_NULL];
+ }
+ chunk->addBytes(&typereturn, 1);
+ // name
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);
+#else
+ chunk->addBytes(1);
+#endif
+ }
+ break;
+ case LSCP_BUILD_FUNCTION_ARGS:
+ {
+ entry->mFunctionArgs.addType(mType->mType);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " ");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ default:
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+void LLScriptGlobalFunctions::addGlobalFunction(LLScriptGlobalFunctions *global)
+{
+ if (mNextp)
+ {
+ global->mNextp = mNextp;
+ }
+ mNextp = global;
+}
+
+void LLScriptGlobalFunctions::gonext(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ default:
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+}
+
+S32 LLScriptGlobalFunctions::getSize()
+{
+ return 0;
+}
+
+void LLScriptGlobalFunctions::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ if (mType)
+ {
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\t");
+ }
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mParameters)
+ {
+ fprintf(fp, "( ");
+ mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ }
+ else
+ {
+ fprintf(fp, "()\n");
+ }
+ if (mStatements)
+ {
+ fdotabs(fp, tabs, tabsize);
+ mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, entrycount, NULL);
+ }
+ else
+ {
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "{\n");
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "}\n");
+ }
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mParameters)
+ {
+ fprintf(fp, "( ");
+ mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )\n");
+ }
+ else
+ {
+ fprintf(fp, "()\n");
+ }
+ if (mStatements)
+ {
+ mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, mIdentifier->mScopeEntry->mSize, mIdentifier->mScopeEntry, entrycount, NULL);
+ }
+ if (mbNeedTrailingReturn)
+ {
+ print_return(fp, mIdentifier->mScopeEntry);
+ }
+ fprintf(fp, "\n");
+ break;
+ case LSCP_PRUNE:
+ mbNeedTrailingReturn = FALSE;
+ if (mType)
+ {
+ prunearg = TRUE;
+ mStatements->recurse(fp, tabs, tabsize, pass, LSPRUNE_GLOBAL_NON_VOIDS, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!prunearg)
+ {
+ gErrorToText.writeError(fp, this, LSERROR_NO_RETURN);
+ }
+ }
+ else
+ {
+ prunearg = TRUE;
+ mStatements->recurse(fp, tabs, tabsize, pass, LSPRUNE_GLOBAL_VOIDS, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (!prunearg)
+ {
+ // this means that we didn't end with a return statement, need to add one
+ mbNeedTrailingReturn = TRUE;
+ }
+ }
+ break;
+ case LSCP_SCOPE_PASS1:
+ // add function names into global scope
+ if (scope->checkEntry(mIdentifier->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ if (mType)
+ {
+ mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_FUNCTION, mType->mType);
+ }
+ else
+ {
+ mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_FUNCTION, LST_NULL);
+ }
+ }
+
+ // create function level scope
+ mFunctionScope = new LLScriptScope(gScopeStringTable);
+ mFunctionScope->addParentScope(scope);
+
+ // function parameters
+ if (mParameters)
+ {
+ mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mFunctionScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+
+ mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mFunctionScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_SCOPE_PASS2:
+ mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mFunctionScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+
+ if (mParameters)
+ {
+ if (mIdentifier->mScopeEntry)
+ {
+ mParameters->recurse(fp, tabs, tabsize, LSCP_BUILD_FUNCTION_ARGS, ptype, prunearg, mFunctionScope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
+ }
+ }
+ break;
+ case LSCP_TYPE:
+ if (mType)
+ {
+ mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, mType->mType, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ else
+ {
+ type = LST_NULL;
+ mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_RESOURCE:
+ // first determine resource counts for globals
+ count = 0;
+
+ if (mParameters)
+ {
+ mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+
+ if (mIdentifier->mScopeEntry)
+ {
+ // this isn't a bug . . . Offset is used to determine how much is params vs locals
+ mIdentifier->mScopeEntry->mOffset = (S32)count;
+ }
+
+ if (mStatements)
+ {
+ entrycount = 0;
+ mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, entrycount, NULL);
+ fprintf(fp, "Function Args: %s\n", mIdentifier->mScopeEntry->mFunctionArgs.mString);
+ fprintf(fp, "Local List: %s\n", mIdentifier->mScopeEntry->mLocals.mString);
+ if (mIdentifier->mScopeEntry)
+ {
+ mIdentifier->mScopeEntry->mSize = (S32)count;
+ }
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ // order for global functions
+ // set jump table value
+ S32 jumpoffset = LSCRIPTDataSize[LST_INTEGER]*mIdentifier->mScopeEntry->mCount + LSCRIPTDataSize[LST_INTEGER];
+ integer2bytestream(chunk->mCodeChunk, jumpoffset, chunk->mCurrentOffset);
+
+ // 0 - 3: offset to actual data
+ S32 offsetoffset = chunk->mCurrentOffset;
+ S32 offsetdelta = 0;
+ chunk->addBytes(4);
+
+ // null terminated function name
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);
+#else
+ chunk->addBytes(1);
+#endif
+ // return type
+ char typereturn;
+ if (mType)
+ {
+ typereturn = LSCRIPTTypeByte[mType->mType];
+ }
+ else
+ {
+ typereturn = LSCRIPTTypeByte[LST_NULL];
+ }
+ chunk->addBytes(&typereturn, 1);
+
+ // null terminated parameters, followed by type
+ if (mParameters)
+ {
+ LLScriptByteCodeChunk *params = new LLScriptByteCodeChunk(FALSE);
+ mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, params, heap, stacksize, entry, entrycount, NULL);
+ chunk->addBytes(params->mCodeChunk, params->mCurrentOffset);
+ delete params;
+ }
+ chunk->addBytes(1);
+
+ // now we're at the first opcode
+ offsetdelta = chunk->mCurrentOffset - offsetoffset;
+ integer2bytestream(chunk->mCodeChunk, offsetoffset, offsetdelta);
+
+ if (mStatements)
+ {
+ LLScriptByteCodeChunk *statements = new LLScriptByteCodeChunk(TRUE);
+ mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, statements, heap, mIdentifier->mScopeEntry->mSize, mIdentifier->mScopeEntry, entrycount, NULL);
+ statements->connectJumps();
+ chunk->addBytes(statements->mCodeChunk, statements->mCurrentOffset);
+ delete statements;
+ }
+ if (mbNeedTrailingReturn)
+ {
+ add_return(chunk, mIdentifier->mScopeEntry);
+ }
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ {
+ // Function header.
+ fprintf(fp, ".method public hidebysig instance default ");
+ print_cil_type(fp, mType ? mType->mType : LST_NULL);
+ fprintf(fp, " ");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mParameters)
+ {
+ fprintf(fp, "( ");
+ mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, " )");
+ }
+ else
+ {
+ fprintf(fp, "()");
+ }
+ fprintf(fp, " cil managed\n{\n");
+ fprintf(fp, ".maxstack 500\n"); // TODO: Calculated stack size...
+
+ // Allocate space for locals.
+ print_cil_local_init(fp, mIdentifier->mScopeEntry);
+
+ if (mStatements)
+ {
+ mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, mIdentifier->mScopeEntry->mSize, mIdentifier->mScopeEntry, entrycount, NULL);
+ }
+
+ // Function footer.
+ if (mbNeedTrailingReturn)
+ {
+ fprintf(fp, "ret\n");
+ }
+ fprintf(fp, "}\n");
+ fprintf(fp, "\n");
+ }
+ break;
+ default:
+ if (mType)
+ {
+ mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mParameters)
+ {
+ mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ if (mStatements)
+ {
+ mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+void LLScriptState::addState(LLScriptState *state)
+{
+ if (mNextp)
+ {
+ state->mNextp = mNextp;
+ }
+ mNextp = state;
+}
+
+void LLScriptState::gonext(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ default:
+ if (mNextp)
+ {
+ mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+}
+
+S32 LLScriptState::getSize()
+{
+ return 0;
+}
+
+void LLScriptState::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ fdotabs(fp, tabs, tabsize);
+ if (mType == LSSTYPE_DEFAULT)
+ {
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "{\n");
+ }
+ else
+ {
+ fprintf(fp, "state ");
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "{\n");
+ }
+ if (mEvent)
+ {
+ mEvent->recurse(fp, tabs + 1, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ fdotabs(fp, tabs, tabsize);
+ fprintf(fp, "}\n");
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, ":\n");
+ if (mEvent)
+ {
+ fprintf(fp, "EVENTS\n");
+ mEvent->recurse(fp, tabs + 1, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ }
+ break;
+ case LSCP_SCOPE_PASS1:
+ // add state name
+ if (scope->checkEntry(mIdentifier->mName))
+ {
+ gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
+ }
+ else
+ {
+ mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_STATE, LST_NULL);
+ }
+ // now do the events
+ if (mEvent)
+ {
+ mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_SCOPE_PASS2:
+ if (mEvent)
+ {
+ mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_TYPE:
+ if (mEvent)
+ {
+ mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ // order for states
+ // set jump table value
+
+ S32 jumpoffset;
+ if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)
+ {
+ jumpoffset = LSCRIPTDataSize[LST_INTEGER]*3*mIdentifier->mScopeEntry->mCount + LSCRIPTDataSize[LST_INTEGER];
+ }
+ else
+ {
+ jumpoffset = LSCRIPTDataSize[LST_INTEGER]*2*mIdentifier->mScopeEntry->mCount + LSCRIPTDataSize[LST_INTEGER];
+ }
+ integer2bytestream(chunk->mCodeChunk, jumpoffset, chunk->mCurrentOffset);
+
+ // need to figure out what handlers this state has registered
+ // we'll use to count to find it
+ count = 0;
+
+ if (mEvent)
+ {
+ mEvent->recurse(fp, tabs, tabsize, LSCP_DETERMINE_HANDLERS, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ gCurrentHandler = count;
+ }
+
+ // add description word into chunk
+ if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)
+ {
+ u642bytestream(chunk->mCodeChunk, jumpoffset, gCurrentHandler);
+ }
+ else
+ {
+ integer2bytestream(chunk->mCodeChunk, jumpoffset, (S32)gCurrentHandler);
+ }
+
+
+ // 0 - 3: offset to event jump table
+ S32 offsetoffset = chunk->mCurrentOffset;
+ S32 offsetdelta = 0;
+ chunk->addBytes(4);
+
+ // null terminated state name
+#ifdef LSL_INCLUDE_DEBUG_INFO
+ chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);
+#else
+ chunk->addBytes(1);
+#endif
+ // now we're at the jump table
+ offsetdelta = chunk->mCurrentOffset - offsetoffset;
+ integer2bytestream(chunk->mCodeChunk, offsetoffset, offsetdelta);
+
+ // add the events themselves
+ if (mEvent)
+ {
+ LLScriptByteCodeChunk *events = new LLScriptByteCodeChunk(FALSE);
+ // make space for event jump table
+ events->addBytes(LSCRIPTDataSize[LST_INTEGER]*get_number_of_event_handlers(gCurrentHandler)*2);
+ mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, events, heap, stacksize, entry, entrycount, NULL);
+ chunk->addBytes(events->mCodeChunk, events->mCurrentOffset);
+ delete events;
+ }
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+ if (mEvent)
+ {
+ // Entry not used at this level, so pass state scope as entry parameter, to allow event handlers to do name mangling.
+ mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, entrycount, NULL);
+ }
+ break;
+ default:
+ if (mType == LSSTYPE_DEFAULT)
+ {
+ }
+ else
+ {
+ mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ if (mEvent)
+ {
+ mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ break;
+ }
+ gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+}
+
+S32 LLScriptScript::getSize()
+{
+ return 0;
+}
+
+LLScriptScript::LLScriptScript(LLScritpGlobalStorage *globals,
+ LLScriptState *states) :
+ LLScriptFilePosition(0, 0),
+ mStates(states), mGlobalScope(NULL), mGlobals(NULL), mGlobalFunctions(NULL), mGodLike(FALSE)
+{
+ const char DEFAULT_BYTECODE_FILENAME[] = "lscript.lso";
+ strcpy(mBytecodeDest, DEFAULT_BYTECODE_FILENAME);
+
+ LLScriptGlobalVariable *tvar;
+ LLScriptGlobalFunctions *tfunc;
+ LLScritpGlobalStorage *temp;
+
+ temp = globals;
+ while(temp)
+ {
+ if (temp->mbGlobalFunction)
+ {
+ if (!mGlobalFunctions)
+ {
+ mGlobalFunctions = (LLScriptGlobalFunctions *)temp->mGlobal;
+ }
+ else
+ {
+ tfunc = mGlobalFunctions;
+ while(tfunc->mNextp)
+ {
+ tfunc = tfunc->mNextp;
+ }
+ tfunc->mNextp = (LLScriptGlobalFunctions *)temp->mGlobal;
+ }
+ }
+ else
+ {
+ if (!mGlobals)
+ {
+ mGlobals = (LLScriptGlobalVariable *)temp->mGlobal;
+ }
+ else
+ {
+ tvar = mGlobals;
+ while(tvar->mNextp)
+ {
+ tvar = tvar->mNextp;
+ }
+ tvar->mNextp = (LLScriptGlobalVariable *)temp->mGlobal;
+ }
+ }
+ temp = temp->mNextp;
+ }
+}
+
+void LLScriptScript::setBytecodeDest(const char* dst_filename)
+{
+ strncpy(mBytecodeDest, dst_filename, MAX_STRING);
+ mBytecodeDest[MAX_STRING-1] = '\0';
+}
+
+void print_cil_globals(FILE* fp, LLScriptGlobalVariable* global)
+{
+ fprintf(fp, ".field private ");
+ print_cil_type(fp, global->mType->mType);
+ fprintf(fp, " ");
+ fprintf(fp, global->mIdentifier->mName);
+ fprintf(fp, "\n");
+ if(NULL != global->mNextp)
+ {
+ print_cil_globals(fp, global->mNextp);
+ }
+}
+
+void LLScriptScript::recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+{
+ if (gErrorToText.getErrors())
+ {
+ return;
+ }
+ switch(pass)
+ {
+ case LSCP_PRETTY_PRINT:
+ if (mGlobals)
+ {
+ fdotabs(fp, tabs, tabsize);
+ mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+
+ if (mGlobalFunctions)
+ {
+ fdotabs(fp, tabs, tabsize);
+ mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+
+ fdotabs(fp, tabs, tabsize);
+ mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_PRUNE:
+ if (mGlobalFunctions)
+ {
+ mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ }
+ mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_SCOPE_PASS1:
+ {
+ mGlobalScope = new LLScriptScope(gScopeStringTable);
+ // zeroth, add library functions to global scope
+ S32 i;
+ char *arg;
+ LLScriptScopeEntry *sentry;
+ for (i = 0; i < gScriptLibrary.mNextNumber; i++)
+ {
+ // First, check to make sure this isn't a god only function, or that the viewer's agent is a god.
+ if (!gScriptLibrary.mFunctions[i]->mGodOnly || mGodLike)
+ {
+ if (gScriptLibrary.mFunctions[i]->mReturnType)
+ sentry = mGlobalScope->addEntry(gScriptLibrary.mFunctions[i]->mName, LIT_LIBRARY_FUNCTION, char2type(*gScriptLibrary.mFunctions[i]->mReturnType));
+ else
+ sentry = mGlobalScope->addEntry(gScriptLibrary.mFunctions[i]->mName, LIT_LIBRARY_FUNCTION, LST_NULL);
+ sentry->mLibraryNumber = i;
+ arg = gScriptLibrary.mFunctions[i]->mArgs;
+ if (arg)
+ {
+ while (*arg)
+ {
+ sentry->mFunctionArgs.addType(char2type(*arg));
+ sentry->mSize += LSCRIPTDataSize[char2type(*arg)];
+ sentry->mOffset += LSCRIPTDataSize[char2type(*arg)];
+ arg++;
+ }
+ }
+ }
+ }
+ // first go and collect all the global variables
+ if (mGlobals)
+ mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ // second, do the global functions
+ if (mGlobalFunctions)
+ mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ // now do states
+ mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+ case LSCP_SCOPE_PASS2:
+ // now we're checking jumps, function calls, and state transitions
+ if (mGlobalFunctions)
+ mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_TYPE:
+ // first we need to check global variables
+ if (mGlobals)
+ mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ // now do global functions and states
+ if (mGlobalFunctions)
+ mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_RESOURCE:
+ // first determine resource counts for globals
+ count = 0;
+ if (mGlobals)
+ mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ // now do locals
+ if (mGlobalFunctions)
+ mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ case LSCP_EMIT_ASSEMBLY:
+
+ if (mGlobals)
+ {
+ fprintf(fp, "GLOBALS\n");
+ fdotabs(fp, tabs, tabsize);
+ mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ }
+
+ if (mGlobalFunctions)
+ {
+ fprintf(fp, "GLOBAL FUNCTIONS\n");
+ fdotabs(fp, tabs, tabsize);
+ mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ }
+
+ fprintf(fp, "STATES\n");
+ fdotabs(fp, tabs, tabsize);
+ mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ break;
+ case LSCP_EMIT_BYTE_CODE:
+ {
+ // first, create data structure to hold the whole shebang
+ LLScriptScriptCodeChunk *code = new LLScriptScriptCodeChunk(TOP_OF_MEMORY);
+
+ // ok, let's add the registers, all zeroes for now
+ S32 i;
+ S32 nooffset = 0;
+
+ for (i = LREG_IP; i < LREG_EOF; i++)
+ {
+ if (i < LREG_NCE)
+ code->mRegisters->addBytes(4);
+ else if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)
+ code->mRegisters->addBytes(8);
+ }
+ // global variables
+ if (mGlobals)
+ mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, code->mGlobalVariables, code->mHeap, stacksize, entry, entrycount, NULL);
+
+ // put the ending heap block onto the heap
+ U8 *temp;
+ S32 size = lsa_create_data_block(&temp, NULL, 0);
+ code->mHeap->addBytes(temp, size);
+ delete [] temp;
+
+ // global functions
+ // make space for global function jump table
+ if (mGlobalFunctions)
+ {
+ code->mGlobalFunctions->addBytes(LSCRIPTDataSize[LST_INTEGER]*mGlobalScope->mFunctionCount + LSCRIPTDataSize[LST_INTEGER]);
+ integer2bytestream(code->mGlobalFunctions->mCodeChunk, nooffset, mGlobalScope->mFunctionCount);
+ mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, code->mGlobalFunctions, NULL, stacksize, entry, entrycount, NULL);
+ }
+
+
+ nooffset = 0;
+ // states
+ // make space for state jump/info table
+ if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)
+ {
+ code->mStates->addBytes(LSCRIPTDataSize[LST_INTEGER]*3*mGlobalScope->mStateCount + LSCRIPTDataSize[LST_INTEGER]);
+ }
+ else
+ {
+ code->mStates->addBytes(LSCRIPTDataSize[LST_INTEGER]*2*mGlobalScope->mStateCount + LSCRIPTDataSize[LST_INTEGER]);
+ }
+ integer2bytestream(code->mStates->mCodeChunk, nooffset, mGlobalScope->mStateCount);
+ mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, code->mStates, NULL, stacksize, entry, entrycount, NULL);
+
+ // now, put it all together and spit it out
+ // we need
+ FILE *bcfp = LLFile::fopen(mBytecodeDest, "wb");
+
+ code->build(fp, bcfp);
+ fclose(bcfp);
+ }
+ break;
+ case LSCP_EMIT_CIL_ASSEMBLY:
+
+ // Output dependencies.
+ fprintf(fp, ".assembly extern mscorlib {.ver 1:0:5000:0}\n");
+ fprintf(fp, ".assembly extern LScriptLibrary {.ver 0:0:0:0}\n");
+
+ // Output assembly name.
+ fprintf(fp, ".assembly 'lsl' {.ver 0:0:0:0}\n");
+
+ // Output class header.
+ fprintf(fp, ".class public auto ansi beforefieldinit LSL extends [mscorlib]System.Object\n");
+ fprintf(fp, "{\n");
+
+ // Output globals as members.
+ if(NULL != mGlobals)
+ {
+ print_cil_globals(fp, mGlobals);
+ }
+
+ // Output "runtime". Only needed to allow stand alone execution. Not needed when compiling to DLL and using embedded runtime.
+ fprintf(fp, ".method public static hidebysig default void Main () cil managed\n");
+ fprintf(fp, "{\n");
+ fprintf(fp, ".entrypoint\n");
+ fprintf(fp, ".maxstack 2\n");
+ fprintf(fp, ".locals init (class LSL V_0)\n");
+ fprintf(fp, "newobj instance void class LSL::.ctor()\n");
+ fprintf(fp, "stloc.0\n");
+ fprintf(fp, "ldloc.0\n");
+ fprintf(fp, "callvirt instance void class LSL::defaultstate_entry()\n");
+ fprintf(fp, "ret\n");
+ fprintf(fp, "}\n");
+
+ // Output ctor header.
+ fprintf(fp, ".method public hidebysig specialname rtspecialname instance default void .ctor () cil managed\n");
+ fprintf(fp, "{\n");
+ fprintf(fp, ".maxstack 500\n");
+
+ // Initialise globals as members in ctor.
+ if (mGlobals)
+ {
+ fdotabs(fp, tabs, tabsize);
+ mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ }
+
+ // Output ctor footer.
+ fprintf(fp, "ldarg.0\n");
+ fprintf(fp, "call instance void valuetype [mscorlib]System.Object::.ctor()\n");
+ fprintf(fp, "ret\n");
+ fprintf(fp, "}\n");
+
+ // Output functions as methods.
+ if (mGlobalFunctions)
+ {
+ fdotabs(fp, tabs, tabsize);
+ mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+ }
+
+ // Output states as name mangled methods.
+ fdotabs(fp, tabs, tabsize);
+ mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ fprintf(fp, "\n");
+
+ // Output class footer.
+ fprintf(fp, "}\n");
+
+ break;
+ default:
+ if (mGlobals)
+ mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ if (mGlobalFunctions)
+ mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
+ break;
+ }
+}
diff --git a/indra/lscript/lscript_compile/lscript_tree.h b/indra/lscript/lscript_compile/lscript_tree.h
new file mode 100644
index 0000000000..c36bae06b9
--- /dev/null
+++ b/indra/lscript/lscript_compile/lscript_tree.h
@@ -0,0 +1,2279 @@
+/**
+ * @file lscript_tree.h
+ * @brief provides the classes required to build lscript's abstract syntax tree and symbol table
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LL_LSCRIPT_TREE_H
+#define LL_LSCRIPT_TREE_H
+
+#include <stdio.h>
+#include "stdtypes.h"
+#include "v3math.h"
+#include "llquaternion.h"
+#include "linked_lists.h"
+#include "lscript_error.h"
+#include "lscript_typecheck.h"
+#include "lscript_byteformat.h"
+
+
+// Nota Bene: Class destructors don't delete pointed to classes because it isn't guaranteed that lex/yacc will build
+// complete data structures. Instead various chunks that are allocated are stored and deleted by allocation lists
+
+class LLScriptType : public LLScriptFilePosition
+{
+public:
+ LLScriptType(S32 line, S32 col, LSCRIPTType type)
+ : LLScriptFilePosition(line, col), mType(type)
+ {
+ }
+
+ ~LLScriptType() {}
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LSCRIPTType mType;
+};
+
+// contains a literal or constant value
+class LLScriptConstant : public LLScriptFilePosition
+{
+public:
+ LLScriptConstant(S32 line, S32 col, LSCRIPTType type)
+ : LLScriptFilePosition(line, col), mType(type)
+ {
+ }
+
+ virtual ~LLScriptConstant() {}
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LSCRIPTType mType;
+};
+
+class LLScriptConstantInteger : public LLScriptConstant
+{
+public:
+ LLScriptConstantInteger(S32 line, S32 col, S32 value)
+ : LLScriptConstant(line, col, LST_INTEGER), mValue(value)
+ {
+ }
+
+ ~LLScriptConstantInteger() {}
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ S32 mValue;
+};
+
+class LLScriptConstantFloat : public LLScriptConstant
+{
+public:
+ LLScriptConstantFloat(S32 line, S32 col, F32 value)
+ : LLScriptConstant(line, col, LST_FLOATINGPOINT), mValue(value)
+ {
+ }
+
+ ~LLScriptConstantFloat() {}
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ F32 mValue;
+};
+
+class LLScriptConstantString : public LLScriptConstant
+{
+public:
+ LLScriptConstantString(S32 line, S32 col, char *value)
+ : LLScriptConstant(line, col, LST_STRING), mValue(value)
+ {
+ }
+
+ ~LLScriptConstantString()
+ {
+ delete [] mValue;
+ mValue = NULL;
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ char *mValue;
+};
+
+// container for individual identifiers
+class LLScriptIdentifier : public LLScriptFilePosition
+{
+public:
+ LLScriptIdentifier(S32 line, S32 col, char *name, LLScriptType *type = NULL)
+ : LLScriptFilePosition(line, col), mName(name), mScopeEntry(NULL), mType(type)
+ {
+ }
+
+ ~LLScriptIdentifier()
+ {
+ delete [] mName;
+ mName = NULL;
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ char *mName;
+ LLScriptScopeEntry *mScopeEntry;
+ LLScriptType *mType;
+};
+
+typedef enum e_lscript_simple_assignable_type
+{
+ LSSAT_NULL,
+ LSSAT_IDENTIFIER,
+ LSSAT_CONSTANT,
+ LSSAT_VECTOR_CONSTANT,
+ LSSAT_QUATERNION_CONSTANT,
+ LSSAT_LIST_CONSTANT,
+ LSSAT_EOF
+} LSCRIPTSimpleAssignableType;
+
+class LLScriptSimpleAssignable : public LLScriptFilePosition
+{
+public:
+ LLScriptSimpleAssignable(S32 line, S32 col, LSCRIPTSimpleAssignableType type)
+ : LLScriptFilePosition(line, col), mType(type), mNextp(NULL)
+ {
+ }
+
+ void addAssignable(LLScriptSimpleAssignable *assign);
+
+ virtual ~LLScriptSimpleAssignable()
+ {
+ // don't delete next pointer because we're going to store allocation lists and delete from those
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LSCRIPTSimpleAssignableType mType;
+ LLScriptSimpleAssignable *mNextp;
+};
+
+class LLScriptSAIdentifier : public LLScriptSimpleAssignable
+{
+public:
+ LLScriptSAIdentifier(S32 line, S32 col, LLScriptIdentifier *identifier)
+ : LLScriptSimpleAssignable(line, col, LSSAT_IDENTIFIER), mIdentifier(identifier)
+ {
+ }
+
+ ~LLScriptSAIdentifier()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mIdentifier;
+};
+
+class LLScriptSAConstant : public LLScriptSimpleAssignable
+{
+public:
+ LLScriptSAConstant(S32 line, S32 col, LLScriptConstant *constant)
+ : LLScriptSimpleAssignable(line, col, LSSAT_CONSTANT), mConstant(constant)
+ {
+ }
+
+ ~LLScriptSAConstant()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptConstant *mConstant;
+};
+
+class LLScriptSAVector : public LLScriptSimpleAssignable
+{
+public:
+ LLScriptSAVector(S32 line, S32 col, LLScriptSimpleAssignable *e1,
+ LLScriptSimpleAssignable *e2,
+ LLScriptSimpleAssignable *e3)
+ : LLScriptSimpleAssignable(line, col, LSSAT_VECTOR_CONSTANT),
+ mEntry1(e1), mEntry2(e2), mEntry3(e3)
+ {
+ }
+
+ ~LLScriptSAVector()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptSimpleAssignable *mEntry1;
+ LLScriptSimpleAssignable *mEntry2;
+ LLScriptSimpleAssignable *mEntry3;
+};
+
+class LLScriptSAQuaternion : public LLScriptSimpleAssignable
+{
+public:
+ LLScriptSAQuaternion(S32 line, S32 col, LLScriptSimpleAssignable *e1,
+ LLScriptSimpleAssignable *e2,
+ LLScriptSimpleAssignable *e3,
+ LLScriptSimpleAssignable *e4)
+ : LLScriptSimpleAssignable(line, col, LSSAT_QUATERNION_CONSTANT),
+ mEntry1(e1), mEntry2(e2), mEntry3(e3), mEntry4(e4)
+ {
+ }
+
+ ~LLScriptSAQuaternion()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptSimpleAssignable *mEntry1;
+ LLScriptSimpleAssignable *mEntry2;
+ LLScriptSimpleAssignable *mEntry3;
+ LLScriptSimpleAssignable *mEntry4;
+};
+
+class LLScriptSAList : public LLScriptSimpleAssignable
+{
+public:
+ LLScriptSAList(S32 line, S32 col, LLScriptSimpleAssignable *elist)
+ : LLScriptSimpleAssignable(line, col, LSSAT_QUATERNION_CONSTANT), mEntryList(elist)
+ {
+ }
+
+ ~LLScriptSAList()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptSimpleAssignable *mEntryList;
+};
+
+// global variables
+class LLScriptGlobalVariable : public LLScriptFilePosition
+{
+public:
+ LLScriptGlobalVariable(S32 line, S32 col, LLScriptType *type,
+ LLScriptIdentifier *identifier,
+ LLScriptSimpleAssignable *assignable)
+ : LLScriptFilePosition(line, col), mType(type), mIdentifier(identifier), mAssignable(assignable), mNextp(NULL), mAssignableType(LST_NULL)
+ {
+ }
+
+ void addGlobal(LLScriptGlobalVariable *global);
+
+ ~LLScriptGlobalVariable()
+ {
+ }
+
+ void gonext(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptType *mType;
+ LLScriptIdentifier *mIdentifier;
+ LLScriptSimpleAssignable *mAssignable;
+ LLScriptGlobalVariable *mNextp;
+ LSCRIPTType mAssignableType;
+};
+
+// events
+
+class LLScriptEvent : public LLScriptFilePosition
+{
+public:
+ LLScriptEvent(S32 line, S32 col, LSCRIPTStateEventType type)
+ : LLScriptFilePosition(line, col), mType(type)
+ {
+ }
+
+ virtual ~LLScriptEvent()
+ {
+ // don't delete next pointer because we're going to store allocation lists and delete from those
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LSCRIPTStateEventType mType;
+};
+
+class LLScriptStateEntryEvent : public LLScriptEvent
+{
+public:
+ LLScriptStateEntryEvent(S32 line, S32 col)
+ : LLScriptEvent(line, col, LSTT_STATE_ENTRY)
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ ~LLScriptStateEntryEvent() {}
+};
+
+class LLScriptStateExitEvent : public LLScriptEvent
+{
+public:
+ LLScriptStateExitEvent(S32 line, S32 col)
+ : LLScriptEvent(line, col, LSTT_STATE_EXIT)
+ {
+ }
+
+ ~LLScriptStateExitEvent() {}
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+};
+
+class LLScriptTouchStartEvent : public LLScriptEvent
+{
+public:
+ LLScriptTouchStartEvent(S32 line, S32 col, LLScriptIdentifier *count)
+ : LLScriptEvent(line, col, LSTT_TOUCH_START), mCount(count)
+ {
+ }
+
+ ~LLScriptTouchStartEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mCount;
+};
+
+class LLScriptTouchEvent : public LLScriptEvent
+{
+public:
+ LLScriptTouchEvent(S32 line, S32 col, LLScriptIdentifier *count)
+ : LLScriptEvent(line, col, LSTT_TOUCH), mCount(count)
+ {
+ }
+
+ ~LLScriptTouchEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mCount;
+};
+
+class LLScriptTouchEndEvent : public LLScriptEvent
+{
+public:
+ LLScriptTouchEndEvent(S32 line, S32 col, LLScriptIdentifier *count)
+ : LLScriptEvent(line, col, LSTT_TOUCH_END), mCount(count)
+ {
+ }
+
+ ~LLScriptTouchEndEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mCount;
+};
+
+class LLScriptCollisionStartEvent : public LLScriptEvent
+{
+public:
+ LLScriptCollisionStartEvent(S32 line, S32 col, LLScriptIdentifier *count)
+ : LLScriptEvent(line, col, LSTT_COLLISION_START), mCount(count)
+ {
+ }
+
+ ~LLScriptCollisionStartEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mCount;
+};
+
+class LLScriptCollisionEvent : public LLScriptEvent
+{
+public:
+ LLScriptCollisionEvent(S32 line, S32 col, LLScriptIdentifier *count)
+ : LLScriptEvent(line, col, LSTT_COLLISION), mCount(count)
+ {
+ }
+
+ ~LLScriptCollisionEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mCount;
+};
+
+class LLScriptCollisionEndEvent : public LLScriptEvent
+{
+public:
+ LLScriptCollisionEndEvent(S32 line, S32 col, LLScriptIdentifier *count)
+ : LLScriptEvent(line, col, LSTT_COLLISION_END), mCount(count)
+ {
+ }
+
+ ~LLScriptCollisionEndEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mCount;
+};
+
+class LLScriptLandCollisionStartEvent : public LLScriptEvent
+{
+public:
+ LLScriptLandCollisionStartEvent(S32 line, S32 col, LLScriptIdentifier *pos)
+ : LLScriptEvent(line, col, LSTT_LAND_COLLISION_START), mPosition(pos)
+ {
+ }
+
+ ~LLScriptLandCollisionStartEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mPosition;
+};
+
+class LLScriptLandCollisionEvent : public LLScriptEvent
+{
+public:
+ LLScriptLandCollisionEvent(S32 line, S32 col, LLScriptIdentifier *pos)
+ : LLScriptEvent(line, col, LSTT_LAND_COLLISION), mPosition(pos)
+ {
+ }
+
+ ~LLScriptLandCollisionEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mPosition;
+};
+
+class LLScriptLandCollisionEndEvent : public LLScriptEvent
+{
+public:
+ LLScriptLandCollisionEndEvent(S32 line, S32 col, LLScriptIdentifier *pos)
+ : LLScriptEvent(line, col, LSTT_LAND_COLLISION_END), mPosition(pos)
+ {
+ }
+
+ ~LLScriptLandCollisionEndEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mPosition;
+};
+
+class LLScriptInventoryEvent : public LLScriptEvent
+{
+public:
+ LLScriptInventoryEvent(S32 line, S32 col, LLScriptIdentifier *change)
+ : LLScriptEvent(line, col, LSTT_INVENTORY), mChange(change)
+ {
+ }
+
+ ~LLScriptInventoryEvent() {}
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mChange;
+};
+
+class LLScriptAttachEvent : public LLScriptEvent
+{
+public:
+ LLScriptAttachEvent(S32 line, S32 col, LLScriptIdentifier *attach)
+ : LLScriptEvent(line, col, LSTT_ATTACH), mAttach(attach)
+ {
+ }
+
+ ~LLScriptAttachEvent() {}
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mAttach;
+};
+
+class LLScriptDataserverEvent : public LLScriptEvent
+{
+public:
+ LLScriptDataserverEvent(S32 line, S32 col, LLScriptIdentifier *id, LLScriptIdentifier *data)
+ : LLScriptEvent(line, col, LSTT_DATASERVER), mID(id), mData(data)
+ {
+ }
+
+ ~LLScriptDataserverEvent() {}
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mID;
+ LLScriptIdentifier *mData;
+};
+
+class LLScriptTimerEvent : public LLScriptEvent
+{
+public:
+ LLScriptTimerEvent(S32 line, S32 col)
+ : LLScriptEvent(line, col, LSTT_TIMER)
+ {
+ }
+
+ ~LLScriptTimerEvent() {}
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+};
+
+class LLScriptMovingStartEvent : public LLScriptEvent
+{
+public:
+ LLScriptMovingStartEvent(S32 line, S32 col)
+ : LLScriptEvent(line, col, LSTT_MOVING_START)
+ {
+ }
+
+ ~LLScriptMovingStartEvent() {}
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+};
+
+class LLScriptMovingEndEvent : public LLScriptEvent
+{
+public:
+ LLScriptMovingEndEvent(S32 line, S32 col)
+ : LLScriptEvent(line, col, LSTT_MOVING_END)
+ {
+ }
+
+ ~LLScriptMovingEndEvent() {}
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+};
+
+class LLScriptRTPEvent : public LLScriptEvent
+{
+public:
+ LLScriptRTPEvent(S32 line, S32 col, LLScriptIdentifier *rtperm)
+ : LLScriptEvent(line, col, LSTT_RTPERMISSIONS), mRTPermissions(rtperm)
+ {
+ }
+
+ ~LLScriptRTPEvent() {}
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mRTPermissions;
+};
+
+class LLScriptChatEvent : public LLScriptEvent
+{
+public:
+ LLScriptChatEvent(S32 line, S32 col, LLScriptIdentifier *channel, LLScriptIdentifier *name, LLScriptIdentifier *id, LLScriptIdentifier *message)
+ : LLScriptEvent(line, col, LSTT_CHAT), mChannel(channel), mName(name), mID(id), mMessage(message)
+ {
+ }
+
+ ~LLScriptChatEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mChannel;
+ LLScriptIdentifier *mName;
+ LLScriptIdentifier *mID;
+ LLScriptIdentifier *mMessage;
+};
+
+class LLScriptObjectRezEvent : public LLScriptEvent
+{
+public:
+ LLScriptObjectRezEvent(S32 line, S32 col, LLScriptIdentifier *id)
+ : LLScriptEvent(line, col, LSTT_OBJECT_REZ), mID(id)
+ {
+ }
+
+ ~LLScriptObjectRezEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mID;
+};
+
+class LLScriptSensorEvent : public LLScriptEvent
+{
+public:
+ LLScriptSensorEvent(S32 line, S32 col, LLScriptIdentifier *number)
+ : LLScriptEvent(line, col, LSTT_SENSOR), mNumber(number)
+ {
+ }
+
+ ~LLScriptSensorEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mNumber;
+};
+
+class LLScriptControlEvent : public LLScriptEvent
+{
+public:
+ LLScriptControlEvent(S32 line, S32 col, LLScriptIdentifier *name, LLScriptIdentifier *levels, LLScriptIdentifier *edges)
+ : LLScriptEvent(line, col, LSTT_CONTROL), mName(name), mLevels(levels), mEdges(edges)
+ {
+ }
+
+ ~LLScriptControlEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mName;
+ LLScriptIdentifier *mLevels;
+ LLScriptIdentifier *mEdges;
+};
+
+class LLScriptLinkMessageEvent : public LLScriptEvent
+{
+public:
+ LLScriptLinkMessageEvent(S32 line, S32 col, LLScriptIdentifier *sender, LLScriptIdentifier *num, LLScriptIdentifier *str, LLScriptIdentifier *id)
+ : LLScriptEvent(line, col, LSTT_LINK_MESSAGE), mSender(sender), mNum(num), mStr(str), mID(id)
+ {
+ }
+
+ ~LLScriptLinkMessageEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mSender;
+ LLScriptIdentifier *mNum;
+ LLScriptIdentifier *mStr;
+ LLScriptIdentifier *mID;
+};
+
+class LLScriptRemoteEvent : public LLScriptEvent
+{
+public:
+ LLScriptRemoteEvent(S32 line, S32 col, LLScriptIdentifier *type, LLScriptIdentifier *channel, LLScriptIdentifier *message_id, LLScriptIdentifier *sender, LLScriptIdentifier *int_val, LLScriptIdentifier *str_val)
+ : LLScriptEvent(line, col, LSTT_REMOTE_DATA), mType(type), mChannel(channel), mMessageID(message_id), mSender(sender), mIntVal(int_val), mStrVal(str_val)
+ {
+ }
+
+ ~LLScriptRemoteEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mType;
+ LLScriptIdentifier *mChannel;
+ LLScriptIdentifier *mMessageID;
+ LLScriptIdentifier *mSender;
+ LLScriptIdentifier *mIntVal;
+ LLScriptIdentifier *mStrVal;
+};
+
+class LLScriptHTTPResponseEvent : public LLScriptEvent
+{
+public:
+ LLScriptHTTPResponseEvent(S32 line, S32 col,
+ LLScriptIdentifier *reqeust_id,
+ LLScriptIdentifier *status,
+ LLScriptIdentifier *metadata,
+ LLScriptIdentifier *body)
+ : LLScriptEvent(line, col, LSTT_HTTP_RESPONSE),
+ mRequestId(reqeust_id), mStatus(status), mMetadata(metadata), mBody(body)
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass,
+ LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope,
+ LSCRIPTType &type, LSCRIPTType basetype, U64 &count,
+ LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap,
+ S32 stacksize, LLScriptScopeEntry *entry,
+ S32 entrycount, LLScriptLibData **ldata);
+
+ S32 getSize();
+
+ LLScriptIdentifier *mRequestId;
+ LLScriptIdentifier *mStatus;
+ LLScriptIdentifier *mMetadata;
+ LLScriptIdentifier *mBody;
+};
+
+class LLScriptRezEvent : public LLScriptEvent
+{
+public:
+ LLScriptRezEvent(S32 line, S32 col, LLScriptIdentifier *start_param)
+ : LLScriptEvent(line, col, LSTT_REZ), mStartParam(start_param)
+ {
+ }
+ ~LLScriptRezEvent() {}
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mStartParam;
+};
+
+class LLScriptNoSensorEvent : public LLScriptEvent
+{
+public:
+ LLScriptNoSensorEvent(S32 line, S32 col)
+ : LLScriptEvent(line, col, LSTT_NO_SENSOR)
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ ~LLScriptNoSensorEvent() {}
+};
+
+class LLScriptAtTarget : public LLScriptEvent
+{
+public:
+ LLScriptAtTarget(S32 line, S32 col, LLScriptIdentifier *tnumber, LLScriptIdentifier *tpos, LLScriptIdentifier *ourpos)
+ : LLScriptEvent(line, col, LSTT_AT_TARGET), mTargetNumber(tnumber), mTargetPosition(tpos), mOurPosition(ourpos)
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ ~LLScriptAtTarget() {}
+
+ LLScriptIdentifier *mTargetNumber;
+ LLScriptIdentifier *mTargetPosition;
+ LLScriptIdentifier *mOurPosition;
+};
+
+class LLScriptNotAtTarget : public LLScriptEvent
+{
+public:
+ LLScriptNotAtTarget(S32 line, S32 col)
+ : LLScriptEvent(line, col, LSTT_NOT_AT_TARGET)
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ ~LLScriptNotAtTarget() {}
+};
+
+class LLScriptAtRotTarget : public LLScriptEvent
+{
+public:
+ LLScriptAtRotTarget(S32 line, S32 col, LLScriptIdentifier *tnumber, LLScriptIdentifier *trot, LLScriptIdentifier *ourrot)
+ : LLScriptEvent(line, col, LSTT_AT_ROT_TARGET), mTargetNumber(tnumber), mTargetRotation(trot), mOurRotation(ourrot)
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ ~LLScriptAtRotTarget() {}
+
+ LLScriptIdentifier *mTargetNumber;
+ LLScriptIdentifier *mTargetRotation;
+ LLScriptIdentifier *mOurRotation;
+};
+
+class LLScriptNotAtRotTarget : public LLScriptEvent
+{
+public:
+ LLScriptNotAtRotTarget(S32 line, S32 col)
+ : LLScriptEvent(line, col, LSTT_NOT_AT_ROT_TARGET)
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ ~LLScriptNotAtRotTarget() {}
+};
+
+class LLScriptMoneyEvent : public LLScriptEvent
+{
+public:
+ LLScriptMoneyEvent(S32 line, S32 col, LLScriptIdentifier *name, LLScriptIdentifier *amount)
+ : LLScriptEvent(line, col, LSTT_MONEY), mName(name), mAmount(amount)
+ {
+ }
+
+ ~LLScriptMoneyEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mName;
+ LLScriptIdentifier *mAmount;
+};
+
+class LLScriptEmailEvent : public LLScriptEvent
+{
+public:
+ LLScriptEmailEvent(S32 line, S32 col, LLScriptIdentifier *time, LLScriptIdentifier *address, LLScriptIdentifier *subject, LLScriptIdentifier *body, LLScriptIdentifier *number)
+ : LLScriptEvent(line, col, LSTT_EMAIL), mTime(time), mAddress(address), mSubject(subject), mBody(body), mNumber(number)
+ {
+ }
+
+ ~LLScriptEmailEvent()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mTime;
+ LLScriptIdentifier *mAddress;
+ LLScriptIdentifier *mSubject;
+ LLScriptIdentifier *mBody;
+ LLScriptIdentifier *mNumber;
+};
+
+
+class LLScriptExpression : public LLScriptFilePosition
+{
+public:
+ LLScriptExpression(S32 line, S32 col, LSCRIPTExpressionType type)
+ : LLScriptFilePosition(line, col), mType(type), mNextp(NULL), mLeftType(LST_NULL), mRightType(LST_NULL), mReturnType(LST_NULL)
+ {
+ }
+
+ void addExpression(LLScriptExpression *expression);
+
+ virtual ~LLScriptExpression()
+ {
+ // don't delete next pointer because we're going to store allocation lists and delete from those
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+
+ void gonext(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LSCRIPTExpressionType mType;
+ LLScriptExpression *mNextp;
+ LSCRIPTType mLeftType, mRightType, mReturnType;
+
+};
+
+class LLScriptForExpressionList : public LLScriptExpression
+{
+public:
+ LLScriptForExpressionList(S32 line, S32 col, LLScriptExpression *first, LLScriptExpression *second)
+ : LLScriptExpression(line, col, LET_FOR_EXPRESSION_LIST), mFirstp(first), mSecondp(second)
+ {
+ }
+
+ ~LLScriptForExpressionList()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mFirstp;
+ LLScriptExpression *mSecondp;
+};
+
+class LLScriptFuncExpressionList : public LLScriptExpression
+{
+public:
+ LLScriptFuncExpressionList(S32 line, S32 col, LLScriptExpression *first, LLScriptExpression *second)
+ : LLScriptExpression(line, col, LET_FUNC_EXPRESSION_LIST), mFirstp(first), mSecondp(second)
+ {
+ }
+
+ ~LLScriptFuncExpressionList()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mFirstp;
+ LLScriptExpression *mSecondp;
+};
+
+class LLScriptListExpressionList : public LLScriptExpression
+{
+public:
+ LLScriptListExpressionList(S32 line, S32 col, LLScriptExpression *first, LLScriptExpression *second)
+ : LLScriptExpression(line, col, LET_LIST_EXPRESSION_LIST), mFirstp(first), mSecondp(second)
+ {
+ }
+
+ ~LLScriptListExpressionList()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mFirstp;
+ LLScriptExpression *mSecondp;
+};
+
+class LLScriptLValue : public LLScriptExpression
+{
+public:
+ LLScriptLValue(S32 line, S32 col, LLScriptIdentifier *identifier, LLScriptIdentifier *accessor)
+ : LLScriptExpression(line, col, LET_LVALUE), mOffset(0), mIdentifier(identifier), mAccessor(accessor)
+ {
+ }
+
+ ~LLScriptLValue()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ S32 mOffset;
+ LLScriptIdentifier *mIdentifier;
+ LLScriptIdentifier *mAccessor;
+};
+
+class LLScriptAssignment : public LLScriptExpression
+{
+public:
+ LLScriptAssignment(S32 line, S32 col, LLScriptExpression *lvalue, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_ASSIGNMENT), mLValue(lvalue), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptAssignment()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLValue;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptAddAssignment : public LLScriptExpression
+{
+public:
+ LLScriptAddAssignment(S32 line, S32 col, LLScriptExpression *lvalue, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_ADD_ASSIGN), mLValue(lvalue), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptAddAssignment()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLValue;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptSubAssignment : public LLScriptExpression
+{
+public:
+ LLScriptSubAssignment(S32 line, S32 col, LLScriptExpression *lvalue, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_SUB_ASSIGN), mLValue(lvalue), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptSubAssignment()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLValue;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptMulAssignment : public LLScriptExpression
+{
+public:
+ LLScriptMulAssignment(S32 line, S32 col, LLScriptExpression *lvalue, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_MUL_ASSIGN), mLValue(lvalue), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptMulAssignment()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLValue;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptDivAssignment : public LLScriptExpression
+{
+public:
+ LLScriptDivAssignment(S32 line, S32 col, LLScriptExpression *lvalue, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_DIV_ASSIGN), mLValue(lvalue), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptDivAssignment()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLValue;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptModAssignment : public LLScriptExpression
+{
+public:
+ LLScriptModAssignment(S32 line, S32 col, LLScriptExpression *lvalue, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_MOD_ASSIGN), mLValue(lvalue), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptModAssignment()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLValue;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptEquality : public LLScriptExpression
+{
+public:
+ LLScriptEquality(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_EQUALITY), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptEquality()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptNotEquals : public LLScriptExpression
+{
+public:
+ LLScriptNotEquals(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_NOT_EQUALS), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptNotEquals()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptLessEquals : public LLScriptExpression
+{
+public:
+ LLScriptLessEquals(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_LESS_EQUALS), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptLessEquals()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptGreaterEquals : public LLScriptExpression
+{
+public:
+ LLScriptGreaterEquals(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_GREATER_EQUALS), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptGreaterEquals()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptLessThan : public LLScriptExpression
+{
+public:
+ LLScriptLessThan(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_LESS_THAN), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptLessThan()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptGreaterThan : public LLScriptExpression
+{
+public:
+ LLScriptGreaterThan(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_GREATER_THAN), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptGreaterThan()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptPlus : public LLScriptExpression
+{
+public:
+ LLScriptPlus(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_PLUS), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptPlus()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptMinus : public LLScriptExpression
+{
+public:
+ LLScriptMinus(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_MINUS), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptMinus()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptTimes : public LLScriptExpression
+{
+public:
+ LLScriptTimes(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_TIMES), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptTimes()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptDivide : public LLScriptExpression
+{
+public:
+ LLScriptDivide(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_DIVIDE), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptDivide()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptMod : public LLScriptExpression
+{
+public:
+ LLScriptMod(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_MOD), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptMod()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptBitAnd : public LLScriptExpression
+{
+public:
+ LLScriptBitAnd(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_BIT_AND), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptBitAnd()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptBitOr : public LLScriptExpression
+{
+public:
+ LLScriptBitOr(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_BIT_OR), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptBitOr()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptBitXor : public LLScriptExpression
+{
+public:
+ LLScriptBitXor(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_BIT_XOR), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptBitXor()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptBooleanAnd : public LLScriptExpression
+{
+public:
+ LLScriptBooleanAnd(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_BOOLEAN_AND), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptBooleanAnd()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptBooleanOr : public LLScriptExpression
+{
+public:
+ LLScriptBooleanOr(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_BOOLEAN_OR), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptBooleanOr()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptShiftLeft : public LLScriptExpression
+{
+public:
+ LLScriptShiftLeft(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_SHIFT_LEFT), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptShiftLeft()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptShiftRight : public LLScriptExpression
+{
+public:
+ LLScriptShiftRight(S32 line, S32 col, LLScriptExpression *leftside, LLScriptExpression *rightside)
+ : LLScriptExpression(line, col, LET_SHIFT_RIGHT), mLeftSide(leftside), mRightSide(rightside)
+ {
+ }
+
+ ~LLScriptShiftRight()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mLeftSide;
+ LLScriptExpression *mRightSide;
+};
+
+class LLScriptParenthesis : public LLScriptExpression
+{
+public:
+ LLScriptParenthesis(S32 line, S32 col, LLScriptExpression *expression)
+ : LLScriptExpression(line, col, LET_PARENTHESIS), mExpression(expression)
+ {
+ }
+
+ ~LLScriptParenthesis()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpression;
+};
+
+class LLScriptUnaryMinus : public LLScriptExpression
+{
+public:
+ LLScriptUnaryMinus(S32 line, S32 col, LLScriptExpression *expression)
+ : LLScriptExpression(line, col, LET_UNARY_MINUS), mExpression(expression)
+ {
+ }
+
+ ~LLScriptUnaryMinus()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpression;
+};
+
+class LLScriptBooleanNot : public LLScriptExpression
+{
+public:
+ LLScriptBooleanNot(S32 line, S32 col, LLScriptExpression *expression)
+ : LLScriptExpression(line, col, LET_BOOLEAN_NOT), mExpression(expression)
+ {
+ }
+
+ ~LLScriptBooleanNot()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpression;
+};
+
+class LLScriptBitNot : public LLScriptExpression
+{
+public:
+ LLScriptBitNot(S32 line, S32 col, LLScriptExpression *expression)
+ : LLScriptExpression(line, col, LET_BIT_NOT), mExpression(expression)
+ {
+ }
+
+ ~LLScriptBitNot()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpression;
+};
+
+class LLScriptPreIncrement : public LLScriptExpression
+{
+public:
+ LLScriptPreIncrement(S32 line, S32 col, LLScriptExpression *expression)
+ : LLScriptExpression(line, col, LET_PRE_INCREMENT), mExpression(expression)
+ {
+ }
+
+ ~LLScriptPreIncrement()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpression;
+};
+
+class LLScriptPreDecrement : public LLScriptExpression
+{
+public:
+ LLScriptPreDecrement(S32 line, S32 col, LLScriptExpression *expression)
+ : LLScriptExpression(line, col, LET_PRE_DECREMENT), mExpression(expression)
+ {
+ }
+
+ ~LLScriptPreDecrement()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpression;
+};
+
+class LLScriptTypeCast : public LLScriptExpression
+{
+public:
+ LLScriptTypeCast(S32 line, S32 col, LLScriptType *type, LLScriptExpression *expression)
+ : LLScriptExpression(line, col, LET_CAST), mType(type), mExpression(expression)
+ {
+ }
+
+ ~LLScriptTypeCast()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptType *mType;
+ LLScriptExpression *mExpression;
+};
+
+class LLScriptVectorInitializer : public LLScriptExpression
+{
+public:
+ LLScriptVectorInitializer(S32 line, S32 col, LLScriptExpression *expression1,
+ LLScriptExpression *expression2,
+ LLScriptExpression *expression3)
+ : LLScriptExpression(line, col, LET_VECTOR_INITIALIZER),
+ mExpression1(expression1),
+ mExpression2(expression2),
+ mExpression3(expression3)
+ {
+ }
+
+ ~LLScriptVectorInitializer()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpression1;
+ LLScriptExpression *mExpression2;
+ LLScriptExpression *mExpression3;
+};
+
+class LLScriptQuaternionInitializer : public LLScriptExpression
+{
+public:
+ LLScriptQuaternionInitializer(S32 line, S32 col, LLScriptExpression *expression1,
+ LLScriptExpression *expression2,
+ LLScriptExpression *expression3,
+ LLScriptExpression *expression4)
+ : LLScriptExpression(line, col, LET_VECTOR_INITIALIZER),
+ mExpression1(expression1),
+ mExpression2(expression2),
+ mExpression3(expression3),
+ mExpression4(expression4)
+ {
+ }
+
+ ~LLScriptQuaternionInitializer()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpression1;
+ LLScriptExpression *mExpression2;
+ LLScriptExpression *mExpression3;
+ LLScriptExpression *mExpression4;
+};
+
+class LLScriptListInitializer : public LLScriptExpression
+{
+public:
+ LLScriptListInitializer(S32 line, S32 col, LLScriptExpression *expressionlist)
+ : LLScriptExpression(line, col, LET_LIST_INITIALIZER), mExpressionList(expressionlist)
+ {
+ }
+
+ ~LLScriptListInitializer()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpressionList;
+};
+
+class LLScriptPostIncrement : public LLScriptExpression
+{
+public:
+ LLScriptPostIncrement(S32 line, S32 col, LLScriptExpression *expression)
+ : LLScriptExpression(line, col, LET_POST_INCREMENT), mExpression(expression)
+ {
+ }
+
+ ~LLScriptPostIncrement()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpression;
+};
+
+class LLScriptPostDecrement : public LLScriptExpression
+{
+public:
+ LLScriptPostDecrement(S32 line, S32 col, LLScriptExpression *expression)
+ : LLScriptExpression(line, col, LET_POST_DECREMENT), mExpression(expression)
+ {
+ }
+
+ ~LLScriptPostDecrement()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpression;
+};
+
+class LLScriptFunctionCall : public LLScriptExpression
+{
+public:
+ LLScriptFunctionCall(S32 line, S32 col, LLScriptIdentifier *identifier, LLScriptExpression *expressionlist)
+ : LLScriptExpression(line, col, LET_FUNCTION_CALL), mIdentifier(identifier), mExpressionList(expressionlist)
+ {
+ }
+
+ ~LLScriptFunctionCall()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mIdentifier;
+ LLScriptExpression *mExpressionList;
+};
+
+class LLScriptPrint : public LLScriptExpression
+{
+public:
+ LLScriptPrint(S32 line, S32 col, LLScriptExpression *expression)
+ : LLScriptExpression(line, col, LET_PRINT), mExpression(expression)
+ {
+ }
+
+ ~LLScriptPrint()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpression;
+};
+
+class LLScriptConstantExpression : public LLScriptExpression
+{
+public:
+ LLScriptConstantExpression(S32 line, S32 col, LLScriptConstant *constant)
+ : LLScriptExpression(line, col, LET_CONSTANT), mConstant(constant)
+ {
+ }
+
+ ~LLScriptConstantExpression()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptConstant *mConstant;
+};
+
+// statement
+typedef enum e_lscript_statement_types
+{
+ LSSMT_NULL,
+ LSSMT_SEQUENCE,
+ LSSMT_NOOP,
+ LSSMT_STATE_CHANGE,
+ LSSMT_JUMP,
+ LSSMT_LABEL,
+ LSSMT_RETURN,
+ LSSMT_EXPRESSION,
+ LSSMT_IF,
+ LSSMT_IF_ELSE,
+ LSSMT_FOR,
+ LSSMT_DO_WHILE,
+ LSSMT_WHILE,
+ LSSMT_DECLARATION,
+ LSSMT_COMPOUND_STATEMENT,
+ LSSMT_EOF
+} LSCRIPTStatementType;
+
+class LLScriptStatement : public LLScriptFilePosition
+{
+public:
+ LLScriptStatement(S32 line, S32 col, LSCRIPTStatementType type)
+ : LLScriptFilePosition(line, col), mType(type), mNextp(NULL), mStatementScope(NULL), mAllowDeclarations(TRUE)
+ {
+ }
+
+ virtual ~LLScriptStatement()
+ {
+ delete mStatementScope;
+ }
+
+ void addStatement(LLScriptStatement *event);
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+
+ void gonext(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LSCRIPTStatementType mType;
+ LLScriptStatement *mNextp;
+ LLScriptScope *mStatementScope;
+ BOOL mAllowDeclarations;
+};
+
+class LLScriptStatementSequence : public LLScriptStatement
+{
+public:
+ LLScriptStatementSequence(S32 line, S32 col, LLScriptStatement *first, LLScriptStatement *second)
+ : LLScriptStatement(line, col, LSSMT_SEQUENCE), mFirstp(first), mSecondp(second)
+ {
+ }
+
+ ~LLScriptStatementSequence()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptStatement *mFirstp;
+ LLScriptStatement *mSecondp;
+};
+
+class LLScriptNOOP : public LLScriptStatement
+{
+public:
+ LLScriptNOOP(S32 line, S32 col)
+ : LLScriptStatement(line, col, LSSMT_NOOP)
+ {
+ }
+
+ ~LLScriptNOOP() {}
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+};
+
+class LLScriptStateChange : public LLScriptStatement
+{
+public:
+ LLScriptStateChange(S32 line, S32 col, LLScriptIdentifier *identifier)
+ : LLScriptStatement(line, col, LSSMT_STATE_CHANGE), mIdentifier(identifier)
+ {
+ }
+
+ ~LLScriptStateChange()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mIdentifier;
+};
+
+class LLScriptJump : public LLScriptStatement
+{
+public:
+ LLScriptJump(S32 line, S32 col, LLScriptIdentifier *identifier)
+ : LLScriptStatement(line, col, LSSMT_JUMP), mIdentifier(identifier)
+ {
+ }
+
+ ~LLScriptJump()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mIdentifier;
+};
+
+class LLScriptLabel : public LLScriptStatement
+{
+public:
+ LLScriptLabel(S32 line, S32 col, LLScriptIdentifier *identifier)
+ : LLScriptStatement(line, col, LSSMT_LABEL), mIdentifier(identifier)
+ {
+ }
+
+ ~LLScriptLabel()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptIdentifier *mIdentifier;
+};
+
+class LLScriptReturn : public LLScriptStatement
+{
+public:
+ LLScriptReturn(S32 line, S32 col, LLScriptExpression *expression)
+ : LLScriptStatement(line, col, LSSMT_RETURN), mExpression(expression), mType(LST_NULL)
+ {
+ }
+
+ ~LLScriptReturn()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpression;
+ LSCRIPTType mType;
+};
+
+class LLScriptExpressionStatement : public LLScriptStatement
+{
+public:
+ LLScriptExpressionStatement(S32 line, S32 col, LLScriptExpression *expression)
+ : LLScriptStatement(line, col, LSSMT_EXPRESSION), mExpression(expression)
+ {
+ }
+
+ ~LLScriptExpressionStatement()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpression;
+};
+
+class LLScriptIf : public LLScriptStatement
+{
+public:
+ LLScriptIf(S32 line, S32 col, LLScriptExpression *expression, LLScriptStatement *statement)
+ : LLScriptStatement(line, col, LSSMT_IF), mType(LST_NULL), mExpression(expression), mStatement(statement)
+ {
+ }
+
+ ~LLScriptIf()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LSCRIPTType mType;
+ LLScriptExpression *mExpression;
+ LLScriptStatement *mStatement;
+};
+
+class LLScriptIfElse : public LLScriptStatement
+{
+public:
+ LLScriptIfElse(S32 line, S32 col, LLScriptExpression *expression, LLScriptStatement *statement1, LLScriptStatement *statement2)
+ : LLScriptStatement(line, col, LSSMT_IF_ELSE), mExpression(expression), mStatement1(statement1), mStatement2(statement2), mType(LST_NULL)
+ {
+ }
+
+ ~LLScriptIfElse()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpression;
+ LLScriptStatement *mStatement1;
+ LLScriptStatement *mStatement2;
+ LSCRIPTType mType;
+};
+
+class LLScriptFor : public LLScriptStatement
+{
+public:
+ LLScriptFor(S32 line, S32 col, LLScriptExpression *sequence, LLScriptExpression *expression, LLScriptExpression *expressionlist, LLScriptStatement *statement)
+ : LLScriptStatement(line, col, LSSMT_FOR), mSequence(sequence), mExpression(expression), mExpressionList(expressionlist), mStatement(statement), mType(LST_NULL)
+ {
+ }
+
+ ~LLScriptFor()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mSequence;
+ LLScriptExpression *mExpression;
+ LLScriptExpression *mExpressionList;
+ LLScriptStatement *mStatement;
+ LSCRIPTType mType;
+};
+
+class LLScriptDoWhile : public LLScriptStatement
+{
+public:
+ LLScriptDoWhile(S32 line, S32 col, LLScriptStatement *statement, LLScriptExpression *expression)
+ : LLScriptStatement(line, col, LSSMT_DO_WHILE), mStatement(statement), mExpression(expression), mType(LST_NULL)
+ {
+ }
+
+ ~LLScriptDoWhile()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptStatement *mStatement;
+ LLScriptExpression *mExpression;
+ LSCRIPTType mType;
+};
+
+class LLScriptWhile : public LLScriptStatement
+{
+public:
+ LLScriptWhile(S32 line, S32 col, LLScriptExpression *expression, LLScriptStatement *statement)
+ : LLScriptStatement(line, col, LSSMT_WHILE), mExpression(expression), mStatement(statement), mType(LST_NULL)
+ {
+ }
+
+ ~LLScriptWhile()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptExpression *mExpression;
+ LLScriptStatement *mStatement;
+ LSCRIPTType mType;
+};
+
+// local variables
+class LLScriptDeclaration : public LLScriptStatement
+{
+public:
+ LLScriptDeclaration(S32 line, S32 col, LLScriptType *type, LLScriptIdentifier *identifier, LLScriptExpression *expression)
+ : LLScriptStatement(line, col, LSSMT_DECLARATION), mType(type), mIdentifier(identifier), mExpression(expression)
+ {
+ }
+
+ ~LLScriptDeclaration()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptType *mType;
+ LLScriptIdentifier *mIdentifier;
+ LLScriptExpression *mExpression;
+};
+
+class LLScriptCompoundStatement : public LLScriptStatement
+{
+public:
+ LLScriptCompoundStatement(S32 line, S32 col, LLScriptStatement *statement)
+ : LLScriptStatement(line, col, LSSMT_COMPOUND_STATEMENT), mStatement(statement)
+ {
+ }
+
+ ~LLScriptCompoundStatement()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptStatement *mStatement;
+};
+
+class LLScriptEventHandler : public LLScriptFilePosition
+{
+public:
+ LLScriptEventHandler(S32 line, S32 col, LLScriptEvent *event, LLScriptStatement *statement)
+ : LLScriptFilePosition(line, col), mEventp(event), mStatement(statement), mNextp(NULL), mEventScope(NULL), mbNeedTrailingReturn(FALSE), mScopeEntry(NULL), mStackSpace(0)
+ {
+ }
+
+ ~LLScriptEventHandler()
+ {
+ delete mEventScope;
+ delete mScopeEntry;
+ }
+
+ void addEvent(LLScriptEventHandler *event);
+
+ void gonext(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptEvent *mEventp;
+ LLScriptStatement *mStatement;
+ LLScriptEventHandler *mNextp;
+ LLScriptScope *mEventScope;
+ BOOL mbNeedTrailingReturn;
+ LLScriptScopeEntry *mScopeEntry;
+
+ S32 mStackSpace;
+
+};
+
+
+// global functions
+class LLScriptFunctionDec : public LLScriptFilePosition
+{
+public:
+ LLScriptFunctionDec(S32 line, S32 col, LLScriptType *type, LLScriptIdentifier *identifier)
+ : LLScriptFilePosition(line, col), mType(type), mIdentifier(identifier), mNextp(NULL)
+ {
+ }
+
+ ~LLScriptFunctionDec()
+ {
+ }
+
+ void addFunctionParameter(LLScriptFunctionDec *dec);
+
+ void gonext(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptType *mType;
+ LLScriptIdentifier *mIdentifier;
+ LLScriptFunctionDec *mNextp;
+};
+
+class LLScriptGlobalFunctions : public LLScriptFilePosition
+{
+public:
+ LLScriptGlobalFunctions(S32 line, S32 col, LLScriptType *type,
+ LLScriptIdentifier *identifier,
+ LLScriptFunctionDec *parameters,
+ LLScriptStatement *statements)
+ : LLScriptFilePosition(line, col), mType(type), mIdentifier(identifier), mParameters(parameters), mStatements(statements), mNextp(NULL), mFunctionScope(NULL), mbNeedTrailingReturn(FALSE)
+ {
+ }
+
+ void addGlobalFunction(LLScriptGlobalFunctions *global);
+
+ ~LLScriptGlobalFunctions()
+ {
+ delete mFunctionScope;
+ }
+
+ void gonext(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LLScriptType *mType;
+ LLScriptIdentifier *mIdentifier;
+ LLScriptFunctionDec *mParameters;
+ LLScriptStatement *mStatements;
+ LLScriptGlobalFunctions *mNextp;
+ LLScriptScope *mFunctionScope;
+ BOOL mbNeedTrailingReturn;
+
+};
+
+typedef enum e_lscript_state_type
+{
+ LSSTYPE_NULL,
+ LSSTYPE_DEFAULT,
+ LSSTYPE_USER,
+ LSSTYPE_EOF
+} LSCRIPTStateType;
+
+// info on state
+class LLScriptState : public LLScriptFilePosition
+{
+public:
+ LLScriptState(S32 line, S32 col, LSCRIPTStateType type, LLScriptIdentifier *identifier, LLScriptEventHandler *event)
+ : LLScriptFilePosition(line, col), mType(type), mIdentifier(identifier), mEvent(event), mNextp(NULL)
+ {
+ }
+
+ void addState(LLScriptState *state);
+
+ ~LLScriptState()
+ {
+ }
+
+ void gonext(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ LSCRIPTStateType mType;
+ LLScriptIdentifier *mIdentifier;
+ LLScriptEventHandler *mEvent;
+ LLScriptState *mNextp;
+
+};
+
+class LLScritpGlobalStorage : public LLScriptFilePosition
+{
+public:
+
+ LLScritpGlobalStorage(LLScriptGlobalVariable *var)
+ : LLScriptFilePosition(0, 0), mGlobal(var), mbGlobalFunction(FALSE), mNextp(NULL)
+ {
+ }
+
+ LLScritpGlobalStorage(LLScriptGlobalFunctions *func)
+ : LLScriptFilePosition(0, 0), mGlobal(func), mbGlobalFunction(TRUE), mNextp(NULL)
+ {
+ }
+
+ ~LLScritpGlobalStorage()
+ {
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
+ {
+ }
+
+ S32 getSize()
+ {
+ return 0;
+ }
+
+ void addGlobal(LLScritpGlobalStorage *global)
+ {
+ if (mNextp)
+ {
+ global->mNextp = mNextp;
+ }
+ mNextp = global;
+ }
+
+ LLScriptFilePosition *mGlobal;
+ BOOL mbGlobalFunction;
+ LLScritpGlobalStorage *mNextp;
+};
+
+// top level container for entire script
+class LLScriptScript : public LLScriptFilePosition
+{
+public:
+ LLScriptScript(LLScritpGlobalStorage *globals,
+ LLScriptState *states);
+
+ ~LLScriptScript()
+ {
+ delete mGlobalScope;
+ }
+
+ void recurse(FILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata);
+ S32 getSize();
+
+ void setBytecodeDest(const char* dst_filename);
+
+ LLScriptState *mStates;
+ LLScriptScope *mGlobalScope;
+ LLScriptGlobalVariable *mGlobals;
+ LLScriptGlobalFunctions *mGlobalFunctions;
+ BOOL mGodLike;
+
+private:
+ char mBytecodeDest[MAX_STRING];
+};
+
+class LLScriptAllocationManager
+{
+public:
+ LLScriptAllocationManager() {}
+ ~LLScriptAllocationManager()
+ {
+ mAllocationList.deleteAllData();
+ }
+
+ void addAllocation(LLScriptFilePosition *ptr)
+ {
+ mAllocationList.addData(ptr);
+ }
+
+ void deleteAllocations()
+ {
+ mAllocationList.deleteAllData();
+ }
+
+ LLLinkedList<LLScriptFilePosition> mAllocationList;
+};
+
+extern LLScriptAllocationManager *gAllocationManager;
+extern LLScriptScript *gScriptp;
+
+#endif
diff --git a/indra/lscript/lscript_compile/lscript_typecheck.cpp b/indra/lscript/lscript_compile/lscript_typecheck.cpp
new file mode 100644
index 0000000000..b706ff6dec
--- /dev/null
+++ b/indra/lscript/lscript_compile/lscript_typecheck.cpp
@@ -0,0 +1,562 @@
+/**
+ * @file lscript_typecheck.cpp
+ * @brief typechecks script
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#include "linden_common.h"
+
+#include "lscript_tree.h"
+
+/*
+ LScript automatic type casting
+
+ LST_INTEGER -> LST_INTEGER
+
+ LST_FLOATINGPOINT -> LST_FLOATINGPOINT
+ LST_INTEGER -> LST_FLOATINGPOINT
+
+ LST_FLOATINGPOINT -> LST_STRING
+ LST_INTEGER -> LST_STRING
+ LST_STRING -> LST_STRING
+ LST_VECTOR -> LST_STRING
+ LST_QUATERNION -> LST_STRING
+ LST_LIST -> LST_STRING
+
+ LST_VECTOR -> LST_VECTOR
+
+ LST_QUATERNION -> LST_QUATERNION
+
+ LST_FLOATINGPOINT -> LST_LIST
+ LST_INTEGER -> LST_LIST
+ LST_STRING -> LST_LIST
+ LST_VECTOR -> LST_LIST
+ LST_QUATERNION -> LST_LIST
+ LST_LIST -> LST_LIST
+*/
+
+LSCRIPTType implicit_casts(LSCRIPTType left_side, LSCRIPTType right_side)
+{
+ switch(left_side)
+ {
+ // shouldn't be doing an operation on void types
+ case LST_NULL:
+ return LST_NULL;
+ // shouldn't be doing an operation on undefined types
+ case LST_UNDEFINED:
+ return LST_UNDEFINED;
+ // only integers can become integers
+ case LST_INTEGER:
+ switch(right_side)
+ {
+ case LST_INTEGER:
+ return LST_INTEGER;
+ default:
+ return LST_UNDEFINED;
+ }
+ // only integers and floats can become floats
+ case LST_FLOATINGPOINT:
+ switch(right_side)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+ return LST_FLOATINGPOINT;
+ default:
+ return LST_UNDEFINED;
+ }
+ // only strings and keys can become strings
+ case LST_STRING:
+ switch(right_side)
+ {
+ case LST_STRING:
+ case LST_KEY:
+ return LST_STRING;
+ default:
+ return LST_UNDEFINED;
+ }
+ // only strings and keys can become keys
+ case LST_KEY:
+ switch(right_side)
+ {
+ case LST_STRING:
+ case LST_KEY:
+ return LST_KEY;
+ default:
+ return LST_UNDEFINED;
+ }
+ // only vectors can become vectors
+ case LST_VECTOR:
+ switch(right_side)
+ {
+ case LST_VECTOR:
+ return LST_VECTOR;
+ default:
+ return LST_UNDEFINED;
+ }
+ // only quaternions can become quaternions
+ case LST_QUATERNION:
+ switch(right_side)
+ {
+ case LST_QUATERNION:
+ return LST_QUATERNION;
+ default:
+ return LST_UNDEFINED;
+ }
+ // only lists can become lists
+ case LST_LIST:
+ switch(right_side)
+ {
+ case LST_LIST:
+ return LST_LIST;
+ default:
+ return LST_UNDEFINED;
+ }
+ default:
+ return LST_UNDEFINED;
+ }
+}
+
+LSCRIPTType promote(LSCRIPTType left_side, LSCRIPTType right_side)
+{
+ LSCRIPTType type;
+ type = implicit_casts(left_side, right_side);
+ if (type != LST_UNDEFINED)
+ {
+ return type;
+ }
+ type = implicit_casts(right_side, left_side);
+ if (type != LST_UNDEFINED)
+ {
+ return type;
+ }
+ return LST_UNDEFINED;
+}
+
+BOOL legal_assignment(LSCRIPTType left_side, LSCRIPTType right_side)
+{
+ // this is to prevent cascading errors
+ if ( (left_side == LST_UNDEFINED)
+ ||(right_side == LST_UNDEFINED))
+ {
+ return TRUE;
+ }
+
+ if (implicit_casts(left_side, right_side) != LST_UNDEFINED)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+BOOL legal_casts(LSCRIPTType cast, LSCRIPTType base)
+{
+ switch(base)
+ {
+ // shouldn't be doing an operation on void types
+ case LST_NULL:
+ return FALSE;
+ // shouldn't be doing an operation on undefined types
+ case LST_UNDEFINED:
+ return FALSE;
+ case LST_INTEGER:
+ switch(cast)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+ case LST_STRING:
+ case LST_LIST:
+ return TRUE;
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+ break;
+ case LST_FLOATINGPOINT:
+ switch(cast)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+ case LST_STRING:
+ case LST_LIST:
+ return TRUE;
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+ break;
+ case LST_STRING:
+ switch(cast)
+ {
+ case LST_INTEGER:
+ case LST_FLOATINGPOINT:
+ case LST_STRING:
+ case LST_KEY:
+ case LST_VECTOR:
+ case LST_QUATERNION:
+ case LST_LIST:
+ return TRUE;
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+ break;
+ case LST_KEY:
+ switch(cast)
+ {
+ case LST_STRING:
+ case LST_KEY:
+ case LST_LIST:
+ return TRUE;
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+ break;
+ case LST_VECTOR:
+ switch(cast)
+ {
+ case LST_VECTOR:
+ case LST_STRING:
+ case LST_LIST:
+ return TRUE;
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+ break;
+ case LST_QUATERNION:
+ switch(cast)
+ {
+ case LST_QUATERNION:
+ case LST_STRING:
+ case LST_LIST:
+ return TRUE;
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+ break;
+ // lists can only be cast to lists and strings
+ case LST_LIST:
+ switch(cast)
+ {
+ case LST_LIST:
+ case LST_STRING:
+ return TRUE;
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+}
+
+LSCRIPTType gSupportedExpressionArray[LET_EOF][LST_EOF][LST_EOF];
+
+void init_supported_expressions(void)
+{
+ S32 i, j, k;
+ // zero out, then set the ones that matter
+ for (i = 0; i < LET_EOF; i++)
+ {
+ for (j = 0; j < LST_EOF; j++)
+ {
+ for (k = 0; k < LST_EOF; k++)
+ {
+ gSupportedExpressionArray[i][j][k] = LST_NULL;
+ }
+ }
+ }
+
+ // LET_ASSIGNMENT
+ gSupportedExpressionArray[LET_ASSIGNMENT][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_ASSIGNMENT][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_ASSIGNMENT][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_ASSIGNMENT][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_ASSIGNMENT][LST_STRING][LST_STRING] = LST_STRING;
+ gSupportedExpressionArray[LET_ASSIGNMENT][LST_KEY][LST_KEY] = LST_KEY;
+ gSupportedExpressionArray[LET_ASSIGNMENT][LST_VECTOR][LST_VECTOR] = LST_VECTOR;
+ gSupportedExpressionArray[LET_ASSIGNMENT][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
+ gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_INTEGER] = LST_LIST;
+ gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_FLOATINGPOINT] = LST_LIST;
+ gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_STRING] = LST_LIST;
+ gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_KEY] = LST_LIST;
+ gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_VECTOR] = LST_LIST;
+ gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_QUATERNION] = LST_LIST;
+ gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_LIST] = LST_LIST;
+
+ // LET_ADD_ASSIGN
+ gSupportedExpressionArray[LET_ADD_ASSIGN][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_ADD_ASSIGN][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_ADD_ASSIGN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_ADD_ASSIGN][LST_STRING][LST_STRING] = LST_STRING;
+ gSupportedExpressionArray[LET_ADD_ASSIGN][LST_VECTOR][LST_VECTOR] = LST_VECTOR;
+ gSupportedExpressionArray[LET_ADD_ASSIGN][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
+ gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_INTEGER] = LST_LIST;
+ gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_FLOATINGPOINT] = LST_LIST;
+ gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_STRING] = LST_LIST;
+ gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_KEY] = LST_LIST;
+ gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_VECTOR] = LST_LIST;
+ gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_QUATERNION] = LST_LIST;
+ gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_LIST] = LST_LIST;
+
+ // LET_SUB_ASSIGN
+ gSupportedExpressionArray[LET_SUB_ASSIGN][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_SUB_ASSIGN][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_SUB_ASSIGN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_SUB_ASSIGN][LST_VECTOR][LST_VECTOR] = LST_VECTOR;
+ gSupportedExpressionArray[LET_SUB_ASSIGN][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
+
+ // LET_MUL_ASSIGN
+ gSupportedExpressionArray[LET_MUL_ASSIGN][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_MUL_ASSIGN][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_MUL_ASSIGN][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_MUL_ASSIGN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_MUL_ASSIGN][LST_VECTOR][LST_INTEGER] = LST_VECTOR;
+ gSupportedExpressionArray[LET_MUL_ASSIGN][LST_INTEGER][LST_VECTOR] = LST_VECTOR;
+ gSupportedExpressionArray[LET_MUL_ASSIGN][LST_VECTOR][LST_FLOATINGPOINT] = LST_VECTOR;
+ gSupportedExpressionArray[LET_MUL_ASSIGN][LST_FLOATINGPOINT][LST_VECTOR] = LST_VECTOR;
+ gSupportedExpressionArray[LET_MUL_ASSIGN][LST_VECTOR][LST_VECTOR] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_MUL_ASSIGN][LST_VECTOR][LST_QUATERNION] = LST_VECTOR;
+ gSupportedExpressionArray[LET_MUL_ASSIGN][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
+
+ // LET_DIV_ASSIGN
+ gSupportedExpressionArray[LET_DIV_ASSIGN][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_DIV_ASSIGN][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_DIV_ASSIGN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_DIV_ASSIGN][LST_VECTOR][LST_INTEGER] = LST_VECTOR;
+ gSupportedExpressionArray[LET_DIV_ASSIGN][LST_VECTOR][LST_FLOATINGPOINT] = LST_VECTOR;
+ gSupportedExpressionArray[LET_DIV_ASSIGN][LST_VECTOR][LST_QUATERNION] = LST_VECTOR;
+ gSupportedExpressionArray[LET_DIV_ASSIGN][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
+
+ // LET_MOD_ASSIGN
+ gSupportedExpressionArray[LET_MOD_ASSIGN][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_MOD_ASSIGN][LST_VECTOR][LST_VECTOR] = LST_VECTOR;
+
+ // LET_EQUALITY
+ gSupportedExpressionArray[LET_EQUALITY][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_EQUALITY][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER;
+ gSupportedExpressionArray[LET_EQUALITY][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_EQUALITY][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER;
+ gSupportedExpressionArray[LET_EQUALITY][LST_STRING][LST_STRING] = LST_INTEGER;
+ gSupportedExpressionArray[LET_EQUALITY][LST_STRING][LST_KEY] = LST_INTEGER;
+ gSupportedExpressionArray[LET_EQUALITY][LST_KEY][LST_STRING] = LST_INTEGER;
+ gSupportedExpressionArray[LET_EQUALITY][LST_KEY][LST_KEY] = LST_INTEGER;
+ gSupportedExpressionArray[LET_EQUALITY][LST_VECTOR][LST_VECTOR] = LST_INTEGER;
+ gSupportedExpressionArray[LET_EQUALITY][LST_QUATERNION][LST_QUATERNION] = LST_INTEGER;
+ gSupportedExpressionArray[LET_EQUALITY][LST_LIST][LST_LIST] = LST_INTEGER;
+
+ // LET_NOT_EQUALS
+ gSupportedExpressionArray[LET_NOT_EQUALS][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_NOT_EQUALS][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER;
+ gSupportedExpressionArray[LET_NOT_EQUALS][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_NOT_EQUALS][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER;
+ gSupportedExpressionArray[LET_NOT_EQUALS][LST_STRING][LST_STRING] = LST_INTEGER;
+ gSupportedExpressionArray[LET_NOT_EQUALS][LST_STRING][LST_KEY] = LST_INTEGER;
+ gSupportedExpressionArray[LET_NOT_EQUALS][LST_KEY][LST_STRING] = LST_INTEGER;
+ gSupportedExpressionArray[LET_NOT_EQUALS][LST_KEY][LST_KEY] = LST_INTEGER;
+ gSupportedExpressionArray[LET_NOT_EQUALS][LST_VECTOR][LST_VECTOR] = LST_INTEGER;
+ gSupportedExpressionArray[LET_NOT_EQUALS][LST_QUATERNION][LST_QUATERNION] = LST_INTEGER;
+ gSupportedExpressionArray[LET_NOT_EQUALS][LST_LIST][LST_LIST] = LST_INTEGER;
+
+ // LET_LESS_EQUALS
+ gSupportedExpressionArray[LET_LESS_EQUALS][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_LESS_EQUALS][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER;
+ gSupportedExpressionArray[LET_LESS_EQUALS][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_LESS_EQUALS][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER;
+
+ // LET_GREATER_EQUALS
+ gSupportedExpressionArray[LET_GREATER_EQUALS][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_GREATER_EQUALS][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER;
+ gSupportedExpressionArray[LET_GREATER_EQUALS][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_GREATER_EQUALS][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER;
+
+ // LET_LESS_THAN
+ gSupportedExpressionArray[LET_LESS_THAN][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_LESS_THAN][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER;
+ gSupportedExpressionArray[LET_LESS_THAN][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_LESS_THAN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER;
+
+ // LET_GREATER_THAN
+ gSupportedExpressionArray[LET_GREATER_THAN][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_GREATER_THAN][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER;
+ gSupportedExpressionArray[LET_GREATER_THAN][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_GREATER_THAN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER;
+
+ // LET_PLUS
+ gSupportedExpressionArray[LET_PLUS][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_PLUS][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_PLUS][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_PLUS][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_PLUS][LST_STRING][LST_STRING] = LST_STRING;
+ gSupportedExpressionArray[LET_PLUS][LST_VECTOR][LST_VECTOR] = LST_VECTOR;
+ gSupportedExpressionArray[LET_PLUS][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
+ gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_INTEGER] = LST_LIST;
+ gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_FLOATINGPOINT] = LST_LIST;
+ gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_STRING] = LST_LIST;
+ gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_KEY] = LST_LIST;
+ gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_VECTOR] = LST_LIST;
+ gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_QUATERNION] = LST_LIST;
+ gSupportedExpressionArray[LET_PLUS][LST_INTEGER][LST_LIST] = LST_LIST;
+ gSupportedExpressionArray[LET_PLUS][LST_FLOATINGPOINT][LST_LIST] = LST_LIST;
+ gSupportedExpressionArray[LET_PLUS][LST_STRING][LST_LIST] = LST_LIST;
+ gSupportedExpressionArray[LET_PLUS][LST_KEY][LST_LIST] = LST_LIST;
+ gSupportedExpressionArray[LET_PLUS][LST_VECTOR][LST_LIST] = LST_LIST;
+ gSupportedExpressionArray[LET_PLUS][LST_QUATERNION][LST_LIST] = LST_LIST;
+ gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_LIST] = LST_LIST;
+
+ // LET_MINUS
+ gSupportedExpressionArray[LET_MINUS][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_MINUS][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_MINUS][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_MINUS][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_MINUS][LST_VECTOR][LST_VECTOR] = LST_VECTOR;
+ gSupportedExpressionArray[LET_MINUS][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
+
+ // LET_TIMES
+ gSupportedExpressionArray[LET_TIMES][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_TIMES][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_TIMES][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_TIMES][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_TIMES][LST_VECTOR][LST_INTEGER] = LST_VECTOR;
+ gSupportedExpressionArray[LET_TIMES][LST_INTEGER][LST_VECTOR] = LST_VECTOR;
+ gSupportedExpressionArray[LET_TIMES][LST_VECTOR][LST_FLOATINGPOINT] = LST_VECTOR;
+ gSupportedExpressionArray[LET_TIMES][LST_FLOATINGPOINT][LST_VECTOR] = LST_VECTOR;
+ gSupportedExpressionArray[LET_TIMES][LST_VECTOR][LST_VECTOR] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_TIMES][LST_VECTOR][LST_QUATERNION] = LST_VECTOR;
+ gSupportedExpressionArray[LET_TIMES][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
+
+ // LET_DIVIDE
+ gSupportedExpressionArray[LET_DIVIDE][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_DIVIDE][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_DIVIDE][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_DIVIDE][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_DIVIDE][LST_VECTOR][LST_INTEGER] = LST_VECTOR;
+ gSupportedExpressionArray[LET_DIVIDE][LST_VECTOR][LST_FLOATINGPOINT] = LST_VECTOR;
+ gSupportedExpressionArray[LET_DIVIDE][LST_VECTOR][LST_QUATERNION] = LST_VECTOR;
+ gSupportedExpressionArray[LET_DIVIDE][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION;
+
+ // LET_MOD
+ gSupportedExpressionArray[LET_MOD][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+ gSupportedExpressionArray[LET_MOD][LST_VECTOR][LST_VECTOR] = LST_VECTOR;
+
+ // LET_BIT_AND
+ gSupportedExpressionArray[LET_BIT_AND][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+
+ // LET_BIT_OR
+ gSupportedExpressionArray[LET_BIT_OR][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+
+ // LET_BIT_XOR
+ gSupportedExpressionArray[LET_BIT_XOR][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+
+ // LET_BOOLEAN_AND
+ gSupportedExpressionArray[LET_BOOLEAN_AND][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+
+ // LET_BOOLEAN_OR
+ gSupportedExpressionArray[LET_BOOLEAN_OR][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+
+ // LET_SHIFT_LEFT
+ gSupportedExpressionArray[LET_SHIFT_LEFT][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+
+ // LET_SHIFT_RIGHT
+ gSupportedExpressionArray[LET_SHIFT_RIGHT][LST_INTEGER][LST_INTEGER] = LST_INTEGER;
+
+ // LET_PARENTHESIS
+ gSupportedExpressionArray[LET_PARENTHESIS][LST_INTEGER][LST_NULL] = LST_INTEGER;
+ gSupportedExpressionArray[LET_PARENTHESIS][LST_FLOATINGPOINT][LST_NULL] = LST_INTEGER;
+ gSupportedExpressionArray[LET_PARENTHESIS][LST_STRING][LST_NULL] = LST_INTEGER;
+ gSupportedExpressionArray[LET_PARENTHESIS][LST_LIST][LST_NULL] = LST_INTEGER;
+
+ // LET_UNARY_MINUS
+ gSupportedExpressionArray[LET_UNARY_MINUS][LST_INTEGER][LST_NULL] = LST_INTEGER;
+ gSupportedExpressionArray[LET_UNARY_MINUS][LST_FLOATINGPOINT][LST_NULL] = LST_FLOATINGPOINT;
+ gSupportedExpressionArray[LET_UNARY_MINUS][LST_VECTOR][LST_NULL] = LST_VECTOR;
+ gSupportedExpressionArray[LET_UNARY_MINUS][LST_QUATERNION][LST_NULL] = LST_QUATERNION;
+
+ // LET_BOOLEAN_NOT
+ gSupportedExpressionArray[LET_BOOLEAN_NOT][LST_INTEGER][LST_NULL] = LST_INTEGER;
+
+ // LET_BIT_NOT
+ gSupportedExpressionArray[LET_BIT_NOT][LST_INTEGER][LST_NULL] = LST_INTEGER;
+
+ // LET_PRE_INCREMENT
+ gSupportedExpressionArray[LET_PRE_INCREMENT][LST_INTEGER][LST_NULL] = LST_INTEGER;
+ gSupportedExpressionArray[LET_PRE_INCREMENT][LST_FLOATINGPOINT][LST_NULL] = LST_FLOATINGPOINT;
+
+ // LET_PRE_DECREMENT
+ gSupportedExpressionArray[LET_PRE_DECREMENT][LST_INTEGER][LST_NULL] = LST_INTEGER;
+ gSupportedExpressionArray[LET_PRE_DECREMENT][LST_FLOATINGPOINT][LST_NULL] = LST_FLOATINGPOINT;
+
+ // LET_POST_INCREMENT
+ gSupportedExpressionArray[LET_POST_INCREMENT][LST_INTEGER][LST_NULL] = LST_INTEGER;
+ gSupportedExpressionArray[LET_POST_INCREMENT][LST_FLOATINGPOINT][LST_NULL] = LST_FLOATINGPOINT;
+
+ // LET_POST_DECREMENT
+ gSupportedExpressionArray[LET_POST_DECREMENT][LST_INTEGER][LST_NULL] = LST_INTEGER;
+ gSupportedExpressionArray[LET_POST_DECREMENT][LST_FLOATINGPOINT][LST_NULL] = LST_FLOATINGPOINT;
+}
+
+BOOL legal_binary_expression(LSCRIPTType &result, LSCRIPTType left_side, LSCRIPTType right_side, LSCRIPTExpressionType expression)
+{
+ if ( (left_side == LST_UNDEFINED)
+ ||(right_side == LST_UNDEFINED))
+ {
+ result = LST_UNDEFINED;
+ return TRUE;
+ }
+
+ if ( (left_side == LST_NULL)
+ ||(right_side == LST_NULL))
+ {
+ result = LST_UNDEFINED;
+ return FALSE;
+ }
+
+ result = gSupportedExpressionArray[expression][left_side][right_side];
+ if (result)
+ return TRUE;
+ else
+ {
+ result = LST_UNDEFINED;
+ return FALSE;
+ }
+}
+
+BOOL legal_unary_expression(LSCRIPTType &result, LSCRIPTType left_side, LSCRIPTExpressionType expression)
+{
+ if (left_side == LST_UNDEFINED)
+ {
+ result = LST_UNDEFINED;
+ return TRUE;
+ }
+
+ if (left_side == LST_NULL)
+ {
+ result = LST_UNDEFINED;
+ return FALSE;
+ }
+
+ result = gSupportedExpressionArray[expression][left_side][LST_NULL];
+ if (result)
+ return TRUE;
+ else
+ {
+ result = LST_UNDEFINED;
+ return FALSE;
+ }
+}
diff --git a/indra/lscript/lscript_compile/lscript_typecheck.h b/indra/lscript/lscript_compile/lscript_typecheck.h
new file mode 100644
index 0000000000..959a85e18e
--- /dev/null
+++ b/indra/lscript/lscript_compile/lscript_typecheck.h
@@ -0,0 +1,100 @@
+/**
+ * @file lscript_typecheck.h
+ * @brief typechecks script
+ *
+ * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LL_LSCRIPT_TYPECHECK_H
+#define LL_LSCRIPT_TYPECHECK_H
+
+#include "lscript_error.h"
+
+LSCRIPTType implicit_casts(LSCRIPTType left_side, LSCRIPTType right_side);
+BOOL legal_casts(LSCRIPTType cast, LSCRIPTType base);
+LSCRIPTType promote(LSCRIPTType left_side, LSCRIPTType right_side);
+BOOL legal_assignment(LSCRIPTType left_side, LSCRIPTType right_side);
+
+typedef enum e_lscript_expression_types
+{
+ LET_NULL,
+ LET_ASSIGNMENT,
+ LET_ADD_ASSIGN,
+ LET_SUB_ASSIGN,
+ LET_MUL_ASSIGN,
+ LET_DIV_ASSIGN,
+ LET_MOD_ASSIGN,
+ LET_EQUALITY,
+ LET_NOT_EQUALS,
+ LET_LESS_EQUALS,
+ LET_GREATER_EQUALS,
+ LET_LESS_THAN,
+ LET_GREATER_THAN,
+ LET_PLUS,
+ LET_MINUS,
+ LET_TIMES,
+ LET_DIVIDE,
+ LET_MOD,
+ LET_BIT_AND,
+ LET_BIT_OR,
+ LET_BIT_XOR,
+ LET_BOOLEAN_AND,
+ LET_BOOLEAN_OR,
+ LET_PARENTHESIS,
+ LET_UNARY_MINUS,
+ LET_BOOLEAN_NOT,
+ LET_BIT_NOT,
+ LET_PRE_INCREMENT,
+ LET_PRE_DECREMENT,
+ LET_CAST,
+ LET_VECTOR_INITIALIZER,
+ LET_QUATERNION_INITIALIZER,
+ LET_LIST_INITIALIZER,
+ LET_LVALUE,
+ LET_POST_INCREMENT,
+ LET_POST_DECREMENT,
+ LET_FUNCTION_CALL,
+ LET_CONSTANT,
+ LET_FOR_EXPRESSION_LIST,
+ LET_FUNC_EXPRESSION_LIST,
+ LET_LIST_EXPRESSION_LIST,
+ LET_PRINT,
+ LET_SHIFT_LEFT,
+ LET_SHIFT_RIGHT,
+ LET_EOF
+} LSCRIPTExpressionType;
+
+BOOL legal_binary_expression(LSCRIPTType &result, LSCRIPTType left_side, LSCRIPTType right_side, LSCRIPTExpressionType expression);
+BOOL legal_unary_expression(LSCRIPTType &result, LSCRIPTType left_side, LSCRIPTExpressionType expression);
+
+void init_supported_expressions(void);
+
+/*
+ LScript automatic type casting
+
+ LST_INTEGER -> LST_INTEGER
+
+ LST_FLOATINGPOINT -> LST_FLOATINGPOINT
+ LST_INTEGER -> LST_FLOATINGPOINT
+
+ LST_FLOATINGPOINT -> LST_STRING
+ LST_INTEGER -> LST_STRING
+ LST_STRING -> LST_STRING
+ LST_VECTOR -> LST_STRING
+ LST_QUATERNION -> LST_STRING
+ LST_LIST -> LST_STRING
+
+ LST_VECTOR -> LST_VECTOR
+
+ LST_QUATERNION -> LST_QUATERNION
+
+ LST_FLOATINGPOINT -> LST_LIST
+ LST_INTEGER -> LST_LIST
+ LST_STRING -> LST_LIST
+ LST_VECTOR -> LST_LIST
+ LST_QUATERNION -> LST_LIST
+ LST_LIST -> LST_LIST
+*/
+
+#endif