lscript_tree.cpp

Go to the documentation of this file.
00001 
00032 // TO DO: Move print functionality from .h file to here
00033 
00034 #include "linden_common.h"
00035 
00036 #include "lscript_tree.h"
00037 #include "lscript_typecheck.h"
00038 #include "lscript_resource.h"
00039 #include "lscript_bytecode.h"
00040 #include "lscript_heap.h"
00041 #include "lscript_library.h"
00042 #include "lscript_alloc.h"
00043 
00044 //#define LSL_INCLUDE_DEBUG_INFO
00045 
00046 void print_cil_box(FILE* fp, LSCRIPTType type)
00047 {
00048         switch(type)
00049         {
00050         case LST_INTEGER:
00051                 fprintf(fp, "box [mscorlib]System.Int32\n");
00052                 break;
00053         case LST_FLOATINGPOINT:
00054                 fprintf(fp, "box [mscorlib]System.Double\n");
00055                 break;
00056         case LST_STRING:
00057         case LST_KEY:
00058                 fprintf(fp, "box [mscorlib]System.String\n");
00059                 break;
00060         case LST_VECTOR:
00061                 fprintf(fp, "box [LScriptLibrary]LLVector\n");
00062                 break;
00063         case LST_QUATERNION:
00064                 fprintf(fp, "box [LScriptLibrary]LLQuaternion\n");
00065                 break;
00066         default:
00067                 break;
00068         }
00069 }
00070 
00071 void print_cil_type(FILE* fp, LSCRIPTType type)
00072 {
00073         switch(type)
00074         {
00075         case LST_INTEGER:
00076                 fprintf(fp, "int32");
00077                 break;
00078         case LST_FLOATINGPOINT:
00079                 fprintf(fp, "float32");
00080                 break;
00081         case LST_STRING:
00082         case LST_KEY:
00083                 fprintf(fp, "string");
00084                 break;
00085         case LST_VECTOR:
00086                 fprintf(fp, "valuetype [LScriptLibrary]LLVector");
00087                 break;
00088         case LST_QUATERNION:
00089                 fprintf(fp, "valuetype [LScriptLibrary]LLQuaternion");
00090                 break;
00091         case LST_LIST:
00092                 fprintf(fp, "class [mscorlib]System.Collections.ArrayList");
00093                 break;
00094         case LST_NULL:
00095                 fprintf(fp, "void");
00096                 break;
00097         default:
00098                 break;
00099         }
00100 }
00101 
00102 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)
00103 {
00104         if (gErrorToText.getErrors())
00105         {
00106                 return;
00107         }
00108         switch(pass)
00109         {
00110         case LSCP_PRETTY_PRINT:
00111         case LSCP_EMIT_ASSEMBLY:
00112                 fprintf(fp,"%s",LSCRIPTTypeNames[mType]);
00113                 break;
00114         case LSCP_TYPE:
00115                 type = mType;
00116                 break;
00117         case LSCP_EMIT_CIL_ASSEMBLY:
00118                 print_cil_type(fp, mType);
00119                 break;
00120         default:
00121                 break;
00122         }
00123 }
00124 
00125 S32 LLScriptType::getSize()
00126 {
00127         return LSCRIPTDataSize[mType];
00128 }
00129 
00130 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)
00131 {
00132         if (gErrorToText.getErrors())
00133         {
00134                 return;
00135         }
00136         switch(pass)
00137         {
00138         case LSCP_PRETTY_PRINT:
00139         case LSCP_EMIT_ASSEMBLY:
00140                 fprintf(fp,"Script Constant Base class -- should never get here!\n");
00141                 break;
00142         default:
00143                 break;
00144         }
00145 }
00146 
00147 S32 LLScriptConstant::getSize()
00148 {
00149         printf("Script Constant Base class -- should never get here!\n");
00150         return 0;
00151 }
00152 
00153 
00154 
00155 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)
00156 {
00157         if (gErrorToText.getErrors())
00158         {
00159                 return;
00160         }
00161         switch(pass)
00162         {
00163         case LSCP_PRETTY_PRINT:
00164                 fprintf(fp, "%d", mValue);
00165                 break;
00166         case LSCP_EMIT_ASSEMBLY:
00167                 fprintf(fp, "PUSHARGI %d\n", mValue);
00168                 break;
00169         case LSCP_TYPE:
00170                 type = mType;
00171                 break;
00172         case LSCP_EMIT_BYTE_CODE:
00173                 {
00174                         chunk->addInteger(mValue);
00175                         type = mType;
00176                 }
00177                 break;
00178         case LSCP_TO_STACK:
00179                 {
00180                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
00181                         chunk->addInteger(mValue);
00182                         type = mType;
00183                 }
00184                 break;
00185         case LSCP_LIST_BUILD_SIMPLE:
00186                 {
00187                         *ldata = new LLScriptLibData(mValue);
00188                 }
00189                 break;
00190         case LSCP_EMIT_CIL_ASSEMBLY:
00191                 fprintf(fp, "ldc.i4 %d\n", mValue);
00192                 break;
00193         default:
00194                 break;
00195         }
00196 }
00197 
00198 S32 LLScriptConstantInteger::getSize()
00199 {
00200         return LSCRIPTDataSize[LST_INTEGER];
00201 }
00202 
00203 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)
00204 {
00205         if (gErrorToText.getErrors())
00206         {
00207                 return;
00208         }
00209         switch(pass)
00210         {
00211         case LSCP_PRETTY_PRINT:
00212                 fprintf(fp, "%5.5f", mValue);
00213                 break;
00214         case LSCP_EMIT_ASSEMBLY:
00215                 fprintf(fp, "PUSHARGF %5.5f\n", mValue);
00216                 break;
00217         case LSCP_TYPE:
00218                 type = mType;
00219                 break;
00220         case LSCP_EMIT_BYTE_CODE:
00221                 {
00222                         chunk->addFloat(mValue);
00223                         type = mType;
00224                 }
00225                 break;
00226         case LSCP_TO_STACK:
00227                 {
00228                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
00229                         chunk->addFloat(mValue);
00230                         type = mType;
00231                 }
00232                 break;
00233         case LSCP_LIST_BUILD_SIMPLE:
00234                 {
00235                         *ldata = new LLScriptLibData(mValue);
00236                 }
00237                 break;
00238         case LSCP_EMIT_CIL_ASSEMBLY:
00239                 fprintf(fp, "ldc.r8 %5.5f\n", mValue); // NOTE: Precision?
00240         default:
00241                 break;
00242         }
00243 }
00244 
00245 S32 LLScriptConstantFloat::getSize()
00246 {
00247         return LSCRIPTDataSize[LST_FLOATINGPOINT];
00248 }
00249 
00250 void print_escape_quotes(FILE* fp, const char* str)
00251 {
00252   putc('"', fp);
00253   for(const char* c = str; *c != '\0'; ++c)
00254   {
00255           if(*c == '"')
00256           {
00257                   putc('\\', fp);
00258           }
00259           putc(*c, fp);
00260   }
00261   putc('"', fp);
00262 }
00263 
00264 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)
00265 {
00266         if (gErrorToText.getErrors())
00267         {
00268                 return;
00269         }
00270         switch(pass)
00271         {
00272         case LSCP_PRETTY_PRINT:
00273                 fprintf(fp, "\"%s\"", mValue);
00274                 break;
00275         case LSCP_EMIT_ASSEMBLY:
00276                 fprintf(fp, "PUSHARGS \"%s\"\n", mValue);
00277                 break;
00278         case LSCP_TYPE:
00279                 type = mType;
00280                 break;
00281         case LSCP_EMIT_BYTE_CODE:
00282                 {
00283                         chunk->addInteger(heap->mCurrentOffset + 1);
00284                         LLScriptLibData *data = new LLScriptLibData(mValue);
00285                         U8 *temp;
00286                         S32 size = lsa_create_data_block(&temp, data, heap->mCurrentOffset);
00287 
00288                         heap->addBytes(temp, size);
00289                         delete [] temp;
00290                         delete data;
00291                 }
00292                 break;
00293         case LSCP_TO_STACK:
00294                 {
00295                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGS]);
00296                         chunk->addBytes(mValue, (S32)strlen(mValue) + 1);               /*Flawfinder: ignore*/
00297                         type = mType;
00298                 }
00299                 break;
00300         case LSCP_LIST_BUILD_SIMPLE:
00301                 {
00302                         *ldata = new LLScriptLibData(mValue);
00303                 }
00304                 break;
00305         case LSCP_EMIT_CIL_ASSEMBLY:
00306                 fprintf(fp, "ldstr ");
00307                 print_escape_quotes(fp, mValue);
00308                 fprintf(fp, "\n");
00309         default:
00310                 break;
00311         }
00312 }
00313 
00314 S32 LLScriptConstantString::getSize()
00315 {
00316         return (S32)strlen(mValue) + 1;         /*Flawfinder: ignore*/
00317 }
00318 
00319 
00320 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)
00321 {
00322         if (gErrorToText.getErrors())
00323         {
00324                 return;
00325         }
00326         switch(pass)
00327         {
00328         case LSCP_PRETTY_PRINT:
00329                 fprintf(fp, "%s", mName);
00330                 break;
00331         case LSCP_EMIT_ASSEMBLY:
00332                 if (mScopeEntry)
00333                 {
00334                         if (mScopeEntry->mIDType == LIT_VARIABLE)
00335                         {
00336                                 fprintf(fp, "$BP + %d [%s]", mScopeEntry->mOffset, mName);
00337                         }
00338                         else if (mScopeEntry->mIDType == LIT_GLOBAL)
00339                         {
00340                                 fprintf(fp, "$GVR + %d [%s]", mScopeEntry->mOffset, mName);
00341                         }
00342                         else
00343                         {
00344                                 fprintf(fp, "%s", mName);
00345                         }
00346                 }
00347                 break;
00348         case LSCP_TYPE:
00349                 if (mScopeEntry)
00350                         type = mScopeEntry->mType;
00351                 else
00352                         type = LST_NULL;
00353                 break;
00354         case LSCP_RESOURCE:
00355                 if (mScopeEntry)
00356                 {
00357                         if (mScopeEntry->mIDType == LIT_VARIABLE)
00358                         {
00359 //                              fprintf(fp, "LOCAL : %d : %d : %s\n", mScopeEntry->mOffset, mScopeEntry->mSize, mName);
00360                         }
00361                         else if (mScopeEntry->mIDType == LIT_GLOBAL)
00362                         {
00363 //                              fprintf(fp, "GLOBAL: %d : %d : %s\n", mScopeEntry->mOffset, mScopeEntry->mSize, mName);
00364                         }
00365                 }
00366                 break;
00367         case LSCP_LIST_BUILD_SIMPLE:
00368                 {
00369                         if (mScopeEntry)
00370                         {
00371                                 if (mScopeEntry->mType == LST_LIST)
00372                                 {
00373                                         gErrorToText.writeError(fp, this, LSERROR_NO_LISTS_IN_LISTS);
00374                                 }
00375                                 else if (mScopeEntry->mAssignable)
00376                                 {
00377                                         mScopeEntry->mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
00378                                 }
00379                                 else
00380                                 {
00381                                         gErrorToText.writeError(fp, this, LSERROR_NO_UNITIALIZED_VARIABLES_IN_LISTS);
00382                                 }
00383                         }
00384                         else
00385                         {
00386                                 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
00387                         }
00388                 }
00389                 break;
00390         case LSCP_EMIT_CIL_ASSEMBLY:
00391                 fprintf(fp, "%s", mName);
00392                 break;
00393         default:
00394                 break;
00395         }
00396 }
00397 
00398 S32 LLScriptIdentifier::getSize()
00399 {
00400         
00401         return 0;
00402 }
00403 
00404 
00405 
00406 void LLScriptSimpleAssignable::addAssignable(LLScriptSimpleAssignable *assign)
00407 {
00408         if (mNextp)
00409         {
00410                 assign->mNextp = mNextp;
00411         }
00412         mNextp = assign;
00413 }
00414 
00415 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)
00416 {
00417         if (gErrorToText.getErrors())
00418         {
00419                 return;
00420         }
00421         fprintf(fp, "Simple Assignable Base Class -- should never get here!\n");
00422 }
00423 
00424 S32 LLScriptSimpleAssignable::getSize()
00425 {
00426         
00427         printf("Simple Assignable Base Class -- should never get here!\n");
00428         return 0;
00429 }
00430 
00431 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)
00432 {
00433         if (gErrorToText.getErrors())
00434         {
00435                 return;
00436         }
00437         switch(pass)
00438         {
00439         case LSCP_PRETTY_PRINT:
00440         case LSCP_EMIT_ASSEMBLY:
00441                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00442                 if (mNextp)
00443                 {
00444                         fprintf(fp, ", ");
00445                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00446                 }
00447                 break;
00448         case LSCP_SCOPE_PASS1:
00449                 { 
00450                         LLScriptScopeEntry *entry = scope->findEntry(mIdentifier->mName);
00451                         if (!entry)
00452                         {
00453                                 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
00454                         }
00455                         else
00456                         {
00457                                 // if we did find it, make sure this identifier is associated with the correct scope entry
00458                                 mIdentifier->mScopeEntry = entry;
00459                         }
00460                         if (mNextp)
00461                         {
00462                                 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00463                         }
00464                 }
00465                 break;
00466         case LSCP_EMIT_BYTE_CODE:
00467                 {
00468                         if (mIdentifier->mScopeEntry)
00469                         {
00470                                 if(mIdentifier->mScopeEntry->mAssignable)
00471                                 {
00472                                         mIdentifier->mScopeEntry->mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00473                                 }
00474                                 else
00475                                 {
00476                                         // Babbage: 29/8/06: If the scope entry has no mAssignable,
00477                                         // set the default type and add the default 0 value to the 
00478                                         // chunk. Without this SAVectors and SAQuaternions will 
00479                                         // assume the arbitrary current type is the assignable type 
00480                                         // and may attempt to access a null chunk. (SL-20156)
00481                                         type = mIdentifier->mScopeEntry->mType;
00482                                         chunk->addBytes(LSCRIPTDataSize[type]);
00483                                 }
00484                         }
00485                         if (mNextp)
00486                         {
00487                                 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00488                         }
00489                 }
00490                 break;
00491         case LSCP_LIST_BUILD_SIMPLE:
00492                 {
00493                         mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
00494                         if (mNextp)
00495                         {
00496                                 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
00497                         }
00498                 }
00499                 break;
00500         default:
00501                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00502                 if (mNextp)
00503                 {
00504                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00505                 }
00506                 break;
00507         }
00508 }
00509 
00510 S32 LLScriptSAIdentifier::getSize()
00511 {
00512         return mIdentifier->getSize();
00513 }
00514 
00515 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)
00516 {
00517         if (gErrorToText.getErrors())
00518         {
00519                 return;
00520         }
00521         switch(pass)
00522         {
00523         case LSCP_PRETTY_PRINT:
00524         case LSCP_EMIT_ASSEMBLY:
00525                 mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00526                 if (mNextp)
00527                 {
00528                         fprintf(fp, ", ");
00529                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00530                 }
00531                 break;
00532         case LSCP_LIST_BUILD_SIMPLE:
00533                 {
00534                         mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
00535                         if (mNextp)
00536                         {
00537                                 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
00538                         }
00539                 }
00540                 break;
00541         default:
00542                 mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00543                 if (mNextp)
00544                 {
00545                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00546                 }
00547                 break;
00548         }
00549 }
00550 
00551 S32 LLScriptSAConstant::getSize()
00552 {
00553         return mConstant->getSize();
00554 }
00555 
00556 void print_cil_cast(FILE* fp, LSCRIPTType srcType, LSCRIPTType targetType)
00557 {
00558         switch(srcType)
00559         {
00560         case LST_INTEGER:
00561                 switch(targetType)
00562                 {
00563                 case LST_FLOATINGPOINT:
00564                         fprintf(fp, "conv.r8\n");
00565                         break;
00566                 case LST_STRING:
00567                         fprintf(fp, "call string class [mscorlib]System.Convert::ToString(int32)\n");
00568                         break;
00569                 case LST_LIST:
00570                         fprintf(fp, "box [mscorlib]System.Int32\n");
00571                         fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::CreateList()\n");
00572                         fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::AddReturnList(object, class [mscorlib]System.Collections.ArrayList)\n");
00573                         break;
00574                 default:
00575                         break;
00576                 }
00577                 break;
00578         case LST_FLOATINGPOINT:
00579                 switch(targetType)
00580                 {
00581                 case LST_INTEGER:
00582                         fprintf(fp, "conv.i4\n");
00583                         break;
00584                 case LST_STRING:
00585                         fprintf(fp, "call string class [mscorlib]System.Convert::ToString(float32)\n");
00586                         break;
00587                 case LST_LIST:
00588                         fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
00589                         break;
00590                 default:
00591                         break;
00592                 }
00593                 break;
00594         case LST_STRING:
00595                 switch(targetType)
00596                 {
00597                 case LST_INTEGER:
00598                         fprintf(fp, "call int32 valuetype [mscorlib]System.Int32::Parse(string)\n");
00599                         break;
00600                 case LST_FLOATINGPOINT:
00601                         fprintf(fp, "call float64 valuetype [mscorlib]System.Double::Parse(string)\n");
00602                         break;
00603                 case LST_LIST:
00604                         fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
00605                         break;
00606                 case LST_VECTOR:
00607                         fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'Parse'(string)\n");
00608                         break;
00609                 case LST_QUATERNION:
00610                         fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'Parse'(string)\n");
00611                         break;
00612                 default:
00613                         break;
00614                 }
00615                 break;
00616         case LST_KEY:
00617                 switch(targetType)
00618                 {
00619                 case LST_KEY:
00620                         break;
00621                 case LST_STRING:
00622                         break;
00623                 case LST_LIST:
00624                         fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
00625                         break;
00626                 default:
00627                         break;
00628                 }
00629                 break;
00630         case LST_VECTOR:
00631                 switch(targetType)
00632                 {
00633                 case LST_VECTOR:
00634                         break;
00635                 case LST_STRING:
00636                         fprintf(fp, "call string valuetype [LScriptLibrary]LLVector::'ToString'(valuetype [LScriptLibrary]LLVector)\n");
00637                         break;
00638                 case LST_LIST:
00639                         fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
00640                         break;
00641                 default:
00642                         break;
00643                 }
00644                 break;
00645         case LST_QUATERNION:
00646                 switch(targetType)
00647                 {
00648                 case LST_QUATERNION:
00649                         break;
00650                 case LST_STRING:
00651                         fprintf(fp, "call string valuetype [LScriptLibrary]LLQuaternion::'ToString'(valuetype [LScriptLibrary]LLQuaternion)\n");
00652                         break;
00653                 case LST_LIST:
00654                         fprintf(fp, "call class [mscorlib]System.Collections.ArrayList [LScriptLibrary]LScriptInternal::CreateList(object)\n");
00655                         break;
00656                 default:
00657                         break;
00658                 }
00659                 break;
00660         case LST_LIST:
00661                 switch(targetType)
00662                 {
00663                 case LST_LIST:
00664                         break;
00665                 case LST_STRING:
00666                         fprintf(fp, "call string [LScriptLibrary]LScriptInternal::ListToString(class [mscorlib]System.Collections.ArrayList)\n");
00667                         break;
00668                 default:
00669                         break;
00670                 }
00671                 break;
00672         default:
00673                 break;
00674         }
00675 }
00676 
00677 bool is_SA_constant_integer(LLScriptSimpleAssignable* sa)
00678 {
00679         // HACK: Downcast based on type.
00680         return (sa->mType == LSSAT_CONSTANT && ((LLScriptSAConstant*) sa)->mConstant->mType == LST_INTEGER);
00681 }
00682 
00683 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)
00684 {
00685         if (gErrorToText.getErrors())
00686         {
00687                 return;
00688         }
00689         switch(pass)
00690         {
00691         case LSCP_PRETTY_PRINT:
00692         case LSCP_EMIT_ASSEMBLY:
00693                 fprintf(fp, "< ");
00694                 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00695                 fprintf(fp, ", ");
00696                 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00697                 fprintf(fp, ", ");
00698                 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00699                 fprintf(fp, " >");
00700                 if (mNextp)
00701                 {
00702                         fprintf(fp, ", ");
00703                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00704                 }
00705                 break;
00706         case LSCP_TYPE:
00707                 // vector's take floats
00708                 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00709                 if (!legal_assignment(LST_FLOATINGPOINT, type))
00710                 {
00711                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
00712                 }
00713                 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00714                 if (!legal_assignment(LST_FLOATINGPOINT, type))
00715                 {
00716                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
00717                 }
00718                 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00719                 if (!legal_assignment(LST_FLOATINGPOINT, type))
00720                 {
00721                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
00722                 }
00723                 type = LST_VECTOR;
00724                 if (mNextp)
00725                 {
00726                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00727                 }
00728                 break;
00729         case LSCP_EMIT_BYTE_CODE:
00730                 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00731                 if (type == LST_INTEGER)
00732                 {
00733                         S32 offset = chunk->mCurrentOffset - 4;
00734                         bytestream_int2float(chunk->mCodeChunk, offset);
00735                 }
00736                 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00737                 if (type == LST_INTEGER)
00738                 {
00739                         S32 offset = chunk->mCurrentOffset - 4;
00740                         bytestream_int2float(chunk->mCodeChunk, offset);
00741                 }
00742                 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00743                 if (type == LST_INTEGER)
00744                 {
00745                         S32 offset = chunk->mCurrentOffset - 4;
00746                         bytestream_int2float(chunk->mCodeChunk, offset);
00747                 }
00748                 if (mNextp)
00749                 {
00750                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00751                 }
00752                 break;
00753         case LSCP_LIST_BUILD_SIMPLE:
00754                 {
00755                         LLScriptByteCodeChunk   *list = new LLScriptByteCodeChunk(FALSE);
00756                         mEntry3->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
00757                         if (type == LST_INTEGER)
00758                         {
00759                                 S32 offset = list->mCurrentOffset - 4;
00760                                 bytestream_int2float(list->mCodeChunk, offset);
00761                         }
00762                         mEntry2->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
00763                         if (type == LST_INTEGER)
00764                         {
00765                                 S32 offset = list->mCurrentOffset - 4;
00766                                 bytestream_int2float(list->mCodeChunk, offset);
00767                         }
00768                         mEntry1->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
00769                         if (type == LST_INTEGER)
00770                         {
00771                                 S32 offset = list->mCurrentOffset - 4;
00772                                 bytestream_int2float(list->mCodeChunk, offset);
00773                         }
00774                         LLVector3 vec;
00775                         S32 offset = 0;
00776                         bytestream2vector(vec, list->mCodeChunk, offset);
00777                         *ldata = new LLScriptLibData(vec);
00778                         delete list;
00779                         if (mNextp)
00780                         {
00781                                 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
00782                         }
00783                 }
00784                 break;
00785         case LSCP_EMIT_CIL_ASSEMBLY:
00786 
00787                 // Load arguments.
00788                 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00789                 if(is_SA_constant_integer(mEntry1))
00790                 {
00791                         print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
00792                 }
00793                 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00794                 if(is_SA_constant_integer(mEntry3))
00795                 {
00796                         print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
00797                 }
00798                 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00799                 if(is_SA_constant_integer(mEntry3))
00800                 {
00801                         print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
00802                 }
00803                 
00804                 // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
00805                 fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'create'(float32, float32, float32)\n");
00806 
00807                 // Next.
00808                 if (mNextp)
00809                 {
00810                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00811                 }
00812                 break;
00813         default:
00814                 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00815                 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00816                 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00817                 if (mNextp)
00818                 {
00819                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00820                 }
00821                 break;
00822         }
00823 }
00824 
00825 S32 LLScriptSAVector::getSize()
00826 {
00827         return mEntry1->getSize() + mEntry2->getSize() + mEntry3->getSize();
00828 }
00829 
00830 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)
00831 {
00832         if (gErrorToText.getErrors())
00833         {
00834                 return;
00835         }
00836         switch(pass)
00837         {
00838         case LSCP_PRETTY_PRINT:
00839         case LSCP_EMIT_ASSEMBLY:
00840                 fprintf(fp, "< ");
00841                 mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00842                 fprintf(fp, ", ");
00843                 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00844                 fprintf(fp, ", ");
00845                 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00846                 fprintf(fp, ", ");
00847                 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00848                 fprintf(fp, " >");
00849                 if (mNextp)
00850                 {
00851                         fprintf(fp, ", ");
00852                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00853                 }
00854                 break;
00855         case LSCP_TYPE:
00856                 // vector's take floats
00857                 mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00858                 if (!legal_assignment(LST_FLOATINGPOINT, type))
00859                 {
00860                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
00861                 }
00862                 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00863                 if (!legal_assignment(LST_FLOATINGPOINT, type))
00864                 {
00865                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
00866                 }
00867                 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00868                 if (!legal_assignment(LST_FLOATINGPOINT, type))
00869                 {
00870                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
00871                 }
00872                 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00873                 if (!legal_assignment(LST_FLOATINGPOINT, type))
00874                 {
00875                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
00876                 }
00877                 type = LST_QUATERNION;
00878                 if (mNextp)
00879                 {
00880                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00881                 }
00882                 break;
00883         case LSCP_EMIT_BYTE_CODE:
00884                 mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00885                 if (type == LST_INTEGER)
00886                 {
00887                         S32 offset = chunk->mCurrentOffset - 4;
00888                         bytestream_int2float(chunk->mCodeChunk, offset);
00889                 }
00890                 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00891                 if (type == LST_INTEGER)
00892                 {
00893                         S32 offset = chunk->mCurrentOffset - 4;
00894                         bytestream_int2float(chunk->mCodeChunk, offset);
00895                 }
00896                 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00897                 if (type == LST_INTEGER)
00898                 {
00899                         S32 offset = chunk->mCurrentOffset - 4;
00900                         bytestream_int2float(chunk->mCodeChunk, offset);
00901                 }
00902                 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00903                 if (type == LST_INTEGER)
00904                 {
00905                         S32 offset = chunk->mCurrentOffset - 4;
00906                         bytestream_int2float(chunk->mCodeChunk, offset);
00907                 }
00908                 if (mNextp)
00909                 {
00910                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00911                 }
00912                 break;
00913         case LSCP_LIST_BUILD_SIMPLE:
00914                 {
00915                         LLScriptByteCodeChunk   *list = new LLScriptByteCodeChunk(FALSE);
00916                         mEntry4->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
00917                         if (type == LST_INTEGER)
00918                         {
00919                                 S32 offset = list->mCurrentOffset - 4;
00920                                 bytestream_int2float(list->mCodeChunk, offset);
00921                         }
00922                         mEntry3->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
00923                         if (type == LST_INTEGER)
00924                         {
00925                                 S32 offset = list->mCurrentOffset - 4;
00926                                 bytestream_int2float(list->mCodeChunk, offset);
00927                         }
00928                         mEntry2->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
00929                         if (type == LST_INTEGER)
00930                         {
00931                                 S32 offset = list->mCurrentOffset - 4;
00932                                 bytestream_int2float(list->mCodeChunk, offset);
00933                         }
00934                         mEntry1->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, list, heap, stacksize, entry, entrycount, NULL);
00935                         if (type == LST_INTEGER)
00936                         {
00937                                 S32 offset = list->mCurrentOffset - 4;
00938                                 bytestream_int2float(list->mCodeChunk, offset);
00939                         }
00940                         LLQuaternion quat;
00941                         S32 offset = 0;
00942                         bytestream2quaternion(quat, list->mCodeChunk, offset);
00943                         *ldata = new LLScriptLibData(quat);
00944                         delete list;
00945                         if (mNextp)
00946                         {
00947                                 mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, &(*ldata)->mListp);
00948                         }
00949                 }
00950                 break;
00951         case LSCP_EMIT_CIL_ASSEMBLY:
00952 
00953                 // Load arguments.
00954                 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00955                 if(is_SA_constant_integer(mEntry1))
00956                 {
00957                         print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
00958                 }
00959                 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00960                 if(is_SA_constant_integer(mEntry2))
00961                 {
00962                         print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
00963                 }
00964                 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00965                 if(is_SA_constant_integer(mEntry3))
00966                 {
00967                         print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
00968                 }
00969                 mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00970                 if(is_SA_constant_integer(mEntry4))
00971                 {
00972                         print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
00973                 }
00974                 
00975                 // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
00976                 fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'create'(float32, float32, float32, float32)\n");
00977 
00978                 // Next.
00979                 if (mNextp)
00980                 {
00981                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00982                 }
00983                 break;
00984         default:
00985                 mEntry4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00986                 mEntry3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00987                 mEntry2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00988                 mEntry1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00989                 if (mNextp)
00990                 {
00991                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
00992                 }
00993                 break;
00994         }
00995 }
00996 
00997 S32 LLScriptSAQuaternion::getSize()
00998 {
00999         return mEntry1->getSize() + mEntry2->getSize() + mEntry3->getSize() + mEntry4->getSize();
01000 }
01001 
01002 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)
01003 {
01004         if (gErrorToText.getErrors())
01005         {
01006                 return;
01007         }
01008         switch(pass)
01009         {
01010         case LSCP_PRETTY_PRINT:
01011         case LSCP_EMIT_ASSEMBLY:
01012                 fprintf(fp, "[ ");
01013                 if (mEntryList)
01014                         mEntryList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01015                 fprintf(fp, " ]");
01016                 if (mNextp)
01017                 {
01018                         fprintf(fp, ", ");
01019                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01020                 }
01021                 break;
01022         case LSCP_TYPE:
01023                 if (mEntryList)
01024                         mEntryList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01025                 type = LST_LIST;
01026                 if (mNextp)
01027                 {
01028                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01029                 }
01030                 break;
01031         case LSCP_EMIT_BYTE_CODE:
01032                 {
01033                         LLScriptLibData *list_data = new LLScriptLibData;
01034 
01035                         list_data->mType = LST_LIST;
01036                         if (mEntryList)
01037                                 mEntryList->recurse(fp, tabs, tabsize, LSCP_LIST_BUILD_SIMPLE, ptype, prunearg, scope, type, basetype, count, chunk, NULL, stacksize, entry, entrycount, &(list_data->mListp));
01038 
01039                         U8 *temp;
01040                         chunk->addInteger(heap->mCurrentOffset + 1);
01041                         S32 size = lsa_create_data_block(&temp, list_data, heap->mCurrentOffset);
01042                         heap->addBytes(temp, size);
01043                         delete list_data;
01044                         delete [] temp;
01045 
01046                         if (mNextp)
01047                         {
01048                                 mNextp->recurse(fp, tabs, tabsize, LSCP_EMIT_BYTE_CODE, ptype, prunearg, scope, type, basetype, count, chunk, NULL, stacksize, entry, entrycount, NULL);
01049                         }
01050                 }
01051                 break;
01052         default:
01053                 if (mEntryList)
01054                         mEntryList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
01055                 if (mNextp)
01056                 {
01057                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, ldata);
01058                 }
01059                 break;
01060         }
01061 }
01062 
01063 S32 LLScriptSAList::getSize()
01064 {
01065         return mEntryList->getSize();
01066 }
01067 
01068 void LLScriptGlobalVariable::addGlobal(LLScriptGlobalVariable *global)
01069 {
01070         if (mNextp)
01071         {
01072                 global->mNextp = mNextp;
01073         }
01074         mNextp = global;
01075 }
01076 
01077 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)
01078 {
01079         switch(pass)
01080         {
01081         case LSCP_PRETTY_PRINT:
01082                 if (mNextp)
01083                 {
01084                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01085                 }
01086                 break;
01087         default:
01088                 if (mNextp)
01089                 {
01090                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01091                 }
01092                 break;
01093         }
01094 }
01095 
01096 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)
01097 {
01098         if (gErrorToText.getErrors())
01099         {
01100                 return;
01101         }
01102         switch(pass)
01103         {
01104         case LSCP_PRETTY_PRINT:
01105                 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01106                 fprintf(fp,"\t");
01107                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01108                 if (mAssignable)
01109                 {
01110                         fprintf(fp, " = ");
01111                         mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01112                 }
01113                 fprintf(fp, ";\n");
01114                 break;
01115         case LSCP_EMIT_ASSEMBLY:
01116                 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01117                 fprintf(fp,"\t");
01118                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01119                 if (mAssignable)
01120                 {
01121                         fprintf(fp, " = ");
01122                         mAssignable->recurse(fp, tabs, tabsize, LSCP_PRETTY_PRINT, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01123                         fprintf(fp, "\n");
01124                         fprintf(fp, "Offset: %d Type: %d\n", mIdentifier->mScopeEntry->mOffset, (S32)LSCRIPTTypeByte[mType->mType]);
01125                 }
01126                 else
01127                 {
01128                         fprintf(fp, "\n");
01129                         fprintf(fp, "Offset: %d Type: %d\n", mIdentifier->mScopeEntry->mOffset, (S32)LSCRIPTTypeByte[mType->mType]);
01130                 }
01131                 break;
01132         case LSCP_SCOPE_PASS1:
01133                 if (scope->checkEntry(mIdentifier->mName))
01134                 {
01135                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
01136                 }
01137                 else
01138                 {
01139                         if (mAssignable)
01140                         {
01141                                 mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01142                         }                       
01143                         // this needs to go after expression decent to make sure that we don't add ourselves or something silly
01144                         mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_GLOBAL, mType->mType);
01145                         if (mIdentifier->mScopeEntry && mAssignable)
01146                                         mIdentifier->mScopeEntry->mAssignable = mAssignable;
01147                 }
01148                 break;
01149         case LSCP_TYPE:
01150                 // if the variable has an assignable, it must assignable to the variable's type
01151                 if (mAssignable)
01152                 {
01153                         mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01154                         mAssignableType = type;
01155                         if (!legal_assignment(mType->mType, mAssignableType))
01156                         {
01157                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
01158                         }
01159                 }
01160                 break;
01161         case LSCP_RESOURCE:
01162                 {
01163                         // we're just tryng to determine how much space the variable needs
01164                         // it also includes the name of the variable as well as the type
01165                         // plus 4 bytes of offset from it's apparent address to the actual data
01166 #ifdef LSL_INCLUDE_DEBUG_INFO
01167                         count += strlen(mIdentifier->mName) + 1 + 1 + 4;        /*Flawfinder: ignore*/
01168 #else
01169                         count += 1 + 1 + 4;
01170 #endif
01171                         mIdentifier->mScopeEntry->mOffset = (S32)count;
01172                         mIdentifier->mScopeEntry->mSize = mType->getSize();
01173                         count += mIdentifier->mScopeEntry->mSize;
01174                         mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01175                 }
01176                 break;
01177         case LSCP_EMIT_BYTE_CODE:
01178                 {
01179                         // order for global variables
01180                         // 0 - 4: offset to actual data
01181                         S32 offsetoffset = chunk->mCurrentOffset;
01182                         S32 offsetdelta = 0;
01183                         chunk->addBytes(4);
01184                         // type
01185                         char vtype;
01186                         vtype = LSCRIPTTypeByte[mType->mType]; 
01187                         chunk->addBytes(&vtype, 1);
01188                         // null terminated name
01189 #ifdef LSL_INCLUDE_DEBUG_INFO
01190                         chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);    /*Flawfinder: ignore*/
01191 #else
01192                         chunk->addBytes(1);
01193 #endif
01194                         // put correct offset delta in
01195                         offsetdelta = chunk->mCurrentOffset - offsetoffset;
01196                         integer2bytestream(chunk->mCodeChunk, offsetoffset, offsetdelta);
01197 
01198                         // now we need space for the variable itself
01199                         LLScriptByteCodeChunk   *value = new LLScriptByteCodeChunk(FALSE);
01200                         if (mAssignable)
01201                         {
01202                                 mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, value, heap, stacksize, entry, entrycount, NULL);
01203                                 // need to put sneaky type conversion here
01204                                 if (mAssignableType != mType->mType)
01205                                 {
01206                                         // the only legal case that is a problem is int->float
01207                                         if (mType->mType == LST_FLOATINGPOINT && mAssignableType == LST_INTEGER)
01208                                         {
01209                                                 S32 offset = value->mCurrentOffset - 4;
01210                                                 bytestream_int2float(value->mCodeChunk, offset);
01211                                         }
01212                                 }
01213                         }
01214                         else
01215                         {
01216                                 if (  (mType->mType == LST_STRING)
01217                                         ||(mType->mType == LST_KEY))
01218                                 {
01219                                         // string and keys (even empty ones) need heap entries
01220                                         chunk->addInteger(heap->mCurrentOffset + 1);
01221                                         LLScriptLibData *data = new LLScriptLibData("");
01222                                         U8 *temp;
01223                                         S32 size = lsa_create_data_block(&temp, data, heap->mCurrentOffset);
01224 
01225                                         heap->addBytes(temp, size);
01226                                         delete [] temp;
01227                                         delete data;
01228                                 }
01229                                 else if (mType->mType == LST_LIST)
01230                                 {
01231                                         chunk->addInteger(heap->mCurrentOffset + 1);
01232                                         LLScriptLibData *data = new LLScriptLibData;
01233                                         data->mType = LST_LIST;
01234                                         U8 *temp;
01235                                         S32 size = lsa_create_data_block(&temp, data, heap->mCurrentOffset);
01236 
01237                                         heap->addBytes(temp, size);
01238                                         delete [] temp;
01239                                         delete data;
01240                                 }
01241                                 else if (mType->mType == LST_QUATERNION)
01242                                 {
01243                                         chunk->addFloat(1.f);
01244                                         chunk->addFloat(0.f);
01245                                         chunk->addFloat(0.f);
01246                                         chunk->addFloat(0.f);
01247                                 }
01248                                 else
01249                                 {
01250                                         value->addBytes(LSCRIPTDataSize[mType->mType]);
01251                                 }
01252                         }
01253                         chunk->addBytes(value->mCodeChunk, value->mCurrentOffset);
01254                         delete value;
01255                 }
01256                 break;
01257         case LSCP_EMIT_CIL_ASSEMBLY:
01258 
01259                 // Initialisation inside ctor.
01260                 if (mAssignable)
01261                 {
01262                         fprintf(fp, "ldarg.0\n");
01263                         mAssignable->recurse(fp, tabs, tabsize, LSCP_EMIT_CIL_ASSEMBLY, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01264                         fprintf(fp, "stfld ");
01265                         mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01266                         fprintf(fp," LSL::");
01267                         mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01268                         fprintf(fp, "\n");
01269                 }
01270                 break;
01271         default:
01272                 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01273                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01274                 if (mAssignable)
01275                 {
01276                         mAssignable->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01277                 }
01278                 break;
01279         }
01280         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01281 }
01282 
01283 S32 LLScriptGlobalVariable::getSize()
01284 {
01285         S32 return_size;
01286 
01287         return_size = mType->getSize();
01288         return return_size;
01289 }
01290 
01291 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)
01292 {
01293         fprintf(fp, "Event Base Class -- should never get here!\n");
01294 }
01295 
01296 S32 LLScriptEvent::getSize()
01297 {
01298         printf("Event Base Class -- should never get here!\n");
01299         return 0;
01300 }
01301 
01302 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)
01303 {
01304         if (gErrorToText.getErrors())
01305         {
01306                 return;
01307         }
01308         switch(pass)
01309         {
01310         case LSCP_PRETTY_PRINT:
01311                 fdotabs(fp, tabs, tabsize);
01312                 fprintf(fp, "state_entry()\n");
01313                 break;
01314         case LSCP_EMIT_ASSEMBLY:
01315                 fprintf(fp, "state_entry()\n");
01316                 break;
01317         case LSCP_EMIT_BYTE_CODE:
01318                 {
01319 #ifdef LSL_INCLUDE_DEBUG_INFO
01320                         char name[] = "state_entry";
01321                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
01322 #endif
01323                 }
01324                 break;
01325         case LSCP_EMIT_CIL_ASSEMBLY:
01326                 fprintf(fp, "state_entry()");
01327                 break;
01328         default:
01329                 break;
01330         }
01331 }
01332 
01333 S32 LLScriptStateEntryEvent::getSize()
01334 {
01335         return 0;
01336 }
01337 
01338 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)
01339 {
01340         if (gErrorToText.getErrors())
01341         {
01342                 return;
01343         }
01344         switch(pass)
01345         {
01346         case LSCP_PRETTY_PRINT:
01347                 fdotabs(fp, tabs, tabsize);
01348                 fprintf(fp, "state_exit()\n");
01349                 break;
01350         case LSCP_EMIT_ASSEMBLY:
01351                 fprintf(fp, "state_exit()\n");
01352                 break;
01353         case LSCP_EMIT_BYTE_CODE:
01354                 {
01355 #ifdef LSL_INCLUDE_DEBUG_INFO
01356                         char name[] = "state_exit";
01357                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
01358 #endif
01359                 }
01360                 break;
01361         case LSCP_EMIT_CIL_ASSEMBLY:
01362                 fprintf(fp, "state_exit()");
01363                 break;
01364         default:
01365                 break;
01366         }
01367 }
01368 
01369 S32 LLScriptStateExitEvent::getSize()
01370 {
01371         return 0;
01372 }
01373 
01374 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)
01375 {
01376         if (gErrorToText.getErrors())
01377         {
01378                 return;
01379         }
01380         switch(pass)
01381         {
01382         case LSCP_PRETTY_PRINT:
01383         case LSCP_EMIT_ASSEMBLY:
01384                 fdotabs(fp, tabs, tabsize);
01385                 fprintf(fp, "touch_start( integer ");
01386                 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01387                 fprintf(fp, " )\n");
01388                 break;
01389                 break;
01390         case LSCP_SCOPE_PASS1:
01391                 if (scope->checkEntry(mCount->mName))
01392                 {
01393                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
01394                 }
01395                 else
01396                 {
01397                         mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
01398                 }
01399                 break;
01400         case LSCP_RESOURCE:
01401                 {
01402                         // we're just tryng to determine how much space the variable needs
01403                         if (mCount->mScopeEntry)
01404                         {
01405                                 mCount->mScopeEntry->mOffset = (S32)count;
01406                                 mCount->mScopeEntry->mSize = 4;
01407                                 count += mCount->mScopeEntry->mSize;
01408                         }
01409                 }
01410                 break;
01411         case LSCP_EMIT_BYTE_CODE:
01412                 {
01413 #ifdef LSL_INCLUDE_DEBUG_INFO
01414                         char name[] = "touch_start";
01415                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
01416                         chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);              /*Flawfinder: ignore*/
01417 #endif
01418                 }
01419                 break;
01420         default:
01421                 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01422                 break;
01423         }
01424 }
01425 
01426 S32 LLScriptTouchStartEvent::getSize()
01427 {
01428         // integer = 4
01429         return 4;
01430 }
01431 
01432 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)
01433 {
01434         if (gErrorToText.getErrors())
01435         {
01436                 return;
01437         }
01438         switch(pass)
01439         {
01440         case LSCP_PRETTY_PRINT:
01441         case LSCP_EMIT_ASSEMBLY:
01442                 fdotabs(fp, tabs, tabsize);
01443                 fprintf(fp, "touch( integer ");
01444                 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01445                 fprintf(fp, " )\n");
01446                 break;
01447                 break;
01448         case LSCP_SCOPE_PASS1:
01449                 if (scope->checkEntry(mCount->mName))
01450                 {
01451                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
01452                 }
01453                 else
01454                 {
01455                         mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
01456                 }
01457                 break;
01458         case LSCP_RESOURCE:
01459                 {
01460                         // we're just tryng to determine how much space the variable needs
01461                         if (mCount->mScopeEntry)
01462                         {
01463                                 mCount->mScopeEntry->mOffset = (S32)count;
01464                                 mCount->mScopeEntry->mSize = 4;
01465                                 count += mCount->mScopeEntry->mSize;
01466                         }
01467                 }
01468                 break;
01469         case LSCP_EMIT_BYTE_CODE:
01470                 {
01471 #ifdef LSL_INCLUDE_DEBUG_INFO
01472                         char name[] = "touch";
01473                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
01474                         chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);              /*Flawfinder: ignore*/
01475 #endif
01476                 }
01477                 break;
01478         default:
01479                 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01480                 break;
01481         }
01482 }
01483 
01484 S32 LLScriptTouchEvent::getSize()
01485 {
01486         // integer = 4
01487         return 4;
01488 }
01489 
01490 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)
01491 {
01492         if (gErrorToText.getErrors())
01493         {
01494                 return;
01495         }
01496         switch(pass)
01497         {
01498         case LSCP_PRETTY_PRINT:
01499         case LSCP_EMIT_ASSEMBLY:
01500                 fdotabs(fp, tabs, tabsize);
01501                 fprintf(fp, "touch_end( integer ");
01502                 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01503                 fprintf(fp, " )\n");
01504                 break;
01505                 break;
01506         case LSCP_SCOPE_PASS1:
01507                 if (scope->checkEntry(mCount->mName))
01508                 {
01509                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
01510                 }
01511                 else
01512                 {
01513                         mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
01514                 }
01515                 break;
01516         case LSCP_RESOURCE:
01517                 {
01518                         // we're just tryng to determine how much space the variable needs
01519                         if (mCount->mScopeEntry)
01520                         {
01521                                 mCount->mScopeEntry->mOffset = (S32)count;
01522                                 mCount->mScopeEntry->mSize = 4;
01523                                 count += mCount->mScopeEntry->mSize;
01524                         }
01525                 }
01526                 break;
01527         case LSCP_EMIT_BYTE_CODE:
01528                 {
01529 #ifdef LSL_INCLUDE_DEBUG_INFO
01530                         char name[] = "touch_end";
01531                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
01532                         chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);              /*Flawfinder: ignore*/
01533 #endif
01534                 }
01535                 break;
01536         default:
01537                 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01538                 break;
01539         }
01540 }
01541 
01542 S32 LLScriptTouchEndEvent::getSize()
01543 {
01544         // integer = 4
01545         return 4;
01546 }
01547 
01548 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)
01549 {
01550         if (gErrorToText.getErrors())
01551         {
01552                 return;
01553         }
01554         switch(pass)
01555         {
01556         case LSCP_PRETTY_PRINT:
01557         case LSCP_EMIT_ASSEMBLY:
01558                 fdotabs(fp, tabs, tabsize);
01559                 fprintf(fp, "collision_start( integer ");
01560                 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01561                 fprintf(fp, " )\n");
01562                 break;
01563                 break;
01564         case LSCP_SCOPE_PASS1:
01565                 if (scope->checkEntry(mCount->mName))
01566                 {
01567                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
01568                 }
01569                 else
01570                 {
01571                         mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
01572                 }
01573                 break;
01574         case LSCP_RESOURCE:
01575                 {
01576                         // we're just tryng to determine how much space the variable needs
01577                         if (mCount->mScopeEntry)
01578                         {
01579                                 mCount->mScopeEntry->mOffset = (S32)count;
01580                                 mCount->mScopeEntry->mSize = 4;
01581                                 count += mCount->mScopeEntry->mSize;
01582                         }
01583                 }
01584                 break;
01585         case LSCP_EMIT_BYTE_CODE:
01586                 {
01587 #ifdef LSL_INCLUDE_DEBUG_INFO
01588                         char name[] = "collision_start";
01589                         chunk->addBytes(name, (S32)strlen(name) + 1);           /*Flawfinder: ignore*/
01590                         chunk->addBytes(mCount->mName, (S32)strlen(mCount->mName) + 1);         /*Flawfinder: ignore*/
01591 #endif
01592                 }
01593                 break;
01594         default:
01595                 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01596                 break;
01597         }
01598 }
01599 
01600 S32 LLScriptCollisionStartEvent::getSize()
01601 {
01602         // integer = 4
01603         return 4;
01604 }
01605 
01606 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)
01607 {
01608         if (gErrorToText.getErrors())
01609         {
01610                 return;
01611         }
01612         switch(pass)
01613         {
01614         case LSCP_PRETTY_PRINT:
01615         case LSCP_EMIT_ASSEMBLY:
01616                 fdotabs(fp, tabs, tabsize);
01617                 fprintf(fp, "collision( integer ");
01618                 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01619                 fprintf(fp, " )\n");
01620                 break;
01621                 break;
01622         case LSCP_SCOPE_PASS1:
01623                 if (scope->checkEntry(mCount->mName))
01624                 {
01625                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
01626                 }
01627                 else
01628                 {
01629                         mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
01630                 }
01631                 break;
01632         case LSCP_RESOURCE:
01633                 {
01634                         // we're just tryng to determine how much space the variable needs
01635                         if (mCount->mScopeEntry)
01636                         {
01637                                 mCount->mScopeEntry->mOffset = (S32)count;
01638                                 mCount->mScopeEntry->mSize = 4;
01639                                 count += mCount->mScopeEntry->mSize;
01640                         }
01641                 }
01642                 break;
01643         case LSCP_EMIT_BYTE_CODE:
01644                 {
01645 #ifdef LSL_INCLUDE_DEBUG_INFO
01646                         char name[] = "collision";
01647                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
01648                         chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);              /*Flawfinder: ignore*/
01649 #endif
01650                 }
01651                 break;
01652         default:
01653                 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01654                 break;
01655         }
01656 }
01657 
01658 S32 LLScriptCollisionEvent::getSize()
01659 {
01660         // integer = 4
01661         return 4;
01662 }
01663 
01664 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)
01665 {
01666         if (gErrorToText.getErrors())
01667         {
01668                 return;
01669         }
01670         switch(pass)
01671         {
01672         case LSCP_PRETTY_PRINT:
01673         case LSCP_EMIT_ASSEMBLY:
01674                 fdotabs(fp, tabs, tabsize);
01675                 fprintf(fp, "collision_end( integer ");
01676                 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01677                 fprintf(fp, " )\n");
01678                 break;
01679                 break;
01680         case LSCP_SCOPE_PASS1:
01681                 if (scope->checkEntry(mCount->mName))
01682                 {
01683                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
01684                 }
01685                 else
01686                 {
01687                         mCount->mScopeEntry = scope->addEntry(mCount->mName, LIT_VARIABLE, LST_INTEGER);
01688                 }
01689                 break;
01690         case LSCP_RESOURCE:
01691                 {
01692                         // we're just tryng to determine how much space the variable needs
01693                         if (mCount->mScopeEntry)
01694                         {
01695                                 mCount->mScopeEntry->mOffset = (S32)count;
01696                                 mCount->mScopeEntry->mSize = 4;
01697                                 count += mCount->mScopeEntry->mSize;
01698                         }
01699                 }
01700                 break;
01701         case LSCP_EMIT_BYTE_CODE:
01702                 {
01703 #ifdef LSL_INCLUDE_DEBUG_INFO
01704                         char name[] = "collision_end";
01705                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
01706                         chunk->addBytes(mCount->mName, strlen(mCount->mName) + 1);              /*Flawfinder: ignore*/
01707 #endif
01708                 }
01709                 break;
01710         default:
01711                 mCount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01712                 break;
01713         }
01714 }
01715 
01716 S32 LLScriptCollisionEndEvent::getSize()
01717 {
01718         // integer = 4
01719         return 4;
01720 }
01721 
01722 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)
01723 {
01724         if (gErrorToText.getErrors())
01725         {
01726                 return;
01727         }
01728         switch(pass)
01729         {
01730         case LSCP_PRETTY_PRINT:
01731         case LSCP_EMIT_ASSEMBLY:
01732                 fdotabs(fp, tabs, tabsize);
01733                 fprintf(fp, "land_collision_start( vector ");
01734                 mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01735                 fprintf(fp, " )\n");
01736                 break;
01737         case LSCP_SCOPE_PASS1:
01738                 if (scope->checkEntry(mPosition->mName))
01739                 {
01740                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
01741                 }
01742                 else
01743                 {
01744                         mPosition->mScopeEntry = scope->addEntry(mPosition->mName, LIT_VARIABLE, LST_VECTOR);
01745                 }
01746                 break;
01747         case LSCP_RESOURCE:
01748                 {
01749                         // we're just tryng to determine how much space the variable needs
01750                         if (mPosition->mScopeEntry)
01751                         {
01752                                 mPosition->mScopeEntry->mOffset = (S32)count;
01753                                 mPosition->mScopeEntry->mSize = 12;
01754                                 count += mPosition->mScopeEntry->mSize;
01755                         }
01756                 }
01757                 break;
01758         case LSCP_EMIT_BYTE_CODE:
01759                 {
01760 #ifdef LSL_INCLUDE_DEBUG_INFO
01761                         char name[] = "land_collision_start";
01762                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
01763                         chunk->addBytes(mPosition->mName, strlen(mPosition->mName) + 1);                /*Flawfinder: ignore*/
01764 #endif
01765                 }
01766                 break;
01767         default:
01768                 mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01769                 break;
01770         }
01771 }
01772 
01773 S32 LLScriptLandCollisionStartEvent::getSize()
01774 {
01775         // vector = 12
01776         return 12;
01777 }
01778 
01779 
01780 
01781 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)
01782 {
01783         if (gErrorToText.getErrors())
01784         {
01785                 return;
01786         }
01787         switch(pass)
01788         {
01789         case LSCP_PRETTY_PRINT:
01790         case LSCP_EMIT_ASSEMBLY:
01791                 fdotabs(fp, tabs, tabsize);
01792                 fprintf(fp, "land_collision( vector ");
01793                 mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01794                 fprintf(fp, " )\n");
01795                 break;
01796         case LSCP_SCOPE_PASS1:
01797                 if (scope->checkEntry(mPosition->mName))
01798                 {
01799                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
01800                 }
01801                 else
01802                 {
01803                         mPosition->mScopeEntry = scope->addEntry(mPosition->mName, LIT_VARIABLE, LST_VECTOR);
01804                 }
01805                 break;
01806         case LSCP_RESOURCE:
01807                 {
01808                         // we're just tryng to determine how much space the variable needs
01809                         if (mPosition->mScopeEntry)
01810                         {
01811                                 mPosition->mScopeEntry->mOffset = (S32)count;
01812                                 mPosition->mScopeEntry->mSize = 12;
01813                                 count += mPosition->mScopeEntry->mSize;
01814                         }
01815                 }
01816                 break;
01817         case LSCP_EMIT_BYTE_CODE:
01818                 {
01819 #ifdef LSL_INCLUDE_DEBUG_INFO
01820                         char name[] = "land_collision";
01821                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
01822                         chunk->addBytes(mPosition->mName, strlen(mPosition->mName) + 1);                /*Flawfinder: ignore*/
01823 #endif
01824                 }
01825                 break;
01826         default:
01827                 mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01828                 break;
01829         }
01830 }
01831 
01832 S32 LLScriptLandCollisionEvent::getSize()
01833 {
01834         // vector = 12
01835         return 12;
01836 }
01837 
01838 
01839 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)
01840 {
01841         if (gErrorToText.getErrors())
01842         {
01843                 return;
01844         }
01845         switch(pass)
01846         {
01847         case LSCP_PRETTY_PRINT:
01848         case LSCP_EMIT_ASSEMBLY:
01849                 fdotabs(fp, tabs, tabsize);
01850                 fprintf(fp, "land_collision_end( vector ");
01851                 mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01852                 fprintf(fp, " )\n");
01853                 break;
01854         case LSCP_SCOPE_PASS1:
01855                 if (scope->checkEntry(mPosition->mName))
01856                 {
01857                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
01858                 }
01859                 else
01860                 {
01861                         mPosition->mScopeEntry = scope->addEntry(mPosition->mName, LIT_VARIABLE, LST_VECTOR);
01862                 }
01863                 break;
01864         case LSCP_RESOURCE:
01865                 {
01866                         // we're just tryng to determine how much space the variable needs
01867                         if (mPosition->mScopeEntry)
01868                         {
01869                                 mPosition->mScopeEntry->mOffset = (S32)count;
01870                                 mPosition->mScopeEntry->mSize = 12;
01871                                 count += mPosition->mScopeEntry->mSize;
01872                         }
01873                 }
01874                 break;
01875         case LSCP_EMIT_BYTE_CODE:
01876                 {
01877 #ifdef LSL_INCLUDE_DEBUG_INFO
01878                         char name[] = "land_collision_end";     /*Flawfinder: ignore*/
01879                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
01880                         chunk->addBytes(mPosition->mName, strlen(mPosition->mName) + 1);        /*Flawfinder: ignore*/
01881 #endif
01882                 }
01883                 break;
01884         default:
01885                 mPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01886                 break;
01887         }
01888 }
01889 
01890 S32 LLScriptLandCollisionEndEvent::getSize()
01891 {
01892         // vector = 12
01893         return 12;
01894 }
01895 
01896 
01897 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)
01898 {
01899         if (gErrorToText.getErrors())
01900         {
01901                 return;
01902         }
01903         switch(pass)
01904         {
01905         case LSCP_PRETTY_PRINT:
01906         case LSCP_EMIT_ASSEMBLY:
01907                 fdotabs(fp, tabs, tabsize);
01908                 fprintf(fp, "changed( integer ");
01909                 mChange->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01910                 fprintf(fp, " )\n");
01911                 break;
01912         case LSCP_SCOPE_PASS1:
01913                 if (scope->checkEntry(mChange->mName))
01914                 {
01915                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
01916                 }
01917                 else
01918                 {
01919                         mChange->mScopeEntry = scope->addEntry(mChange->mName, LIT_VARIABLE, LST_INTEGER);
01920                 }
01921                 break;
01922         case LSCP_RESOURCE:
01923                 {
01924                         // we're just tryng to determine how much space the variable needs
01925                         if (mChange->mScopeEntry)
01926                         {
01927                                 mChange->mScopeEntry->mOffset = (S32)count;
01928                                 mChange->mScopeEntry->mSize = 4;
01929                                 count += mChange->mScopeEntry->mSize;
01930                         }
01931                 }
01932                 break;
01933         case LSCP_EMIT_BYTE_CODE:
01934                 {
01935 #ifdef LSL_INCLUDE_DEBUG_INFO
01936                         char name[] = "changed";
01937                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
01938                         chunk->addBytes(mChange->mName, strlen(mChange->mName) + 1);            /*Flawfinder: ignore*/
01939 #endif
01940                 }
01941                 break;
01942         default:
01943                 mChange->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01944                 break;
01945         }
01946 }
01947 
01948 S32 LLScriptInventoryEvent::getSize()
01949 {
01950         // integer = 4
01951         return 4;
01952 }
01953 
01954 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)
01955 {
01956         if (gErrorToText.getErrors())
01957         {
01958                 return;
01959         }
01960         switch(pass)
01961         {
01962         case LSCP_PRETTY_PRINT:
01963         case LSCP_EMIT_ASSEMBLY:
01964                 fdotabs(fp, tabs, tabsize);
01965                 fprintf(fp, "attach( key ");
01966                 mAttach->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
01967                 fprintf(fp, " )\n");
01968                 break;
01969         case LSCP_SCOPE_PASS1:
01970                 if (scope->checkEntry(mAttach->mName))
01971                 {
01972                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
01973                 }
01974                 else
01975                 {
01976                         mAttach->mScopeEntry = scope->addEntry(mAttach->mName, LIT_VARIABLE, LST_KEY);
01977                 }
01978                 break;
01979         case LSCP_RESOURCE:
01980                 {
01981                         // we're just tryng to determine how much space the variable needs
01982                         if (mAttach->mScopeEntry)
01983                         {
01984                                 mAttach->mScopeEntry->mOffset = (S32)count;
01985                                 mAttach->mScopeEntry->mSize = 4;
01986                                 count += mAttach->mScopeEntry->mSize;
01987                         }
01988                 }
01989                 break;
01990         case LSCP_EMIT_BYTE_CODE:
01991                 {
01992 #ifdef LSL_INCLUDE_DEBUG_INFO
01993                         char name[] = "attach";
01994                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
01995                         chunk->addBytes(mAttach->mName, strlen(mAttach->mName) + 1);            /*Flawfinder: ignore*/
01996 #endif
01997                 }
01998                 break;
01999         default:
02000                 mAttach->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02001                 break;
02002         }
02003 }
02004 
02005 S32 LLScriptAttachEvent::getSize()
02006 {
02007         // key = 4
02008         return 4;
02009 }
02010 
02011 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)
02012 {
02013         if (gErrorToText.getErrors())
02014         {
02015                 return;
02016         }
02017         switch(pass)
02018         {
02019         case LSCP_PRETTY_PRINT:
02020         case LSCP_EMIT_ASSEMBLY:
02021                 fdotabs(fp, tabs, tabsize);
02022                 fprintf(fp, "dataserver( key ");
02023                 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02024                 fprintf(fp, ", string ");
02025                 mData->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02026                 fprintf(fp, " )\n");
02027                 break;
02028         case LSCP_SCOPE_PASS1:
02029                 if (scope->checkEntry(mID->mName))
02030                 {
02031                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02032                 }
02033                 else
02034                 {
02035                         mID->mScopeEntry = scope->addEntry(mID->mName, LIT_VARIABLE, LST_KEY);
02036                 }
02037                 if (scope->checkEntry(mData->mName))
02038                 {
02039                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02040                 }
02041                 else
02042                 {
02043                         mData->mScopeEntry = scope->addEntry(mData->mName, LIT_VARIABLE, LST_STRING);
02044                 }
02045                 break;
02046         case LSCP_RESOURCE:
02047                 {
02048                         // we're just tryng to determine how much space the variable needs
02049                         if (mID->mScopeEntry)
02050                         {
02051                                 mID->mScopeEntry->mOffset = (S32)count;
02052                                 mID->mScopeEntry->mSize = 4;
02053                                 count += mID->mScopeEntry->mSize;
02054                                 mData->mScopeEntry->mOffset = (S32)count;
02055                                 mData->mScopeEntry->mSize = 4;
02056                                 count += mData->mScopeEntry->mSize;
02057                         }
02058                 }
02059                 break;
02060         case LSCP_EMIT_BYTE_CODE:
02061                 {
02062 #ifdef LSL_INCLUDE_DEBUG_INFO
02063                         char name[] = "dataserver";
02064                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
02065                         chunk->addBytes(mID->mName, strlen(mID->mName) + 1);            /*Flawfinder: ignore*/
02066                         chunk->addBytes(mData->mName, strlen(mData->mName) + 1);                /*Flawfinder: ignore*/
02067 #endif
02068                 }
02069                 break;
02070         default:
02071                 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02072                 mData->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02073                 break;
02074         }
02075 }
02076 
02077 S32 LLScriptDataserverEvent::getSize()
02078 {
02079         // key + string = 8
02080         return 8;
02081 }
02082 
02083 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)
02084 {
02085         if (gErrorToText.getErrors())
02086         {
02087                 return;
02088         }
02089         switch(pass)
02090         {
02091         case LSCP_PRETTY_PRINT:
02092                 fdotabs(fp, tabs, tabsize);
02093                 fprintf(fp, "timer()\n");
02094                 break;
02095         case LSCP_EMIT_ASSEMBLY:
02096                 fprintf(fp, "timer()\n");
02097                 break;
02098         case LSCP_EMIT_BYTE_CODE:
02099                 {
02100 #ifdef LSL_INCLUDE_DEBUG_INFO
02101                         char name[] = "timer";
02102                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
02103 #endif
02104                 }
02105                 break;
02106         default:
02107                 break;
02108         }
02109 }
02110 
02111 S32 LLScriptTimerEvent::getSize()
02112 {
02113         return 0;
02114 }
02115 
02116 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)
02117 {
02118         if (gErrorToText.getErrors())
02119         {
02120                 return;
02121         }
02122         switch(pass)
02123         {
02124         case LSCP_PRETTY_PRINT:
02125         case LSCP_EMIT_ASSEMBLY:
02126                 fdotabs(fp, tabs, tabsize);
02127                 fprintf(fp, "moving_start()\n");
02128                 break;
02129         case LSCP_EMIT_BYTE_CODE:
02130                 {
02131 #ifdef LSL_INCLUDE_DEBUG_INFO
02132                         char name[] = "moving_start";
02133                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
02134 #endif
02135                 }
02136                 break;
02137         default:
02138                 break;
02139         }
02140 }
02141 
02142 S32 LLScriptMovingStartEvent::getSize()
02143 {
02144         return 0;
02145 }
02146 
02147 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)
02148 {
02149         if (gErrorToText.getErrors())
02150         {
02151                 return;
02152         }
02153         switch(pass)
02154         {
02155         case LSCP_PRETTY_PRINT:
02156         case LSCP_EMIT_ASSEMBLY:
02157                 fdotabs(fp, tabs, tabsize);
02158                 fprintf(fp, "moving_end()\n");
02159                 break;
02160         case LSCP_EMIT_BYTE_CODE:
02161                 {
02162 #ifdef LSL_INCLUDE_DEBUG_INFO
02163                         char name[] = "moving_end";
02164                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
02165 #endif
02166                 }
02167                 break;
02168         default:
02169                 break;
02170         }
02171 }
02172 
02173 S32 LLScriptMovingEndEvent::getSize()
02174 {
02175         return 0;
02176 }
02177 
02178 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)
02179 {
02180         if (gErrorToText.getErrors())
02181         {
02182                 return;
02183         }
02184         switch(pass)
02185         {
02186         case LSCP_PRETTY_PRINT:
02187         case LSCP_EMIT_ASSEMBLY:
02188                 fdotabs(fp, tabs, tabsize);
02189                 fprintf(fp, "chat( integer ");
02190                 mRTPermissions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02191                 fprintf(fp, " )\n");
02192                 break;
02193         case LSCP_SCOPE_PASS1:
02194                 if (scope->checkEntry(mRTPermissions->mName))
02195                 {
02196                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02197                 }
02198                 else
02199                 {
02200                         mRTPermissions->mScopeEntry = scope->addEntry(mRTPermissions->mName, LIT_VARIABLE, LST_INTEGER);
02201                 }
02202                 break;
02203         case LSCP_RESOURCE:
02204                 {
02205                         // we're just tryng to determine how much space the variable needs
02206                         if (mRTPermissions->mScopeEntry)
02207                         {
02208                                 mRTPermissions->mScopeEntry->mOffset = (S32)count;
02209                                 mRTPermissions->mScopeEntry->mSize = 4;
02210                                 count += mRTPermissions->mScopeEntry->mSize;
02211                         }
02212                 }
02213                 break;
02214         case LSCP_EMIT_BYTE_CODE:
02215                 {
02216 #ifdef LSL_INCLUDE_DEBUG_INFO
02217                         char name[] = "chat";
02218                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
02219                         chunk->addBytes(mRTPermissions->mName, strlen(mRTPermissions->mName) + 1);              /*Flawfinder: ignore*/
02220 #endif
02221                 }
02222                 break;
02223         default:
02224                 mRTPermissions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02225                 break;
02226         }
02227 }
02228 
02229 S32 LLScriptRTPEvent::getSize()
02230 {
02231         // integer = 4
02232         return 4;
02233 }
02234 
02235 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)
02236 {
02237         if (gErrorToText.getErrors())
02238         {
02239                 return;
02240         }
02241         switch(pass)
02242         {
02243         case LSCP_PRETTY_PRINT:
02244         case LSCP_EMIT_ASSEMBLY:
02245                 fdotabs(fp, tabs, tabsize);
02246                 fprintf(fp, "chat( integer ");
02247                 mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02248                 fprintf(fp, ", string ");
02249                 mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02250                 fprintf(fp, ", key ");
02251                 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02252                 fprintf(fp, ", string ");
02253                 mMessage->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02254                 fprintf(fp, " )\n");
02255                 break;
02256         case LSCP_SCOPE_PASS1:
02257                 if (scope->checkEntry(mChannel->mName))
02258                 {
02259                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02260                 }
02261                 else
02262                 {
02263                         mChannel->mScopeEntry = scope->addEntry(mChannel->mName, LIT_VARIABLE, LST_INTEGER);
02264                 }
02265                 if (scope->checkEntry(mName->mName))
02266                 {
02267                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02268                 }
02269                 else
02270                 {
02271                         mName->mScopeEntry = scope->addEntry(mName->mName, LIT_VARIABLE, LST_STRING);
02272                 }
02273                 if (scope->checkEntry(mID->mName))
02274                 {
02275                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02276                 }
02277                 else
02278                 {
02279                         mID->mScopeEntry = scope->addEntry(mID->mName, LIT_VARIABLE, LST_KEY);
02280                 }
02281                 if (scope->checkEntry(mMessage->mName))
02282                 {
02283                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02284                 }
02285                 else
02286                 {
02287                         mMessage->mScopeEntry = scope->addEntry(mMessage->mName, LIT_VARIABLE, LST_STRING);
02288                 }
02289                 break;
02290         case LSCP_RESOURCE:
02291                 {
02292                         // we're just tryng to determine how much space the variable needs
02293                         if (mName->mScopeEntry)
02294                         {
02295                                 mChannel->mScopeEntry->mOffset = (S32)count;
02296                                 mChannel->mScopeEntry->mSize = 4;
02297                                 count += mChannel->mScopeEntry->mSize;
02298                                 mName->mScopeEntry->mOffset = (S32)count;
02299                                 mName->mScopeEntry->mSize = 4;
02300                                 count += mName->mScopeEntry->mSize;
02301                                 mID->mScopeEntry->mOffset = (S32)count;
02302                                 mID->mScopeEntry->mSize = 4;
02303                                 count += mID->mScopeEntry->mSize;
02304                                 mMessage->mScopeEntry->mOffset = (S32)count;
02305                                 mMessage->mScopeEntry->mSize = 4;
02306                                 count += mMessage->mScopeEntry->mSize;
02307                         }
02308                 }
02309                 break;
02310         case LSCP_EMIT_BYTE_CODE:
02311                 {
02312 #ifdef LSL_INCLUDE_DEBUG_INFO
02313                         char name[] = "chat";
02314                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
02315                         chunk->addBytes(mChannel->mName, strlen(mChannel->mName) + 1);          /*Flawfinder: ignore*/
02316                         chunk->addBytes(mName->mName, strlen(mName->mName) + 1);                /*Flawfinder: ignore*/
02317                         chunk->addBytes(mID->mName, strlen(mID->mName) + 1);            /*Flawfinder: ignore*/
02318                         chunk->addBytes(mMessage->mName, strlen(mMessage->mName) + 1);          /*Flawfinder: ignore*/
02319 #endif
02320                 }
02321                 break;
02322         default:
02323                 mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02324                 mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02325                 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02326                 mMessage->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02327                 break;
02328         }
02329 }
02330 
02331 S32 LLScriptChatEvent::getSize()
02332 {
02333         // integer + key + string + string = 16
02334         return 16;
02335 }
02336 
02337 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)
02338 {
02339         if (gErrorToText.getErrors())
02340         {
02341                 return;
02342         }
02343         switch(pass)
02344         {
02345         case LSCP_PRETTY_PRINT:
02346         case LSCP_EMIT_ASSEMBLY:
02347                 fdotabs(fp, tabs, tabsize);
02348                 fprintf(fp, "sensor( integer ");
02349                 mNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02350                 fprintf(fp, " )\n");
02351                 break;
02352         case LSCP_SCOPE_PASS1:
02353                 if (scope->checkEntry(mNumber->mName))
02354                 {
02355                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02356                 }
02357                 else
02358                 {
02359                         mNumber->mScopeEntry = scope->addEntry(mNumber->mName, LIT_VARIABLE, LST_INTEGER);
02360                 }
02361                 break;
02362         case LSCP_RESOURCE:
02363                 {
02364                         // we're just tryng to determine how much space the variable needs
02365                         if (mNumber->mScopeEntry)
02366                         {
02367                                 mNumber->mScopeEntry->mOffset = (S32)count;
02368                                 mNumber->mScopeEntry->mSize = 4;
02369                                 count += mNumber->mScopeEntry->mSize;
02370                         }
02371                 }
02372                 break;
02373         case LSCP_EMIT_BYTE_CODE:
02374                 {
02375 #ifdef LSL_INCLUDE_DEBUG_INFO
02376                         char name[] = "sensor";
02377                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
02378                         chunk->addBytes(mNumber->mName, strlen(mNumber->mName) + 1);            /*Flawfinder: ignore*/
02379 #endif
02380                 }
02381                 break;
02382         default:
02383                 mNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02384                 break;
02385         }
02386 }
02387 
02388 S32 LLScriptSensorEvent::getSize()
02389 {
02390         // integer = 4
02391         return 4;
02392 }
02393 
02394 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)
02395 {
02396         if (gErrorToText.getErrors())
02397         {
02398                 return;
02399         }
02400         switch(pass)
02401         {
02402         case LSCP_PRETTY_PRINT:
02403         case LSCP_EMIT_ASSEMBLY:
02404                 fdotabs(fp, tabs, tabsize);
02405                 fprintf(fp, "object_rez( key ");
02406                 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02407                 fprintf(fp, " )\n");
02408                 break;
02409         case LSCP_SCOPE_PASS1:
02410                 if (scope->checkEntry(mID->mName))
02411                 {
02412                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02413                 }
02414                 else
02415                 {
02416                         mID->mScopeEntry = scope->addEntry(mID->mName, LIT_VARIABLE, LST_KEY);
02417                 }
02418                 break;
02419         case LSCP_RESOURCE:
02420                 {
02421                         // we're just tryng to determine how much space the variable needs
02422                         if (mID->mScopeEntry)
02423                         {
02424                                 mID->mScopeEntry->mOffset = (S32)count;
02425                                 mID->mScopeEntry->mSize = 4;
02426                                 count += mID->mScopeEntry->mSize;
02427                         }
02428                 }
02429                 break;
02430         case LSCP_EMIT_BYTE_CODE:
02431                 {
02432 #ifdef LSL_INCLUDE_DEBUG_INFO
02433                         char name[] = "sensor";
02434                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
02435                         chunk->addBytes(mID->mName, strlen(mID->mName) + 1);            /*Flawfinder: ignore*/
02436 #endif
02437                 }
02438                 break;
02439         default:
02440                 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02441                 break;
02442         }
02443 }
02444 
02445 S32 LLScriptObjectRezEvent::getSize()
02446 {
02447         // key = 4
02448         return 4;
02449 }
02450 
02451 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)
02452 {
02453         if (gErrorToText.getErrors())
02454         {
02455                 return;
02456         }
02457         switch(pass)
02458         {
02459         case LSCP_PRETTY_PRINT:
02460         case LSCP_EMIT_ASSEMBLY:
02461                 fdotabs(fp, tabs, tabsize);
02462                 fprintf(fp, "control( key ");
02463                 mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02464                 fprintf(fp, ", integer ");
02465                 mLevels->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02466                 fprintf(fp, ", integer ");
02467                 mEdges->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02468                 fprintf(fp, " )\n");
02469                 break;
02470         case LSCP_SCOPE_PASS1:
02471                 if (scope->checkEntry(mName->mName))
02472                 {
02473                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02474                 }
02475                 else
02476                 {
02477                         mName->mScopeEntry = scope->addEntry(mName->mName, LIT_VARIABLE, LST_KEY);
02478                 }
02479                 if (scope->checkEntry(mLevels->mName))
02480                 {
02481                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02482                 }
02483                 else
02484                 {
02485                         mLevels->mScopeEntry = scope->addEntry(mLevels->mName, LIT_VARIABLE, LST_INTEGER);
02486                 }
02487                 if (scope->checkEntry(mEdges->mName))
02488                 {
02489                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02490                 }
02491                 else
02492                 {
02493                         mEdges->mScopeEntry = scope->addEntry(mEdges->mName, LIT_VARIABLE, LST_INTEGER);
02494                 }
02495                 break;
02496         case LSCP_RESOURCE:
02497                 {
02498                         // we're just tryng to determine how much space the variable needs
02499                         if (mName->mScopeEntry)
02500                         {
02501                                 mName->mScopeEntry->mOffset = (S32)count;
02502                                 mName->mScopeEntry->mSize = 4;
02503                                 count += mName->mScopeEntry->mSize;
02504                                 mLevels->mScopeEntry->mOffset = (S32)count;
02505                                 mLevels->mScopeEntry->mSize = 4;
02506                                 count += mLevels->mScopeEntry->mSize;
02507                                 mEdges->mScopeEntry->mOffset = (S32)count;
02508                                 mEdges->mScopeEntry->mSize = 4;
02509                                 count += mEdges->mScopeEntry->mSize;
02510                         }
02511                 }
02512                 break;
02513         case LSCP_EMIT_BYTE_CODE:
02514                 {
02515 #ifdef LSL_INCLUDE_DEBUG_INFO
02516                         char name[] = "control";
02517                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
02518                         chunk->addBytes(mName->mName, strlen(mName->mName) + 1);                /*Flawfinder: ignore*/
02519                         chunk->addBytes(mLevels->mName, strlen(mLevels->mName) + 1);            /*Flawfinder: ignore*/
02520                         chunk->addBytes(mEdges->mName, strlen(mEdges->mName) + 1);              /*Flawfinder: ignore*/
02521 #endif
02522                 }
02523                 break;
02524         default:
02525                 mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02526                 mLevels->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02527                 mEdges->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02528                 break;
02529         }
02530 }
02531 
02532 S32 LLScriptControlEvent::getSize()
02533 {
02534         // key + integer + integer = 12
02535         return 12;
02536 }
02537 
02538 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)
02539 {
02540         if (gErrorToText.getErrors())
02541         {
02542                 return;
02543         }
02544         switch(pass)
02545         {
02546         case LSCP_PRETTY_PRINT:
02547         case LSCP_EMIT_ASSEMBLY:
02548                 fdotabs(fp, tabs, tabsize);
02549                 fprintf(fp, "link_message( integer ");
02550                 mSender->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02551                 fprintf(fp, ", integer ");
02552                 mNum->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02553                 fprintf(fp, ", string ");
02554                 mStr->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02555                 fprintf(fp, ", key ");
02556                 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02557                 fprintf(fp, " )\n");
02558                 break;
02559         case LSCP_SCOPE_PASS1:
02560                 if (scope->checkEntry(mSender->mName))
02561                 {
02562                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02563                 }
02564                 else
02565                 {
02566                         mSender->mScopeEntry = scope->addEntry(mSender->mName, LIT_VARIABLE, LST_INTEGER);
02567                 }
02568                 if (scope->checkEntry(mNum->mName))
02569                 {
02570                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02571                 }
02572                 else
02573                 {
02574                         mNum->mScopeEntry = scope->addEntry(mNum->mName, LIT_VARIABLE, LST_INTEGER);
02575                 }
02576                 if (scope->checkEntry(mStr->mName))
02577                 {
02578                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02579                 }
02580                 else
02581                 {
02582                         mStr->mScopeEntry = scope->addEntry(mStr->mName, LIT_VARIABLE, LST_STRING);
02583                 }
02584                 if (scope->checkEntry(mID->mName))
02585                 {
02586                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02587                 }
02588                 else
02589                 {
02590                         mID->mScopeEntry = scope->addEntry(mID->mName, LIT_VARIABLE, LST_KEY);
02591                 }
02592                 break;
02593         case LSCP_RESOURCE:
02594                 {
02595                         // we're just tryng to determine how much space the variable needs
02596                         if (mSender->mScopeEntry)
02597                         {
02598                                 mSender->mScopeEntry->mOffset = (S32)count;
02599                                 mSender->mScopeEntry->mSize = 4;
02600                                 count += mSender->mScopeEntry->mSize;
02601                                 mNum->mScopeEntry->mOffset = (S32)count;
02602                                 mNum->mScopeEntry->mSize = 4;
02603                                 count += mNum->mScopeEntry->mSize;
02604                                 mStr->mScopeEntry->mOffset = (S32)count;
02605                                 mStr->mScopeEntry->mSize = 4;
02606                                 count += mStr->mScopeEntry->mSize;
02607                                 mID->mScopeEntry->mOffset = (S32)count;
02608                                 mID->mScopeEntry->mSize = 4;
02609                                 count += mID->mScopeEntry->mSize;
02610                         }
02611                 }
02612                 break;
02613         case LSCP_EMIT_BYTE_CODE:
02614                 {
02615 #ifdef LSL_INCLUDE_DEBUG_INFO
02616                         char name[] = "link_message";
02617                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
02618                         chunk->addBytes(mSender->mName, strlen(mSender->mName) + 1);            /*Flawfinder: ignore*/
02619                         chunk->addBytes(mNum->mName, strlen(mNum->mName) + 1);          /*Flawfinder: ignore*/
02620                         chunk->addBytes(mStr->mName, strlen(mStr->mName) + 1);          /*Flawfinder: ignore*/
02621                         chunk->addBytes(mID->mName, strlen(mID->mName) + 1);            /*Flawfinder: ignore*/
02622 #endif
02623                 }
02624                 break;
02625         default:
02626                 mSender->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02627                 mNum->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02628                 mStr->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02629                 mID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02630                 break;
02631         }
02632 }
02633 
02634 S32 LLScriptLinkMessageEvent::getSize()
02635 {
02636         // integer + key + integer + string = 16
02637         return 16;
02638 }
02639 
02640 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)
02641 {
02642         if (gErrorToText.getErrors())
02643         {
02644                 return;
02645         }
02646         switch(pass)
02647         {
02648         case LSCP_PRETTY_PRINT:
02649         case LSCP_EMIT_ASSEMBLY:
02650                 fdotabs(fp, tabs, tabsize);
02651                 fprintf(fp, "remote_event( integer ");
02652                 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02653                 fprintf(fp, ", key ");
02654                 mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02655                 fprintf(fp, ", key ");
02656                 mMessageID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02657                 fprintf(fp, ", string ");
02658                 mSender->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02659                 fprintf(fp, ", integer ");
02660                 mIntVal->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02661                 fprintf(fp, ", string ");
02662                 mStrVal->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02663                 fprintf(fp, " )\n");
02664                 break;
02665         case LSCP_SCOPE_PASS1:
02666                 if (scope->checkEntry(mType->mName))
02667                 {
02668                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02669                 }
02670                 else
02671                 {
02672                         mType->mScopeEntry = scope->addEntry(mType->mName, LIT_VARIABLE, LST_INTEGER);
02673                 }
02674                 if (scope->checkEntry(mChannel->mName))
02675                 {
02676                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02677                 }
02678                 else
02679                 {
02680                         mChannel->mScopeEntry = scope->addEntry(mChannel->mName, LIT_VARIABLE, LST_KEY);
02681                 }
02682                 if (scope->checkEntry(mMessageID->mName))
02683                 {
02684                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02685                 }
02686                 else
02687                 {
02688                         mMessageID->mScopeEntry = scope->addEntry(mMessageID->mName, LIT_VARIABLE, LST_KEY);
02689                 }
02690                 if (scope->checkEntry(mSender->mName))
02691                 {
02692                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02693                 }
02694                 else
02695                 {
02696                         mSender->mScopeEntry = scope->addEntry(mSender->mName, LIT_VARIABLE, LST_STRING);
02697                 }
02698                 if (scope->checkEntry(mIntVal->mName))
02699                 {
02700                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02701                 }
02702                 else
02703                 {
02704                         mIntVal->mScopeEntry = scope->addEntry(mIntVal->mName, LIT_VARIABLE, LST_INTEGER);
02705                 }
02706                 if (scope->checkEntry(mStrVal->mName))
02707                 {
02708                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02709                 }
02710                 else
02711                 {
02712                         mStrVal->mScopeEntry = scope->addEntry(mStrVal->mName, LIT_VARIABLE, LST_STRING);
02713                 }
02714                 break;
02715         case LSCP_RESOURCE:
02716                 {
02717                         // we're just tryng to determine how much space the variable needs
02718                         if (mType->mScopeEntry)
02719                         {
02720                                 mType->mScopeEntry->mOffset = (S32)count;
02721                                 mType->mScopeEntry->mSize = 4;
02722                                 count += mType->mScopeEntry->mSize;
02723                                 mChannel->mScopeEntry->mOffset = (S32)count;
02724                                 mChannel->mScopeEntry->mSize = 4;
02725                                 count += mChannel->mScopeEntry->mSize;
02726                                 mMessageID->mScopeEntry->mOffset = (S32)count;
02727                                 mMessageID->mScopeEntry->mSize = 4;
02728                                 count += mMessageID->mScopeEntry->mSize;
02729                                 mSender->mScopeEntry->mOffset = (S32)count;
02730                                 mSender->mScopeEntry->mSize = 4;
02731                                 count += mSender->mScopeEntry->mSize;
02732                                 mIntVal->mScopeEntry->mOffset = (S32)count;
02733                                 mIntVal->mScopeEntry->mSize = 4;
02734                                 count += mIntVal->mScopeEntry->mSize;
02735                                 mStrVal->mScopeEntry->mOffset = (S32)count;
02736                                 mStrVal->mScopeEntry->mSize = 4;
02737                                 count += mStrVal->mScopeEntry->mSize;
02738                         }
02739                 }
02740                 break;
02741         case LSCP_EMIT_BYTE_CODE:
02742                 {
02743 #ifdef LSL_INCLUDE_DEBUG_INFO
02744                         char name[] = "remote_event";
02745                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
02746                         chunk->addBytes(mType->mName, strlen(mType->mName) + 1);                /*Flawfinder: ignore*/
02747                         chunk->addBytes(mChannel->mName, strlen(mChannel->mName) + 1);          /*Flawfinder: ignore*/
02748                         chunk->addBytes(mMessageID->mName, strlen(mMessageID->mName) + 1);              /*Flawfinder: ignore*/
02749                         chunk->addBytes(mSender->mName, strlen(mSender->mName) + 1);            /*Flawfinder: ignore*/
02750                         chunk->addBytes(mIntVal->mName, strlen(mIntVal->mName) + 1);            /*Flawfinder: ignore*/
02751                         chunk->addBytes(mStrVal->mName, strlen(mStrVal->mName) + 1);            /*Flawfinder: ignore*/
02752 #endif
02753                 }
02754                 break;
02755         default:
02756                 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02757                 mChannel->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02758                 mMessageID->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02759                 mSender->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02760                 mIntVal->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02761                 mStrVal->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02762                 break;
02763         }
02764 }
02765 
02766 S32 LLScriptRemoteEvent::getSize()
02767 {
02768         // integer + key + key + string + integer + string = 24
02769         return 24;
02770 }
02771 
02772 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)
02773 {
02774         if (gErrorToText.getErrors())
02775         {
02776                 return;
02777         }
02778         switch(pass)
02779         {
02780         case LSCP_PRETTY_PRINT:
02781         case LSCP_EMIT_ASSEMBLY:
02782                 fdotabs(fp, tabs, tabsize);
02783                 fprintf(fp, "http_response( key ");
02784                 mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02785                 fprintf(fp, ", integer ");
02786                 mStatus->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02787                 fprintf(fp, ", list ");
02788                 mMetadata->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02789                 fprintf(fp, ", string ");
02790                 mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02791                 fprintf(fp, " )\n");
02792                 break;
02793                 
02794         case LSCP_SCOPE_PASS1:
02795                 if (scope->checkEntry(mRequestId->mName))
02796                 {
02797                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02798                 }
02799                 else
02800                 {
02801                         mRequestId->mScopeEntry = scope->addEntry(mRequestId->mName, LIT_VARIABLE, LST_KEY);
02802                 }
02803                 
02804                 if (scope->checkEntry(mStatus->mName))
02805                 {
02806                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02807                 }
02808                 else
02809                 {
02810                         mStatus->mScopeEntry = scope->addEntry(mStatus->mName, LIT_VARIABLE, LST_INTEGER);
02811                 }
02812                 
02813                 if (scope->checkEntry(mMetadata->mName))
02814                 {
02815                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02816                 }
02817                 else
02818                 {
02819                         mMetadata->mScopeEntry = scope->addEntry(mMetadata->mName, LIT_VARIABLE, LST_LIST);
02820                 }
02821                 
02822                 if (scope->checkEntry(mBody->mName))
02823                 {
02824                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02825                 }
02826                 else
02827                 {
02828                         mBody->mScopeEntry = scope->addEntry(mBody->mName, LIT_VARIABLE, LST_STRING);
02829                 }
02830                 break;
02831                 
02832         case LSCP_RESOURCE:
02833                 {
02834                         // we're just tryng to determine how much space the variable needs
02835                         if (mRequestId->mScopeEntry)
02836                         {
02837                                 mRequestId->mScopeEntry->mOffset = (S32)count;
02838                                 mRequestId->mScopeEntry->mSize = 4;
02839                                 count += mRequestId->mScopeEntry->mSize;
02840 
02841                                 mStatus->mScopeEntry->mOffset = (S32)count;
02842                                 mStatus->mScopeEntry->mSize = 4;
02843                                 count += mStatus->mScopeEntry->mSize;
02844 
02845                                 mMetadata->mScopeEntry->mOffset = (S32)count;
02846                                 mMetadata->mScopeEntry->mSize = 4;
02847                                 count += mMetadata->mScopeEntry->mSize;
02848 
02849                                 mBody->mScopeEntry->mOffset = (S32)count;
02850                                 mBody->mScopeEntry->mSize = 4;
02851                                 count += mBody->mScopeEntry->mSize;
02852                         }
02853                 }
02854                 break;
02855                 
02856         case LSCP_EMIT_BYTE_CODE:
02857                 {
02858 #ifdef LSL_INCLUDE_DEBUG_INFO
02859                         char name[] = "http_response";
02860                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
02861                         chunk->addBytes(mRequestId->mName, strlen(mRequestId->mName) + 1);              /*Flawfinder: ignore*/
02862                         chunk->addBytes(mStatus->mName, strlen(mStatus->mName) + 1);            /*Flawfinder: ignore*/
02863                         chunk->addBytes(mMetadata->mName, strlen(mMetadata->mName) + 1);                /*Flawfinder: ignore*/
02864                         chunk->addBytes(mBody->mName, strlen(mBody->mName) + 1);                /*Flawfinder: ignore*/
02865 #endif
02866                 }
02867                 break;
02868                 
02869         default:
02870                 mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02871                 mStatus->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02872                 mMetadata->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02873                 mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02874                 break;
02875         }
02876 }
02877 
02878 S32 LLScriptHTTPResponseEvent::getSize()
02879 {
02880         // key + integer + list + string = 16
02881         return 16;
02882 }
02883 
02884 
02885 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)
02886 {
02887         if (gErrorToText.getErrors())
02888         {
02889                 return;
02890         }
02891         switch(pass)
02892         {
02893         case LSCP_PRETTY_PRINT:
02894         case LSCP_EMIT_ASSEMBLY:
02895                 fdotabs(fp, tabs, tabsize);
02896                 fprintf(fp, "money( key ");
02897                 mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02898                 fprintf(fp, ", integer ");
02899                 mAmount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02900                 fprintf(fp, " )\n");
02901                 break;
02902         case LSCP_SCOPE_PASS1:
02903                 if (scope->checkEntry(mName->mName))
02904                 {
02905                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02906                 }
02907                 else
02908                 {
02909                         mName->mScopeEntry = scope->addEntry(mName->mName, LIT_VARIABLE, LST_KEY);
02910                 }
02911                 if (scope->checkEntry(mAmount->mName))
02912                 {
02913                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02914                 }
02915                 else
02916                 {
02917                         mAmount->mScopeEntry = scope->addEntry(mAmount->mName, LIT_VARIABLE, LST_INTEGER);
02918                 }
02919                 break;
02920         case LSCP_RESOURCE:
02921                 {
02922                         // we're just tryng to determine how much space the variable needs
02923                         if (mName->mScopeEntry)
02924                         {
02925                                 mName->mScopeEntry->mOffset = (S32)count;
02926                                 mName->mScopeEntry->mSize = 4;
02927                                 count += mName->mScopeEntry->mSize;
02928                                 mAmount->mScopeEntry->mOffset = (S32)count;
02929                                 mAmount->mScopeEntry->mSize = 4;
02930                                 count += mAmount->mScopeEntry->mSize;
02931                         }
02932                 }
02933                 break;
02934         case LSCP_EMIT_BYTE_CODE:
02935                 {
02936 #ifdef LSL_INCLUDE_DEBUG_INFO
02937                         char name[] = "money";
02938                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
02939                         chunk->addBytes(mName->mName, strlen(mName->mName) + 1);                /*Flawfinder: ignore*/
02940                         chunk->addBytes(mAmount->mName, strlen(mAmount->mName) + 1);            /*Flawfinder: ignore*/
02941 #endif
02942                 }
02943                 break;
02944         default:
02945                 mName->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02946                 mAmount->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02947                 break;
02948         }
02949 }
02950 
02951 S32 LLScriptMoneyEvent::getSize()
02952 {
02953         // key + integer = 8
02954         return 8;
02955 }
02956 
02957 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)
02958 {
02959         if (gErrorToText.getErrors())
02960         {
02961                 return;
02962         }
02963         switch(pass)
02964         {
02965         case LSCP_PRETTY_PRINT:
02966         case LSCP_EMIT_ASSEMBLY:
02967                 fdotabs(fp, tabs, tabsize);
02968                 fprintf(fp, "email( string ");
02969                 mTime->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02970                 fprintf(fp, ", string ");
02971                 mAddress->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02972                 fprintf(fp, ", string ");
02973                 mSubject->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02974                 fprintf(fp, ", string ");
02975                 mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02976                 fprintf(fp, ", integer ");
02977                 mNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
02978                 fprintf(fp, " )\n");
02979                 break;
02980         case LSCP_SCOPE_PASS1:
02981                 if (scope->checkEntry(mTime->mName))
02982                 {
02983                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02984                 }
02985                 else
02986                 {
02987                         mTime->mScopeEntry = scope->addEntry(mTime->mName, LIT_VARIABLE, LST_STRING);
02988                 }
02989                 if (scope->checkEntry(mAddress->mName))
02990                 {
02991                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
02992                 }
02993                 else
02994                 {
02995                         mAddress->mScopeEntry = scope->addEntry(mAddress->mName, LIT_VARIABLE, LST_STRING);
02996                 }
02997                 if (scope->checkEntry(mSubject->mName))
02998                 {
02999                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
03000                 }
03001                 else
03002                 {
03003                         mSubject->mScopeEntry = scope->addEntry(mSubject->mName, LIT_VARIABLE, LST_STRING);
03004                 }
03005                 if (scope->checkEntry(mBody->mName))
03006                 {
03007                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
03008                 }
03009                 else
03010                 {
03011                         mBody->mScopeEntry = scope->addEntry(mBody->mName, LIT_VARIABLE, LST_STRING);
03012                 }
03013                 if (scope->checkEntry(mNumber->mName))
03014                 {
03015                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
03016                 }
03017                 else
03018                 {
03019                         mNumber->mScopeEntry = scope->addEntry(mNumber->mName, LIT_VARIABLE, LST_INTEGER);
03020                 }
03021                 break;
03022         case LSCP_RESOURCE:
03023                 {
03024                         // we're just tryng to determine how much space the variable needs
03025                         if (mAddress->mScopeEntry)
03026                         {
03027                                 mTime->mScopeEntry->mOffset = (S32)count;
03028                                 mTime->mScopeEntry->mSize = 4;
03029                                 count += mTime->mScopeEntry->mSize;
03030                                 mAddress->mScopeEntry->mOffset = (S32)count;
03031                                 mAddress->mScopeEntry->mSize = 4;
03032                                 count += mAddress->mScopeEntry->mSize;
03033                                 mSubject->mScopeEntry->mOffset = (S32)count;
03034                                 mSubject->mScopeEntry->mSize = 4;
03035                                 count += mSubject->mScopeEntry->mSize;
03036                                 mBody->mScopeEntry->mOffset = (S32)count;
03037                                 mBody->mScopeEntry->mSize = 4;
03038                                 count += mBody->mScopeEntry->mSize;
03039                                 mNumber->mScopeEntry->mOffset = (S32)count;
03040                                 mNumber->mScopeEntry->mSize = 4;
03041                                 count += mNumber->mScopeEntry->mSize;
03042                         }
03043                 }
03044                 break;
03045         case LSCP_EMIT_BYTE_CODE:
03046                 {
03047 #ifdef LSL_INCLUDE_DEBUG_INFO
03048                         char name[] = "email";
03049                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
03050                         chunk->addBytes(mTime->mName, strlen(mTime->mName) + 1);                /*Flawfinder: ignore*/
03051                         chunk->addBytes(mAddress->mName, strlen(mAddress->mName) + 1);          /*Flawfinder: ignore*/
03052                         chunk->addBytes(mSubject->mName, strlen(mSubject->mName) + 1);          /*Flawfinder: ignore*/
03053                         chunk->addBytes(mBody->mName, strlen(mBody->mName) + 1);                /*Flawfinder: ignore*/
03054                         chunk->addBytes(mNumber->mName, strlen(mNumber->mName) + 1);            /*Flawfinder: ignore*/
03055 #endif
03056                 }
03057                 break;
03058         default:
03059                 mTime->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03060                 mAddress->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03061                 mSubject->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03062                 mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03063                 mNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03064                 break;
03065         }
03066 }
03067 
03068 S32 LLScriptEmailEvent::getSize()
03069 {
03070         // string + string + string + string + integer = 16
03071         return 20;
03072 }
03073 
03074 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)
03075 {
03076         if (gErrorToText.getErrors())
03077         {
03078                 return;
03079         }
03080         switch(pass)
03081         {
03082         case LSCP_PRETTY_PRINT:
03083         case LSCP_EMIT_ASSEMBLY:
03084                 fdotabs(fp, tabs, tabsize);
03085                 fprintf(fp, "rez( integer ");
03086                 mStartParam->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03087                 fprintf(fp, " )\n");
03088                 break;
03089         case LSCP_SCOPE_PASS1:
03090                 if (scope->checkEntry(mStartParam->mName))
03091                 {
03092                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
03093                 }
03094                 else
03095                 {
03096                         mStartParam->mScopeEntry = scope->addEntry(mStartParam->mName, LIT_VARIABLE, LST_INTEGER);
03097                 }
03098                 break;
03099         case LSCP_RESOURCE:
03100                 {
03101                         // we're just tryng to determine how much space the variable needs
03102                         if (mStartParam->mScopeEntry)
03103                         {
03104                                 mStartParam->mScopeEntry->mOffset = (S32)count;
03105                                 mStartParam->mScopeEntry->mSize = 4;
03106                                 count += mStartParam->mScopeEntry->mSize;
03107                         }
03108                 }
03109                 break;
03110         case LSCP_EMIT_BYTE_CODE:
03111                 {
03112 #ifdef LSL_INCLUDE_DEBUG_INFO
03113                         char name[] = "rez";
03114                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
03115                         chunk->addBytes(mStartParam->mName, strlen(mStartParam->mName) + 1);            /*Flawfinder: ignore*/
03116 #endif
03117                 }
03118                 break;
03119         default:
03120                 mStartParam->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03121                 break;
03122         }
03123 }
03124 
03125 S32 LLScriptRezEvent::getSize()
03126 {
03127         // integer = 4
03128         return 4;
03129 }
03130 
03131 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)
03132 {
03133         if (gErrorToText.getErrors())
03134         {
03135                 return;
03136         }
03137         switch(pass)
03138         {
03139         case LSCP_PRETTY_PRINT:
03140                 fdotabs(fp, tabs, tabsize);
03141                 fprintf(fp, "no_sensor()\n");
03142                 break;
03143         case LSCP_EMIT_ASSEMBLY:
03144                 fprintf(fp, "no_sensor()\n");
03145                 break;
03146         case LSCP_EMIT_BYTE_CODE:
03147                 {
03148 #ifdef LSL_INCLUDE_DEBUG_INFO
03149                         char name[] = "no_sensor";
03150                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
03151 #endif
03152                 }
03153                 break;
03154         default:
03155                 break;
03156         }
03157 }
03158 
03159 S32 LLScriptNoSensorEvent::getSize()
03160 {
03161         return 0;
03162 }
03163 
03164 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)
03165 {
03166         if (gErrorToText.getErrors())
03167         {
03168                 return;
03169         }
03170         switch(pass)
03171         {
03172         case LSCP_PRETTY_PRINT:
03173         case LSCP_EMIT_ASSEMBLY:
03174                 fdotabs(fp, tabs, tabsize);
03175                 fprintf(fp, "at_target( integer ");
03176                 mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03177                 fprintf(fp, ", vector ");
03178                 mTargetPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03179                 fprintf(fp, ", vector ");
03180                 mOurPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03181                 fprintf(fp, " )\n");
03182                 break;
03183         case LSCP_SCOPE_PASS1:
03184                 if (scope->checkEntry(mTargetNumber->mName))
03185                 {
03186                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
03187                 }
03188                 else
03189                 {
03190                         mTargetNumber->mScopeEntry = scope->addEntry(mTargetNumber->mName, LIT_VARIABLE, LST_INTEGER);
03191                 }
03192                 if (scope->checkEntry(mTargetPosition->mName))
03193                 {
03194                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
03195                 }
03196                 else
03197                 {
03198                         mTargetPosition->mScopeEntry = scope->addEntry(mTargetPosition->mName, LIT_VARIABLE, LST_VECTOR);
03199                 }
03200                 if (scope->checkEntry(mOurPosition->mName))
03201                 {
03202                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
03203                 }
03204                 else
03205                 {
03206                         mOurPosition->mScopeEntry = scope->addEntry(mOurPosition->mName, LIT_VARIABLE, LST_VECTOR);
03207                 }
03208                 break;
03209         case LSCP_RESOURCE:
03210                 {
03211                         // we're just tryng to determine how much space the variable needs
03212                         if (mTargetNumber->mScopeEntry)
03213                         {
03214                                 mTargetNumber->mScopeEntry->mOffset = (S32)count;
03215                                 mTargetNumber->mScopeEntry->mSize = 4;
03216                                 count += mTargetNumber->mScopeEntry->mSize;
03217                                 mTargetPosition->mScopeEntry->mOffset = (S32)count;
03218                                 mTargetPosition->mScopeEntry->mSize = 12;
03219                                 count += mTargetPosition->mScopeEntry->mSize;
03220                                 mOurPosition->mScopeEntry->mOffset = (S32)count;
03221                                 mOurPosition->mScopeEntry->mSize = 12;
03222                                 count += mOurPosition->mScopeEntry->mSize;
03223                         }
03224                 }
03225                 break;
03226         case LSCP_EMIT_BYTE_CODE:
03227                 {
03228 #ifdef LSL_INCLUDE_DEBUG_INFO
03229                         char name[] = "at_target";      /*Flawfinder: ignore*/
03230                         chunk->addBytes(name, strlen(name) + 1);        /*Flawfinder: ignore*/
03231                         chunk->addBytes(mTargetNumber->mName, strlen(mTargetNumber->mName) + 1);        /*Flawfinder: ignore*/
03232                         chunk->addBytes(mTargetPosition->mName, strlen(mTargetPosition->mName) + 1);    /*Flawfinder: ignore*/
03233                         chunk->addBytes(mOurPosition->mName, strlen(mOurPosition->mName) + 1);                  /*Flawfinder: ignore*/
03234 #endif
03235                 }
03236                 break;
03237         default:
03238                 mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03239                 mTargetPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03240                 mOurPosition->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03241                 break;
03242         }
03243 }
03244 
03245 S32 LLScriptAtTarget::getSize()
03246 {
03247         // integer + vector + vector = 28
03248         return 28;
03249 }
03250 
03251 
03252 
03253 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)
03254 {
03255         if (gErrorToText.getErrors())
03256         {
03257                 return;
03258         }
03259         switch(pass)
03260         {
03261         case LSCP_PRETTY_PRINT:
03262                 fdotabs(fp, tabs, tabsize);
03263                 fprintf(fp, "not_at_target()\n");
03264                 break;
03265         case LSCP_EMIT_ASSEMBLY:
03266                 fprintf(fp, "not_at_target()\n");
03267                 break;
03268         case LSCP_EMIT_BYTE_CODE:
03269                 {
03270 #ifdef LSL_INCLUDE_DEBUG_INFO
03271                         char name[] = "not_at_target";  /*Flawfinder: ignore*/
03272                         chunk->addBytes(name, strlen(name) + 1);        /*Flawfinder: ignore*/
03273 #endif
03274                 }
03275                 break;
03276         default:
03277                 break;
03278         }
03279 }
03280 
03281 S32 LLScriptNotAtTarget::getSize()
03282 {
03283         return 0;
03284 }
03285 
03286 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)
03287 {
03288         if (gErrorToText.getErrors())
03289         {
03290                 return;
03291         }
03292         switch(pass)
03293         {
03294         case LSCP_PRETTY_PRINT:
03295         case LSCP_EMIT_ASSEMBLY:
03296                 fdotabs(fp, tabs, tabsize);
03297                 fprintf(fp, "at_target( integer ");
03298                 mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03299                 fprintf(fp, ", quaternion ");
03300                 mTargetRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03301                 fprintf(fp, ", quaternion ");
03302                 mOurRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03303                 fprintf(fp, " )\n");
03304                 break;
03305         case LSCP_SCOPE_PASS1:
03306                 if (scope->checkEntry(mTargetNumber->mName))
03307                 {
03308                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
03309                 }
03310                 else
03311                 {
03312                         mTargetNumber->mScopeEntry = scope->addEntry(mTargetNumber->mName, LIT_VARIABLE, LST_INTEGER);
03313                 }
03314                 if (scope->checkEntry(mTargetRotation->mName))
03315                 {
03316                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
03317                 }
03318                 else
03319                 {
03320                         mTargetRotation->mScopeEntry = scope->addEntry(mTargetRotation->mName, LIT_VARIABLE, LST_QUATERNION);
03321                 }
03322                 if (scope->checkEntry(mOurRotation->mName))
03323                 {
03324                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
03325                 }
03326                 else
03327                 {
03328                         mOurRotation->mScopeEntry = scope->addEntry(mOurRotation->mName, LIT_VARIABLE, LST_QUATERNION);
03329                 }
03330                 break;
03331         case LSCP_RESOURCE:
03332                 {
03333                         // we're just tryng to determine how much space the variable needs
03334                         if (mTargetNumber->mScopeEntry)
03335                         {
03336                                 mTargetNumber->mScopeEntry->mOffset = (S32)count;
03337                                 mTargetNumber->mScopeEntry->mSize = 4;
03338                                 count += mTargetNumber->mScopeEntry->mSize;
03339                                 mTargetRotation->mScopeEntry->mOffset = (S32)count;
03340                                 mTargetRotation->mScopeEntry->mSize = 16;
03341                                 count += mTargetRotation->mScopeEntry->mSize;
03342                                 mOurRotation->mScopeEntry->mOffset = (S32)count;
03343                                 mOurRotation->mScopeEntry->mSize = 16;
03344                                 count += mOurRotation->mScopeEntry->mSize;
03345                         }
03346                 }
03347                 break;
03348         case LSCP_EMIT_BYTE_CODE:
03349                 {
03350 #ifdef LSL_INCLUDE_DEBUG_INFO
03351                         char name[] = "at_rot_target";
03352                         chunk->addBytes(name, strlen(name) + 1);        /*Flawfinder: ignore*/
03353                         chunk->addBytes(mTargetNumber->mName, strlen(mTargetNumber->mName) + 1);        /*Flawfinder: ignore*/
03354                         chunk->addBytes(mTargetRotation->mName, strlen(mTargetRotation->mName) + 1);    /*Flawfinder: ignore*/
03355                         chunk->addBytes(mOurRotation->mName, strlen(mOurRotation->mName) + 1);  /*Flawfinder: ignore*/
03356 #endif
03357                 }
03358                 break;
03359         default:
03360                 mTargetNumber->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03361                 mTargetRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03362                 mOurRotation->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03363                 break;
03364         }
03365 }
03366 
03367 S32 LLScriptAtRotTarget::getSize()
03368 {
03369         // integer + quaternion + quaternion = 36
03370         return 36;
03371 }
03372 
03373 
03374 
03375 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)
03376 {
03377         if (gErrorToText.getErrors())
03378         {
03379                 return;
03380         }
03381         switch(pass)
03382         {
03383         case LSCP_PRETTY_PRINT:
03384                 fdotabs(fp, tabs, tabsize);
03385                 fprintf(fp, "not_at_rot_target()\n");
03386                 break;
03387         case LSCP_EMIT_ASSEMBLY:
03388                 fprintf(fp, "not_at_rot_target()\n");
03389                 break;
03390         case LSCP_EMIT_BYTE_CODE:
03391                 {
03392 #ifdef LSL_INCLUDE_DEBUG_INFO
03393                         char name[] = "not_at_rot_target";
03394                         chunk->addBytes(name, strlen(name) + 1);                /*Flawfinder: ignore*/
03395 #endif
03396                 }
03397                 break;
03398         default:
03399                 break;
03400         }
03401 }
03402 
03403 S32 LLScriptNotAtRotTarget::getSize()
03404 {
03405         return 0;
03406 }
03407 
03408 
03409 
03410 void LLScriptExpression::addExpression(LLScriptExpression *expression)
03411 {
03412         if (mNextp)
03413         {
03414                 expression->mNextp = mNextp;
03415         }
03416         mNextp = expression;
03417 }
03418 
03419 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)
03420 {
03421         fprintf(fp, "Expression Base Class -- should never get here!\n");
03422 }
03423 
03424 S32 LLScriptExpression::getSize()
03425 {
03426         printf("Expression Base Class -- should never get here!\n");
03427         return 0;
03428 }
03429 
03430 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)
03431 {
03432         if (gErrorToText.getErrors())
03433         {
03434                 return;
03435         }
03436         switch(pass)
03437         {
03438         case LSCP_PRETTY_PRINT:
03439                 if (mNextp)
03440                 {
03441                         fprintf(fp, ", ");
03442                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03443                 }
03444                 break;
03445         default:
03446                 if (mNextp)
03447                 {
03448                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03449                 }
03450                 break;
03451         }
03452 }
03453 
03454 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)
03455 {
03456         if (gErrorToText.getErrors())
03457         {
03458                 return;
03459         }
03460         switch(pass)
03461         {
03462         case LSCP_PRETTY_PRINT:
03463                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03464                 if (mSecondp)
03465                 {
03466                         fprintf(fp, ", ");
03467                         mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03468                 }
03469                 break;
03470         case LSCP_EMIT_ASSEMBLY:
03471                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03472                 if (mFirstp->mReturnType)
03473                 {
03474                         fprintf(fp, "%s\n", LSCRIPTTypePop[mFirstp->mReturnType]);
03475                 }
03476                 if (mSecondp)
03477                 {
03478                         mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03479                         if (mSecondp->mReturnType)
03480                         {
03481                                 fprintf(fp, "%s\n", LSCRIPTTypePop[mSecondp->mReturnType]);
03482                         }
03483                 }
03484                 break;
03485         case LSCP_TO_STACK:
03486                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03487                 switch(mFirstp->mReturnType)
03488                 {
03489                 case LST_INTEGER:
03490                 case LST_FLOATINGPOINT:
03491                         chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
03492                         break;
03493                 case LST_STRING:
03494                 case LST_KEY:
03495                         chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
03496                         break;
03497                 case LST_LIST:
03498                         chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
03499                         break;
03500                 case LST_VECTOR:
03501                         chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
03502                         break;
03503                 case LST_QUATERNION:
03504                         chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
03505                         break;
03506                 default:
03507                         break;
03508                 }
03509                 if (mSecondp)
03510                 {
03511                         mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03512                         switch(mSecondp->mReturnType)
03513                         {
03514                         case LST_INTEGER:
03515                         case LST_FLOATINGPOINT:
03516                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
03517                                 break;
03518                         case LST_STRING:
03519                         case LST_KEY:
03520                         chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
03521                                 break;
03522                         case LST_LIST:
03523                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
03524                                 break;
03525                         case LST_VECTOR:
03526                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
03527                                 break;
03528                         case LST_QUATERNION:
03529                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
03530                                 break;
03531                         default:
03532                                 break;
03533                         }
03534                 }
03535                 break;
03536         case LSCP_EMIT_CIL_ASSEMBLY:
03537                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03538                 if (mFirstp->mReturnType)
03539                 {
03540                         fprintf(fp, "pop\n");
03541                 }
03542                 if (mSecondp)
03543                 {
03544                         mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03545                         if (mSecondp->mReturnType)
03546                         {
03547                                 fprintf(fp, "pop\n");
03548                         }
03549                 }
03550                 break;
03551         default:
03552                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03553                 if (mSecondp)
03554                 {
03555                         mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03556                 }
03557                 break;
03558         }
03559 }
03560 
03561 S32 LLScriptForExpressionList::getSize()
03562 {
03563         return 0;
03564 }
03565 
03566 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)
03567 {
03568         if (gErrorToText.getErrors())
03569         {
03570                 return;
03571         }
03572         switch(pass)
03573         {
03574         case LSCP_PRETTY_PRINT:
03575                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03576                 if (mSecondp)
03577                 {
03578                         fprintf(fp, ", ");
03579                         mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03580                 }
03581                 break;
03582         case LSCP_TYPE:
03583                 {
03584                         mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03585                         if (!entry->mFunctionArgs.getType(entrycount))
03586                         {
03587                                 gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
03588                         }
03589                         if (!legal_assignment(entry->mFunctionArgs.getType(entrycount), mFirstp->mReturnType))
03590                         {
03591                                 gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
03592                         }
03593                         count++;
03594                         entrycount++;
03595                         if (mSecondp)
03596                         {
03597                                 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03598                                 if (mSecondp->mReturnType)
03599                                 {
03600                                         count++;
03601                                         if (!entry->mFunctionArgs.getType(entrycount))
03602                                         {
03603                                                 gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
03604                                         }
03605                                         if (!legal_assignment(entry->mFunctionArgs.getType(entrycount), mSecondp->mReturnType))
03606                                         {
03607                                                 gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
03608                                         }
03609                                 }
03610                         }
03611                 }
03612                 break;
03613         case LSCP_EMIT_ASSEMBLY:
03614                 {
03615                         mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03616                         LSCRIPTType argtype = entry->mFunctionArgs.getType(entrycount);
03617                         if (argtype != mFirstp->mReturnType)
03618                         {
03619                                 fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mFirstp->mReturnType], LSCRIPTTypeNames[argtype]);
03620                         }
03621                         entrycount++;
03622                         if (mSecondp)
03623                         {
03624                                 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03625                                 if (mSecondp->mReturnType)
03626                                 {
03627                                         argtype = entry->mFunctionArgs.getType(entrycount);
03628                                         if (argtype != mSecondp->mReturnType)
03629                                         {
03630                                                 fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mSecondp->mReturnType], LSCRIPTTypeNames[argtype]);
03631                                         }
03632                                 }
03633                         }
03634                 }
03635                 break;
03636         case LSCP_TO_STACK:
03637                 {
03638                         mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03639                         LSCRIPTType argtype = entry->mFunctionArgs.getType(entrycount);
03640                         if (argtype != mFirstp->mReturnType)
03641                         {
03642                                 chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
03643                                 U8 castbyte = LSCRIPTTypeByte[argtype] | LSCRIPTTypeHi4Bits[mFirstp->mReturnType];
03644                                 chunk->addByte(castbyte);
03645                         }
03646                         entrycount++;
03647                         if (mSecondp)
03648                         {
03649                                 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03650                                 if (mSecondp->mReturnType)
03651                                 {
03652                                         argtype = entry->mFunctionArgs.getType(entrycount);
03653                                         if (argtype != mSecondp->mReturnType)
03654                                         {
03655                                                 chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
03656                                                 U8 castbyte = LSCRIPTTypeByte[argtype] | LSCRIPTTypeHi4Bits[mSecondp->mReturnType];
03657                                                 chunk->addByte(castbyte);
03658                                         }
03659                                 }
03660                         }
03661                 }
03662                 break;
03663         /* TODO: Fix conflict between global/local variable determination needing caller scope and cast determination here needs callee scope...
03664         case LSCP_EMIT_CIL_ASSEMBLY:
03665                 {
03666                         mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03667                         LSCRIPTType argtype = entry->mFunctionArgs.getType(entrycount);
03668                         if (argtype != mFirstp->mReturnType)
03669                         {
03670                                 print_cil_cast(fp, mFirstp->mReturnType, argtype);
03671                         }
03672                         entrycount++;
03673                         if (mSecondp)
03674                         {
03675                                 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03676                                 if (mSecondp->mReturnType)
03677                                 {
03678                                         argtype = entry->mFunctionArgs.getType(entrycount);
03679                                         if (argtype != mSecondp->mReturnType)
03680                                         {
03681                                                 print_cil_cast(fp, mFirstp->mReturnType, argtype);
03682                                         }
03683                                 }
03684                         }
03685                 }
03686                 break;
03687                 */
03688         default:
03689                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03690                 if (mSecondp)
03691                 {
03692                         mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03693                 }
03694                 break;
03695         }
03696 }
03697 
03698 S32 LLScriptFuncExpressionList::getSize()
03699 {
03700         return 0;
03701 }
03702 
03703 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)
03704 {
03705         if (gErrorToText.getErrors())
03706         {
03707                 return;
03708         }
03709         switch(pass)
03710         {
03711         case LSCP_PRETTY_PRINT:
03712                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03713                 if (mSecondp)
03714                 {
03715                         fprintf(fp, ", ");
03716                         mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03717                 }
03718                 break;
03719         case LSCP_EMIT_ASSEMBLY:
03720                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03721                 if (mFirstp->mType != LET_LIST_EXPRESSION_LIST)
03722                 {
03723                         fprintf(fp, "%s\n", LSCRIPTListDescription[mFirstp->mReturnType]);
03724                         count++;
03725                 }
03726                 if (mSecondp)
03727                 {
03728                         mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03729                         if (mSecondp->mType != LET_LIST_EXPRESSION_LIST)
03730                         {
03731                                 fprintf(fp, "%s\n", LSCRIPTListDescription[mSecondp->mReturnType]);
03732                                 count++;
03733                         }
03734                 }
03735                 break;
03736         case LSCP_TO_STACK:
03737                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03738                 if (mFirstp->mType != LET_LIST_EXPRESSION_LIST)
03739                 {
03740                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGB]);
03741                         chunk->addByte(LSCRIPTTypeByte[mFirstp->mReturnType]);
03742                         count++;
03743                 }
03744                 if (mSecondp)
03745                 {
03746                         mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03747                         if (mSecondp->mType != LET_LIST_EXPRESSION_LIST)
03748                         {
03749                                 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGB]);
03750                                 chunk->addByte(LSCRIPTTypeByte[mSecondp->mReturnType]);
03751                                 count++;
03752                         }
03753                 }
03754                 break;
03755         case LSCP_EMIT_CIL_ASSEMBLY:
03756                 // Evaluate expressions in reverse order so first expression is on top of stack.
03757                 // Results can then be popped and appended to list to result in list with correct order.
03758                 if (mSecondp)
03759                 {
03760                         mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03761                         if (mSecondp->mType != LET_LIST_EXPRESSION_LIST)
03762                         {
03763                                 // Box value.
03764                                 print_cil_box(fp, mSecondp->mReturnType);
03765 
03766                                 ++count;
03767                         }
03768                 }
03769                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03770                 if (mFirstp->mType != LET_LIST_EXPRESSION_LIST)
03771                 {
03772                         // Box value.
03773                         print_cil_box(fp, mFirstp->mReturnType);
03774 
03775                         ++count;
03776                 }
03777                 break;
03778         default:
03779                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03780                 if (mSecondp)
03781                 {
03782                         mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03783                 }
03784                 break;
03785         }
03786 }
03787 
03788 S32 LLScriptListExpressionList::getSize()
03789 {
03790         return 0;
03791 }
03792 
03793 // Returns true if identifier is a parameter and false if identifier is a local variable within function_scope.
03794 bool is_parameter(LLScriptIdentifier* identifier, LLScriptScopeEntry* function_scope)
03795 {
03796         // Function offset stores offset of first local.
03797         // Compare variable offset with function offset to
03798         // determine whether variable is local or parameter.
03799         return (identifier->mScopeEntry->mOffset < function_scope->mOffset);
03800 }
03801 
03802 // If assignment is to global variable, pushes this pointer on to stack.
03803 void print_cil_load_address(FILE* fp, LLScriptExpression* exp, LLScriptScopeEntry* function_scope)
03804 {
03805         LLScriptLValue *lvalue = (LLScriptLValue *) exp;
03806         LLScriptIdentifier *ident = lvalue->mIdentifier;
03807 
03808         // If global (member), load this pointer.
03809         if(ident->mScopeEntry->mIDType == LIT_GLOBAL)
03810         {
03811                 fprintf(fp, "ldarg.0\n");
03812         }
03813 
03814         // If accessor, load address of object.
03815         if(lvalue->mAccessor)
03816         {
03817                 if(ident->mScopeEntry->mIDType == LIT_VARIABLE)
03818                 {
03819                         if(is_parameter(ident, function_scope))
03820                         {
03821                                 // Parameter, load by name.
03822                                 fprintf(fp, "ldarga.s %s\n", ident->mScopeEntry->mIdentifier);
03823                         }
03824                         else
03825                         {
03826                                 // Local, load by index.
03827                                 fprintf(fp, "ldloca.s %d\n", ident->mScopeEntry->mCount);
03828                         }
03829                 }
03830                 else if (ident->mScopeEntry->mIDType == LIT_GLOBAL)
03831                 {
03832                         fprintf(fp, "ldflda ");
03833                         print_cil_type(fp, ident->mScopeEntry->mType);
03834                         fprintf(fp, " LSL::%s\n", ident->mScopeEntry->mIdentifier);
03835                 }
03836         }
03837 }
03838 
03839 void print_cil_accessor(FILE* fp, LLScriptLValue *lvalue)
03840 {
03841         LLScriptIdentifier *ident = lvalue->mIdentifier;
03842         print_cil_type(fp, lvalue->mReturnType);
03843         fprintf(fp, " ");
03844         print_cil_type(fp, ident->mScopeEntry->mType);
03845         fprintf(fp, "::%s\n", lvalue->mAccessor->mName);
03846 }
03847 
03848 void print_cil_member(FILE* fp, LLScriptIdentifier *ident)
03849 {
03850         print_cil_type(fp, ident->mScopeEntry->mType);
03851         fprintf(fp, " LSL::%s\n", ident->mScopeEntry->mIdentifier);
03852 }
03853 
03854 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)
03855 {
03856         if (gErrorToText.getErrors())
03857         {
03858                 return;
03859         }
03860         switch(pass)
03861         {
03862         case LSCP_PRETTY_PRINT:
03863                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03864                 if (mAccessor)
03865                 {
03866                         fprintf(fp, ".");
03867                         mAccessor->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
03868                 }
03869                 break;
03870         case LSCP_EMIT_ASSEMBLY:
03871                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
03872                 {
03873                         if (mAccessor)
03874                         {
03875                                 fprintf(fp, "%s%d [%s.%s]\n", LSCRIPTTypeLocalPush[mReturnType], mIdentifier->mScopeEntry->mOffset + mOffset, mIdentifier->mName, mAccessor->mName);
03876                         }
03877                         else
03878                         {
03879                                 fprintf(fp, "%s%d [%s]\n", LSCRIPTTypeLocalPush[mIdentifier->mScopeEntry->mType], mIdentifier->mScopeEntry->mOffset, mIdentifier->mName);
03880                         }
03881                 }
03882                 else if (mIdentifier->mScopeEntry->mIDType == LIT_GLOBAL)
03883                 {
03884                         if (mAccessor)
03885                         {
03886                                 fprintf(fp, "%s%d [%s.%s]\n", LSCRIPTTypeGlobalPush[mReturnType], mIdentifier->mScopeEntry->mOffset + mOffset, mIdentifier->mName, mAccessor->mName);
03887                         }
03888                         else
03889                         {
03890                                 fprintf(fp, "%s%d [%s]\n", LSCRIPTTypeGlobalPush[mIdentifier->mScopeEntry->mType], mIdentifier->mScopeEntry->mOffset, mIdentifier->mName);
03891                         }
03892                 }
03893                 else
03894                 {
03895                         fprintf(fp, "Unexpected LValue!\n");
03896                 }
03897                 break;
03898         case LSCP_SCOPE_PASS1:
03899                 {
03900                         LLScriptScopeEntry *entry = scope->findEntry(mIdentifier->mName);
03901                         if (!entry || (  (entry->mIDType != LIT_GLOBAL) && (entry->mIDType != LIT_VARIABLE)))
03902                         {
03903                                 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
03904                         }
03905                         else
03906                         {
03907                                 // if we did find it, make sure this identifier is associated with the correct scope entry
03908                                 mIdentifier->mScopeEntry = entry;
03909                         }
03910                 }
03911                 break;
03912         case LSCP_TYPE:
03913                 // if we have an accessor, we need to change what type our identifier returns and set our offset value
03914                 if (mIdentifier->mScopeEntry)
03915                 {
03916                         if (mAccessor)
03917                         {
03918                                 BOOL b_ok = FALSE;
03919                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
03920                                 {
03921                                         if (mIdentifier->mScopeEntry->mType == LST_VECTOR)
03922                                         {
03923                                                 if (!strcmp("x", mAccessor->mName))
03924                                                 {
03925                                                         mOffset = 0;
03926                                                         b_ok = TRUE;
03927                                                 }
03928                                                 else if (!strcmp("y", mAccessor->mName))
03929                                                 {
03930                                                         mOffset = 4;
03931                                                         b_ok = TRUE;
03932                                                 }
03933                                                 else if (!strcmp("z", mAccessor->mName))
03934                                                 {
03935                                                         mOffset = 8;
03936                                                         b_ok = TRUE;
03937                                                 }
03938                                         }
03939                                         else if (mIdentifier->mScopeEntry->mType == LST_QUATERNION)
03940                                         {
03941                                                 if (!strcmp("x", mAccessor->mName))
03942                                                 {
03943                                                         mOffset = 0;
03944                                                         b_ok = TRUE;
03945                                                 }
03946                                                 else if (!strcmp("y", mAccessor->mName))
03947                                                 {
03948                                                         mOffset = 4;
03949                                                         b_ok = TRUE;
03950                                                 }
03951                                                 else if (!strcmp("z", mAccessor->mName))
03952                                                 {
03953                                                         mOffset = 8;
03954                                                         b_ok = TRUE;
03955                                                 }
03956                                                 else if (!strcmp("s", mAccessor->mName))
03957                                                 {
03958                                                         mOffset = 12;
03959                                                         b_ok = TRUE;
03960                                                 }
03961                                         }
03962                                 }
03963                                 else
03964                                 {
03965                                         if (mIdentifier->mScopeEntry->mType == LST_VECTOR)
03966                                         {
03967                                                 if (!strcmp("x", mAccessor->mName))
03968                                                 {
03969                                                         mOffset = 8;
03970                                                         b_ok = TRUE;
03971                                                 }
03972                                                 else if (!strcmp("y", mAccessor->mName))
03973                                                 {
03974                                                         mOffset = 4;
03975                                                         b_ok = TRUE;
03976                                                 }
03977                                                 else if (!strcmp("z", mAccessor->mName))
03978                                                 {
03979                                                         mOffset = 0;
03980                                                         b_ok = TRUE;
03981                                                 }
03982                                         }
03983                                         else if (mIdentifier->mScopeEntry->mType == LST_QUATERNION)
03984                                         {
03985                                                 if (!strcmp("x", mAccessor->mName))
03986                                                 {
03987                                                         mOffset = 12;
03988                                                         b_ok = TRUE;
03989                                                 }
03990                                                 else if (!strcmp("y", mAccessor->mName))
03991                                                 {
03992                                                         mOffset = 8;
03993                                                         b_ok = TRUE;
03994                                                 }
03995                                                 else if (!strcmp("z", mAccessor->mName))
03996                                                 {
03997                                                         mOffset = 4;
03998                                                         b_ok = TRUE;
03999                                                 }
04000                                                 else if (!strcmp("s", mAccessor->mName))
04001                                                 {
04002                                                         mOffset = 0;
04003                                                         b_ok = TRUE;
04004                                                 }
04005                                         }
04006                                 }
04007                                 if (b_ok)
04008                                 {
04009                                         mReturnType = type =  LST_FLOATINGPOINT;
04010                                 }
04011                                 else
04012                                 {
04013                                         gErrorToText.writeError(fp, this, LSERROR_VECTOR_METHOD_ERROR);
04014                                 }
04015                         }
04016                         else
04017                         {
04018                                 mReturnType = type = mIdentifier->mScopeEntry->mType;
04019                         }
04020                 }
04021                 else
04022                 {
04023                         mReturnType = type = LST_UNDEFINED;
04024                 }
04025                 break;
04026         case LSCP_TO_STACK:
04027                 {
04028                         switch(mReturnType)
04029                         {
04030                         case LST_INTEGER:
04031                         case LST_FLOATINGPOINT:
04032                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
04033                                 {
04034                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSH]);
04035                                 }
04036                                 else
04037                                 {
04038                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHG]);
04039                                 }
04040                                 break;
04041                         case LST_KEY:
04042                         case LST_STRING:
04043                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
04044                                 {
04045                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHS]);
04046                                 }
04047                                 else
04048                                 {
04049                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHGS]);
04050                                 }
04051                                 break;
04052                         case LST_LIST:
04053                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
04054                                 {
04055                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHL]);
04056                                 }
04057                                 else
04058                                 {
04059                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHGL]);
04060                                 }
04061                                 break;
04062                         case LST_VECTOR:
04063                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
04064                                 {
04065                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHV]);
04066                                 }
04067                                 else
04068                                 {
04069                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHGV]);
04070                                 }
04071                                 break;
04072                         case LST_QUATERNION:
04073                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
04074                                 {
04075                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHQ]);
04076                                 }
04077                                 else
04078                                 {
04079                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHGQ]);
04080                                 }
04081                                 break;
04082                         default:
04083                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
04084                                 {
04085                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSH]);
04086                                 }
04087                                 else
04088                                 {
04089                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHG]);
04090                                 }
04091                                 break;
04092                         }
04093                         S32 address = mIdentifier->mScopeEntry->mOffset + mOffset;
04094                         chunk->addInteger(address);
04095                 }       
04096                 break;
04097         case LSCP_EMIT_CIL_ASSEMBLY:
04098                 print_cil_load_address(fp, this, entry);
04099                 if(mAccessor)
04100                 {
04101                         fprintf(fp, "ldfld ");
04102                         print_cil_accessor(fp, this);
04103                 }
04104                 else if(mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
04105                 {
04106                         if(is_parameter(mIdentifier, entry))
04107                         {
04108                                 // Parameter, load by name.
04109                                 fprintf(fp, "ldarg.s %s\n", mIdentifier->mScopeEntry->mIdentifier);
04110                         }
04111                         else
04112                         {
04113                                 // Local, load by index.
04114                                 fprintf(fp, "ldloc.s %d\n", mIdentifier->mScopeEntry->mCount);
04115                         }
04116                 }
04117                 else if (mIdentifier->mScopeEntry->mIDType == LIT_GLOBAL)
04118                 {
04119                         fprintf(fp, "ldfld ");
04120                         print_cil_member(fp, mIdentifier);
04121                 }
04122                 else
04123                 {
04124                         fprintf(fp, "Unexpected LValue!\n");
04125                 }
04126                 break;
04127         default:
04128                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04129                 break;
04130         }
04131         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04132 }
04133 
04134 S32 LLScriptLValue::getSize()
04135 {
04136         return 0;
04137 }
04138 
04139 void print_asignment(FILE *fp, LLScriptExpression *exp)
04140 {
04141         LLScriptLValue *lvalue = (LLScriptLValue *)exp;
04142         LLScriptIdentifier *ident = lvalue->mIdentifier;
04143         if (lvalue->mAccessor)
04144         {
04145                 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
04146                 {
04147                         fprintf(fp, "%s%d [%s.%s]\n", LSCRIPTTypeLocalStore[ident->mScopeEntry->mType], ident->mScopeEntry->mOffset + lvalue->mOffset, ident->mName, lvalue->mAccessor->mName);
04148                 }
04149                 else if (ident->mScopeEntry->mIDType == LIT_GLOBAL)
04150                 {
04151                         fprintf(fp, "%s%d [%s.%s]\n", LSCRIPTTypeGlobalStore[ident->mScopeEntry->mType], ident->mScopeEntry->mOffset + lvalue->mOffset, ident->mName, lvalue->mAccessor->mName);
04152                 }
04153         }
04154         else
04155         {
04156                 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
04157                 {
04158                         fprintf(fp, "%s%d [%s]\n", LSCRIPTTypeLocalStore[ident->mScopeEntry->mType], ident->mScopeEntry->mOffset, ident->mName);
04159                 }
04160                 else if (ident->mScopeEntry->mIDType == LIT_GLOBAL)
04161                 {
04162                         fprintf(fp, "%s%d [%s]\n", LSCRIPTTypeGlobalStore[ident->mScopeEntry->mType], ident->mScopeEntry->mOffset, ident->mName);
04163                 }
04164         }
04165 }
04166 
04167 void print_cil_asignment(FILE *fp, LLScriptExpression *exp, LLScriptScopeEntry* function_scope)
04168 {
04169         LLScriptLValue *lvalue = (LLScriptLValue *) exp;
04170         LLScriptIdentifier *ident = lvalue->mIdentifier;
04171         if (lvalue->mAccessor)
04172         {
04173                 // Object address loaded, store in to field.
04174                 fprintf(fp, "stfld ");
04175                 print_cil_accessor(fp, lvalue);
04176 
04177                 // Load object address.
04178                 print_cil_load_address(fp, exp, function_scope);
04179 
04180                 // Load field.
04181                 fprintf(fp, "ldfld ");
04182                 print_cil_accessor(fp, lvalue);
04183         }
04184         else
04185         {
04186                 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
04187                 {
04188                         // Language semantics require value of assignment to be left on stack. 
04189                         // TODO: Optimise away redundant dup/pop pairs.
04190                         fprintf(fp, "dup\n"); 
04191                         if(is_parameter(ident, function_scope))
04192                         {
04193                                 // Parameter, store by name.
04194                                 fprintf(fp, "starg.s %s\n", ident->mScopeEntry->mIdentifier);
04195                         }
04196                         else
04197                         {
04198                                 // Local, store by index.
04199                                 fprintf(fp, "stloc.s %d\n", ident->mScopeEntry->mCount);
04200                         }
04201                 }
04202                 else if (ident->mScopeEntry->mIDType == LIT_GLOBAL)
04203                 {
04204                         // Object address loaded, store in to field.
04205                         fprintf(fp, "stfld ");
04206                         print_cil_member(fp, ident);
04207 
04208                         // Load object address.
04209                         print_cil_load_address(fp, exp, function_scope);
04210 
04211                         // Load field.
04212                         fprintf(fp, "ldfld ");
04213                         print_cil_member(fp, ident);
04214                 }
04215         }
04216 }
04217 
04218 void print_cast(FILE *fp, LSCRIPTType ret_type, LSCRIPTType right_type)
04219 {
04220         if (right_type != ret_type)
04221         {
04222                 fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[right_type], LSCRIPTTypeNames[ret_type]);
04223         }
04224 }
04225 
04226 void cast2stack(LLScriptByteCodeChunk *chunk, LSCRIPTType ret_type, LSCRIPTType right_type)
04227 {
04228         if (right_type != ret_type)
04229         {
04230                 chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
04231                 U8 castbyte = LSCRIPTTypeByte[right_type] | LSCRIPTTypeHi4Bits[ret_type];
04232                 chunk->addByte(castbyte);
04233         }
04234 }
04235 
04236 void operation2stack(LLScriptByteCodeChunk *chunk, LSCRIPTType ret_type, LSCRIPTType right_type)
04237 {
04238         U8 typebyte = LSCRIPTTypeByte[right_type] | LSCRIPTTypeHi4Bits[ret_type];
04239         chunk->addByte(typebyte);
04240 }
04241 
04242 void store2stack(LLScriptExpression *exp, LLScriptExpression *lv, LLScriptByteCodeChunk *chunk, LSCRIPTType right_type)
04243 {
04244         LLScriptLValue *lvalue = (LLScriptLValue *)lv;
04245         LLScriptIdentifier *ident = lvalue->mIdentifier;
04246         LSCRIPTType rettype = exp->mReturnType;
04247 
04248         if (exp->mRightType != LST_NULL)
04249         {
04250                 if (legal_binary_expression(rettype, exp->mLeftType, exp->mRightType, exp->mType)) 
04251                         cast2stack(chunk, right_type, exp->mReturnType);
04252         }
04253         switch(exp->mReturnType)
04254         {
04255         case LST_INTEGER:
04256         case LST_FLOATINGPOINT:
04257                 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
04258                 {
04259                         chunk->addByte(LSCRIPTOpCodes[LOPC_STORE]);
04260                 }
04261                 else
04262                 {
04263                         chunk->addByte(LSCRIPTOpCodes[LOPC_STOREG]);
04264                 }
04265                 break;
04266         case LST_KEY:
04267         case LST_STRING:
04268                 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
04269                 {
04270                         chunk->addByte(LSCRIPTOpCodes[LOPC_STORES]);
04271                 }
04272                 else
04273                 {
04274                         chunk->addByte(LSCRIPTOpCodes[LOPC_STOREGS]);
04275                 }
04276                 break;
04277         case LST_LIST:
04278                 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
04279                 {
04280                         chunk->addByte(LSCRIPTOpCodes[LOPC_STOREL]);
04281                 }
04282                 else
04283                 {
04284                         chunk->addByte(LSCRIPTOpCodes[LOPC_STOREGL]);
04285                 }
04286                 break;
04287         case LST_VECTOR:
04288                 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
04289                 {
04290                         chunk->addByte(LSCRIPTOpCodes[LOPC_STOREV]);
04291                 }
04292                 else
04293                 {
04294                         chunk->addByte(LSCRIPTOpCodes[LOPC_STOREGV]);
04295                 }
04296                 break;
04297         case LST_QUATERNION:
04298                 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
04299                 {
04300                         chunk->addByte(LSCRIPTOpCodes[LOPC_STOREQ]);
04301                 }
04302                 else
04303                 {
04304                         chunk->addByte(LSCRIPTOpCodes[LOPC_STOREGQ]);
04305                 }
04306                 break;
04307         default:
04308                 if (ident->mScopeEntry->mIDType == LIT_VARIABLE)
04309                 {
04310                         chunk->addByte(LSCRIPTOpCodes[LOPC_STORE]);
04311                 }
04312                 else
04313                 {
04314                         chunk->addByte(LSCRIPTOpCodes[LOPC_STOREG]);
04315                 }
04316                 break;
04317         }
04318         S32 address = ident->mScopeEntry->mOffset + lvalue->mOffset;
04319         chunk->addInteger(address);
04320 }
04321 
04322 void print_cil_numeric_cast(FILE* fp, LSCRIPTType currentArg, LSCRIPTType otherArg)
04323 {
04324         if((currentArg == LST_INTEGER) && (otherArg == LST_FLOATINGPOINT))
04325         {
04326                 print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
04327         }
04328 }
04329 
04330 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)
04331 {
04332         if (gErrorToText.getErrors())
04333         {
04334                 return;
04335         }
04336         switch(pass)
04337         {
04338         case LSCP_PRETTY_PRINT:
04339                 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04340                 fprintf(fp, " = ");
04341                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04342                 break;
04343         case LSCP_EMIT_ASSEMBLY:
04344                 {
04345                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04346                         print_cast(fp, mReturnType, mRightType);
04347                         print_asignment(fp, mLValue);
04348                 }
04349                 break;
04350         case LSCP_TYPE:
04351                 {
04352                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04353                         mLeftType = type;
04354                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04355                         mRightType = type;
04356                         if (!legal_assignment(mLeftType, mRightType))
04357                         {
04358                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
04359                         }
04360                         type = mReturnType = mLeftType;
04361                 }
04362                 break;
04363         case LSCP_TO_STACK:
04364                 {
04365                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04366                         store2stack(this, mLValue, chunk, mRightType);
04367                 }
04368                 break;
04369         case LSCP_EMIT_CIL_ASSEMBLY:
04370                 {
04371                         print_cil_load_address(fp, mLValue, entry);
04372                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04373                         print_cil_numeric_cast(fp, mRightType, mReturnType);
04374                         print_cil_asignment(fp, mLValue, entry);
04375                 }
04376                 break;
04377         default:
04378                 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04379                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04380                 break;
04381         }
04382         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04383 }
04384 
04385 S32 LLScriptAssignment::getSize()
04386 {
04387         return 0;
04388 }
04389 
04390 void print_cil_add(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
04391 {
04392         switch(left_type)
04393         {
04394         case LST_INTEGER:
04395         case LST_FLOATINGPOINT:
04396 
04397                 // Numeric addition.
04398                 fprintf(fp, "add\n");
04399                 break;
04400 
04401         case LST_STRING:
04402         case LST_KEY:
04403 
04404                 // String concatenation.
04405                 fprintf(fp, "call string valuetype [mscorlib]System.String::Concat(string, string)");
04406                 break;
04407         
04408         case LST_VECTOR:
04409 
04410                 // Vector addition.
04411                 // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
04412                 fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'add_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
04413                 break;
04414 
04415         case LST_QUATERNION:
04416 
04417                 // Rotation addition.
04418                 // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
04419                 fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'add_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
04420                 break;
04421 
04422         case LST_LIST:
04423                 print_cil_box(fp, right_type);
04424                 fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::AddReturnList(class [mscorlib]System.Collections.ArrayList, object)\n");
04425                 break;
04426 
04427         default:
04428                 break;
04429         }
04430 }
04431 
04432 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)
04433 {
04434         if (gErrorToText.getErrors())
04435         {
04436                 return;
04437         }
04438         switch(pass)
04439         {
04440         case LSCP_PRETTY_PRINT:
04441                 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04442                 fprintf(fp, " += ");
04443                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04444                 break;
04445         case LSCP_EMIT_ASSEMBLY:
04446                 {
04447                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04448                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04449                         fprintf(fp, "ADD %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
04450                         print_asignment(fp, mLValue);
04451                 }
04452                 break;
04453         case LSCP_TYPE:
04454                 {
04455                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04456                         mLeftType = type;
04457                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04458                         mRightType = type;
04459                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
04460                         {
04461                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
04462                         }
04463                         type = mReturnType;
04464                 }
04465                 break;
04466         case LSCP_TO_STACK:
04467                 {
04468                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04469                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04470                         chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
04471                         operation2stack(chunk, mReturnType, mRightType);
04472                         store2stack(this, mLValue, chunk, mReturnType);
04473                 }
04474                 break;
04475         case LSCP_EMIT_CIL_ASSEMBLY:
04476                 {
04477                         print_cil_load_address(fp, mLValue, entry);
04478                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04479                         print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
04480                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04481                         print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
04482                         print_cil_add(fp, mLValue->mReturnType, mRightSide->mReturnType);
04483                         print_cil_asignment(fp, mLValue, entry);
04484                 }
04485                 break;
04486         default:
04487                 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04488                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04489                 break;
04490         }
04491         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04492 }
04493 
04494 S32 LLScriptAddAssignment::getSize()
04495 {
04496         return 0;
04497 }
04498 
04499 void print_cil_sub(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
04500 {
04501         switch(left_type)
04502         {
04503         case LST_INTEGER:
04504         case LST_FLOATINGPOINT:
04505 
04506                 // Numeric subtraction.
04507                 fprintf(fp, "sub\n");
04508                 break;
04509         
04510         case LST_VECTOR:
04511 
04512                 // Vector subtraction.
04513                 // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
04514                 fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'subtract_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
04515                 break;
04516 
04517         case LST_QUATERNION:
04518 
04519                 // Rotation subtraction.
04520                 // TODO: Inline (requires temporary variables, which must be identified in earlier pass).
04521                 fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'subtract_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
04522                 break;
04523 
04524         default:
04525 
04526                 // Error.
04527                 break;
04528         }
04529 }
04530 
04531 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)
04532 {
04533         if (gErrorToText.getErrors())
04534         {
04535                 return;
04536         }
04537         switch(pass)
04538         {
04539         case LSCP_PRETTY_PRINT:
04540                 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04541                 fprintf(fp, " -= ");
04542                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04543                 break;
04544         case LSCP_EMIT_ASSEMBLY:
04545                 {
04546                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04547                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04548                         fprintf(fp, "SUB %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
04549                         print_asignment(fp, mLValue);
04550                 }
04551                 break;
04552         case LSCP_TYPE:
04553                 {
04554                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04555                         mLeftType = type;
04556                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04557                         mRightType = type;
04558                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
04559                         {
04560                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
04561                         }
04562                         type = mReturnType;
04563                 }
04564                 break;
04565         case LSCP_TO_STACK:
04566                 {
04567                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04568                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04569                         chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
04570                         operation2stack(chunk, mReturnType, mRightType);
04571                         store2stack(this, mLValue, chunk, mReturnType);
04572                 }
04573                 break;
04574         case LSCP_EMIT_CIL_ASSEMBLY:
04575                 {
04576                         print_cil_load_address(fp, mLValue, entry);
04577                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04578                         print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
04579                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04580                         print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
04581                         print_cil_sub(fp, mLValue->mReturnType, mRightSide->mReturnType);
04582                         print_cil_asignment(fp, mLValue, entry);
04583                 }
04584                 break;
04585         default:
04586                 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04587                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04588                 break;
04589         }
04590         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04591 }
04592 
04593 S32 LLScriptSubAssignment::getSize()
04594 {
04595         return 0;
04596 }
04597 
04598 void print_cil_mul(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
04599 {
04600         switch(left_type)
04601         {
04602         case LST_INTEGER:
04603         case LST_FLOATINGPOINT:
04604 
04605                 // Numeric multiplication.
04606                 fprintf(fp, "mul\n");
04607                 break;
04608         
04609         case LST_VECTOR:
04610 
04611                 switch(right_type)
04612                 {
04613                 case LST_INTEGER:
04614 
04615                         print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
04616 
04617                 case LST_FLOATINGPOINT:
04618 
04619                         // Vector scaling.
04620                         fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'multiply_float'(valuetype [LScriptLibrary]LLVector, float32)\n");
04621                         break;
04622 
04623                 case LST_VECTOR:
04624 
04625                         // Dot product.
04626                         fprintf(fp, "call float32 valuetype [LScriptLibrary]LLVector::'multiply_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
04627                         break;
04628 
04629                 case LST_QUATERNION:
04630 
04631                         // Vector rotation.
04632                         fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'multiply_quat'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLQuaternion)\n");
04633                         break;
04634 
04635                 default:
04636                         break;
04637                 }
04638                 break;
04639 
04640         case LST_QUATERNION:
04641 
04642                 // Rotation multiplication.
04643                 fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'multiply_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
04644                 break;
04645 
04646         default:
04647 
04648                 // Error.
04649                 break;
04650         }
04651 }
04652 
04653 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)
04654 {
04655         if (gErrorToText.getErrors())
04656         {
04657                 return;
04658         }
04659         switch(pass)
04660         {
04661         case LSCP_PRETTY_PRINT:
04662                 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04663                 fprintf(fp, " *= ");
04664                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04665                 break;
04666         case LSCP_EMIT_ASSEMBLY:
04667                 {
04668                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04669                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04670                         fprintf(fp, "MUL %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
04671                         print_asignment(fp, mLValue);
04672                 }
04673                 break;
04674         case LSCP_TYPE:
04675                 {
04676                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04677                         mLeftType = type;
04678                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04679                         mRightType = type;
04680                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
04681                         {
04682                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
04683                         }
04684                         type = mReturnType;
04685                 }
04686                 break;
04687         case LSCP_TO_STACK:
04688                 {
04689                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04690                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04691                         chunk->addByte(LSCRIPTOpCodes[LOPC_MUL]);
04692                         operation2stack(chunk, mReturnType, mRightType);
04693                         store2stack(this, mLValue, chunk, mReturnType);
04694                 }
04695                 break;
04696         case LSCP_EMIT_CIL_ASSEMBLY:
04697                 {
04698                         print_cil_load_address(fp, mLValue, entry);
04699                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04700                         print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
04701                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04702                         print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
04703                         print_cil_mul(fp, mLValue->mReturnType, mRightSide->mReturnType);
04704                         print_cil_asignment(fp, mLValue, entry);
04705                 }
04706                 break;
04707         default:
04708                 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04709                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04710                 break;
04711         }
04712         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04713 }
04714 
04715 S32 LLScriptMulAssignment::getSize()
04716 {
04717         return 0;
04718 }
04719 
04720 void print_cil_div(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
04721 {
04722         switch(left_type)
04723         {
04724         case LST_INTEGER:
04725         case LST_FLOATINGPOINT:
04726 
04727                 // Numeric addition.
04728                 fprintf(fp, "div\n");
04729                 break;
04730         
04731         case LST_VECTOR:
04732 
04733                 switch(right_type)
04734                 {
04735                 case LST_INTEGER:
04736 
04737                         print_cil_cast(fp, LST_INTEGER, LST_FLOATINGPOINT);
04738 
04739                 case LST_FLOATINGPOINT:
04740 
04741                         // Scale.
04742                         fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'divide_float'(valuetype [LScriptLibrary]LLVector, float32)\n");
04743                         break;
04744 
04745                 case LST_QUATERNION:
04746 
04747                         // Inverse rotation.
04748                         fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'divide_quat'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLQuaternion)\n");
04749                         break;
04750 
04751                 default:
04752                         break;
04753                 }
04754                 break;
04755 
04756         case LST_QUATERNION:
04757 
04758                 fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'divide_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");             
04759                 break;
04760 
04761         default:
04762 
04763                 // Error.
04764                 break;
04765         }
04766 }
04767 
04768 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)
04769 {
04770         if (gErrorToText.getErrors())
04771         {
04772                 return;
04773         }
04774         switch(pass)
04775         {
04776         case LSCP_PRETTY_PRINT:
04777                 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04778                 fprintf(fp, " /= ");
04779                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04780                 break;
04781         case LSCP_EMIT_ASSEMBLY:
04782                 {
04783                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04784                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04785                         fprintf(fp, "DIV %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
04786                         print_asignment(fp, mLValue);
04787                 }
04788                 break;
04789         case LSCP_TYPE:
04790                 {
04791                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04792                         mLeftType = type;
04793                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04794                         mRightType = type;
04795                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
04796                         {
04797                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
04798                         }
04799                         type = mReturnType;
04800                 }
04801                 break;
04802         case LSCP_TO_STACK:
04803                 {
04804                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04805                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04806                         chunk->addByte(LSCRIPTOpCodes[LOPC_DIV]);
04807                         operation2stack(chunk, mReturnType, mRightType);
04808                         store2stack(this, mLValue, chunk, mReturnType);
04809                 }
04810                 break;
04811         case LSCP_EMIT_CIL_ASSEMBLY:
04812                 {
04813                         print_cil_load_address(fp, mLValue, entry);
04814                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04815                         print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
04816                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04817                         print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
04818                         print_cil_div(fp, mLValue->mReturnType, mRightSide->mReturnType);
04819                         print_cil_asignment(fp, mLValue, entry);
04820                 }
04821                 break;
04822         default:
04823                 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04824                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04825                 break;
04826         }
04827         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04828 }
04829 
04830 S32 LLScriptDivAssignment::getSize()
04831 {
04832         return 0;
04833 }
04834 
04835 void print_cil_mod(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
04836 {
04837         switch(left_type)
04838         {
04839         case LST_INTEGER:
04840 
04841                 // Numeric remainder.
04842                 fprintf(fp, "rem\n");
04843                 break;
04844         
04845         case LST_VECTOR:
04846 
04847                 // Vector cross product.
04848                 fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'mod_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
04849                 break;
04850 
04851         default:
04852 
04853                 // Error.
04854                 break;
04855         }
04856 }
04857 
04858 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)
04859 {
04860         if (gErrorToText.getErrors())
04861         {
04862                 return;
04863         }
04864         switch(pass)
04865         {
04866         case LSCP_PRETTY_PRINT:
04867                 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04868                 fprintf(fp, " %%= ");
04869                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04870                 break;
04871         case LSCP_EMIT_ASSEMBLY:
04872                 {
04873                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04874                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04875                         fprintf(fp, "MOD %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
04876                         print_asignment(fp, mLValue);
04877                 }
04878                 break;
04879         case LSCP_TYPE:
04880                 {
04881                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04882                         mLeftType = type;
04883                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04884                         mRightType = type;
04885                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
04886                         {
04887                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
04888                         }
04889                         type = mReturnType;
04890                 }
04891                 break;
04892         case LSCP_TO_STACK:
04893                 {
04894                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04895                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04896                         chunk->addByte(LSCRIPTOpCodes[LOPC_MOD]);
04897                         operation2stack(chunk, mReturnType, mRightType);
04898                         store2stack(this, mLValue, chunk, mReturnType);
04899                 }
04900                 break;
04901         case LSCP_EMIT_CIL_ASSEMBLY:
04902                 {
04903                         print_cil_load_address(fp, mLValue, entry);
04904                         mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04905                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04906                         print_cil_mod(fp, mLValue->mReturnType, mRightSide->mReturnType);
04907                         print_cil_asignment(fp, mLValue, entry);
04908                 }
04909                 break;
04910         default:
04911                 mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04912                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04913                 break;
04914         }
04915         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04916 }
04917 
04918 S32 LLScriptModAssignment::getSize()
04919 {
04920         return 0;
04921 }
04922 
04923 void print_cil_eq(FILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
04924 {
04925         switch(left_type)
04926         {
04927         case LST_INTEGER:
04928         case LST_FLOATINGPOINT:
04929 
04930                 // Numeric equality.
04931                 fprintf(fp, "ceq\n");
04932                 break;
04933 
04934         case LST_STRING:
04935         case LST_KEY:
04936 
04937                 // String equality.
04938                 fprintf(fp, "call bool valuetype [mscorlib]System.String::op_Equality(string, string)\n");
04939                 break;
04940         
04941         case LST_VECTOR:
04942 
04943                 // Vector equality.
04944                 fprintf(fp, "call bool [LScriptLibrary]LLVector::'equals_vec'(valuetype [LScriptLibrary]LLVector, valuetype [LScriptLibrary]LLVector)\n");
04945                 break;
04946 
04947         case LST_QUATERNION:
04948 
04949                 // Rotation equality.
04950                 fprintf(fp, "call bool [LScriptLibrary]LLQuaternion::'equals_quat'(valuetype [LScriptLibrary]LLQuaternion, valuetype [LScriptLibrary]LLQuaternion)\n");
04951                 break;
04952 
04953         case LST_LIST:
04954                 fprintf(fp, "call bool [LScriptLibrary]LScriptInternal::EqualsList(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)\n");
04955                 break;
04956 
04957         default:
04958 
04959                 // Error.
04960                 break;
04961         }
04962 }
04963 
04964 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)
04965 {
04966         if (gErrorToText.getErrors())
04967         {
04968                 return;
04969         }
04970         switch(pass)
04971         {
04972         case LSCP_PRETTY_PRINT:
04973                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04974                 fprintf(fp, " == ");
04975                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04976                 break;
04977         case LSCP_EMIT_ASSEMBLY:
04978                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04979                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04980                 fprintf(fp, "EQ %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
04981                 break;
04982         case LSCP_TYPE:
04983                 {
04984                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04985                         mLeftType = type;
04986                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04987                         mRightType = type;
04988                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
04989                         {
04990                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
04991                         }
04992                         type = mReturnType;
04993                 }
04994                 break;
04995         case LSCP_TO_STACK:
04996                 {
04997                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04998                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
04999                         U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
05000                         chunk->addByte(LSCRIPTOpCodes[LOPC_EQ]);
05001                         chunk->addByte(typebyte);
05002                 }
05003                 break;
05004         case LSCP_EMIT_CIL_ASSEMBLY:
05005                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05006                 print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
05007                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05008                 print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
05009                 print_cil_eq(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
05010                 break;
05011         default:
05012                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05013                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05014                 break;
05015         }
05016         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05017 }
05018 
05019 S32 LLScriptEquality::getSize()
05020 {
05021         return 0;
05022 }
05023 
05024 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)
05025 {
05026         if (gErrorToText.getErrors())
05027         {
05028                 return;
05029         }
05030         switch(pass)
05031         {
05032         case LSCP_PRETTY_PRINT:
05033                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05034                 fprintf(fp, " != ");
05035                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05036                 break;
05037         case LSCP_EMIT_ASSEMBLY:
05038                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05039                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05040                 fprintf(fp, "NEQ %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
05041                 break;
05042         case LSCP_TYPE:
05043                 {
05044                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05045                         mLeftType = type;
05046                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05047                         mRightType = type;
05048                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05049                         {
05050                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05051                         }
05052                         type = mReturnType;
05053                 }
05054                 break;
05055         case LSCP_TO_STACK:
05056                 {
05057                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05058                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05059                         U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
05060                         chunk->addByte(LSCRIPTOpCodes[LOPC_NEQ]);
05061                         chunk->addByte(typebyte);
05062                 }
05063                 break;
05064         case LSCP_EMIT_CIL_ASSEMBLY:
05065                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05066                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05067                 fprintf(fp, "ceq\n");
05068                 fprintf(fp, "ldc.i4.0\n");
05069                 fprintf(fp, "ceq\n"); // Compare result of first compare equal with 0 to get compare not equal.
05070                 break;
05071         default:
05072                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05073                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05074                 break;
05075         }
05076         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05077 }
05078 
05079 S32 LLScriptNotEquals::getSize()
05080 {
05081         return 0;
05082 }
05083 
05084 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)
05085 {
05086         if (gErrorToText.getErrors())
05087         {
05088                 return;
05089         }
05090         switch(pass)
05091         {
05092         case LSCP_PRETTY_PRINT:
05093                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05094                 fprintf(fp, " <= ");
05095                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05096                 break;
05097         case LSCP_EMIT_ASSEMBLY:
05098                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05099                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05100                 fprintf(fp, "LEQ %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
05101                 break;
05102         case LSCP_TYPE:
05103                 {
05104                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05105                         mLeftType = type;
05106                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05107                         mRightType = type;
05108                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05109                         {
05110                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05111                         }
05112                         type = mReturnType;
05113                 }
05114                 break;
05115         case LSCP_TO_STACK:
05116                 {
05117                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05118                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05119                         U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
05120                         chunk->addByte(LSCRIPTOpCodes[LOPC_LEQ]);
05121                         chunk->addByte(typebyte);
05122                 }
05123                 break;
05124         case LSCP_EMIT_CIL_ASSEMBLY:
05125                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05126                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05127                 fprintf(fp, "cgt\n"); // Test greater than.
05128                 fprintf(fp, "ldc.i4.0\n"); // Use (b == 0) implementation of boolean not.
05129                 fprintf(fp, "ceq\n"); // Apply boolean not to greater than. If not greater than, then less or equal.
05130                 break;
05131         default:
05132                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05133                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05134                 break;
05135         }
05136         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05137 }
05138 
05139 S32 LLScriptLessEquals::getSize()
05140 {
05141         return 0;
05142 }
05143 
05144 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)
05145 {
05146         if (gErrorToText.getErrors())
05147         {
05148                 return;
05149         }
05150         switch(pass)
05151         {
05152         case LSCP_PRETTY_PRINT:
05153                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05154                 fprintf(fp, " >= ");
05155                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05156                 break;
05157         case LSCP_EMIT_ASSEMBLY:
05158                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05159                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05160                 fprintf(fp, "GEQ %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
05161                 break;
05162         case LSCP_TYPE:
05163                 {
05164                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05165                         mLeftType = type;
05166                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05167                         mRightType = type;
05168                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05169                         {
05170                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05171                         }
05172                         type = mReturnType;
05173                 }
05174                 break;
05175         case LSCP_TO_STACK:
05176                 {
05177                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05178                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05179                         U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
05180                         chunk->addByte(LSCRIPTOpCodes[LOPC_GEQ]);
05181                         chunk->addByte(typebyte);
05182                 }
05183                 break;
05184         case LSCP_EMIT_CIL_ASSEMBLY:
05185                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05186                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05187                 fprintf(fp, "clt\n"); // Test less than.
05188                 fprintf(fp, "ldc.i4.0\n"); // Use (b == 0) implementation of boolean not.
05189                 fprintf(fp, "ceq\n"); // Apply boolean not to less than. If not less than, then greater or equal.
05190                 break;
05191         default:
05192                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05193                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05194                 break;
05195         }
05196         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05197 }
05198 
05199 S32 LLScriptGreaterEquals::getSize()
05200 {
05201         return 0;
05202 }
05203 
05204 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)
05205 {
05206         if (gErrorToText.getErrors())
05207         {
05208                 return;
05209         }
05210         switch(pass)
05211         {
05212         case LSCP_PRETTY_PRINT:
05213                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05214                 fprintf(fp, " < ");
05215                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05216                 break;
05217         case LSCP_EMIT_ASSEMBLY:
05218                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05219                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05220                 fprintf(fp, "LESS %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
05221                 break;
05222         case LSCP_TYPE:
05223                 {
05224                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05225                         mLeftType = type;
05226                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05227                         mRightType = type;
05228                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05229                         {
05230                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05231                         }
05232                         type = mReturnType;
05233                 }
05234                 break;
05235         case LSCP_TO_STACK:
05236                 {
05237                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05238                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05239                         U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
05240                         chunk->addByte(LSCRIPTOpCodes[LOPC_LESS]);
05241                         chunk->addByte(typebyte);
05242                 }
05243                 break;
05244         case LSCP_EMIT_CIL_ASSEMBLY:
05245                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05246                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05247                 fprintf(fp, "clt\n");
05248                 break;
05249         default:
05250                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05251                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05252                 break;
05253         }
05254         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05255 }
05256 
05257 S32 LLScriptLessThan::getSize()
05258 {
05259         return 0;
05260 }
05261 
05262 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)
05263 {
05264         if (gErrorToText.getErrors())
05265         {
05266                 return;
05267         }
05268         switch(pass)
05269         {
05270         case LSCP_PRETTY_PRINT:
05271                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05272                 fprintf(fp, " > ");
05273                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05274                 break;
05275         case LSCP_EMIT_ASSEMBLY:
05276                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05277                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05278                 fprintf(fp, "GREATER %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
05279                 break;
05280         case LSCP_TYPE:
05281                 {
05282                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05283                         mLeftType = type;
05284                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05285                         mRightType = type;
05286                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05287                         {
05288                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05289                         }
05290                         type = mReturnType;
05291                 }
05292                 break;
05293         case LSCP_TO_STACK:
05294                 {
05295                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05296                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05297                         U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
05298                         chunk->addByte(LSCRIPTOpCodes[LOPC_GREATER]);
05299                         chunk->addByte(typebyte);
05300                 }
05301                 break;
05302         case LSCP_EMIT_CIL_ASSEMBLY:
05303                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05304                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05305                 fprintf(fp, "cgt\n");
05306                 break;
05307         default:
05308                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05309                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05310                 break;
05311         }
05312         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05313 }
05314 
05315 S32 LLScriptGreaterThan::getSize()
05316 {
05317         return 0;
05318 }
05319 
05320 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)
05321 {
05322         if (gErrorToText.getErrors())
05323         {
05324                 return;
05325         }
05326         switch(pass)
05327         {
05328         case LSCP_PRETTY_PRINT:
05329                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05330                 fprintf(fp, " + ");
05331                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05332                 break;
05333         case LSCP_EMIT_ASSEMBLY:
05334                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05335                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05336                 fprintf(fp, "ADD %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
05337                 break;
05338         case LSCP_TYPE:
05339                 {
05340                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05341                         mLeftType = type;
05342                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05343                         mRightType = type;
05344                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05345                         {
05346                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05347                         }
05348                         type = mReturnType;
05349                 }
05350                 break;
05351         case LSCP_TO_STACK:
05352                 {
05353                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05354                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05355                         U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
05356                         chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
05357                         chunk->addByte(typebyte);
05358                 }
05359                 break;
05360         case LSCP_EMIT_CIL_ASSEMBLY:
05361                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05362                 print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
05363                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05364                 print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
05365                 print_cil_add(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
05366                 break;
05367         default:
05368                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05369                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05370                 break;
05371         }
05372         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05373 }
05374 
05375 S32 LLScriptPlus::getSize()
05376 {
05377         return 0;
05378 }
05379 
05380 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)
05381 {
05382         if (gErrorToText.getErrors())
05383         {
05384                 return;
05385         }
05386         switch(pass)
05387         {
05388         case LSCP_PRETTY_PRINT:
05389                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05390                 fprintf(fp, " - ");
05391                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05392                 break;
05393         case LSCP_EMIT_ASSEMBLY:
05394                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05395                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05396                 fprintf(fp, "SUB %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
05397                 break;
05398         case LSCP_TYPE:
05399                 {
05400                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05401                         mLeftType = type;
05402                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05403                         mRightType = type;
05404                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05405                         {
05406                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05407                         }
05408                         type = mReturnType;
05409                 }
05410                 break;
05411         case LSCP_TO_STACK:
05412                 {
05413                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05414                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05415                         U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
05416                         chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
05417                         chunk->addByte(typebyte);
05418                 }
05419                 break;
05420         case LSCP_EMIT_CIL_ASSEMBLY:
05421                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05422                 print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
05423                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05424                 print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
05425                 print_cil_sub(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
05426                 break;
05427         default:
05428                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05429                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05430                 break;
05431         }
05432         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05433 }
05434 
05435 S32 LLScriptMinus::getSize()
05436 {
05437         return 0;
05438 }
05439 
05440 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)
05441 {
05442         if (gErrorToText.getErrors())
05443         {
05444                 return;
05445         }
05446         switch(pass)
05447         {
05448         case LSCP_PRETTY_PRINT:
05449                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05450                 fprintf(fp, " * ");
05451                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05452                 break;
05453         case LSCP_EMIT_ASSEMBLY:
05454                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05455                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05456                 fprintf(fp, "MUL %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
05457                 break;
05458         case LSCP_TYPE:
05459                 {
05460                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05461                         mLeftType = type;
05462                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05463                         mRightType = type;
05464                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05465                         {
05466                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05467                         }
05468                         type = mReturnType;
05469                 }
05470                 break;
05471         case LSCP_TO_STACK:
05472                 {
05473                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05474                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05475                         U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
05476                         chunk->addByte(LSCRIPTOpCodes[LOPC_MUL]);
05477                         chunk->addByte(typebyte);
05478                 }
05479                 break;
05480         case LSCP_EMIT_CIL_ASSEMBLY:
05481                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05482                 print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
05483                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05484                 print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
05485                 print_cil_mul(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
05486                 break;
05487         default:
05488                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05489                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05490                 break;
05491         }
05492         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05493 }
05494 
05495 S32 LLScriptTimes::getSize()
05496 {
05497         return 0;
05498 }
05499 
05500 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)
05501 {
05502         if (gErrorToText.getErrors())
05503         {
05504                 return;
05505         }
05506         switch(pass)
05507         {
05508         case LSCP_PRETTY_PRINT:
05509                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05510                 fprintf(fp, " / ");
05511                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05512                 break;
05513         case LSCP_EMIT_ASSEMBLY:
05514                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05515                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05516                 fprintf(fp, "DIV %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
05517                 break;
05518         case LSCP_TYPE:
05519                 {
05520                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05521                         mLeftType = type;
05522                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05523                         mRightType = type;
05524                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05525                         {
05526                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05527                         }
05528                         type = mReturnType;
05529                 }
05530                 break;
05531         case LSCP_TO_STACK:
05532                 {
05533                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05534                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05535                         U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
05536                         chunk->addByte(LSCRIPTOpCodes[LOPC_DIV]);
05537                         chunk->addByte(typebyte);
05538                 }
05539                 break;
05540         case LSCP_EMIT_CIL_ASSEMBLY:
05541                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05542                 print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
05543                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05544                 print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
05545                 print_cil_div(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
05546                 break;
05547         default:
05548                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05549                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05550                 break;
05551         }
05552         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05553 }
05554 
05555 S32 LLScriptDivide::getSize()
05556 {
05557         return 0;
05558 }
05559 
05560 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)
05561 {
05562         if (gErrorToText.getErrors())
05563         {
05564                 return;
05565         }
05566         switch(pass)
05567         {
05568         case LSCP_PRETTY_PRINT:
05569                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05570                 fprintf(fp, " %% ");
05571                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05572                 break;
05573         case LSCP_EMIT_ASSEMBLY:
05574                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05575                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05576                 fprintf(fp, "MOD %s, %s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
05577                 break;
05578         case LSCP_TYPE:
05579                 {
05580                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05581                         mLeftType = type;
05582                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05583                         mRightType = type;
05584                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05585                         {
05586                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05587                         }
05588                         type = mReturnType;
05589                 }
05590                 break;
05591         case LSCP_TO_STACK:
05592                 {
05593                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05594                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05595                         U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
05596                         chunk->addByte(LSCRIPTOpCodes[LOPC_MOD]);
05597                         chunk->addByte(typebyte);
05598                 }
05599                 break;
05600         case LSCP_EMIT_CIL_ASSEMBLY:
05601                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05602                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05603                 print_cil_mod(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
05604                 break;
05605         default:
05606                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05607                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05608                 break;
05609         }
05610         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05611 }
05612 
05613 S32 LLScriptMod::getSize()
05614 {
05615         return 0;
05616 }
05617 
05618 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)
05619 {
05620         if (gErrorToText.getErrors())
05621         {
05622                 return;
05623         }
05624         switch(pass)
05625         {
05626         case LSCP_PRETTY_PRINT:
05627                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05628                 fprintf(fp, " & ");
05629                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05630                 break;
05631         case LSCP_EMIT_ASSEMBLY:
05632                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05633                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05634                 fprintf(fp, "BITAND\n");
05635                 break;
05636         case LSCP_TYPE:
05637                 {
05638                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05639                         mLeftType = type;
05640                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05641                         mRightType = type;
05642                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05643                         {
05644                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05645                         }
05646                         type = mReturnType;
05647                 }
05648                 break;
05649         case LSCP_TO_STACK:
05650                 {
05651                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05652                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05653                         chunk->addByte(LSCRIPTOpCodes[LOPC_BITAND]);
05654                 }
05655                 break;
05656         case LSCP_EMIT_CIL_ASSEMBLY:
05657                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05658                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05659                 fprintf(fp, "and\n");
05660                 break;
05661         default:
05662                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05663                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05664                 break;
05665         }
05666         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05667 }
05668 
05669 S32 LLScriptBitAnd::getSize()
05670 {
05671         return 0;
05672 }
05673 
05674 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)
05675 {
05676         if (gErrorToText.getErrors())
05677         {
05678                 return;
05679         }
05680         switch(pass)
05681         {
05682         case LSCP_PRETTY_PRINT:
05683                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05684                 fprintf(fp, " | ");
05685                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05686                 break;
05687         case LSCP_EMIT_ASSEMBLY:
05688                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05689                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05690                 fprintf(fp, "BITOR\n");
05691                 break;
05692         case LSCP_TYPE:
05693                 {
05694                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05695                         mLeftType = type;
05696                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05697                         mRightType = type;
05698                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05699                         {
05700                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05701                         }
05702                         type = mReturnType;
05703                 }
05704                 break;
05705         case LSCP_TO_STACK:
05706                 {
05707                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05708                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05709                         chunk->addByte(LSCRIPTOpCodes[LOPC_BITOR]);
05710                 }
05711                 break;
05712         case LSCP_EMIT_CIL_ASSEMBLY:
05713                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05714                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05715                 fprintf(fp, "or\n");
05716                 break;
05717         default:
05718                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05719                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05720                 break;
05721         }
05722         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05723 }
05724 
05725 S32 LLScriptBitOr::getSize()
05726 {
05727         return 0;
05728 }
05729 
05730 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)
05731 {
05732         if (gErrorToText.getErrors())
05733         {
05734                 return;
05735         }
05736         switch(pass)
05737         {
05738         case LSCP_PRETTY_PRINT:
05739                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05740                 fprintf(fp, " ^ ");
05741                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05742                 break;
05743         case LSCP_EMIT_ASSEMBLY:
05744                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05745                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05746                 fprintf(fp, "BITXOR\n");
05747                 break;
05748         case LSCP_TYPE:
05749                 {
05750                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05751                         mLeftType = type;
05752                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05753                         mRightType = type;
05754                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05755                         {
05756                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05757                         }
05758                         type = mReturnType;
05759                 }
05760                 break;
05761         case LSCP_TO_STACK:
05762                 {
05763                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05764                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05765                         chunk->addByte(LSCRIPTOpCodes[LOPC_BITXOR]);
05766                 }
05767                 break;
05768         case LSCP_EMIT_CIL_ASSEMBLY:
05769                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05770                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05771                 fprintf(fp, "xor\n");
05772                 break;
05773         default:
05774                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05775                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05776                 break;
05777         }
05778         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05779 }
05780 
05781 S32 LLScriptBitXor::getSize()
05782 {
05783         return 0;
05784 }
05785 
05786 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)
05787 {
05788         if (gErrorToText.getErrors())
05789         {
05790                 return;
05791         }
05792         switch(pass)
05793         {
05794         case LSCP_PRETTY_PRINT:
05795                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05796                 fprintf(fp, " && ");
05797                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05798                 break;
05799         case LSCP_EMIT_ASSEMBLY:
05800                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05801                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05802                 fprintf(fp, "BOOLAND\n");
05803                 break;
05804         case LSCP_TYPE:
05805                 {
05806                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05807                         mLeftType = type;
05808                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05809                         mRightType = type;
05810                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05811                         {
05812                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05813                         }
05814                         type = mReturnType;
05815                 }
05816                 break;
05817         case LSCP_TO_STACK:
05818                 {
05819                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05820                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05821                         chunk->addByte(LSCRIPTOpCodes[LOPC_BOOLAND]);
05822                 }
05823                 break;
05824         case LSCP_EMIT_CIL_ASSEMBLY:
05825                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05826                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05827                 fprintf(fp, "and\n");
05828                 break;
05829         default:
05830                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05831                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05832                 break;
05833         }
05834         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05835 }
05836 
05837 S32 LLScriptBooleanAnd::getSize()
05838 {
05839         return 0;
05840 }
05841 
05842 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)
05843 {
05844         if (gErrorToText.getErrors())
05845         {
05846                 return;
05847         }
05848         switch(pass)
05849         {
05850         case LSCP_PRETTY_PRINT:
05851                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05852                 fprintf(fp, " || ");
05853                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05854                 break;
05855         case LSCP_EMIT_ASSEMBLY:
05856                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05857                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05858                 fprintf(fp, "BOOLOR\n");
05859                 break;
05860         case LSCP_TYPE:
05861                 {
05862                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05863                         mLeftType = type;
05864                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05865                         mRightType = type;
05866                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05867                         {
05868                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05869                         }
05870                         type = mReturnType;
05871                 }
05872                 break;
05873         case LSCP_TO_STACK:
05874                 {
05875                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05876                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05877                         chunk->addByte(LSCRIPTOpCodes[LOPC_BOOLOR]);
05878                 }
05879                 break;
05880         case LSCP_EMIT_CIL_ASSEMBLY:
05881                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05882                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05883                 fprintf(fp, "or\n");
05884                 break;
05885         default:
05886                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05887                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05888                 break;
05889         }
05890         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05891 }
05892 
05893 S32 LLScriptBooleanOr::getSize()
05894 {
05895         return 0;
05896 }
05897 
05898 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)
05899 {
05900         if (gErrorToText.getErrors())
05901         {
05902                 return;
05903         }
05904         switch(pass)
05905         {
05906         case LSCP_PRETTY_PRINT:
05907                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05908                 fprintf(fp, " << ");
05909                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05910                 break;
05911         case LSCP_EMIT_ASSEMBLY:
05912                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05913                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05914                 fprintf(fp, "SHL\n");
05915                 break;
05916         case LSCP_TYPE:
05917                 {
05918                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05919                         mLeftType = type;
05920                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05921                         mRightType = type;
05922                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05923                         {
05924                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05925                         }
05926                         type = mReturnType;
05927                 }
05928                 break;
05929         case LSCP_TO_STACK:
05930                 {
05931                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05932                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05933                         chunk->addByte(LSCRIPTOpCodes[LOPC_SHL]);
05934                 }
05935                 break;
05936         case LSCP_EMIT_CIL_ASSEMBLY:
05937                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05938                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05939                 fprintf(fp, "shl\n");
05940                 break;
05941         default:
05942                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05943                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05944                 break;
05945         }
05946         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05947 }
05948 
05949 S32 LLScriptShiftLeft::getSize()
05950 {
05951         return 0;
05952 }
05953 
05954 
05955 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)
05956 {
05957         if (gErrorToText.getErrors())
05958         {
05959                 return;
05960         }
05961         switch(pass)
05962         {
05963         case LSCP_PRETTY_PRINT:
05964                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05965                 fprintf(fp, " >> ");
05966                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05967                 break;
05968         case LSCP_EMIT_ASSEMBLY:
05969                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05970                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05971                 fprintf(fp, "SHR\n");
05972                 break;
05973         case LSCP_TYPE:
05974                 {
05975                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05976                         mLeftType = type;
05977                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05978                         mRightType = type;
05979                         if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
05980                         {
05981                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
05982                         }
05983                         type = mReturnType;
05984                 }
05985                 break;
05986         case LSCP_TO_STACK:
05987                 {
05988                         mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05989                         mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05990                         chunk->addByte(LSCRIPTOpCodes[LOPC_SHR]);
05991                 }
05992                 break;
05993         case LSCP_EMIT_CIL_ASSEMBLY:
05994                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05995                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
05996                 fprintf(fp, "shr\n");
05997                 break;
05998         default:
05999                 mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06000                 mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06001                 break;
06002         }
06003         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06004 }
06005 
06006 S32 LLScriptShiftRight::getSize()
06007 {
06008         return 0;
06009 }
06010 
06011 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)
06012 {
06013         if (gErrorToText.getErrors())
06014         {
06015                 return;
06016         }
06017         switch(pass)
06018         {
06019         case LSCP_PRETTY_PRINT:
06020                 fprintf(fp, "( ");
06021                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06022                 fprintf(fp, " )");
06023                 break;
06024         case LSCP_TYPE:
06025                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06026                 mReturnType = mLeftType = type;
06027                 break;
06028         case LSCP_EMIT_ASSEMBLY:
06029                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06030                 mReturnType = mLeftType = type;
06031                 break;
06032         default:
06033                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06034                 break;
06035         }
06036         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06037 }
06038 
06039 S32 LLScriptParenthesis::getSize()
06040 {
06041         return 0;
06042 }
06043 
06044 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)
06045 {
06046         if (gErrorToText.getErrors())
06047         {
06048                 return;
06049         }
06050         switch(pass)
06051         {
06052         case LSCP_PRETTY_PRINT:
06053                 fprintf(fp, "-");
06054                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06055                 break;
06056         case LSCP_EMIT_ASSEMBLY:
06057                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06058                 fprintf(fp, "NEG %s\n", LSCRIPTTypeNames[mLeftType]);
06059                 break;
06060         case LSCP_TYPE:
06061                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06062                 if (!legal_unary_expression(type, type, mType))
06063                 {
06064                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
06065                 }
06066                 else
06067                 {
06068                         mReturnType = mLeftType = type;
06069                 }
06070                 break;
06071         case LSCP_TO_STACK:
06072                 {
06073                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06074                         U8 typebyte = LSCRIPTTypeByte[mLeftType];
06075                         chunk->addByte(LSCRIPTOpCodes[LOPC_NEG]);
06076                         chunk->addByte(typebyte);
06077                 }
06078                 break;
06079         default:
06080                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06081                 break;
06082         }
06083         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06084 }
06085 
06086 S32 LLScriptUnaryMinus::getSize()
06087 {
06088         return 0;
06089 }
06090 
06091 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)
06092 {
06093         if (gErrorToText.getErrors())
06094         {
06095                 return;
06096         }
06097         switch(pass)
06098         {
06099         case LSCP_PRETTY_PRINT:
06100                 fprintf(fp, "!");
06101                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06102                 break;
06103         case LSCP_EMIT_ASSEMBLY:
06104                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06105                 fprintf(fp, "BOOLNOT\n");
06106                 break;
06107         case LSCP_TYPE:
06108                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06109                 if (!legal_unary_expression(type, type, mType))
06110                 {
06111                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
06112                 }
06113                 else
06114                 {
06115                         mReturnType = mLeftType = type;
06116                 }
06117                 break;
06118         case LSCP_TO_STACK:
06119                 {
06120                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06121                         chunk->addByte(LSCRIPTOpCodes[LOPC_BOOLNOT]);
06122                 }
06123                 break;
06124         case LSCP_EMIT_CIL_ASSEMBLY:
06125                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06126                 fprintf(fp, "ldc.i4.0\n");
06127                 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.
06128                 break;
06129         default:
06130                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06131                 break;
06132         }
06133         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06134 }
06135 
06136 S32 LLScriptBooleanNot::getSize()
06137 {
06138         return 0;
06139 }
06140 
06141 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)
06142 {
06143         if (gErrorToText.getErrors())
06144         {
06145                 return;
06146         }
06147         switch(pass)
06148         {
06149         case LSCP_PRETTY_PRINT:
06150                 fprintf(fp, "~");
06151                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06152                 break;
06153         case LSCP_EMIT_ASSEMBLY:
06154                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06155                 fprintf(fp, "BITNOT\n");
06156                 break;
06157         case LSCP_TYPE:
06158                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06159                 if (!legal_unary_expression(type, type, mType))
06160                 {
06161                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
06162                 }
06163                 else
06164                 {
06165                         mReturnType = mLeftType = type;
06166                 }
06167                 break;
06168         case LSCP_TO_STACK:
06169                 {
06170                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06171                         chunk->addByte(LSCRIPTOpCodes[LOPC_BITNOT]);
06172                 }
06173                 break;
06174         case LSCP_EMIT_CIL_ASSEMBLY:
06175                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06176                 fprintf(fp, "not\n");
06177                 break;
06178         default:
06179                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06180                 break;
06181         }
06182         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06183 }
06184 
06185 S32 LLScriptBitNot::getSize()
06186 {
06187         return 0;
06188 }
06189 
06190 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)
06191 {
06192         if (gErrorToText.getErrors())
06193         {
06194                 return;
06195         }
06196         switch(pass)
06197         {
06198         case LSCP_PRETTY_PRINT:
06199                 fprintf(fp, "++");
06200                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06201                 break;
06202         case LSCP_EMIT_ASSEMBLY:
06203                 {
06204                         if (mReturnType == LST_INTEGER)
06205                         {
06206                                 fprintf(fp, "PUSHARGI 1\n");
06207                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06208                                 fprintf(fp, "\n");
06209                                 fprintf(fp, "ADD integer, integer\n");
06210                         }
06211                         else if (mReturnType == LST_FLOATINGPOINT)
06212                         {
06213                                 fprintf(fp, "PUSHARGF 1\n");
06214                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06215                                 fprintf(fp, "\n");
06216                                 fprintf(fp, "ADD float, float\n");
06217                         }
06218                         else
06219                         {
06220                                 fprintf(fp, "Unexpected Type\n");
06221                         }
06222                         print_asignment(fp, mExpression);
06223                 }
06224                 break;
06225         case LSCP_TYPE:
06226                 if (mExpression->mType != LET_LVALUE)
06227                 {
06228                         gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
06229                 }
06230                 else
06231                 {
06232                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06233                         if (!legal_unary_expression(type, type, mType))
06234                         {
06235                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
06236                         }
06237                         else
06238                         {
06239                                 mReturnType = mLeftType = type;
06240                         }
06241                 }
06242                 break;
06243         case LSCP_TO_STACK:
06244                 {
06245                         if (mReturnType == LST_INTEGER)
06246                         {
06247                                 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
06248                                 chunk->addInteger(1);
06249                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06250                                 chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
06251                                 chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
06252                         }
06253                         else if (mReturnType == LST_FLOATINGPOINT)
06254                         {
06255                                 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
06256                                 chunk->addFloat(1.f);
06257                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06258                                 chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
06259                                 chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
06260                         }
06261                         store2stack(this, mExpression, chunk, mReturnType);
06262                 }
06263                 break;
06264         case LSCP_EMIT_CIL_ASSEMBLY:
06265                 {
06266                         print_cil_load_address(fp, mExpression, entry);
06267                         if (mReturnType == LST_INTEGER)
06268                         {
06269                                 fprintf(fp, "ldc.i4.1\n");
06270                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06271                                 fprintf(fp, "add\n");
06272                         }
06273                         else if (mReturnType == LST_FLOATINGPOINT)
06274                         {
06275                                 fprintf(fp, "ldc.r8.1\n");
06276                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06277                                 fprintf(fp, "add\n");
06278                         }
06279                         else
06280                         {
06281                                 fprintf(fp, "Unexpected Type\n");
06282                         }
06283                         print_cil_asignment(fp, mExpression, entry);
06284                 }
06285                 break;
06286         default:
06287                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06288                 break;
06289         }
06290         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06291 }
06292 
06293 S32 LLScriptPreIncrement::getSize()
06294 {
06295         return 0;
06296 }
06297 
06298 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)
06299 {
06300         if (gErrorToText.getErrors())
06301         {
06302                 return;
06303         }
06304         switch(pass)
06305         {
06306         case LSCP_PRETTY_PRINT:
06307                 fprintf(fp, "--");
06308                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06309                 break;
06310         case LSCP_EMIT_ASSEMBLY:
06311                 {
06312                         if (mReturnType == LST_INTEGER)
06313                         {
06314                                 fprintf(fp, "PUSHARGI 1\n");
06315                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06316                                 fprintf(fp, "\n");
06317                                 fprintf(fp, "SUB integer, integer\n");
06318                         }
06319                         else if (mReturnType == LST_FLOATINGPOINT)
06320                         {
06321                                 fprintf(fp, "PUSHARGF 1\n");
06322                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06323                                 fprintf(fp, "\n");
06324                                 fprintf(fp, "SUB float, float\n");
06325                         }
06326                         else
06327                         {
06328                                 fprintf(fp, "Unexpected Type\n");
06329                         }
06330                         print_asignment(fp, mExpression);
06331                 }
06332                 break;
06333         case LSCP_TYPE:
06334                 if (mExpression->mType != LET_LVALUE)
06335                 {
06336                         gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
06337                 }
06338                 else
06339                 {
06340                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06341                         if (!legal_unary_expression(type, type, mType))
06342                         {
06343                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
06344                         }
06345                         else
06346                         {
06347                                 mReturnType = mLeftType = type;
06348                         }
06349                 }
06350                 break;
06351         case LSCP_TO_STACK:
06352                 {
06353                         if (mReturnType == LST_INTEGER)
06354                         {
06355                                 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
06356                                 chunk->addInteger(1);
06357                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06358                                 chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
06359                                 chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
06360                         }
06361                         else if (mReturnType == LST_FLOATINGPOINT)
06362                         {
06363                                 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
06364                                 chunk->addFloat(1.f);
06365                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06366                                 chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
06367                                 chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
06368                         }
06369                         store2stack(this, mExpression, chunk, mReturnType);
06370                 }
06371                 break;
06372         case LSCP_EMIT_CIL_ASSEMBLY:
06373                 {
06374                         print_cil_load_address(fp, mExpression, entry);
06375                         if (mReturnType == LST_INTEGER)
06376                         {
06377                                 fprintf(fp, "ldc.i4.1\n");
06378                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06379                                 fprintf(fp, "sub\n");
06380                         }
06381                         else if (mReturnType == LST_FLOATINGPOINT)
06382                         {
06383                                 fprintf(fp, "ldc.r8.1\n");
06384                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06385                                 fprintf(fp, "sub\n");
06386                         }
06387                         else
06388                         {
06389                                 fprintf(fp, "Unexpected Type\n");
06390                         }
06391                         print_cil_asignment(fp, mExpression, entry);
06392                 }
06393                 break;
06394         default:
06395                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06396                 break;
06397         }
06398         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06399 }
06400 
06401 S32 LLScriptPreDecrement::getSize()
06402 {
06403         return 0;
06404 }
06405 
06406 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)
06407 {
06408         if (gErrorToText.getErrors())
06409         {
06410                 return;
06411         }
06412         switch(pass)
06413         {
06414         case LSCP_PRETTY_PRINT:
06415                 fprintf(fp, "( ");
06416                 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06417                 fprintf(fp, ") ");
06418                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06419                 break;
06420         case LSCP_EMIT_ASSEMBLY:
06421                 fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mType->mType]);
06422                 break;
06423         case LSCP_TYPE:
06424                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06425                 mRightType = type;
06426                 if (!legal_casts(mType->mType, type))
06427                 {
06428                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
06429                 }
06430                 type = mType->mType;
06431                 mReturnType = mLeftType = type;
06432                 break;
06433         case LSCP_TO_STACK:
06434                 {
06435                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06436                         chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
06437                         U8 castbyte = LSCRIPTTypeByte[mType->mType] | LSCRIPTTypeHi4Bits[mRightType];
06438                         chunk->addByte(castbyte);
06439                 }
06440                 break;
06441         case LSCP_EMIT_CIL_ASSEMBLY:
06442                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06443                 print_cil_cast(fp, mRightType, mType->mType);
06444                 break;
06445         default:
06446                 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06447                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06448                 break;
06449         }
06450         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06451 }
06452 
06453 S32 LLScriptTypeCast::getSize()
06454 {
06455         return 0;
06456 }
06457 
06458 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)
06459 {
06460         if (gErrorToText.getErrors())
06461         {
06462                 return;
06463         }
06464         switch(pass)
06465         {
06466         case LSCP_PRETTY_PRINT:
06467                 fprintf(fp, "< ");
06468                 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06469                 fprintf(fp, ", ");
06470                 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06471                 fprintf(fp, ", ");
06472                 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06473                 fprintf(fp, " >");
06474                 break;
06475         case LSCP_EMIT_ASSEMBLY:
06476                 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06477                 if (mExpression1->mReturnType != LST_FLOATINGPOINT)
06478                 {
06479                         fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression1->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
06480                 }
06481                 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06482                 if (mExpression2->mReturnType != LST_FLOATINGPOINT)
06483                 {
06484                         fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression2->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
06485                 }
06486                 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06487                 if (mExpression3->mReturnType != LST_FLOATINGPOINT)
06488                 {
06489                         fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression3->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
06490                 }
06491                 break;
06492         case LSCP_TYPE:
06493                 // vector's take floats
06494                 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06495                 if (!legal_assignment(LST_FLOATINGPOINT, type))
06496                 {
06497                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
06498                 }
06499                 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06500                 if (!legal_assignment(LST_FLOATINGPOINT, type))
06501                 {
06502                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
06503                 }
06504                 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06505                 if (!legal_assignment(LST_FLOATINGPOINT, type))
06506                 {
06507                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
06508                 }
06509                 mReturnType = type = LST_VECTOR;
06510                 if (mNextp)
06511                 {
06512                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06513                 }
06514                 break;
06515         case LSCP_TO_STACK:
06516                 pass = LSCP_TO_STACK;
06517                 mExpression1->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06518                 if (mExpression1->mReturnType != LST_FLOATINGPOINT)
06519                 {
06520                         chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
06521                         U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression1->mReturnType];
06522                         chunk->addByte(castbyte);
06523                 }
06524                 mExpression2->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06525                 if (mExpression2->mReturnType != LST_FLOATINGPOINT)
06526                 {
06527                         chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
06528                         U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression2->mReturnType];
06529                         chunk->addByte(castbyte);
06530                 }
06531                 mExpression3->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06532                 if (mExpression3->mReturnType != LST_FLOATINGPOINT)
06533                 {
06534                         chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
06535                         U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression3->mReturnType];
06536                         chunk->addByte(castbyte);
06537                 }
06538                 break;
06539         case LSCP_EMIT_CIL_ASSEMBLY:
06540 
06541                 // Load arguments.
06542                 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06543                 if (mExpression1->mReturnType != LST_FLOATINGPOINT)
06544                 {
06545                         print_cil_cast(fp, mExpression1->mReturnType, LST_FLOATINGPOINT);
06546                 }
06547                 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06548                 if (mExpression2->mReturnType != LST_FLOATINGPOINT)
06549                 {
06550                         print_cil_cast(fp, mExpression2->mReturnType, LST_FLOATINGPOINT);
06551                 }
06552                 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06553                 if (mExpression3->mReturnType != LST_FLOATINGPOINT)
06554                 {
06555                         print_cil_cast(fp, mExpression3->mReturnType, LST_FLOATINGPOINT);
06556                 }
06557                 // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
06558                 fprintf(fp, "call valuetype [LScriptLibrary]LLVector valuetype [LScriptLibrary]LLVector::'create'(float32, float32, float32)\n");
06559                 break;
06560         default:
06561                 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06562                 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06563                 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06564                 break;
06565         }
06566         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06567 }
06568 
06569 S32 LLScriptVectorInitializer::getSize()
06570 {
06571         return 0;
06572 }
06573 
06574 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)
06575 {
06576         if (gErrorToText.getErrors())
06577         {
06578                 return;
06579         }
06580         switch(pass)
06581         {
06582         case LSCP_PRETTY_PRINT:
06583                 fprintf(fp, "< ");
06584                 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06585                 fprintf(fp, ", ");
06586                 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06587                 fprintf(fp, ", ");
06588                 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06589                 fprintf(fp, ", ");
06590                 mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06591                 fprintf(fp, " >");
06592                 break;
06593         case LSCP_EMIT_ASSEMBLY:
06594                 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06595                 if (mExpression1->mReturnType != LST_FLOATINGPOINT)
06596                 {
06597                         fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression1->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
06598                 }
06599                 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06600                 if (mExpression2->mReturnType != LST_FLOATINGPOINT)
06601                 {
06602                         fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression2->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
06603                 }
06604                 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06605                 if (mExpression3->mReturnType != LST_FLOATINGPOINT)
06606                 {
06607                         fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression3->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
06608                 }
06609                 mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06610                 if (mExpression4->mReturnType != LST_FLOATINGPOINT)
06611                 {
06612                         fprintf(fp, "CAST %s->%s\n", LSCRIPTTypeNames[mExpression4->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
06613                 }
06614                 break;
06615         case LSCP_TYPE:
06616                 // vector's take floats
06617                 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06618                 if (!legal_assignment(LST_FLOATINGPOINT, type))
06619                 {
06620                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
06621                 }
06622                 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06623                 if (!legal_assignment(LST_FLOATINGPOINT, type))
06624                 {
06625                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
06626                 }
06627                 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06628                 if (!legal_assignment(LST_FLOATINGPOINT, type))
06629                 {
06630                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
06631                 }
06632                 mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06633                 if (!legal_assignment(LST_FLOATINGPOINT, type))
06634                 {
06635                         gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
06636                 }
06637                 mReturnType = type = LST_QUATERNION;
06638                 if (mNextp)
06639                 {
06640                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06641                 }
06642                 break;
06643         case LSCP_TO_STACK:
06644                 pass = LSCP_TO_STACK;
06645                 mExpression1->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06646                 if (mExpression1->mReturnType != LST_FLOATINGPOINT)
06647                 {
06648                         chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
06649                         U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression1->mReturnType];
06650                         chunk->addByte(castbyte);
06651                 }
06652                 mExpression2->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06653                 if (mExpression2->mReturnType != LST_FLOATINGPOINT)
06654                 {
06655                         chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
06656                         U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression2->mReturnType];
06657                         chunk->addByte(castbyte);
06658                 }
06659                 mExpression3->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06660                 if (mExpression3->mReturnType != LST_FLOATINGPOINT)
06661                 {
06662                         chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
06663                         U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression3->mReturnType];
06664                         chunk->addByte(castbyte);
06665                 }
06666                 mExpression4->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06667                 if (mExpression4->mReturnType != LST_FLOATINGPOINT)
06668                 {
06669                         chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
06670                         U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression4->mReturnType];
06671                         chunk->addByte(castbyte);
06672                 }
06673                 break;
06674         case LSCP_EMIT_CIL_ASSEMBLY:
06675 
06676                 // Load arguments.
06677                 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06678                 if (mExpression1->mReturnType != LST_FLOATINGPOINT)
06679                 {
06680                         print_cil_cast(fp, mExpression1->mReturnType, LST_FLOATINGPOINT);
06681                 }
06682                 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06683                 if (mExpression2->mReturnType != LST_FLOATINGPOINT)
06684                 {
06685                         print_cil_cast(fp, mExpression2->mReturnType, LST_FLOATINGPOINT);
06686                 }
06687                 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06688                 if (mExpression3->mReturnType != LST_FLOATINGPOINT)
06689                 {
06690                         print_cil_cast(fp, mExpression3->mReturnType, LST_FLOATINGPOINT);
06691                 }
06692                 mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06693                 if (mExpression4->mReturnType != LST_FLOATINGPOINT)
06694                 {
06695                         print_cil_cast(fp, mExpression4->mReturnType, LST_FLOATINGPOINT);
06696                 }
06697 
06698                 // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
06699                 fprintf(fp, "call valuetype [LScriptLibrary]LLQuaternion valuetype [LScriptLibrary]LLQuaternion::'create'(float32, float32, float32, float32)\n");
06700                 break;
06701         default:
06702                 mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06703                 mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06704                 mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06705                 mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06706                 break;
06707         }
06708         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06709 }
06710 
06711 S32 LLScriptQuaternionInitializer::getSize()
06712 {
06713         return 0;
06714 }
06715 
06716 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)
06717 {
06718         if (gErrorToText.getErrors())
06719         {
06720                 return;
06721         }
06722         switch(pass)
06723         {
06724         case LSCP_PRETTY_PRINT:
06725                 fprintf(fp, "[ ");
06726                 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06727                 fprintf(fp, " ]");
06728                 break;
06729         case LSCP_EMIT_ASSEMBLY:
06730                 count = 0;
06731                 if (mExpressionList)
06732                 {
06733                         mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06734                         fprintf(fp, "STACKTOL %llu\n", count);
06735                 }
06736                 break;
06737         case LSCP_TYPE:
06738                 if (mExpressionList)
06739                 {
06740                         mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06741                         mReturnType = type = LST_LIST;
06742                 }
06743                 mReturnType = type = LST_LIST;
06744                 break;
06745         case LSCP_TO_STACK:
06746                 if (mExpressionList)
06747                 {
06748                         pass = LSCP_TO_STACK;
06749                         count = 0;
06750                         mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06751                         chunk->addByte(LSCRIPTOpCodes[LOPC_STACKTOL]);
06752                         chunk->addInteger((S32)count);
06753                         count = 0;
06754                 }
06755                 else
06756                 {
06757                         chunk->addByte(LSCRIPTOpCodes[LOPC_STACKTOL]);
06758                         chunk->addInteger(0);
06759                 }
06760                 break;
06761         case LSCP_EMIT_CIL_ASSEMBLY:
06762 
06763                 // Push boxed elements on stack.
06764                 count = 0;
06765                 if (mExpressionList)
06766                 {
06767                         mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06768                 }
06769 
06770                 // Create list on stack, consuming first boxed element.
06771                 fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::CreateList()\n");
06772 
06773                 // Call AddReturnList to add remaining boxed expressions.
06774                 for(U64 i = 0; i < count; i++)
06775                 {
06776                         fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LScriptLibrary]LScriptInternal::AddReturnList(object, class [mscorlib]System.Collections.ArrayList)\n");
06777                 }
06778                 count = 0;
06779                 
06780                 break;
06781         default:
06782                 if (mExpressionList)
06783                 {
06784                         mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06785                 }
06786                 break;
06787         }
06788         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06789 }
06790 
06791 S32 LLScriptListInitializer::getSize()
06792 {
06793         return 0;
06794 }
06795 
06796 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)
06797 {
06798         if (gErrorToText.getErrors())
06799         {
06800                 return;
06801         }
06802         switch(pass)
06803         {
06804         case LSCP_PRETTY_PRINT:
06805                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06806                 fprintf(fp, "++");
06807                 break;
06808         case LSCP_EMIT_ASSEMBLY:
06809                 {
06810                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06811                         if (mReturnType == LST_INTEGER)
06812                         {
06813                                 fprintf(fp, "PUSHARGI 1\n");
06814                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06815                                 fprintf(fp, "ADD integer, integer\n");
06816                         }
06817                         else if (mReturnType == LST_FLOATINGPOINT)
06818                         {
06819                                 fprintf(fp, "PUSHARGF 1\n");
06820                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06821                                 fprintf(fp, "ADD float, float\n");
06822                         }
06823                         else
06824                         {
06825                                 fprintf(fp, "Unexpected Type\n");
06826                         }
06827                         print_asignment(fp, mExpression);
06828                         fprintf(fp, "%s\n", LSCRIPTTypePop[mReturnType]);
06829                 }
06830                 break;
06831         case LSCP_TYPE:
06832                 if (mExpression->mType != LET_LVALUE)
06833                 {
06834                         gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
06835                 }
06836                 else
06837                 {
06838                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06839                         if (!legal_unary_expression(type, type, mType))
06840                         {
06841                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
06842                         }
06843                         else
06844                         {
06845                                 mReturnType = mLeftType = type;
06846                         }
06847                 }
06848                 break;
06849         case LSCP_TO_STACK:
06850                 {
06851                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06852                         if (mReturnType == LST_INTEGER)
06853                         {
06854                                 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
06855                                 chunk->addInteger(1);
06856                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06857                                 chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
06858                                 chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
06859                         }
06860                         else if (mReturnType == LST_FLOATINGPOINT)
06861                         {
06862                                 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
06863                                 chunk->addFloat(1.f);
06864                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06865                                 chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
06866                                 chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
06867                         }
06868                         store2stack(this, mExpression, chunk, mReturnType);
06869                         switch(mReturnType)
06870                         {
06871                         case LST_INTEGER:
06872                         case LST_FLOATINGPOINT:
06873                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
06874                                 break;
06875                         case LST_KEY:
06876                         case LST_STRING:
06877                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
06878                                 break;
06879                         case LST_LIST:
06880                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
06881                                 break;
06882                         case LST_VECTOR:
06883                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
06884                                 break;
06885                         case LST_QUATERNION:
06886                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
06887                                 break;
06888                         default:
06889                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
06890                                 break;
06891                         }
06892                 }
06893                 break;
06894         case LSCP_EMIT_CIL_ASSEMBLY:
06895                 {
06896                         print_cil_load_address(fp, mExpression, entry);
06897                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06898                         fprintf(fp,"dup\n"); // Copy expression result to use as increment operand.
06899                         if (mReturnType == LST_INTEGER)
06900                         {
06901                                 fprintf(fp, "ldc.i4.1\n");
06902                         }
06903                         else if (mReturnType == LST_FLOATINGPOINT)
06904                         {
06905                                 fprintf(fp, "ldc.r8.1\n");
06906                         }
06907                         else
06908                         {
06909                                 fprintf(fp, "Unexpected Type\n");
06910                         }
06911                         fprintf(fp, "add\n");
06912                         print_cil_asignment(fp, mExpression, entry);
06913                         fprintf(fp, "pop\n"); // Pop assignment result to leave original expression result on stack. TODO: Optimise away redundant pop/dup pairs.
06914                 }
06915                 break;
06916         default:
06917                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06918                 break;
06919         }
06920         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06921 }
06922 
06923 S32 LLScriptPostIncrement::getSize()
06924 {
06925         return 0;
06926 }
06927 
06928 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)
06929 {
06930         if (gErrorToText.getErrors())
06931         {
06932                 return;
06933         }
06934         switch(pass)
06935         {
06936         case LSCP_PRETTY_PRINT:
06937                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06938                 fprintf(fp, "--");
06939                 break;
06940         case LSCP_EMIT_ASSEMBLY:
06941                 {
06942                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06943                         if (mReturnType == LST_INTEGER)
06944                         {
06945                                 fprintf(fp, "PUSHARGI 1\n");
06946                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06947                                 fprintf(fp, "SUB integer, integer\n");
06948                         }
06949                         else if (mReturnType == LST_FLOATINGPOINT)
06950                         {
06951                                 fprintf(fp, "PUSHARGF 1\n");
06952                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06953                                 fprintf(fp, "SUB float, float\n");
06954                         }
06955                         else
06956                         {
06957                                 fprintf(fp, "Unexpected Type\n");
06958                         }
06959                         print_asignment(fp, mExpression);
06960                         fprintf(fp, "%s\n", LSCRIPTTypePop[mReturnType]);
06961                 }
06962                 break;
06963         case LSCP_TYPE:
06964                 if (mExpression->mType != LET_LVALUE)
06965                 {
06966                         gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
06967                 }
06968                 else
06969                 {
06970                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06971                         if (!legal_unary_expression(type, type, mType))
06972                         {
06973                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
06974                         }
06975                         else
06976                         {
06977                                 mReturnType = mLeftType = type;
06978                         }
06979                 }
06980                 break;
06981         case LSCP_TO_STACK:
06982                 {
06983                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06984                         if (mReturnType == LST_INTEGER)
06985                         {
06986                                 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
06987                                 chunk->addInteger(1);
06988                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06989                                 chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
06990                                 chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
06991                         }
06992                         else if (mReturnType == LST_FLOATINGPOINT)
06993                         {
06994                                 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
06995                                 chunk->addFloat(1.f);
06996                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
06997                                 chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
06998                                 chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
06999                         }
07000                         store2stack(this, mExpression, chunk, mReturnType);
07001                         switch(mReturnType)
07002                         {
07003                         case LST_INTEGER:
07004                         case LST_FLOATINGPOINT:
07005                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
07006                                 break;
07007                         case LST_KEY:
07008                         case LST_STRING:
07009                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
07010                                 break;
07011                         case LST_LIST:
07012                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
07013                                 break;
07014                         case LST_VECTOR:
07015                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
07016                                 break;
07017                         case LST_QUATERNION:
07018                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
07019                                 break;
07020                         default:
07021                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
07022                                 break;
07023                         }
07024                 }
07025                 break;
07026         case LSCP_EMIT_CIL_ASSEMBLY:
07027                 {
07028                         print_cil_load_address(fp, mExpression, entry);
07029                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07030                         fprintf(fp,"dup\n"); // Copy expression result to use as decrement operand.
07031                         if (mReturnType == LST_INTEGER)
07032                         {
07033                                 fprintf(fp, "ldc.i4.1\n");
07034                         }
07035                         else if (mReturnType == LST_FLOATINGPOINT)
07036                         {
07037                                 fprintf(fp, "ldc.r8.1\n");
07038                         }
07039                         else
07040                         {
07041                                 fprintf(fp, "Unexpected Type\n");
07042                         }
07043                         fprintf(fp, "sub\n");
07044                         print_cil_asignment(fp, mExpression, entry);
07045                         fprintf(fp, "pop\n"); // Pop assignment result to leave original expression result on stack. TODO: Optimise away redundant pop/dup pairs.
07046                 }
07047                 break;
07048         default:
07049                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07050                 break;
07051         }
07052         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07053 }
07054 
07055 S32 LLScriptPostDecrement::getSize()
07056 {
07057         return 0;
07058 }
07059 
07060 // Generate arg list.
07061 void print_cil_arg_list(FILE *fp, LLScriptFuncExpressionList* exp_list)
07062 {
07063         // Print first argument.
07064         print_cil_type(fp, exp_list->mFirstp->mReturnType);
07065 
07066         // Recursively print next arguments.
07067         if(exp_list->mSecondp != NULL)
07068         {
07069                 fprintf(fp, ", ");
07070                 print_cil_arg_list(fp, (LLScriptFuncExpressionList*) exp_list->mSecondp);
07071         }
07072 }
07073 
07074 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)
07075 {
07076         if (gErrorToText.getErrors())
07077         {
07078                 return;
07079         }
07080         switch(pass)
07081         {
07082         case LSCP_PRETTY_PRINT:
07083                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07084                 fprintf(fp, "( ");
07085                 if (mExpressionList)
07086                         mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07087                 fprintf(fp, " )");
07088                 break;
07089         case LSCP_EMIT_ASSEMBLY:
07090                 if (mIdentifier->mScopeEntry->mType)
07091                         fprintf(fp, "%s\n", LSCRIPTTypePush[mIdentifier->mScopeEntry->mType]);
07092                 fprintf(fp,"PUSHE\n");
07093                 fprintf(fp, "PUSHBP\n");
07094                 if (mExpressionList)
07095                         mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
07096                 fprintf(fp, "PUSHARGE %d\n", mIdentifier->mScopeEntry->mSize - mIdentifier->mScopeEntry->mOffset);
07097                 fprintf(fp, "PUSHSP\n");
07098                 fprintf(fp, "PUSHARGI %d\n", mIdentifier->mScopeEntry->mSize);
07099                 fprintf(fp, "ADD integer, integer\n");
07100                 fprintf(fp, "POPBP\n");
07101                 if (mIdentifier->mScopeEntry->mIDType != LIT_LIBRARY_FUNCTION)
07102                 {
07103                         fprintf(fp, "CALL ");
07104                         mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07105                 }
07106                 else
07107                 {
07108                         fprintf(fp, "CALLLID ");
07109                         mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07110                         fprintf(fp, ", %d", (U32)mIdentifier->mScopeEntry->mLibraryNumber);
07111                 }
07112                 fprintf(fp, "\n");
07113                 fprintf(fp, "POPBP\n");
07114                 break;
07115         case LSCP_SCOPE_PASS1:
07116                 if (mExpressionList)
07117                         mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07118                 break;
07119         case LSCP_SCOPE_PASS2:
07120                 {
07121                         LLScriptScopeEntry *entry = scope->findEntryTyped(mIdentifier->mName, LIT_FUNCTION);
07122                         if (!entry)
07123                         {
07124                                 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
07125                         }
07126                         else
07127                         {
07128                                 // if we did find it, make sure this identifier is associated with the correct scope entry
07129                                 mIdentifier->mScopeEntry = entry;
07130                         }
07131                         if (mExpressionList)
07132                                 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07133                 }
07134                 break;
07135         case LSCP_TYPE:
07136                 if (mIdentifier->mScopeEntry)
07137                 {
07138                         U64 argcount = 0;
07139                         if (mExpressionList)
07140                                 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, argcount, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
07141 
07142                         if (!mIdentifier->mScopeEntry->mFunctionArgs.mString)
07143                         {
07144                                 if (argcount)
07145                                 {
07146                                         gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
07147                                 }
07148                         }
07149                         else if (argcount != strlen(mIdentifier->mScopeEntry->mFunctionArgs.mString))           /*Flawfinder: ignore*/
07150                         {
07151                                 gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
07152                         }
07153                 }
07154 
07155                 if (mIdentifier->mScopeEntry)
07156                         type = mIdentifier->mScopeEntry->mType;
07157                 else
07158                         type = LST_NULL;
07159                 mReturnType = type;
07160                 break;
07161         case LSCP_TO_STACK:
07162                 switch(mIdentifier->mScopeEntry->mType)
07163                 {
07164                 case LST_INTEGER:
07165                 case LST_FLOATINGPOINT:
07166                 case LST_STRING:
07167                 case LST_KEY:
07168                 case LST_LIST:
07169                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHE]);
07170                         break;
07171                 case LST_VECTOR:
07172                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHEV]);
07173                         break;
07174                 case LST_QUATERNION:
07175                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHEQ]);
07176                         break;
07177                 default:
07178                         break;
07179                 }
07180                 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHE]);
07181                 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHBP]);
07182                 if (mExpressionList)
07183                 {
07184                         // Don't let this change the count.
07185                         U64 dummy_count = 0;
07186                         mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, dummy_count, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
07187                         //mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
07188                 }
07189                 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGE]);
07190                 chunk->addInteger(mIdentifier->mScopeEntry->mSize - mIdentifier->mScopeEntry->mOffset);
07191                 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHSP]);
07192                 chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
07193                 chunk->addInteger(mIdentifier->mScopeEntry->mSize);
07194                 chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
07195                 chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
07196                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPBP]);
07197                 if (mIdentifier->mScopeEntry->mIDType != LIT_LIBRARY_FUNCTION)
07198                 {
07199                         chunk->addByte(LSCRIPTOpCodes[LOPC_CALL]);
07200                         chunk->addInteger(mIdentifier->mScopeEntry->mCount);
07201                 }
07202                 else
07203                 {
07204                         chunk->addByte(LSCRIPTOpCodes[LOPC_CALLLIB_TWO_BYTE]);
07205                         chunk->addU16(mIdentifier->mScopeEntry->mLibraryNumber);
07206                 }
07207                 break;
07208         case LSCP_EMIT_CIL_ASSEMBLY:
07209                 {
07210                         bool library_call = (mIdentifier->mScopeEntry->mIDType == LIT_LIBRARY_FUNCTION);
07211                         if(! library_call)
07212                         {
07213                                 // Load this pointer.
07214                                 fprintf(fp, "ldarg.0\n");
07215                         }
07216 
07217                         // Load args on to stack.
07218                         if (mExpressionList)
07219                         {
07220                                 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry /* Needed for is_parameter calls */, 0, NULL);
07221                         }
07222 
07223                         // Make call.
07224                         if (! library_call)
07225                         {
07226                                 fprintf(fp, "callvirt instance ");
07227                         }
07228                         else
07229                         {
07230                                 fprintf(fp, "call ");
07231                         }
07232                         print_cil_type(fp, mIdentifier->mScopeEntry->mType);
07233                         fprintf(fp, " class ");
07234                         if (library_call)
07235                         {
07236                                 fprintf(fp, "[LScriptLibrary]LScriptLibrary");
07237                         }
07238                         else
07239                         {
07240                                 fprintf(fp, "LSL");
07241                         }
07242                         fprintf(fp, "::");
07243                         mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07244                         fprintf(fp, "(");
07245                         if (mExpressionList) {print_cil_arg_list(fp, (LLScriptFuncExpressionList*) mExpressionList);}
07246                         fprintf(fp, ")\n");
07247                 }
07248                 break;
07249         default:
07250                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07251                 if (mExpressionList)
07252                         mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07253                 break;
07254         }
07255         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07256 }
07257 
07258 S32 LLScriptFunctionCall::getSize()
07259 {
07260         return 0;
07261 }
07262 
07263 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)
07264 {
07265         if (gErrorToText.getErrors())
07266         {
07267                 return;
07268         }
07269         switch(pass)
07270         {
07271         case LSCP_PRETTY_PRINT:
07272                 fprintf(fp, " PRINT ( ");
07273                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07274                 fprintf(fp, " )");
07275                 break;
07276         case LSCP_EMIT_ASSEMBLY:
07277                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07278                 fprintf(fp, "PRINT %s\n", LSCRIPTTypeNames[mLeftType]);
07279                 break;
07280         case LSCP_TYPE:
07281                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07282                 mLeftType = type;
07283                 mReturnType = LST_NULL;
07284                 break;
07285         case LSCP_TO_STACK:
07286                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07287                 chunk->addByte(LSCRIPTOpCodes[LOPC_PRINT]);
07288                 chunk->addByte(LSCRIPTTypeByte[mLeftType]);
07289                 break;
07290         default:
07291                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07292                 break;
07293         }
07294         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07295 }
07296 
07297 S32 LLScriptPrint::getSize()
07298 {
07299         return 0;
07300 }
07301 
07302 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)
07303 {
07304         if (gErrorToText.getErrors())
07305         {
07306                 return;
07307         }
07308         switch(pass)
07309         {
07310         case LSCP_PRETTY_PRINT:
07311                 mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07312                 break;
07313         case LSCP_TYPE:
07314                 mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07315                 mReturnType = type;
07316                 break;
07317         case LSCP_TO_STACK:
07318                 mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07319                 break;
07320         default:
07321                 mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07322                 break;
07323         }
07324         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07325 }
07326 
07327 S32 LLScriptConstantExpression::getSize()
07328 {
07329         return 0;
07330 }
07331 
07332 void LLScriptStatement::addStatement(LLScriptStatement *event)
07333 {
07334         if (mNextp)
07335         {
07336                 event->mNextp = mNextp;
07337         }
07338         mNextp = event;
07339 }
07340 
07341 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)
07342 {
07343         fprintf(fp, "Statement Base Class -- should never get here!\n");
07344 }
07345 
07346 S32 LLScriptStatement::getSize()
07347 {
07348         printf("Statement Base Class -- should never get here!\n");
07349         return 0;
07350 }
07351 
07352 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)
07353 {
07354         if (gErrorToText.getErrors())
07355         {
07356                 return;
07357         }
07358         switch(pass)
07359         {
07360         case LSCP_PRETTY_PRINT:
07361                 if (mNextp)
07362                 {
07363                         fprintf(fp, ", ");
07364                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07365                 }
07366                 break;
07367         case LSCP_EMIT_ASSEMBLY:
07368                 if (mNextp)
07369                 {
07370                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07371                 }
07372                 break;
07373         default:
07374                 if (mNextp)
07375                 {
07376                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07377                 }
07378                 break;
07379         }
07380 }
07381 
07382 S32 LLScriptStatementSequence::getSize()
07383 {
07384         return 0;
07385 }
07386 
07387 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)
07388 {
07389         if (gErrorToText.getErrors())
07390         {
07391                 return;
07392         }
07393         switch(pass)
07394         {
07395         case LSCP_PRETTY_PRINT:
07396                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07397                 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07398                 break;
07399         case LSCP_EMIT_ASSEMBLY:
07400                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07401                 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07402                 break;
07403         case LSCP_PRUNE:
07404                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07405                 if (prunearg)
07406                 {
07407                         ptype = LSPRUNE_DEAD_CODE;
07408                         gErrorToText.writeWarning(fp, this, LSWARN_DEAD_CODE);
07409                 }
07410                 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07411                 break;
07412         case LSCP_TYPE:
07413                 // pass the return type into all statements so we can check returns
07414                 {
07415                         LSCRIPTType     return_type = type;
07416                         mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, return_type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07417                         return_type = type;
07418                         mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, return_type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07419                 }
07420                 break;
07421         default:
07422                 mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07423                 mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07424                 break;
07425         }
07426         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07427 }
07428 
07429 S32 LLScriptNOOP::getSize()
07430 {
07431         return 0;
07432 }
07433 
07434 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)
07435 {
07436         if (gErrorToText.getErrors())
07437         {
07438                 return;
07439         }
07440         switch(pass)
07441         {
07442         case LSCP_PRETTY_PRINT:
07443                 fdotabs(fp, tabs, tabsize);
07444                 fprintf(fp, ";\n");
07445                 break;
07446         case LSCP_PRUNE:
07447                 if (ptype == LSPRUNE_DEAD_CODE)
07448                         prunearg = TRUE;
07449                 else
07450                         prunearg = FALSE;
07451                 break;
07452         default:
07453                 break;
07454         }
07455         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07456 }
07457 
07458 void add_exit_pops(LLScriptByteCodeChunk *chunk, LLScriptScopeEntry *entry)
07459 {
07460         // remember that we need to pop in reverse order
07461         S32 number, i;
07462 
07463         if (entry->mLocals.mString)
07464         {
07465                 number = (S32)strlen(entry->mLocals.mString);   /*Flawfinder: ignore*/
07466                 for (i = number - 1; i >= 0; i--)
07467                 {
07468                         switch(entry->mLocals.getType(i))
07469                         {
07470                         case LST_INTEGER:
07471                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
07472                                 break;
07473                         case LST_FLOATINGPOINT:
07474                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
07475                                 break;
07476                         case LST_STRING:
07477                         case LST_KEY:
07478                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
07479                                 break;
07480                         case LST_VECTOR:
07481                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
07482                                 break;
07483                         case LST_QUATERNION:
07484                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
07485                                 break;
07486                         case LST_LIST:
07487                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
07488                                 break;
07489 
07490                         default:
07491                                 break;
07492                         }
07493                 }
07494         }
07495 
07496         if (entry->mFunctionArgs.mString)
07497         {
07498                 number = (S32)strlen(entry->mFunctionArgs.mString);     /*Flawfinder: ignore*/
07499                 for (i = number - 1; i >= 0; i--)
07500                 {
07501                         switch(entry->mFunctionArgs.getType(i))
07502                         {
07503                         case LST_INTEGER:
07504                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
07505                                 break;
07506                         case LST_FLOATINGPOINT:
07507                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
07508                                 break;
07509                         case LST_STRING:
07510                         case LST_KEY:
07511                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
07512                                 break;
07513                         case LST_VECTOR:
07514                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
07515                                 break;
07516                         case LST_QUATERNION:
07517                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
07518                                 break;
07519                         case LST_LIST:
07520                                 chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
07521                                 break;
07522 
07523                         default:
07524                                 break;
07525                         }
07526                 }
07527         }
07528 }
07529 
07530 void print_exit_pops(FILE *fp, LLScriptScopeEntry *entry)
07531 {
07532         // remember that we need to pop in reverse order
07533         S32 number, i;
07534 
07535         if (entry->mLocals.mString)
07536         {
07537                 number = (S32)strlen(entry->mLocals.mString);   /*Flawfinder: ignore*/
07538                 for (i = number - 1; i >= 0; i--)
07539                 {
07540                         fprintf(fp, "%s", LSCRIPTTypePop[entry->mLocals.getType(i)]);
07541                 }
07542         }
07543 
07544         if (entry->mFunctionArgs.mString)
07545         {
07546                 number = (S32)strlen(entry->mFunctionArgs.mString);     /*Flawfinder: ignore*/
07547                 for (i = number - 1; i >= 0; i--)
07548                 {
07549                         fprintf(fp, "%s", LSCRIPTTypePop[entry->mFunctionArgs.getType(i)]);
07550                 }
07551         }
07552 }
07553 
07554 
07555 S32 LLScriptStateChange::getSize()
07556 {
07557         return 0;
07558 }
07559 
07560 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)
07561 {
07562         if (gErrorToText.getErrors())
07563         {
07564                 return;
07565         }
07566         switch(pass)
07567         {
07568         case LSCP_PRETTY_PRINT:
07569                 fdotabs(fp, tabs, tabsize);
07570                 fprintf(fp, "state ");
07571                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07572                 fprintf(fp, ";\n");
07573                 break;
07574         case LSCP_EMIT_ASSEMBLY:
07575                 print_exit_pops(fp, entry);
07576                 fprintf(fp, "STATE ");
07577                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07578                 fprintf(fp, "\n");
07579                 break;
07580         case LSCP_PRUNE:
07581                 if (  (ptype == LSPRUNE_GLOBAL_VOIDS)
07582                         ||(ptype == LSPRUNE_GLOBAL_NON_VOIDS))
07583                 {
07584                         gErrorToText.writeError(fp, this, LSERROR_STATE_CHANGE_IN_GLOBAL);
07585                 }
07586                 if (ptype == LSPRUNE_DEAD_CODE)
07587                         prunearg = TRUE;
07588                 else
07589                         prunearg = FALSE;
07590                 break;
07591         case LSCP_SCOPE_PASS2:
07592                 {
07593                         LLScriptScopeEntry *entry = scope->findEntryTyped(mIdentifier->mName, LIT_STATE);
07594                         if (!entry)
07595                         {
07596                                 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
07597                         }
07598                         else
07599                         {
07600                                 // if we did find it, make sure this identifier is associated with the correct scope entry
07601                                 mIdentifier->mScopeEntry = entry;
07602                         }
07603                 }
07604                 break;
07605         case LSCP_EMIT_BYTE_CODE:
07606                 {
07607                         add_exit_pops(chunk, entry);
07608                         chunk->addByte(LSCRIPTOpCodes[LOPC_STATE]);
07609                         chunk->addInteger(mIdentifier->mScopeEntry->mCount);
07610                 }
07611                 break;
07612         case LSCP_EMIT_CIL_ASSEMBLY:
07613                 fprintf(fp, "ldstr \"");
07614                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07615                 fprintf(fp, "\"\n");
07616                 fprintf(fp, "call void class [LScriptLibrary]LScriptInternal::change_state(string)\n");
07617                 break;
07618         default:
07619                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07620                 break;
07621         }
07622         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07623 }
07624 
07625 S32 LLScriptJump::getSize()
07626 {
07627         return 0;
07628 }
07629 
07630 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)
07631 {
07632         if (gErrorToText.getErrors())
07633         {
07634                 return;
07635         }
07636         switch(pass)
07637         {
07638         case LSCP_PRETTY_PRINT:
07639                 fdotabs(fp, tabs, tabsize);
07640                 fprintf(fp, "jump ");
07641                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07642                 fprintf(fp, ";\n");
07643                 break;
07644         case LSCP_EMIT_ASSEMBLY:
07645                 fprintf(fp, "JUMP ");
07646                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07647                 fprintf(fp, "\n");
07648                 break;
07649         case LSCP_PRUNE:
07650                 if (ptype == LSPRUNE_DEAD_CODE)
07651                         prunearg = TRUE;
07652                 else
07653                         prunearg = FALSE;
07654                 break;
07655         case LSCP_SCOPE_PASS2:
07656                 {
07657                         LLScriptScopeEntry *entry = scope->findEntryTyped(mIdentifier->mName, LIT_LABEL);
07658                         if (!entry)
07659                         {
07660                                 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
07661                         }
07662                         else
07663                         {
07664                                 // if we did find it, make sure this identifier is associated with the correct scope entry
07665                                 mIdentifier->mScopeEntry = entry;
07666                         }
07667                 }
07668                 break;
07669         case LSCP_EMIT_BYTE_CODE:
07670                 {
07671                         chunk->addByte(LSCRIPTOpCodes[LOPC_JUMP]);
07672                         chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
07673                         chunk->addJump(mIdentifier->mName);
07674                 }
07675                 break;
07676         case LSCP_EMIT_CIL_ASSEMBLY:
07677                 fprintf(fp, "br ");
07678                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07679                 fprintf(fp, "\n");
07680                 break;
07681         default:
07682                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07683                 break;
07684         }
07685         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07686 }
07687 
07688 S32 LLScriptLabel::getSize()
07689 {
07690         return 0;
07691 }
07692 
07693 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)
07694 {
07695         if (gErrorToText.getErrors())
07696         {
07697                 return;
07698         }
07699         switch(pass)
07700         {
07701         case LSCP_PRETTY_PRINT:
07702                 fdotabs(fp, tabs, tabsize);
07703                 fprintf(fp, "@");
07704                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07705                 fprintf(fp, ";\n");
07706                 break;
07707         case LSCP_EMIT_ASSEMBLY:
07708                 fprintf(fp, "LABEL ");
07709                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07710                 fprintf(fp, "\n");
07711                 break;
07712         case LSCP_PRUNE:
07713                 // Always clear this flag, to stop pruning after return statements.  A jump
07714                 // might start up code at this label, so we need to stop pruning.
07715                 prunearg = FALSE;
07716                 break;
07717         case LSCP_SCOPE_PASS1:
07718                 // add labels to scope
07719                 if (scope->checkEntry(mIdentifier->mName))
07720                 {
07721                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
07722                 }
07723                 else
07724                 {
07725                         mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_LABEL, LST_NULL);
07726                 }
07727                 break;
07728         case LSCP_EMIT_BYTE_CODE:
07729                 {
07730                         chunk->addLabel(mIdentifier->mName);
07731                 }
07732                 break;
07733         case LSCP_EMIT_CIL_ASSEMBLY:
07734                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07735                 fprintf(fp, ":\n");
07736                 break;
07737         default:
07738                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07739                 break;
07740         }
07741         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07742 }
07743 
07744 void add_return(LLScriptByteCodeChunk *chunk, LLScriptScopeEntry *entry)
07745 {
07746         add_exit_pops(chunk, entry);
07747         chunk->addByte(LSCRIPTOpCodes[LOPC_RETURN]);
07748 }
07749 
07750 void print_return(FILE *fp, LLScriptScopeEntry *entry)
07751 {
07752         print_exit_pops(fp, entry);
07753         fprintf(fp, "RETURN\n");
07754 }
07755 
07756 
07757 S32 LLScriptReturn::getSize()
07758 {
07759         return 0;
07760 }
07761 
07762 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)
07763 {
07764         if (gErrorToText.getErrors())
07765         {
07766                 return;
07767         }
07768         switch(pass)
07769         {
07770         case LSCP_PRETTY_PRINT:
07771                 if (mExpression)
07772                 {
07773                         fdotabs(fp, tabs, tabsize);
07774                         fprintf(fp, "return ");
07775                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07776                         fprintf(fp, ";\n");
07777                 }
07778                 else
07779                 {
07780                         fdotabs(fp, tabs, tabsize);
07781                         fprintf(fp, "return;\n");
07782                 }
07783                 break;
07784         case LSCP_EMIT_ASSEMBLY:
07785                 if (mExpression)
07786                 {
07787                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07788                         fprintf(fp, "%s\n", LSCRIPTTypeReturn[mType]);
07789                 }
07790                 print_return(fp, entry);
07791                 break;
07792         case LSCP_PRUNE:
07793                 if (  (ptype == LSPRUNE_GLOBAL_VOIDS)
07794                         ||(ptype == LSPRUNE_EVENTS))
07795                 {
07796                         if (mExpression)
07797                         {
07798                                 gErrorToText.writeError(fp, this, LSERROR_INVALID_RETURN);
07799                         }
07800                 }
07801                 else if (ptype == LSPRUNE_GLOBAL_NON_VOIDS)
07802                 {
07803                         if (!mExpression)
07804                         {
07805                                 gErrorToText.writeError(fp, this, LSERROR_INVALID_VOID_RETURN);
07806                         }
07807                 }
07808                 prunearg = TRUE;
07809         case LSCP_TYPE:
07810                 // if there is a return expression, it must be promotable to the return type of the function
07811                 if (mExpression)
07812                 {
07813                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07814                         if (!legal_assignment(basetype, type))
07815                         {
07816                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
07817                         }
07818                         else
07819                         {
07820                                 mType = basetype;
07821                         }
07822                 }
07823                 break;
07824         case LSCP_EMIT_BYTE_CODE:
07825                 if (mExpression)
07826                 {
07827                         mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07828                         switch(mType)
07829                         {
07830                         case LST_INTEGER:
07831                         case LST_FLOATINGPOINT:
07832                                 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
07833                                 chunk->addInteger(-12);
07834                                 break;
07835                         case LST_STRING:
07836                         case LST_KEY:
07837                                 // use normal store for reference counted types
07838                                 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADSP]);
07839                                 chunk->addInteger(-12);
07840                                 break;
07841                         case LST_LIST:
07842                                 // use normal store for reference counted types
07843                                 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADLP]);
07844                                 chunk->addInteger(-12);
07845                                 break;
07846                         case LST_VECTOR:
07847                                 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADVP]);
07848                                 chunk->addInteger(-20);
07849                                 break;
07850                         case LST_QUATERNION:
07851                                 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADQP]);
07852                                 chunk->addInteger(-24);
07853                                 break;
07854                         default:
07855                                 chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
07856                                 chunk->addInteger(-12);
07857                                 break;
07858                         }
07859                 }
07860                 add_return(chunk, entry);
07861                 break;
07862         case LSCP_EMIT_CIL_ASSEMBLY:
07863                 if (mExpression)
07864                 {
07865                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07866                 }
07867                 fprintf(fp, "ret\n");
07868                 break;
07869         default:
07870                 if (mExpression)
07871                 {
07872                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07873                 }
07874                 break;
07875         }
07876         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07877 }
07878 
07879 S32 LLScriptExpressionStatement::getSize()
07880 {
07881         return 0;
07882 }
07883 
07884 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)
07885 {
07886         if (gErrorToText.getErrors())
07887         {
07888                 return;
07889         }
07890         switch(pass)
07891         {
07892         case LSCP_PRETTY_PRINT:
07893                 fdotabs(fp, tabs, tabsize);
07894                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07895                 fprintf(fp, ";\n");
07896                 break;
07897         case LSCP_EMIT_ASSEMBLY:
07898                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07899                 if (mExpression->mReturnType)
07900                 {
07901                         fprintf(fp, "%s\n", LSCRIPTTypePop[mExpression->mReturnType]);
07902                 }
07903                 break;
07904         case LSCP_PRUNE:
07905                 if (ptype == LSPRUNE_DEAD_CODE)
07906                         prunearg = TRUE;
07907                 else
07908                         prunearg = FALSE;
07909                 break;
07910         case LSCP_EMIT_BYTE_CODE:
07911                 mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07912                 switch(mExpression->mReturnType)
07913                 {
07914                 case LST_INTEGER:
07915                 case LST_FLOATINGPOINT:
07916                         chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
07917                         break;
07918                 case LST_STRING:
07919                 case LST_KEY:
07920                         chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
07921                         break;
07922                 case LST_LIST:
07923                         chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
07924                         break;
07925                 case LST_VECTOR:
07926                         chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
07927                         break;
07928                 case LST_QUATERNION:
07929                         chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
07930                         break;
07931                 default:
07932                         break;
07933                 }
07934                 break;
07935         case LSCP_EMIT_CIL_ASSEMBLY:
07936                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07937                 if(mExpression->mReturnType)
07938                 {
07939                         fprintf(fp, "pop\n");
07940                 }
07941                 break;
07942         default:
07943                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07944                 break;
07945         }
07946         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07947 }
07948 
07949 S32 LLScriptIf::getSize()
07950 {
07951         return 0;
07952 }
07953 
07954 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)
07955 {
07956         if (gErrorToText.getErrors())
07957         {
07958                 return;
07959         }
07960         switch(pass)
07961         {
07962         case LSCP_PRETTY_PRINT:
07963                 fdotabs(fp, tabs, tabsize);
07964                 fprintf(fp, "if ( ");
07965                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07966                 fprintf(fp, " )\n");
07967                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07968                 break;
07969         case LSCP_EMIT_ASSEMBLY:
07970                 {
07971                         S32 tjump =  gTempJumpCount++;
07972                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07973                         fprintf(fp, "JUMPNIF ##Temp Jump %d##\n", tjump);
07974                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07975                         fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump);
07976                 }
07977                 break;
07978         case LSCP_PRUNE:
07979                 if (ptype == LSPRUNE_DEAD_CODE)
07980                         prunearg = TRUE;
07981                 else
07982                         prunearg = FALSE;
07983                 break;
07984         case LSCP_TYPE:
07985                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07986                 mType = type;
07987                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07988                 break;
07989         case LSCP_EMIT_BYTE_CODE:
07990                 {
07991                         char jumpname[32];              /*Flawfinder: ignore*/
07992                         snprintf(jumpname, sizeof(jumpname),"##Temp Jump %d##", gTempJumpCount++);      /* Flawfinder: ignore */
07993 
07994                         mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
07995                         chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPNIF]);
07996                         chunk->addByte(LSCRIPTTypeByte[mType]);
07997                         chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
07998                         chunk->addJump(jumpname);
07999                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08000                         chunk->addLabel(jumpname);
08001                 }
08002                 break;
08003         case LSCP_EMIT_CIL_ASSEMBLY:
08004                 {
08005                         S32 tjump = gTempJumpCount++;
08006                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08007                         fprintf(fp, "brfalse LabelTempJump%d\n", tjump);
08008                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08009                         fprintf(fp, "LabelTempJump%d:\n", tjump);
08010                 }
08011                 break;
08012         default:
08013                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08014                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08015                 break;
08016         }
08017         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08018 }
08019 
08020 S32 LLScriptIfElse::getSize()
08021 {
08022         return 0;
08023 }
08024 
08025 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)
08026 {
08027         if (gErrorToText.getErrors())
08028         {
08029                 return;
08030         }
08031         switch(pass)
08032         {
08033         case LSCP_PRETTY_PRINT:
08034                 fdotabs(fp, tabs, tabsize);
08035                 fprintf(fp, "if ( ");
08036                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08037                 fprintf(fp, " )\n");
08038                 mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08039                 fdotabs(fp, tabs, tabsize);
08040                 fprintf(fp, "else\n");
08041                 mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08042                 break;
08043         case LSCP_EMIT_ASSEMBLY:
08044                 {
08045                         S32 tjump1 =  gTempJumpCount++;
08046                         S32 tjump2 =  gTempJumpCount++;
08047                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08048                         fprintf(fp, "JUMPNIF ##Temp Jump %d##\n", tjump1);
08049                         mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08050                         fprintf(fp, "JUMP ##Temp Jump %d##\n", tjump2);
08051                         fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump1);
08052                         mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08053                         fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump2);
08054                 }
08055                 break;
08056         case LSCP_PRUNE:
08057                 {
08058                         BOOL arg1 = TRUE, arg2 = TRUE;
08059                         mStatement1->recurse(fp, tabs, tabsize, pass, ptype, arg1, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08060                         mStatement2->recurse(fp, tabs, tabsize, pass, ptype, arg2, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08061                         prunearg = arg1 && arg2;
08062                 }
08063                 break;
08064         case LSCP_TYPE:
08065                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08066                 mType = type;
08067                 mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08068                 mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08069                 break;
08070         case LSCP_EMIT_BYTE_CODE:
08071                 {
08072                         char jumpname1[32];                             /*Flawfinder: ignore*/
08073                         snprintf(jumpname1, sizeof(jumpname1), "##Temp Jump %d##", gTempJumpCount++);   /* Flawfinder: ignore */
08074                         char jumpname2[32];                             /*Flawfinder: ignore*/
08075                         snprintf(jumpname2, sizeof(jumpname2), "##Temp Jump %d##", gTempJumpCount++);    /* Flawfinder: ignore */
08076 
08077                         mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08078                         chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPNIF]);
08079                         chunk->addByte(LSCRIPTTypeByte[mType]);
08080                         chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
08081                         chunk->addJump(jumpname1);
08082                         mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08083                         chunk->addByte(LSCRIPTOpCodes[LOPC_JUMP]);
08084                         chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
08085                         chunk->addJump(jumpname2);
08086                         chunk->addLabel(jumpname1);
08087                         mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08088                         chunk->addLabel(jumpname2);
08089                 }
08090                 break;
08091         case LSCP_EMIT_CIL_ASSEMBLY:
08092                 {
08093                         S32 tjump1 =  gTempJumpCount++;
08094                         S32 tjump2 =  gTempJumpCount++;
08095                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08096                         fprintf(fp, "brfalse LabelTempJump%d\n", tjump1);
08097                         mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08098                         fprintf(fp, "br LabelTempJump%d\n", tjump2);
08099                         fprintf(fp, "LabelTempJump%d:\n", tjump1);
08100                         mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08101                         fprintf(fp, "LabelTempJump%d:\n", tjump2);
08102                 }
08103                 break;
08104         default:
08105                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08106                 mStatement1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08107                 mStatement2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08108                 break;
08109         };
08110         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08111 }
08112 
08113 S32 LLScriptFor::getSize()
08114 {
08115         return 0;
08116 }
08117 
08118 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)
08119 {
08120         if (gErrorToText.getErrors())
08121         {
08122                 return;
08123         }
08124         switch(pass)
08125         {
08126         case LSCP_PRETTY_PRINT:
08127                 fdotabs(fp, tabs, tabsize);
08128                 fprintf(fp, "for ( ");
08129                 if(mSequence)
08130                         mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08131                 fprintf(fp, " ; ");
08132                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08133                 fprintf(fp, " ; ");
08134                 if(mExpressionList)
08135                         mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08136                 fprintf(fp, " )\n");
08137                 if(mStatement)
08138                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08139                 break;
08140         case LSCP_EMIT_ASSEMBLY:
08141                 {
08142                         S32 tjump1 =  gTempJumpCount++;
08143                         S32 tjump2 =  gTempJumpCount++;
08144                         if(mSequence)
08145                                 mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08146                         fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump1);
08147                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08148                         fprintf(fp, "JUMPNIF ##Temp Jump %d##\n", tjump2);
08149                         if(mStatement)
08150                                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08151                         if(mExpressionList)
08152                                 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08153                         fprintf(fp, "JUMP ##Temp Jump %d##\n", tjump1);
08154                         fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump2);
08155                 }
08156                 break;
08157         case LSCP_PRUNE:
08158                 if (ptype == LSPRUNE_DEAD_CODE)
08159                         prunearg = TRUE;
08160                 else
08161                         prunearg = FALSE;
08162                 break;
08163         case LSCP_TYPE:
08164                 if(mSequence)
08165                         mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08166                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08167                 mType = type;
08168                 if(mExpressionList)
08169                         mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08170                 if(mStatement)
08171                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08172                 break;
08173         case LSCP_EMIT_BYTE_CODE:
08174                 {
08175                         char jumpname1[32];                     /*Flawfinder: ignore*/
08176                         snprintf(jumpname1, sizeof(jumpname1), "##Temp Jump %d##", gTempJumpCount++);   /* Flawfinder: ignore */
08177                         char jumpname2[32];                             /*Flawfinder: ignore*/
08178                         snprintf(jumpname2, sizeof(jumpname2), "##Temp Jump %d##", gTempJumpCount++);           /* Flawfinder: ignore */
08179 
08180                         if(mSequence)
08181                                 mSequence->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08182                         chunk->addLabel(jumpname1);
08183                         mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08184                         chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPNIF]);
08185                         chunk->addByte(LSCRIPTTypeByte[mType]);
08186                         chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
08187                         chunk->addJump(jumpname2);
08188                         if(mStatement)
08189                                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08190                         if(mExpressionList)
08191                                 mExpressionList->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08192                         chunk->addByte(LSCRIPTOpCodes[LOPC_JUMP]);
08193                         chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
08194                         chunk->addJump(jumpname1);
08195                         chunk->addLabel(jumpname2);
08196                 }
08197                 break;
08198         case LSCP_EMIT_CIL_ASSEMBLY:
08199                 {
08200                         S32 tjump1 =  gTempJumpCount++;
08201                         S32 tjump2 =  gTempJumpCount++;
08202                         if(mSequence)
08203                                 mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08204                         fprintf(fp, "LabelTempJump%d:\n", tjump1);
08205                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08206                         fprintf(fp, "brfalse LabelTempJump%d\n", tjump2);
08207                         if(mStatement)
08208                                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08209                         if(mExpressionList)
08210                                 mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08211                         fprintf(fp, "br LabelTempJump%d\n", tjump1);
08212                         fprintf(fp, "LabelTempJump%d:\n", tjump2);
08213                 }
08214                 break;
08215         default:
08216                 if(mSequence)
08217                         mSequence->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08218                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08219                 if(mExpressionList)
08220                         mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08221                 if(mStatement)
08222                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08223                 break;
08224         }
08225         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08226 }
08227 
08228 S32 LLScriptDoWhile::getSize()
08229 {
08230         return 0;
08231 }
08232 
08233 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)
08234 {
08235         if (gErrorToText.getErrors())
08236         {
08237                 return;
08238         }
08239         switch(pass)
08240         {
08241         case LSCP_PRETTY_PRINT:
08242                 fdotabs(fp, tabs, tabsize);
08243                 fprintf(fp, "do\n");
08244                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08245                 fdotabs(fp, tabs, tabsize);
08246                 fprintf(fp, "while( ");
08247                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08248                 fprintf(fp, " );\n");
08249                 break;
08250         case LSCP_EMIT_ASSEMBLY:
08251                 {
08252                         S32 tjump1 =  gTempJumpCount++;
08253                         fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump1);
08254                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08255                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08256                         fprintf(fp, "JUMPIF ##Temp Jump %d##\n", tjump1);
08257                 }
08258                 break;
08259         case LSCP_PRUNE:
08260                 if (ptype == LSPRUNE_DEAD_CODE)
08261                         prunearg = TRUE;
08262                 else
08263                         prunearg = FALSE;
08264                 break;
08265         case LSCP_TYPE:
08266                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08267                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08268                 mType = type;
08269                 break;
08270         case LSCP_EMIT_BYTE_CODE:
08271                 {
08272                         char jumpname1[32];             /*Flawfinder: ignore*/
08273                         snprintf(jumpname1, sizeof(jumpname1), "##Temp Jump %d##", gTempJumpCount++);           /* Flawfinder: ignore */
08274 
08275                         chunk->addLabel(jumpname1);
08276                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08277                         mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08278                         chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPIF]);
08279                         chunk->addByte(LSCRIPTTypeByte[mType]);
08280                         chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
08281                         chunk->addJump(jumpname1);
08282                 }
08283                 break;
08284         case LSCP_EMIT_CIL_ASSEMBLY:
08285                 {
08286                         S32 tjump1 =  gTempJumpCount++;
08287                         fprintf(fp, "LabelTempJump%d:\n", tjump1);
08288                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08289                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08290                         fprintf(fp, "brtrue LabelTempJump%d\n", tjump1);
08291                 }
08292                 break;
08293         default:
08294                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08295                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08296                 break;
08297         }
08298         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08299 }
08300 
08301 S32 LLScriptWhile::getSize()
08302 {
08303         return 0;
08304 }
08305 
08306 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)
08307 {
08308         if (gErrorToText.getErrors())
08309         {
08310                 return;
08311         }
08312         switch(pass)
08313         {
08314         case LSCP_PRETTY_PRINT:
08315                 fdotabs(fp, tabs, tabsize);
08316                 fprintf(fp, "while( ");
08317                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08318                 fprintf(fp, " )\n");
08319                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08320                 break;
08321         case LSCP_EMIT_ASSEMBLY:
08322                 {
08323                         S32 tjump1 =  gTempJumpCount++;
08324                         S32 tjump2 =  gTempJumpCount++;
08325                         fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump1);
08326                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08327                         fprintf(fp, "JUMPNIF ##Temp Jump %d##\n", tjump2);
08328                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08329                         fprintf(fp, "JUMP ##Temp Jump %d##\n", tjump1);
08330                         fprintf(fp, "LABEL ##Temp Jump %d##\n", tjump2);
08331                 }
08332                 break;
08333         case LSCP_PRUNE:
08334                 if (ptype == LSPRUNE_DEAD_CODE)
08335                         prunearg = TRUE;
08336                 else
08337                         prunearg = FALSE;
08338                 break;
08339         case LSCP_TYPE:
08340                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08341                 mType = type;
08342                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08343                 break;
08344         case LSCP_EMIT_BYTE_CODE:
08345                 {
08346                         char jumpname1[32];     /*Flawfinder: ignore*/
08347                         snprintf(jumpname1, sizeof(jumpname1), "##Temp Jump %d##", gTempJumpCount++);   /* Flawfinder: ignore */
08348                         char jumpname2[32];     /*Flawfinder: ignore*/
08349                         snprintf(jumpname2, sizeof(jumpname2), "##Temp Jump %d##", gTempJumpCount++);   /* Flawfinder: ignore */
08350 
08351                         chunk->addLabel(jumpname1);
08352                         mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08353                         chunk->addByte(LSCRIPTOpCodes[LOPC_JUMPNIF]);
08354                         chunk->addByte(LSCRIPTTypeByte[mType]);
08355                         chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
08356                         chunk->addJump(jumpname2);
08357                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08358                         chunk->addByte(LSCRIPTOpCodes[LOPC_JUMP]);
08359                         chunk->addBytes(LSCRIPTDataSize[LST_INTEGER]);
08360                         chunk->addJump(jumpname1);
08361                         chunk->addLabel(jumpname2);
08362                 }
08363                 break;
08364         case LSCP_EMIT_CIL_ASSEMBLY:
08365                 {
08366                         S32 tjump1 =  gTempJumpCount++;
08367                         S32 tjump2 =  gTempJumpCount++;
08368                         fprintf(fp, "LabelTempJump%d:\n", tjump1);
08369                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08370                         fprintf(fp, "brfalse LabelTempJump%d\n", tjump2);
08371                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08372                         fprintf(fp, "br LabelTempJump%d\n", tjump1);
08373                         fprintf(fp, "LabelTempJump%d:\n", tjump2);
08374                 }
08375                 break;
08376         default:
08377                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08378                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08379                 break;
08380         }
08381         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08382 }
08383 
08384 S32 LLScriptDeclaration::getSize()
08385 {
08386         return mType->getSize();
08387 }
08388 
08389 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)
08390 {
08391         if (gErrorToText.getErrors())
08392         {
08393                 return;
08394         }
08395         switch(pass)
08396         {
08397         case LSCP_PRETTY_PRINT:
08398                 if (mExpression)
08399                 {
08400                         fdotabs(fp, tabs, tabsize);
08401                         mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08402                         fprintf(fp, "\t");
08403                         mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08404                         fprintf(fp, " = ");
08405                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08406                         fprintf(fp, ";\n");
08407                 }
08408                 else
08409                 {
08410                         fdotabs(fp, tabs, tabsize);
08411                         mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08412                         fprintf(fp, "\t");
08413                         mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08414                         fprintf(fp, ";\n");
08415                 }
08416                 break;
08417         case LSCP_EMIT_ASSEMBLY:
08418                 if (mExpression)
08419                 {
08420                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08421                         if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08422                         {
08423                                 fprintf(fp, "%s%d [%s]\n", LSCRIPTTypeLocalDeclaration[mIdentifier->mScopeEntry->mType], mIdentifier->mScopeEntry->mOffset, mIdentifier->mName);
08424                         }
08425                         else if (mIdentifier->mScopeEntry->mIDType == LIT_GLOBAL)
08426                         {
08427                                 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
08428                         }
08429                 }
08430                 break;
08431         case LSCP_PRUNE:
08432                 if (ptype == LSPRUNE_DEAD_CODE)
08433                         prunearg = TRUE;
08434                 else
08435                         prunearg = FALSE;
08436                 break;
08437         case LSCP_SCOPE_PASS1:
08438                 // Check to see if a declaration is valid here.
08439                 if (!mAllowDeclarations)
08440                 {
08441                         gErrorToText.writeError(fp, this, LSERROR_NEED_NEW_SCOPE);
08442                 }
08443                 // add labels to scope
08444                 else if (scope->checkEntry(mIdentifier->mName))
08445                 {
08446                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
08447                 }
08448                 else
08449                 {
08450                         if (mExpression)
08451                         {
08452                                 mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08453                         }
08454                         // this needs to go after expression decent to make sure that we don't add ourselves or something silly
08455                         // check expression if it exists
08456                         mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_VARIABLE, mType->mType);
08457                 }
08458                 break;
08459         case LSCP_TYPE:
08460                 // if there is an expression, it must be promotable to variable type
08461                 if (mExpression && mIdentifier->mScopeEntry)
08462                 {
08463                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08464                         if (!legal_assignment(mIdentifier->mScopeEntry->mType, type))
08465                         {
08466                                 gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
08467                         }
08468                 }
08469                 break;
08470         case LSCP_RESOURCE:
08471                 {
08472                         mIdentifier->mScopeEntry->mOffset = (S32)count;
08473                         mIdentifier->mScopeEntry->mSize = mType->getSize();
08474                         count += mIdentifier->mScopeEntry->mSize;
08475                         // Index into locals is current number of locals. Stored in mCount member of mScopeEntry.
08476                         mIdentifier->mScopeEntry->mCount = entry->mLocals.getNumber();
08477                         entry->mLocals.addType(mType->mType);
08478                         mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08479                 }
08480                 break;
08481         case LSCP_EMIT_BYTE_CODE:
08482                 if (mExpression)
08483                 {
08484                         mExpression->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08485                         if (mExpression->mReturnType != mIdentifier->mScopeEntry->mType)
08486                         {
08487                                 cast2stack(chunk, mExpression->mReturnType, mIdentifier->mScopeEntry->mType);
08488                         }
08489                         switch(mExpression->mReturnType)
08490                         {
08491                         case LST_INTEGER:
08492                         case LST_FLOATINGPOINT:
08493                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08494                                 {
08495                                         chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
08496                                 }
08497                                 break;
08498                         case LST_STRING:
08499                         case LST_KEY:
08500                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08501                                 {
08502                                         chunk->addByte(LSCRIPTOpCodes[LOPC_LOADSP]);
08503                                 }
08504                                 break;
08505                         case LST_LIST:
08506                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08507                                 {
08508                                         chunk->addByte(LSCRIPTOpCodes[LOPC_LOADLP]);
08509                                 }
08510                                 break;
08511                         case LST_VECTOR:
08512                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08513                                 {
08514                                         chunk->addByte(LSCRIPTOpCodes[LOPC_LOADVP]);
08515                                 }
08516                                 break;
08517                         case LST_QUATERNION:
08518                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08519                                 {
08520                                         chunk->addByte(LSCRIPTOpCodes[LOPC_LOADQP]);
08521                                 }
08522                                 break;
08523                         default:
08524                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08525                                 {
08526                                         chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
08527                                 }
08528                                 break;
08529                         }
08530                         if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08531                         {
08532                                 S32 address = mIdentifier->mScopeEntry->mOffset;
08533                                 chunk->addInteger(address);
08534                         }
08535                 }
08536                 else
08537                 {
08538                         switch(mIdentifier->mScopeEntry->mType)
08539                         {
08540                         case LST_INTEGER:
08541                         case LST_FLOATINGPOINT:
08542                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08543                                 {
08544                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
08545                                         chunk->addInteger(0);
08546                                         chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
08547                                 }
08548                                 break;
08549                         case LST_STRING:
08550                         case LST_KEY:
08551                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08552                                 {
08553                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGS]);
08554                                         chunk->addBytes("", 1);
08555                                         chunk->addByte(LSCRIPTOpCodes[LOPC_LOADSP]);
08556                                 }
08557                                 break;
08558                         case LST_LIST:
08559                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08560                                 {
08561                                         chunk->addByte(LSCRIPTOpCodes[LOPC_STACKTOL]);
08562                                         chunk->addInteger(0);
08563                                         chunk->addByte(LSCRIPTOpCodes[LOPC_LOADLP]);
08564                                 }
08565                                 break;
08566                         case LST_VECTOR:
08567                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08568                                 {
08569                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGV]);
08570                                         chunk->addFloat(0);
08571                                         chunk->addFloat(0);
08572                                         chunk->addFloat(0);
08573                                         chunk->addByte(LSCRIPTOpCodes[LOPC_LOADVP]);
08574                                 }
08575                                 break;
08576                         case LST_QUATERNION:
08577                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08578                                 {
08579                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGQ]);
08580                                         chunk->addFloat(1);
08581                                         chunk->addFloat(0);
08582                                         chunk->addFloat(0);
08583                                         chunk->addFloat(0);
08584                                         chunk->addByte(LSCRIPTOpCodes[LOPC_LOADQP]);
08585                                 }
08586                                 break;
08587                         default:
08588                                 if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08589                                 {
08590                                         chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
08591                                         chunk->addInteger(0);
08592                                         chunk->addByte(LSCRIPTOpCodes[LOPC_LOADP]);
08593                                 }
08594                                 break;
08595                         }
08596                         if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08597                         {
08598                                 S32 address = mIdentifier->mScopeEntry->mOffset;
08599                                 chunk->addInteger(address);
08600                         }
08601                 }
08602                 break;
08603         case LSCP_EMIT_CIL_ASSEMBLY:
08604                 if (mExpression)
08605                 {
08606                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08607                         if (mIdentifier->mScopeEntry->mIDType == LIT_VARIABLE)
08608                         {
08609                                 if(is_parameter(mIdentifier, entry))
08610                                 {
08611                                         // Parameter, store by name.
08612                                         fprintf(fp, "starg.s %s\n", mIdentifier->mScopeEntry->mIdentifier);
08613                                 }
08614                                 else
08615                                 {
08616                                         // Local, store by index.
08617                                         fprintf(fp, "stloc.s %d\n", mIdentifier->mScopeEntry->mCount);
08618                                 }
08619                         }
08620                         else if (mIdentifier->mScopeEntry->mIDType == LIT_GLOBAL)
08621                         {
08622                                 gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
08623                         }
08624                 }
08625                 break;
08626         default:
08627                 if (mExpression)
08628                 {
08629                         mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08630                         mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08631                         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08632                 }
08633                 else
08634                 {
08635                         mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08636                         mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08637                 }
08638                 break;
08639         }
08640         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08641 }
08642 
08643 S32 LLScriptCompoundStatement::getSize()
08644 {
08645         return 0;
08646 }
08647 
08648 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)
08649 {
08650         if (gErrorToText.getErrors())
08651         {
08652                 return;
08653         }
08654         switch(pass)
08655         {
08656         case LSCP_PRETTY_PRINT:
08657                 if (mStatement)
08658                 {
08659                         fdotabs(fp, tabs, tabsize);
08660                         fprintf(fp, "{\n");
08661                         mStatement->recurse(fp, tabs + 1, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08662                         fdotabs(fp, tabs, tabsize);
08663                         fprintf(fp, "}\n");
08664                 }
08665                 else
08666                 {
08667                         fdotabs(fp, tabs, tabsize);
08668                         fprintf(fp, "{\n");
08669                         fdotabs(fp, tabs, tabsize);
08670                         fprintf(fp, "}\n");
08671                 }
08672                 break;
08673         case LSCP_EMIT_ASSEMBLY:
08674                 if (mStatement)
08675                 {
08676                         mStatement->recurse(fp, tabs + 1, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08677                 }
08678                 break;
08679         case LSCP_PRUNE:
08680                 if (mStatement)
08681                 {
08682                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08683                 }
08684                 else
08685                 {
08686                         prunearg = FALSE;
08687                 }
08688                 break;
08689         case LSCP_SCOPE_PASS1:
08690                 // compound statements create a new scope
08691                 if (mStatement)
08692                 {
08693                         mStatementScope = new LLScriptScope(gScopeStringTable);
08694                         mStatementScope->addParentScope(scope);
08695                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mStatementScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08696                 }
08697                 break;
08698         case LSCP_SCOPE_PASS2:
08699                 // compound statements create a new scope
08700                 if (mStatement)
08701                 {
08702                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mStatementScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08703                 }
08704                 break;
08705         default:
08706                 if (mStatement)
08707                 {
08708                         mStatement->recurse(fp, tabs + 1, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08709                 }
08710                 break;
08711         }
08712         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08713 }
08714 
08715 void LLScriptEventHandler::addEvent(LLScriptEventHandler *event)
08716 {
08717         if (mNextp)
08718         {
08719                 event->mNextp = mNextp;
08720         }
08721         mNextp = event;
08722 }
08723 
08724 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)
08725 {
08726         if (gErrorToText.getErrors())
08727         {
08728                 return;
08729         }
08730         switch(pass)
08731         {
08732         case LSCP_PRETTY_PRINT:
08733                 if (mNextp)
08734                 {
08735                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08736                 }
08737                 break;
08738         default:
08739                 if (mNextp)
08740                 {
08741                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08742                 }
08743                 break;
08744         }
08745 }
08746 
08747 S32 LLScriptEventHandler::getSize()
08748 {
08749         return mStackSpace;
08750 }
08751 
08752 U64 gCurrentHandler = 0;
08753 
08754 void print_cil_local_init(FILE* fp, LLScriptScopeEntry* scopeEntry)
08755 {
08756         if(scopeEntry->mLocals.getNumber() > 0)
08757         {
08758                 fprintf(fp, ".locals init (");
08759                 for(int local = 0; local < scopeEntry->mLocals.getNumber(); ++local)
08760                 {
08761                         if(local > 0)
08762                         {
08763                                 fprintf(fp, ", ");
08764                         }
08765                         print_cil_type(fp, scopeEntry->mLocals.getType(local));
08766                 }
08767                 fprintf(fp, ")\n");
08768         }
08769 }
08770 
08771 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)
08772 {
08773         if (gErrorToText.getErrors())
08774         {
08775                 return;
08776         }
08777         switch(pass)
08778         {
08779         case LSCP_PRETTY_PRINT:
08780                 mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08781                 if (mStatement)
08782                 {
08783                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08784                 }
08785                 else
08786                 {
08787                         fdotabs(fp, tabs, tabsize);
08788                         fprintf(fp, "{\n");
08789                         fdotabs(fp, tabs, tabsize);
08790                         fprintf(fp, "}\n");
08791                 }
08792                 break;
08793         case LSCP_EMIT_ASSEMBLY:
08794                 mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08795                 if (mStatement)
08796                 {
08797                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, getSize(), mScopeEntry, entrycount, NULL);
08798                 }
08799                 if (mbNeedTrailingReturn)
08800                 {
08801                         print_return(fp, mScopeEntry);
08802                 }
08803                 fprintf(fp, "\n");
08804                 break;
08805         case LSCP_PRUNE:
08806                 mbNeedTrailingReturn = FALSE;
08807                 prunearg = TRUE;
08808                 mStatement->recurse(fp, tabs, tabsize, pass, LSPRUNE_EVENTS, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08809                 if (!prunearg)
08810                 {
08811                         // this means that we didn't end with a return statement, need to add one
08812                         mbNeedTrailingReturn = TRUE;
08813                 }
08814                 break;
08815         case LSCP_SCOPE_PASS1:
08816                 // create event level scope
08817                 mEventScope = new LLScriptScope(gScopeStringTable);
08818                 mEventScope->addParentScope(scope);
08819 
08820                 // add event parameters
08821                 mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mEventScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08822 
08823                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mEventScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08824                 break;
08825         case LSCP_SCOPE_PASS2:
08826                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mEventScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08827                 break;
08828         case LSCP_TYPE:
08829                 mScopeEntry = new LLScriptScopeEntry("Event", LIT_HANDLER, LST_NULL);
08830                 switch(mEventp->mType)
08831                 {
08832                 case LSTT_STATE_ENTRY:
08833                         break;
08834                 case LSTT_STATE_EXIT:
08835                         break;
08836                 case LSTT_TOUCH_START:
08837                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08838                         break;
08839                 case LSTT_TOUCH:
08840                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08841                         break;
08842                 case LSTT_TOUCH_END:
08843                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08844                         break;
08845                 case LSTT_COLLISION_START:
08846                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08847                         break;
08848                 case LSTT_COLLISION:
08849                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08850                         break;
08851                 case LSTT_COLLISION_END:
08852                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08853                         break;
08854                 case LSTT_LAND_COLLISION_START:
08855                         mScopeEntry->mFunctionArgs.addType(LST_VECTOR);
08856                         break;
08857                 case LSTT_LAND_COLLISION:
08858                         mScopeEntry->mFunctionArgs.addType(LST_VECTOR);
08859                         break;
08860                 case LSTT_LAND_COLLISION_END:
08861                         mScopeEntry->mFunctionArgs.addType(LST_VECTOR);
08862                         break;
08863                 case LSTT_INVENTORY:
08864                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08865                         break;
08866                 case LSTT_ATTACH:
08867                         mScopeEntry->mFunctionArgs.addType(LST_KEY);
08868                         break;
08869                 case LSTT_DATASERVER:
08870                         mScopeEntry->mFunctionArgs.addType(LST_KEY);
08871                         mScopeEntry->mFunctionArgs.addType(LST_STRING);
08872                         break;
08873                 case LSTT_TIMER:
08874                         break;
08875                 case LSTT_MOVING_START:
08876                         break;
08877                 case LSTT_MOVING_END:
08878                         break;
08879                 case LSTT_OBJECT_REZ:
08880                         mScopeEntry->mFunctionArgs.addType(LST_KEY);
08881                         break;
08882                 case LSTT_REMOTE_DATA:
08883                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08884                         mScopeEntry->mFunctionArgs.addType(LST_KEY);
08885                         mScopeEntry->mFunctionArgs.addType(LST_KEY);
08886                         mScopeEntry->mFunctionArgs.addType(LST_STRING);
08887                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08888                         mScopeEntry->mFunctionArgs.addType(LST_STRING);
08889                         break;
08890                 case LSTT_CHAT:
08891                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08892                         mScopeEntry->mFunctionArgs.addType(LST_STRING);
08893                         mScopeEntry->mFunctionArgs.addType(LST_KEY);
08894                         mScopeEntry->mFunctionArgs.addType(LST_STRING);
08895                         break;
08896                 case LSTT_SENSOR:
08897                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08898                         break;
08899                 case LSTT_CONTROL:
08900                         mScopeEntry->mFunctionArgs.addType(LST_KEY);
08901                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08902                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08903                         break;
08904                 case LSTT_LINK_MESSAGE:
08905                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08906                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08907                         mScopeEntry->mFunctionArgs.addType(LST_STRING);
08908                         mScopeEntry->mFunctionArgs.addType(LST_KEY);
08909                         break;
08910                 case LSTT_MONEY:
08911                         mScopeEntry->mFunctionArgs.addType(LST_KEY);
08912                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08913                         break;
08914                 case LSTT_EMAIL:
08915                         mScopeEntry->mFunctionArgs.addType(LST_STRING);
08916                         mScopeEntry->mFunctionArgs.addType(LST_STRING);
08917                         mScopeEntry->mFunctionArgs.addType(LST_STRING);
08918                         mScopeEntry->mFunctionArgs.addType(LST_STRING);
08919                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08920                         break;
08921                 case LSTT_REZ:
08922                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08923                         break;
08924                 case LSTT_NO_SENSOR:
08925                         break;
08926                 case LSTT_AT_TARGET:
08927                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08928                         mScopeEntry->mFunctionArgs.addType(LST_VECTOR);
08929                         mScopeEntry->mFunctionArgs.addType(LST_VECTOR);
08930                         break;
08931                 case LSTT_NOT_AT_TARGET:
08932                         break;
08933                 case LSTT_AT_ROT_TARGET:
08934                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08935                         mScopeEntry->mFunctionArgs.addType(LST_QUATERNION);
08936                         mScopeEntry->mFunctionArgs.addType(LST_QUATERNION);
08937                         break;
08938                 case LSTT_NOT_AT_ROT_TARGET:
08939                         break;
08940                 case LSTT_RTPERMISSIONS:
08941                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08942                         break;
08943                 case LSTT_HTTP_RESPONSE:
08944                         mScopeEntry->mFunctionArgs.addType(LST_KEY);
08945                         mScopeEntry->mFunctionArgs.addType(LST_INTEGER);
08946                         mScopeEntry->mFunctionArgs.addType(LST_LIST);
08947                         mScopeEntry->mFunctionArgs.addType(LST_STRING);
08948                         break;
08949 
08950                 default:
08951                         break;
08952                 }
08953                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08954                 break;
08955         case LSCP_RESOURCE:
08956                 // first determine resource counts for globals
08957                 count = 0;
08958                 mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
08959                 if (mStatement)
08960                 {
08961                         entrycount = 0;
08962                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mScopeEntry, entrycount, NULL);
08963 
08964                         const char *function_args = mScopeEntry->mFunctionArgs.mString;
08965                         fprintf(fp, "Function Args: %s\n", function_args?function_args:"");
08966 
08967                         const char *local_list = mScopeEntry->mLocals.mString;
08968                         fprintf(fp, "Local List: %s\n", local_list?local_list:"");
08969                 }
08970                 mStackSpace = (S32)count;
08971                 break;
08972         case LSCP_DETERMINE_HANDLERS:
08973                 count |= LSCRIPTStateBitField[mEventp->mType];
08974                 break;
08975         case LSCP_EMIT_BYTE_CODE:
08976                 {
08977                         // order for event handler
08978                         // set jump table value
08979                         S32 jumpoffset;
08980                         jumpoffset = LSCRIPTDataSize[LST_INTEGER]*get_event_handler_jump_position(gCurrentHandler, mEventp->mType)*2;
08981 
08982                         integer2bytestream(chunk->mCodeChunk, jumpoffset, chunk->mCurrentOffset);
08983 
08984                         // 0 - 3: offset to actual data
08985                         S32 offsetoffset = chunk->mCurrentOffset;
08986                         S32 offsetdelta = 0;
08987                         chunk->addBytes(4);
08988 
08989                         // null terminated event name and null terminated parameters
08990                         if (mEventp)
08991                         {
08992                                 LLScriptByteCodeChunk   *event = new LLScriptByteCodeChunk(FALSE);
08993                                 mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, event, heap, stacksize, entry, entrycount, NULL);
08994                                 chunk->addBytes(event->mCodeChunk, event->mCurrentOffset);
08995                                 delete event;
08996                         }
08997                         chunk->addBytes(1);
08998 
08999                         // now we're at the first opcode
09000                         offsetdelta = chunk->mCurrentOffset - offsetoffset;
09001                         integer2bytestream(chunk->mCodeChunk, offsetoffset, offsetdelta);
09002 
09003                         // get ready to compute the number of bytes of opcode
09004                         offsetdelta = chunk->mCurrentOffset;
09005 
09006                         if (mStatement)
09007                         {
09008                                 LLScriptByteCodeChunk   *statements = new LLScriptByteCodeChunk(TRUE);
09009                                 mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, statements, heap, getSize(), mScopeEntry, entrycount, NULL);
09010                                 statements->connectJumps();
09011                                 chunk->addBytes(statements->mCodeChunk, statements->mCurrentOffset);
09012                                 delete statements;
09013                         }
09014                         if (mbNeedTrailingReturn)
09015                         {
09016                                 add_return(chunk, mScopeEntry);
09017                         }
09018                         // now stuff in the number of bytes of stack space that this routine needs
09019                         integer2bytestream(chunk->mCodeChunk, jumpoffset, getSize());
09020                 }
09021                 break;
09022         case LSCP_EMIT_CIL_ASSEMBLY:
09023 
09024                 // Method signature prefix.
09025                 fprintf(fp, ".method public hidebysig instance default void ");
09026 
09027                 // Mangle event handler name by prefixing it with state name. Allows state changing by finding handlers prefixed with new state name.
09028                 fprintf(fp, entry->mIdentifier);                /*Flawfinder: ignore*/
09029 
09030                 // Handler name and arguments.
09031                 mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09032 
09033                 // Method signature postfix.
09034                 fprintf(fp, " cil managed\n");
09035 
09036                 // Function header.
09037                 fprintf(fp,"{\n");
09038                 fprintf(fp, ".maxstack 500\n"); // TODO: Calculated stack size...
09039 
09040                 // Allocate space for locals.
09041                 print_cil_local_init(fp, mScopeEntry);
09042 
09043                 if (mStatement)
09044                 {
09045                         // Pass scope so identifiers can determine parameter or local.
09046                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mScopeEntry, entrycount, NULL);
09047                 }
09048 
09049                 // Function footer.
09050                 fprintf(fp, "\nret\n"); // TODO: Check whether return needed?
09051                 fprintf(fp, "}\n");
09052 
09053                 break;
09054         default:
09055                 mEventp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09056                 if (mStatement)
09057                 {
09058                         mStatement->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09059                 }
09060                 break;
09061         }
09062         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09063 }
09064 
09065 void LLScriptFunctionDec::addFunctionParameter(LLScriptFunctionDec *dec)
09066 {
09067         if (mNextp)
09068         {
09069                 dec->mNextp = mNextp;
09070         }
09071         mNextp = dec;
09072 }
09073 
09074 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)
09075 {
09076         if (gErrorToText.getErrors())
09077         {
09078                 return;
09079         }
09080         switch(pass)
09081         {
09082         case LSCP_PRETTY_PRINT:
09083                 if (mNextp)
09084                 {
09085                         fprintf(fp, ", ");
09086                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09087                 }
09088                 break;
09089         case LSCP_EMIT_ASSEMBLY:
09090                 if (mNextp)
09091                 {
09092                         fprintf(fp, ", ");
09093                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09094                 }
09095                 break;
09096         default:
09097                 if (mNextp)
09098                 {
09099                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09100                 }
09101                 break;
09102         }
09103 
09104 }
09105 
09106 S32 LLScriptFunctionDec::getSize()
09107 {
09108         return 0;
09109 }
09110 
09111 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)
09112 {
09113         if (gErrorToText.getErrors())
09114         {
09115                 return;
09116         }
09117         switch(pass)
09118         {
09119         case LSCP_PRETTY_PRINT:
09120                 fdotabs(fp, tabs, tabsize);
09121                 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09122                 fprintf(fp, " ");
09123                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09124                 break;
09125         case LSCP_EMIT_ASSEMBLY:
09126                 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09127                 fprintf(fp, " ");
09128                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09129                 break;
09130         case LSCP_SCOPE_PASS1:
09131                 // add function names into global scope
09132                 if (scope->checkEntry(mIdentifier->mName))
09133                 {
09134                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
09135                 }
09136                 else
09137                 {
09138                         mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_VARIABLE, mType->mType);
09139                 }
09140                 break;
09141         case LSCP_RESOURCE:
09142                 {
09143                         // we're just tryng to determine how much space the variable needs
09144                         mIdentifier->mScopeEntry->mOffset = (S32)count;
09145                         mIdentifier->mScopeEntry->mSize = mType->getSize();
09146                         count += mIdentifier->mScopeEntry->mSize;
09147                 }
09148                 break;
09149         case LSCP_EMIT_BYTE_CODE:
09150                 {
09151                         // return type
09152                         char typereturn;
09153                         if (mType)
09154                         {
09155                                 typereturn = LSCRIPTTypeByte[mType->mType];
09156                         }
09157                         else
09158                         {
09159                                 typereturn = LSCRIPTTypeByte[LST_NULL]; 
09160                         }
09161                         chunk->addBytes(&typereturn, 1);
09162                         // name
09163 #ifdef LSL_INCLUDE_DEBUG_INFO
09164                         chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);            /*Flawfinder: ignore*/
09165 #else
09166                         chunk->addBytes(1);
09167 #endif
09168                 }
09169                 break;
09170         case LSCP_BUILD_FUNCTION_ARGS:
09171                 {
09172                         entry->mFunctionArgs.addType(mType->mType);
09173                 }
09174                 break;
09175         case LSCP_EMIT_CIL_ASSEMBLY:
09176                 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09177                 fprintf(fp, " ");
09178                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09179                 break;
09180         default:
09181                 mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09182                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09183                 break;
09184         }
09185         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09186 }
09187 
09188 void LLScriptGlobalFunctions::addGlobalFunction(LLScriptGlobalFunctions *global)
09189 {
09190         if (mNextp)
09191         {
09192                 global->mNextp = mNextp;
09193         }
09194         mNextp = global;
09195 }
09196 
09197 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)
09198 {
09199         if (gErrorToText.getErrors())
09200         {
09201                 return;
09202         }
09203         switch(pass)
09204         {
09205         case LSCP_PRETTY_PRINT:
09206                 if (mNextp)
09207                 {
09208                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09209                 }
09210                 break;
09211         default:
09212                 if (mNextp)
09213                 {
09214                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09215                 }
09216                 break;
09217         }
09218 }
09219 
09220 S32 LLScriptGlobalFunctions::getSize()
09221 {
09222         return 0;
09223 }
09224 
09225 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)
09226 {
09227         if (gErrorToText.getErrors())
09228         {
09229                 return;
09230         }
09231         switch(pass)
09232         {
09233         case LSCP_PRETTY_PRINT:
09234                 fdotabs(fp, tabs, tabsize);
09235                 if (mType)
09236                 {
09237                         mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09238                         fprintf(fp, "\t");
09239                 }
09240                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09241                 if (mParameters)
09242                 {
09243                         fprintf(fp, "( ");
09244                         mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09245                         fprintf(fp, " )\n");
09246                 }
09247                 else
09248                 {
09249                         fprintf(fp, "()\n");
09250                 }
09251                 if (mStatements)
09252                 {
09253                         fdotabs(fp, tabs, tabsize);
09254                         mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, entrycount, NULL);
09255                 }
09256                 else
09257                 {
09258                         fdotabs(fp, tabs, tabsize);
09259                         fprintf(fp, "{\n");
09260                         fdotabs(fp, tabs, tabsize);
09261                         fprintf(fp, "}\n");
09262                 }
09263                 break;
09264         case LSCP_EMIT_ASSEMBLY:
09265                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09266                 if (mParameters)
09267                 {
09268                         fprintf(fp, "( ");
09269                         mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09270                         fprintf(fp, " )\n");
09271                 }
09272                 else
09273                 {
09274                         fprintf(fp, "()\n");
09275                 }
09276                 if (mStatements)
09277                 {
09278                         mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, mIdentifier->mScopeEntry->mSize, mIdentifier->mScopeEntry, entrycount, NULL);
09279                 }
09280                 if (mbNeedTrailingReturn)
09281                 {
09282                         print_return(fp, mIdentifier->mScopeEntry);
09283                 }
09284                 fprintf(fp, "\n");
09285                 break;
09286         case LSCP_PRUNE:
09287                 mbNeedTrailingReturn = FALSE;
09288                 if (mType)
09289                 {
09290                         prunearg = TRUE;
09291                         mStatements->recurse(fp, tabs, tabsize, pass, LSPRUNE_GLOBAL_NON_VOIDS, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09292                         if (!prunearg)
09293                         {
09294                                 gErrorToText.writeError(fp, this, LSERROR_NO_RETURN);
09295                         }
09296                 }
09297                 else
09298                 {
09299                         prunearg = TRUE;
09300                         mStatements->recurse(fp, tabs, tabsize, pass, LSPRUNE_GLOBAL_VOIDS, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09301                         if (!prunearg)
09302                         {
09303                                 // this means that we didn't end with a return statement, need to add one
09304                                 mbNeedTrailingReturn = TRUE;
09305                         }
09306                 }
09307                 break;
09308         case LSCP_SCOPE_PASS1:
09309                 // add function names into global scope
09310                 if (scope->checkEntry(mIdentifier->mName))
09311                 {
09312                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
09313                 }
09314                 else
09315                 {
09316                         if (mType)
09317                         {
09318                                 mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_FUNCTION, mType->mType);
09319                         }
09320                         else
09321                         {
09322                                 mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_FUNCTION, LST_NULL);
09323                         }
09324                 }
09325 
09326                 // create function level scope
09327                 mFunctionScope = new LLScriptScope(gScopeStringTable);
09328                 mFunctionScope->addParentScope(scope);
09329 
09330                 // function parameters
09331                 if (mParameters)
09332                 {
09333                         mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mFunctionScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09334                 }
09335 
09336                 mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mFunctionScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09337                 break;
09338         case LSCP_SCOPE_PASS2:
09339                 mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mFunctionScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09340                 
09341                 if (mParameters)
09342                 {
09343                         if (mIdentifier->mScopeEntry)
09344                         {
09345                                 mParameters->recurse(fp, tabs, tabsize, LSCP_BUILD_FUNCTION_ARGS, ptype, prunearg, mFunctionScope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
09346                         }
09347                 }
09348                 break;
09349         case LSCP_TYPE:
09350                 if (mType)
09351                 {
09352                         mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, mType->mType, count, chunk, heap, stacksize, entry, entrycount, NULL);
09353                 }
09354                 else
09355                 {
09356                         type = LST_NULL;
09357                         mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09358                 }
09359                 break;
09360         case LSCP_RESOURCE:
09361                 // first determine resource counts for globals
09362                 count = 0;
09363 
09364                 if (mParameters)
09365                 {
09366                         mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09367                 }
09368 
09369                 if (mIdentifier->mScopeEntry)
09370                 {
09371                         // this isn't a bug . . . Offset is used to determine how much is params vs locals
09372                         mIdentifier->mScopeEntry->mOffset = (S32)count;
09373                 }
09374 
09375                 if (mStatements)
09376                 {
09377                         entrycount = 0;
09378                         mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, entrycount, NULL);
09379                         fprintf(fp, "Function Args: %s\n", mIdentifier->mScopeEntry->mFunctionArgs.mString);
09380                         fprintf(fp, "Local List: %s\n", mIdentifier->mScopeEntry->mLocals.mString);
09381                         if (mIdentifier->mScopeEntry)
09382                         {
09383                                 mIdentifier->mScopeEntry->mSize = (S32)count;
09384                         }
09385                 }
09386                 break;
09387         case LSCP_EMIT_BYTE_CODE:
09388                 {
09389                         // order for global functions
09390                         // set jump table value
09391                         S32 jumpoffset = LSCRIPTDataSize[LST_INTEGER]*mIdentifier->mScopeEntry->mCount + LSCRIPTDataSize[LST_INTEGER];
09392                         integer2bytestream(chunk->mCodeChunk, jumpoffset, chunk->mCurrentOffset);
09393 
09394                         // 0 - 3: offset to actual data
09395                         S32 offsetoffset = chunk->mCurrentOffset;
09396                         S32 offsetdelta = 0;
09397                         chunk->addBytes(4);
09398 
09399                         // null terminated function name
09400 #ifdef LSL_INCLUDE_DEBUG_INFO
09401                         chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);            /*Flawfinder: ignore*/
09402 #else
09403                         chunk->addBytes(1);
09404 #endif
09405                         // return type
09406                         char typereturn;
09407                         if (mType)
09408                         {
09409                                 typereturn = LSCRIPTTypeByte[mType->mType];
09410                         }
09411                         else
09412                         {
09413                                 typereturn = LSCRIPTTypeByte[LST_NULL]; 
09414                         }
09415                         chunk->addBytes(&typereturn, 1);
09416 
09417                         // null terminated parameters, followed by type
09418                         if (mParameters)
09419                         {
09420                                 LLScriptByteCodeChunk   *params = new LLScriptByteCodeChunk(FALSE);
09421                                 mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, params, heap, stacksize, entry, entrycount, NULL);
09422                                 chunk->addBytes(params->mCodeChunk, params->mCurrentOffset);
09423                                 delete params;
09424                         }
09425                         chunk->addBytes(1);
09426 
09427                         // now we're at the first opcode
09428                         offsetdelta = chunk->mCurrentOffset - offsetoffset;
09429                         integer2bytestream(chunk->mCodeChunk, offsetoffset, offsetdelta);
09430 
09431                         if (mStatements)
09432                         {
09433                                 LLScriptByteCodeChunk   *statements = new LLScriptByteCodeChunk(TRUE);
09434                                 mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, statements, heap, mIdentifier->mScopeEntry->mSize, mIdentifier->mScopeEntry, entrycount, NULL);
09435                                 statements->connectJumps();
09436                                 chunk->addBytes(statements->mCodeChunk, statements->mCurrentOffset);
09437                                 delete statements;
09438                         }
09439                         if (mbNeedTrailingReturn)
09440                         {
09441                                 add_return(chunk, mIdentifier->mScopeEntry);
09442                         }
09443                 }
09444                 break;
09445         case LSCP_EMIT_CIL_ASSEMBLY:
09446                 {
09447                         // Function header.
09448                         fprintf(fp, ".method public hidebysig instance default ");
09449                         print_cil_type(fp, mType ? mType->mType : LST_NULL);
09450                         fprintf(fp, " ");
09451                         mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09452                         if (mParameters)
09453                         {
09454                                 fprintf(fp, "( ");
09455                                 mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09456                                 fprintf(fp, " )");
09457                         }
09458                         else
09459                         {
09460                                 fprintf(fp, "()");
09461                         }
09462                         fprintf(fp, " cil managed\n{\n");
09463                         fprintf(fp, ".maxstack 500\n"); // TODO: Calculated stack size...
09464 
09465                         // Allocate space for locals.
09466                         print_cil_local_init(fp, mIdentifier->mScopeEntry);
09467 
09468                         if (mStatements)
09469                         {
09470                                 mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, mIdentifier->mScopeEntry->mSize, mIdentifier->mScopeEntry, entrycount, NULL);
09471                         }
09472 
09473                         // Function footer.
09474                         if (mbNeedTrailingReturn)
09475                         {
09476                                 fprintf(fp, "ret\n");
09477                         }
09478                         fprintf(fp, "}\n");
09479                         fprintf(fp, "\n");
09480                 }
09481                 break;
09482         default:
09483                 if (mType)
09484                 {
09485                         mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09486                 }
09487                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09488                 if (mParameters)
09489                 {
09490                         mParameters->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09491                 }
09492                 if (mStatements)
09493                 {
09494                         mStatements->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09495                 }
09496                 break;
09497         }
09498         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09499 }
09500 
09501 void LLScriptState::addState(LLScriptState *state)
09502 {
09503         if (mNextp)
09504         {
09505                 state->mNextp = mNextp;
09506         }
09507         mNextp = state;
09508 }
09509 
09510 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)
09511 {
09512         if (gErrorToText.getErrors())
09513         {
09514                 return;
09515         }
09516         switch(pass)
09517         {
09518         case LSCP_PRETTY_PRINT:
09519                 if (mNextp)
09520                 {
09521                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09522                 }
09523                 break;
09524         default:
09525                 if (mNextp)
09526                 {
09527                         mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09528                 }
09529                 break;
09530         }
09531 }
09532 
09533 S32 LLScriptState::getSize()
09534 {
09535         return 0;
09536 }
09537 
09538 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)
09539 {
09540         if (gErrorToText.getErrors())
09541         {
09542                 return;
09543         }
09544         switch(pass)
09545         {
09546         case LSCP_PRETTY_PRINT:
09547                 fdotabs(fp, tabs, tabsize);
09548                 if (mType == LSSTYPE_DEFAULT)
09549                 {
09550                         mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09551                         fprintf(fp, "\n");
09552                         fdotabs(fp, tabs, tabsize);
09553                         fprintf(fp, "{\n");
09554                 }
09555                 else
09556                 {
09557                         fprintf(fp, "state ");
09558                         mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09559                         fprintf(fp, "\n");
09560                         fdotabs(fp, tabs, tabsize);
09561                         fprintf(fp, "{\n");
09562                 }
09563                 if (mEvent)
09564                 {
09565                         mEvent->recurse(fp, tabs + 1, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09566                 }
09567                 fdotabs(fp, tabs, tabsize);
09568                 fprintf(fp, "}\n");
09569                 break;
09570         case LSCP_EMIT_ASSEMBLY:
09571                 mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09572                 fprintf(fp, ":\n");
09573                 if (mEvent)
09574                 {
09575                         fprintf(fp, "EVENTS\n");
09576                         mEvent->recurse(fp, tabs + 1, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09577                         fprintf(fp, "\n");
09578                 }
09579                 break;
09580         case LSCP_SCOPE_PASS1:
09581                 // add state name
09582                 if (scope->checkEntry(mIdentifier->mName))
09583                 {
09584                         gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
09585                 }
09586                 else
09587                 {
09588                         mIdentifier->mScopeEntry = scope->addEntry(mIdentifier->mName, LIT_STATE, LST_NULL);
09589                 }
09590                 // now do the events
09591                 if (mEvent)
09592                 {
09593                         mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09594                 }
09595                 break;
09596         case LSCP_SCOPE_PASS2:
09597                 if (mEvent)
09598                 {
09599                         mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09600                 }
09601                 break;
09602         case LSCP_TYPE:
09603                 if (mEvent)
09604                 {
09605                         mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09606                 }
09607                 break;
09608         case LSCP_EMIT_BYTE_CODE:
09609                 {
09610                         // order for states
09611                         // set jump table value
09612                         
09613                         S32 jumpoffset;
09614                         if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)
09615                         {
09616                                 jumpoffset = LSCRIPTDataSize[LST_INTEGER]*3*mIdentifier->mScopeEntry->mCount + LSCRIPTDataSize[LST_INTEGER];
09617                         }
09618                         else
09619                         {
09620                                 jumpoffset = LSCRIPTDataSize[LST_INTEGER]*2*mIdentifier->mScopeEntry->mCount + LSCRIPTDataSize[LST_INTEGER];
09621                         }
09622                         integer2bytestream(chunk->mCodeChunk, jumpoffset, chunk->mCurrentOffset);
09623 
09624                         // need to figure out what handlers this state has registered
09625                         // we'll use to count to find it
09626                         count = 0;
09627 
09628                         if (mEvent)
09629                         {
09630                                 mEvent->recurse(fp, tabs, tabsize, LSCP_DETERMINE_HANDLERS, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09631                                 gCurrentHandler = count;
09632                         }
09633 
09634                         // add description word into chunk
09635                         if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)
09636                         {
09637                                 u642bytestream(chunk->mCodeChunk, jumpoffset, gCurrentHandler);
09638                         }
09639                         else
09640                         {
09641                                 integer2bytestream(chunk->mCodeChunk, jumpoffset, (S32)gCurrentHandler);
09642                         }
09643 
09644 
09645                         // 0 - 3: offset to event jump table
09646                         S32 offsetoffset = chunk->mCurrentOffset;
09647                         S32 offsetdelta = 0;
09648                         chunk->addBytes(4);
09649 
09650                         // null terminated state name
09651 #ifdef LSL_INCLUDE_DEBUG_INFO
09652                         chunk->addBytes(mIdentifier->mName, strlen(mIdentifier->mName) + 1);            /*Flawfinder: ignore*/
09653 #else
09654                         chunk->addBytes(1);
09655 #endif
09656                         // now we're at the jump table
09657                         offsetdelta = chunk->mCurrentOffset - offsetoffset;
09658                         integer2bytestream(chunk->mCodeChunk, offsetoffset, offsetdelta);
09659 
09660                         // add the events themselves
09661                         if (mEvent)
09662                         {
09663                                 LLScriptByteCodeChunk   *events = new LLScriptByteCodeChunk(FALSE);
09664                                 // make space for event jump table
09665                                 events->addBytes(LSCRIPTDataSize[LST_INTEGER]*get_number_of_event_handlers(gCurrentHandler)*2);
09666                                 mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, events, heap, stacksize, entry, entrycount, NULL);
09667                                 chunk->addBytes(events->mCodeChunk, events->mCurrentOffset);
09668                                 delete events;
09669                         }
09670                 }
09671                 break;
09672         case LSCP_EMIT_CIL_ASSEMBLY:
09673                 if (mEvent)
09674                 {
09675                         // Entry not used at this level, so pass state scope as entry parameter, to allow event handlers to do name mangling.
09676                         mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, entrycount, NULL);
09677                 }
09678                 break;
09679         default:
09680                 if (mType == LSSTYPE_DEFAULT)
09681                 {
09682                 }
09683                 else
09684                 {
09685                         mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09686                 }
09687                 if (mEvent)
09688                 {
09689                         mEvent->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09690                 }
09691                 break;
09692         }
09693         gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09694 }
09695 
09696 S32 LLScriptScript::getSize()
09697 {
09698         return 0;
09699 }
09700 
09701 LLScriptScript::LLScriptScript(LLScritpGlobalStorage *globals, 
09702                                                            LLScriptState *states) :
09703     LLScriptFilePosition(0, 0),
09704         mStates(states), mGlobalScope(NULL), mGlobals(NULL), mGlobalFunctions(NULL), mGodLike(FALSE)
09705 {
09706         const char DEFAULT_BYTECODE_FILENAME[] = "lscript.lso";
09707         strncpy(mBytecodeDest, DEFAULT_BYTECODE_FILENAME, sizeof(mBytecodeDest) -1);    /*Flawfinder: ignore*/
09708         mBytecodeDest[MAX_STRING-1] = '\0';
09709         LLScriptGlobalVariable  *tvar;
09710         LLScriptGlobalFunctions *tfunc;
09711         LLScritpGlobalStorage *temp;
09712 
09713         temp = globals;
09714         while(temp)
09715         {
09716                 if (temp->mbGlobalFunction)
09717                 {
09718                         if (!mGlobalFunctions)
09719                         {
09720                                 mGlobalFunctions = (LLScriptGlobalFunctions *)temp->mGlobal;
09721                         }
09722                         else
09723                         {
09724                                 tfunc = mGlobalFunctions;
09725                                 while(tfunc->mNextp)
09726                                 {
09727                                         tfunc = tfunc->mNextp;
09728                                 }
09729                                 tfunc->mNextp = (LLScriptGlobalFunctions *)temp->mGlobal;
09730                         }
09731                 }
09732                 else
09733                 {
09734                         if (!mGlobals)
09735                         {
09736                                 mGlobals = (LLScriptGlobalVariable *)temp->mGlobal;
09737                         }
09738                         else
09739                         {
09740                                 tvar = mGlobals;
09741                                 while(tvar->mNextp)
09742                                 {
09743                                         tvar = tvar->mNextp;
09744                                 }
09745                                 tvar->mNextp = (LLScriptGlobalVariable *)temp->mGlobal;
09746                         }
09747                 }
09748                 temp = temp->mNextp;
09749         }
09750 }
09751 
09752 void LLScriptScript::setBytecodeDest(const char* dst_filename)
09753 {
09754         strncpy(mBytecodeDest, dst_filename, MAX_STRING);       /*Flawfinder: ignore*/
09755         mBytecodeDest[MAX_STRING-1] = '\0';
09756 }
09757 
09758 void print_cil_globals(FILE* fp, LLScriptGlobalVariable* global)
09759 {
09760         fprintf(fp, ".field private ");
09761         print_cil_type(fp, global->mType->mType);
09762         fprintf(fp, " ");
09763         fprintf(fp, global->mIdentifier->mName);                /*Flawfinder: ignore*/
09764         fprintf(fp, "\n");
09765         if(NULL != global->mNextp)
09766         {
09767                 print_cil_globals(fp, global->mNextp);
09768         }
09769 }
09770 
09771 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)
09772 {
09773         if (gErrorToText.getErrors())
09774         {
09775                 return;
09776         }
09777         switch(pass)
09778         {
09779         case LSCP_PRETTY_PRINT:
09780                 if (mGlobals)
09781                 {
09782                         fdotabs(fp, tabs, tabsize);
09783                         mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09784                 }
09785 
09786                 if (mGlobalFunctions)
09787                 {
09788                         fdotabs(fp, tabs, tabsize);
09789                         mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09790                 }
09791 
09792                 fdotabs(fp, tabs, tabsize);
09793                 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09794                 break;
09795         case LSCP_PRUNE:
09796                 if (mGlobalFunctions)
09797                 {
09798                         mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09799                 }
09800                 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09801                 break;
09802         case LSCP_SCOPE_PASS1:
09803                 {
09804                         mGlobalScope = new LLScriptScope(gScopeStringTable);
09805                         // zeroth, add library functions to global scope
09806                         S32 i;
09807                         char *arg;
09808                         LLScriptScopeEntry *sentry;
09809                         for (i = 0; i < gScriptLibrary.mNextNumber; i++)
09810                         {
09811                                 // First, check to make sure this isn't a god only function, or that the viewer's agent is a god.
09812                                 if (!gScriptLibrary.mFunctions[i]->mGodOnly || mGodLike)
09813                                 {
09814                                         if (gScriptLibrary.mFunctions[i]->mReturnType)
09815                                                 sentry = mGlobalScope->addEntry(gScriptLibrary.mFunctions[i]->mName, LIT_LIBRARY_FUNCTION, char2type(*gScriptLibrary.mFunctions[i]->mReturnType));
09816                                         else
09817                                                 sentry = mGlobalScope->addEntry(gScriptLibrary.mFunctions[i]->mName, LIT_LIBRARY_FUNCTION, LST_NULL);
09818                                         sentry->mLibraryNumber = i;
09819                                         arg = gScriptLibrary.mFunctions[i]->mArgs;
09820                                         if (arg)
09821                                         {
09822                                                 while (*arg)
09823                                                 {
09824                                                         sentry->mFunctionArgs.addType(char2type(*arg));
09825                                                         sentry->mSize += LSCRIPTDataSize[char2type(*arg)];
09826                                                         sentry->mOffset += LSCRIPTDataSize[char2type(*arg)];
09827                                                         arg++;
09828                                                 }
09829                                         }
09830                                 }
09831                         }
09832                         // first go and collect all the global variables
09833                         if (mGlobals)
09834                                 mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09835                         // second, do the global functions
09836                         if (mGlobalFunctions)
09837                                 mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09838                         // now do states
09839                         mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09840                         break;
09841                 }
09842         case LSCP_SCOPE_PASS2:
09843                 // now we're checking jumps, function calls, and state transitions
09844                 if (mGlobalFunctions)
09845                         mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09846                 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, mGlobalScope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09847                 break;
09848         case LSCP_TYPE:
09849                 // first we need to check global variables
09850                 if (mGlobals)
09851                         mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09852                 // now do global functions and states
09853                 if (mGlobalFunctions)
09854                         mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09855                 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09856                 break;
09857         case LSCP_RESOURCE:
09858                 // first determine resource counts for globals
09859                 count = 0;
09860                 if (mGlobals)
09861                         mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09862                 // now do locals
09863                 if (mGlobalFunctions)
09864                         mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09865                 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09866                 break;
09867         case LSCP_EMIT_ASSEMBLY:
09868 
09869                 if (mGlobals)
09870                 {
09871                         fprintf(fp, "GLOBALS\n");
09872                         fdotabs(fp, tabs, tabsize);
09873                         mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09874                         fprintf(fp, "\n");
09875                 }
09876 
09877                 if (mGlobalFunctions)
09878                 {
09879                         fprintf(fp, "GLOBAL FUNCTIONS\n");
09880                         fdotabs(fp, tabs, tabsize);
09881                         mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09882                         fprintf(fp, "\n");
09883                 }
09884 
09885                 fprintf(fp, "STATES\n");
09886                 fdotabs(fp, tabs, tabsize);
09887                 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09888                 fprintf(fp, "\n");
09889                 break;
09890         case LSCP_EMIT_BYTE_CODE:
09891                 {
09892                         // first, create data structure to hold the whole shebang
09893                         LLScriptScriptCodeChunk *code = new LLScriptScriptCodeChunk(TOP_OF_MEMORY);
09894 
09895                         // ok, let's add the registers, all zeroes for now
09896                         S32 i;
09897                         S32 nooffset = 0;
09898 
09899                         for (i = LREG_IP; i < LREG_EOF; i++)
09900                         {
09901                                 if (i < LREG_NCE)
09902                                         code->mRegisters->addBytes(4);
09903                                 else if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)
09904                                         code->mRegisters->addBytes(8);
09905                         }
09906                         // global variables
09907                         if (mGlobals)
09908                                 mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, code->mGlobalVariables, code->mHeap, stacksize, entry, entrycount, NULL);
09909 
09910                         // put the ending heap block onto the heap
09911                         U8 *temp;
09912                         S32 size = lsa_create_data_block(&temp, NULL, 0);
09913                         code->mHeap->addBytes(temp, size);
09914                         delete [] temp;
09915 
09916                         // global functions
09917                         // make space for global function jump table
09918                         if (mGlobalFunctions)
09919                         {
09920                                 code->mGlobalFunctions->addBytes(LSCRIPTDataSize[LST_INTEGER]*mGlobalScope->mFunctionCount + LSCRIPTDataSize[LST_INTEGER]);
09921                                 integer2bytestream(code->mGlobalFunctions->mCodeChunk, nooffset, mGlobalScope->mFunctionCount);
09922                                 mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, code->mGlobalFunctions, NULL, stacksize, entry, entrycount, NULL);
09923                         }
09924 
09925 
09926                         nooffset = 0;
09927                         // states
09928                         // make space for state jump/info table
09929                         if (LSL2_CURRENT_MAJOR_VERSION == LSL2_MAJOR_VERSION_TWO)
09930                         {
09931                                 code->mStates->addBytes(LSCRIPTDataSize[LST_INTEGER]*3*mGlobalScope->mStateCount + LSCRIPTDataSize[LST_INTEGER]);
09932                         }
09933                         else
09934                         {
09935                                 code->mStates->addBytes(LSCRIPTDataSize[LST_INTEGER]*2*mGlobalScope->mStateCount + LSCRIPTDataSize[LST_INTEGER]);
09936                         }
09937                         integer2bytestream(code->mStates->mCodeChunk, nooffset, mGlobalScope->mStateCount);
09938                         mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, code->mStates, NULL, stacksize, entry, entrycount, NULL);
09939 
09940                         // now, put it all together and spit it out
09941                         // we need 
09942                         FILE* bcfp = LLFile::fopen(mBytecodeDest, "wb");                /*Flawfinder: ignore*/
09943                         
09944                         code->build(fp, bcfp);
09945                         fclose(bcfp);
09946                                                                            
09947                         delete code;
09948                 }
09949                 break;
09950         case LSCP_EMIT_CIL_ASSEMBLY:
09951 
09952                 // Output dependencies.
09953                 fprintf(fp, ".assembly extern mscorlib {.ver 1:0:5000:0}\n");
09954                 fprintf(fp, ".assembly extern LScriptLibrary {.ver 0:0:0:0}\n");
09955 
09956                 // Output assembly name.
09957                 fprintf(fp, ".assembly 'lsl' {.ver 0:0:0:0}\n");
09958 
09959                 // Output class header.
09960                 fprintf(fp, ".class public auto ansi beforefieldinit LSL extends [mscorlib]System.Object\n");
09961                 fprintf(fp, "{\n");
09962 
09963                 // Output globals as members.
09964                 if(NULL != mGlobals)
09965                 {
09966                         print_cil_globals(fp, mGlobals);
09967                 }
09968 
09969                 // Output "runtime". Only needed to allow stand alone execution. Not needed when compiling to DLL and using embedded runtime.
09970                 fprintf(fp, ".method public static  hidebysig default void Main ()  cil managed\n");
09971                 fprintf(fp, "{\n");
09972                 fprintf(fp, ".entrypoint\n");
09973                 fprintf(fp, ".maxstack 2\n");
09974                 fprintf(fp, ".locals init (class LSL V_0)\n");
09975                 fprintf(fp, "newobj instance void class LSL::.ctor()\n");
09976                 fprintf(fp, "stloc.0\n");
09977                 fprintf(fp, "ldloc.0\n");
09978                 fprintf(fp, "callvirt instance void class LSL::defaultstate_entry()\n");
09979                 fprintf(fp, "ret\n");
09980                 fprintf(fp, "}\n");
09981 
09982                 // Output ctor header.
09983                 fprintf(fp, ".method public hidebysig  specialname  rtspecialname instance default void .ctor ()  cil managed\n");
09984                 fprintf(fp, "{\n");
09985                 fprintf(fp, ".maxstack 500\n");
09986 
09987                 // Initialise globals as members in ctor.
09988                 if (mGlobals)
09989                 {
09990                         fdotabs(fp, tabs, tabsize);
09991                         mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
09992                         fprintf(fp, "\n");
09993                 }
09994 
09995                 // Output ctor footer.
09996                 fprintf(fp, "ldarg.0\n");
09997                 fprintf(fp, "call instance void valuetype [mscorlib]System.Object::.ctor()\n");
09998                 fprintf(fp, "ret\n");
09999                 fprintf(fp, "}\n");
10000 
10001                 // Output functions as methods.
10002                 if (mGlobalFunctions)
10003                 {
10004                         fdotabs(fp, tabs, tabsize);
10005                         mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
10006                         fprintf(fp, "\n");
10007                 }
10008 
10009                 // Output states as name mangled methods.
10010                 fdotabs(fp, tabs, tabsize);
10011                 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
10012                 fprintf(fp, "\n");
10013 
10014                 // Output class footer.
10015                 fprintf(fp, "}\n");
10016 
10017                 break;
10018         default:
10019                 if (mGlobals)
10020                         mGlobals->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
10021                 if (mGlobalFunctions)
10022                         mGlobalFunctions->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
10023                 mStates->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
10024                 break;
10025         }
10026 }

Generated on Thu Jul 1 06:09:53 2010 for Second Life Viewer by  doxygen 1.4.7