summaryrefslogtreecommitdiff
path: root/indra/lscript/lscript_compile/lscript_scope.h
diff options
context:
space:
mode:
authorJames Cook <james@lindenlab.com>2007-01-02 08:33:20 +0000
committerJames Cook <james@lindenlab.com>2007-01-02 08:33:20 +0000
commit420b91db29485df39fd6e724e782c449158811cb (patch)
treeb471a94563af914d3ed3edd3e856d21cb1b69945 /indra/lscript/lscript_compile/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.h388
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