00001
00032 #ifndef LL_LSCRIPT_SCOPE_H
00033 #define LL_LSCRIPT_SCOPE_H
00034
00035 #include "string_table.h"
00036 #include "llmap.h"
00037 #include "lscript_byteformat.h"
00038
00039 typedef enum e_lscript_identifier_type
00040 {
00041 LIT_INVALID,
00042 LIT_GLOBAL,
00043 LIT_VARIABLE,
00044 LIT_FUNCTION,
00045 LIT_LABEL,
00046 LIT_STATE,
00047 LIT_HANDLER,
00048 LIT_LIBRARY_FUNCTION,
00049 LIT_EOF
00050 } LSCRIPTIdentifierType;
00051
00052 const char LSCRIPTFunctionTypeStrings[LST_EOF] =
00053 {
00054 '0',
00055 'i',
00056 'f',
00057 's',
00058 'k',
00059 'v',
00060 'q',
00061 'l',
00062 '0'
00063 };
00064
00065 const char * const LSCRIPTListDescription[LST_EOF] =
00066 {
00067 "PUSHARGB 0",
00068 "PUSHARGB 1",
00069 "PUSHARGB 2",
00070 "PUSHARGB 3",
00071 "PUSHARGB 4",
00072 "PUSHARGB 5",
00073 "PUSHARGB 6",
00074 "PUSHARGB 7",
00075 "PUSHARGB 0"
00076 };
00077
00078 const char * const LSCRIPTTypePush[LST_EOF] =
00079 {
00080 "INVALID",
00081 "PUSHE",
00082 "PUSHE",
00083 "PUSHE",
00084 "PUSHE",
00085 "PUSHEV",
00086 "PUSHEQ",
00087 "PUSHE",
00088 "undefined"
00089 };
00090
00091 const char * const LSCRIPTTypeReturn[LST_EOF] =
00092 {
00093 "INVALID",
00094 "LOADP -12",
00095 "LOADP -12",
00096 "STORES -12\nPOP",
00097 "STORES -12\nPOP",
00098 "LOADVP -20",
00099 "LOADQP -24",
00100 "LOADLP -12",
00101 "undefined"
00102 };
00103
00104 const char * const LSCRIPTTypePop[LST_EOF] =
00105 {
00106 "INVALID",
00107 "POP",
00108 "POP",
00109 "POPS",
00110 "POPS",
00111 "POPV",
00112 "POPQ",
00113 "POPL",
00114 "undefined"
00115 };
00116
00117 const char * const LSCRIPTTypeDuplicate[LST_EOF] =
00118 {
00119 "INVALID",
00120 "DUP",
00121 "DUP",
00122 "DUPS",
00123 "DUPS",
00124 "DUPV",
00125 "DUPQ",
00126 "DUPL",
00127 "undefined"
00128 };
00129
00130 const char * const LSCRIPTTypeLocalStore[LST_EOF] =
00131 {
00132 "INVALID",
00133 "STORE ",
00134 "STORE ",
00135 "STORES ",
00136 "STORES ",
00137 "STOREV ",
00138 "STOREQ ",
00139 "STOREL ",
00140 "undefined"
00141 };
00142
00143 const char * const LSCRIPTTypeLocalDeclaration[LST_EOF] =
00144 {
00145 "INVALID",
00146 "STOREP ",
00147 "STOREP ",
00148 "STORESP ",
00149 "STORESP ",
00150 "STOREVP ",
00151 "STOREQP ",
00152 "STORELP ",
00153 "undefined"
00154 };
00155
00156 const char * const LSCRIPTTypeGlobalStore[LST_EOF] =
00157 {
00158 "INVALID",
00159 "STOREG ",
00160 "STOREG ",
00161 "STORESG ",
00162 "STORESG ",
00163 "STOREGV ",
00164 "STOREGQ ",
00165 "STORELG ",
00166 "undefined"
00167 };
00168
00169 const char * const LSCRIPTTypeLocalPush[LST_EOF] =
00170 {
00171 "INVALID",
00172 "PUSH ",
00173 "PUSH ",
00174 "PUSHS ",
00175 "PUSHS ",
00176 "PUSHV ",
00177 "PUSHQ ",
00178 "PUSHL ",
00179 "undefined"
00180 };
00181
00182 const char * const LSCRIPTTypeLocalPush1[LST_EOF] =
00183 {
00184 "INVALID",
00185 "PUSHARGI 1",
00186 "PUSHARGF 1",
00187 "undefined",
00188 "undefined",
00189 "undefined",
00190 "undefined",
00191 "undefined",
00192 "undefined"
00193 };
00194
00195 const char * const LSCRIPTTypeGlobalPush[LST_EOF] =
00196 {
00197 "INVALID",
00198 "PUSHG ",
00199 "PUSHG ",
00200 "PUSHGS ",
00201 "PUSHGS ",
00202 "PUSHGV ",
00203 "PUSHGQ ",
00204 "PUSHGL ",
00205 "undefined"
00206 };
00207
00208 class LLScriptSimpleAssignable;
00209
00210 class LLScriptArgString
00211 {
00212 public:
00213 LLScriptArgString() : mString(NULL) {}
00214 ~LLScriptArgString() { delete [] mString; }
00215
00216 LSCRIPTType getType(S32 count)
00217 {
00218 if (!mString)
00219 return LST_NULL;
00220 S32 length = (S32)strlen(mString);
00221 if (count >= length)
00222 {
00223 return LST_NULL;
00224 }
00225 switch(mString[count])
00226 {
00227 case 'i':
00228 return LST_INTEGER;
00229 case 'f':
00230 return LST_FLOATINGPOINT;
00231 case 's':
00232 return LST_STRING;
00233 case 'k':
00234 return LST_KEY;
00235 case 'v':
00236 return LST_VECTOR;
00237 case 'q':
00238 return LST_QUATERNION;
00239 case 'l':
00240 return LST_LIST;
00241 default:
00242 return LST_NULL;
00243 }
00244 }
00245
00246 void addType(LSCRIPTType type)
00247 {
00248 S32 count = 0;
00249 if (mString)
00250 {
00251 count = (S32)strlen(mString);
00252 char *temp = new char[count + 2];
00253 memcpy(temp, mString, count);
00254 delete [] mString;
00255 mString = temp;
00256 mString[count + 1] = 0;
00257 }
00258 else
00259 {
00260 mString = new char[count + 2];
00261 mString[count + 1] = 0;
00262 }
00263 mString[count++] = LSCRIPTFunctionTypeStrings[type];
00264 }
00265
00266 S32 getNumber()
00267 {
00268 if (mString)
00269 return (S32)strlen(mString);
00270 else
00271 return 0;
00272 }
00273
00274 char *mString;
00275 };
00276
00277 class LLScriptScopeEntry
00278 {
00279 public:
00280 LLScriptScopeEntry(char *identifier, LSCRIPTIdentifierType idtype, LSCRIPTType type, S32 count = 0)
00281 : mIdentifier(identifier), mIDType(idtype), mType(type), mOffset(0), mSize(0), mAssignable(NULL), mCount(count), mLibraryNumber(0)
00282 {
00283 }
00284
00285 ~LLScriptScopeEntry() {}
00286
00287 char *mIdentifier;
00288 LSCRIPTIdentifierType mIDType;
00289 LSCRIPTType mType;
00290 S32 mOffset;
00291 S32 mSize;
00292 LLScriptSimpleAssignable *mAssignable;
00293 S32 mCount;
00294 U16 mLibraryNumber;
00295 LLScriptArgString mFunctionArgs;
00296 LLScriptArgString mLocals;
00297 };
00298
00299 class LLScriptScope
00300 {
00301 public:
00302 LLScriptScope(LLStringTable *stable)
00303 : mParentScope(NULL), mSTable(stable), mFunctionCount(0), mStateCount(0)
00304 {
00305 }
00306
00307 ~LLScriptScope()
00308 {
00309 mEntryMap.deleteAllData();
00310 }
00311
00312 LLScriptScopeEntry *addEntry(char *identifier, LSCRIPTIdentifierType idtype, LSCRIPTType type)
00313 {
00314 char *name = mSTable->addString(identifier);
00315 if (!mEntryMap.checkData(name))
00316 {
00317 if (idtype == LIT_FUNCTION)
00318 mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type, mFunctionCount++);
00319 else if (idtype == LIT_STATE)
00320 mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type, mStateCount++);
00321 else
00322 mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type);
00323 return mEntryMap[name];
00324 }
00325 else
00326 {
00327
00328 return NULL;
00329 }
00330 }
00331
00332 BOOL checkEntry(char *identifier)
00333 {
00334 char *name = mSTable->addString(identifier);
00335 if (mEntryMap.checkData(name))
00336 {
00337 return TRUE;
00338 }
00339 else
00340 {
00341
00342 return FALSE;
00343 }
00344 }
00345
00346 LLScriptScopeEntry *findEntry(char *identifier)
00347 {
00348 char *name = mSTable->addString(identifier);
00349 LLScriptScope *scope = this;
00350
00351 while (scope)
00352 {
00353 if (scope->mEntryMap.checkData(name))
00354 {
00355
00356 return scope->mEntryMap[name];
00357 }
00358 scope = scope->mParentScope;
00359 }
00360 return NULL;
00361 }
00362
00363 LLScriptScopeEntry *findEntryTyped(char *identifier, LSCRIPTIdentifierType idtype)
00364 {
00365 char *name = mSTable->addString(identifier);
00366 LLScriptScope *scope = this;
00367
00368 while (scope)
00369 {
00370 if (scope->mEntryMap.checkData(name))
00371 {
00372
00373 if (idtype == LIT_FUNCTION)
00374 {
00375 if (scope->mEntryMap[name]->mIDType == LIT_FUNCTION)
00376 {
00377 return scope->mEntryMap[name];
00378 }
00379 else if (scope->mEntryMap[name]->mIDType == LIT_LIBRARY_FUNCTION)
00380 {
00381 return scope->mEntryMap[name];
00382 }
00383 }
00384 else if (scope->mEntryMap[name]->mIDType == idtype)
00385 {
00386
00387 return scope->mEntryMap[name];
00388 }
00389 }
00390 scope = scope->mParentScope;
00391 }
00392 return NULL;
00393 }
00394
00395 void addParentScope(LLScriptScope *scope)
00396 {
00397 mParentScope = scope;
00398 }
00399
00400 LLMap<char *, LLScriptScopeEntry *> mEntryMap;
00401 LLScriptScope *mParentScope;
00402 LLStringTable *mSTable;
00403 S32 mFunctionCount;
00404 S32 mStateCount;
00405 };
00406
00407 extern LLStringTable *gScopeStringTable;
00408
00409
00410
00411 #endif