diff options
author | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
---|---|---|
committer | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
commit | 420b91db29485df39fd6e724e782c449158811cb (patch) | |
tree | b471a94563af914d3ed3edd3e856d21cb1b69945 /indra/lscript/lscript_compile |
Print done when done.
Diffstat (limited to 'indra/lscript/lscript_compile')
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 |