diff options
author | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
---|---|---|
committer | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
commit | 420b91db29485df39fd6e724e782c449158811cb (patch) | |
tree | b471a94563af914d3ed3edd3e856d21cb1b69945 /indra/lscript/lscript_compile/lscript_scope.h |
Print done when done.
Diffstat (limited to 'indra/lscript/lscript_compile/lscript_scope.h')
-rw-r--r-- | indra/lscript/lscript_compile/lscript_scope.h | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/indra/lscript/lscript_compile/lscript_scope.h b/indra/lscript/lscript_compile/lscript_scope.h new file mode 100644 index 0000000000..18640441af --- /dev/null +++ b/indra/lscript/lscript_compile/lscript_scope.h @@ -0,0 +1,388 @@ +/** + * @file lscript_scope.h + * @brief builds nametable and checks scope + * + * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LL_LSCRIPT_SCOPE_H +#define LL_LSCRIPT_SCOPE_H + +#include "string_table.h" +#include "llmap.h" +#include "lscript_byteformat.h" + +typedef enum e_lscript_identifier_type +{ + LIT_INVALID, + LIT_GLOBAL, + LIT_VARIABLE, + LIT_FUNCTION, + LIT_LABEL, + LIT_STATE, + LIT_HANDLER, + LIT_LIBRARY_FUNCTION, + LIT_EOF +} LSCRIPTIdentifierType; + +const char LSCRIPTFunctionTypeStrings[LST_EOF] = +{ + '0', + 'i', + 'f', + 's', + 'k', + 'v', + 'q', + 'l', + '0' +}; + +const char * const LSCRIPTListDescription[LST_EOF] = +{ + "PUSHARGB 0", + "PUSHARGB 1", + "PUSHARGB 2", + "PUSHARGB 3", + "PUSHARGB 4", + "PUSHARGB 5", + "PUSHARGB 6", + "PUSHARGB 7", + "PUSHARGB 0" +}; + +const char * const LSCRIPTTypePush[LST_EOF] = +{ + "INVALID", + "PUSHE", + "PUSHE", + "PUSHE", + "PUSHE", + "PUSHEV", + "PUSHEQ", + "PUSHE", + "undefined" +}; + +const char * const LSCRIPTTypeReturn[LST_EOF] = +{ + "INVALID", + "LOADP -12", + "LOADP -12", + "STORES -12\nPOP", + "STORES -12\nPOP", + "LOADVP -20", + "LOADQP -24", + "LOADLP -12", + "undefined" +}; + +const char * const LSCRIPTTypePop[LST_EOF] = +{ + "INVALID", + "POP", + "POP", + "POPS", + "POPS", + "POPV", + "POPQ", + "POPL", + "undefined" +}; + +const char * const LSCRIPTTypeDuplicate[LST_EOF] = +{ + "INVALID", + "DUP", + "DUP", + "DUPS", + "DUPS", + "DUPV", + "DUPQ", + "DUPL", + "undefined" +}; + +const char * const LSCRIPTTypeLocalStore[LST_EOF] = +{ + "INVALID", + "STORE ", + "STORE ", + "STORES ", + "STORES ", + "STOREV ", + "STOREQ ", + "STOREL ", + "undefined" +}; + +const char * const LSCRIPTTypeLocalDeclaration[LST_EOF] = +{ + "INVALID", + "STOREP ", + "STOREP ", + "STORESP ", + "STORESP ", + "STOREVP ", + "STOREQP ", + "STORELP ", + "undefined" +}; + +const char * const LSCRIPTTypeGlobalStore[LST_EOF] = +{ + "INVALID", + "STOREG ", + "STOREG ", + "STORESG ", + "STORESG ", + "STOREGV ", + "STOREGQ ", + "STORELG ", + "undefined" +}; + +const char * const LSCRIPTTypeLocalPush[LST_EOF] = +{ + "INVALID", + "PUSH ", + "PUSH ", + "PUSHS ", + "PUSHS ", + "PUSHV ", + "PUSHQ ", + "PUSHL ", + "undefined" +}; + +const char * const LSCRIPTTypeLocalPush1[LST_EOF] = +{ + "INVALID", + "PUSHARGI 1", + "PUSHARGF 1", + "undefined", + "undefined", + "undefined", + "undefined", + "undefined", + "undefined" +}; + +const char * const LSCRIPTTypeGlobalPush[LST_EOF] = +{ + "INVALID", + "PUSHG ", + "PUSHG ", + "PUSHGS ", + "PUSHGS ", + "PUSHGV ", + "PUSHGQ ", + "PUSHGL ", + "undefined" +}; + +class LLScriptSimpleAssignable; + +class LLScriptArgString +{ +public: + LLScriptArgString() : mString(NULL) {} + ~LLScriptArgString() { delete [] mString; } + + LSCRIPTType getType(S32 count) + { + if (!mString) + return LST_NULL; + S32 length = (S32)strlen(mString); + if (count >= length) + { + return LST_NULL; + } + switch(mString[count]) + { + case 'i': + return LST_INTEGER; + case 'f': + return LST_FLOATINGPOINT; + case 's': + return LST_STRING; + case 'k': + return LST_KEY; + case 'v': + return LST_VECTOR; + case 'q': + return LST_QUATERNION; + case 'l': + return LST_LIST; + default: + return LST_NULL; + } + } + + void addType(LSCRIPTType type) + { + S32 count = 0; + if (mString) + { + count = (S32)strlen(mString); + char *temp = new char[count + 2]; + memcpy(temp, mString, count); + delete [] mString; + mString = temp; + mString[count + 1] = 0; + } + else + { + mString = new char[count + 2]; + mString[count + 1] = 0; + } + mString[count++] = LSCRIPTFunctionTypeStrings[type]; + } + + S32 getNumber() + { + if (mString) + return (S32)strlen(mString); + else + return 0; + } + + char *mString; +}; + +class LLScriptScopeEntry +{ +public: + LLScriptScopeEntry(char *identifier, LSCRIPTIdentifierType idtype, LSCRIPTType type, S32 count = 0) + : mIdentifier(identifier), mIDType(idtype), mType(type), mOffset(0), mSize(0), mAssignable(NULL), mCount(count), mLibraryNumber(0) + { + } + + ~LLScriptScopeEntry() {} + + char *mIdentifier; + LSCRIPTIdentifierType mIDType; + LSCRIPTType mType; + S32 mOffset; + S32 mSize; + LLScriptSimpleAssignable *mAssignable; + S32 mCount; // NOTE: Index for locals in CIL. + U16 mLibraryNumber; + LLScriptArgString mFunctionArgs; + LLScriptArgString mLocals; +}; + +class LLScriptScope +{ +public: + LLScriptScope(LLStringTable *stable) + : mParentScope(NULL), mSTable(stable), mFunctionCount(0), mStateCount(0) + { + } + + ~LLScriptScope() + { + mEntryMap.deleteAllData(); + } + + LLScriptScopeEntry *addEntry(char *identifier, LSCRIPTIdentifierType idtype, LSCRIPTType type) + { + char *name = mSTable->addString(identifier); + if (!mEntryMap.checkData(name)) + { + if (idtype == LIT_FUNCTION) + mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type, mFunctionCount++); + else if (idtype == LIT_STATE) + mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type, mStateCount++); + else + mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type); + return mEntryMap[name]; + } + else + { + // identifier already exists at this scope + return NULL; + } + } + + BOOL checkEntry(char *identifier) + { + char *name = mSTable->addString(identifier); + if (mEntryMap.checkData(name)) + { + return TRUE; + } + else + { + // identifier already exists at this scope + return FALSE; + } + } + + LLScriptScopeEntry *findEntry(char *identifier) + { + char *name = mSTable->addString(identifier); + LLScriptScope *scope = this; + + while (scope) + { + if (scope->mEntryMap.checkData(name)) + { + // cool, we found it at this scope + return scope->mEntryMap[name]; + } + scope = scope->mParentScope; + } + return NULL; + } + + LLScriptScopeEntry *findEntryTyped(char *identifier, LSCRIPTIdentifierType idtype) + { + char *name = mSTable->addString(identifier); + LLScriptScope *scope = this; + + while (scope) + { + if (scope->mEntryMap.checkData(name)) + { + // need to check type, and if type is function we need to check both types + if (idtype == LIT_FUNCTION) + { + if (scope->mEntryMap[name]->mIDType == LIT_FUNCTION) + { + return scope->mEntryMap[name]; + } + else if (scope->mEntryMap[name]->mIDType == LIT_LIBRARY_FUNCTION) + { + return scope->mEntryMap[name]; + } + } + else if (scope->mEntryMap[name]->mIDType == idtype) + { + // cool, we found it at this scope + return scope->mEntryMap[name]; + } + } + scope = scope->mParentScope; + } + return NULL; + } + + void addParentScope(LLScriptScope *scope) + { + mParentScope = scope; + } + + LLMap<char *, LLScriptScopeEntry *> mEntryMap; + LLScriptScope *mParentScope; + LLStringTable *mSTable; + S32 mFunctionCount; + S32 mStateCount; +}; + +extern LLStringTable *gScopeStringTable; + + + +#endif |