Imported existing code
This commit is contained in:
412
indra/lscript/lscript_compile/lscript_scope.h
Normal file
412
indra/lscript/lscript_compile/lscript_scope.h
Normal file
@@ -0,0 +1,412 @@
|
||||
/**
|
||||
* @file lscript_scope.h
|
||||
* @brief builds nametable and checks scope
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#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] = /*Flawfinder: ignore*/
|
||||
{
|
||||
'0',
|
||||
'i',
|
||||
'f',
|
||||
's',
|
||||
'k',
|
||||
'v',
|
||||
'q',
|
||||
'l',
|
||||
'0'
|
||||
};
|
||||
|
||||
const char * const LSCRIPTListDescription[LST_EOF] = /*Flawfinder: ignore*/
|
||||
{
|
||||
"PUSHARGB 0",
|
||||
"PUSHARGB 1",
|
||||
"PUSHARGB 2",
|
||||
"PUSHARGB 3",
|
||||
"PUSHARGB 4",
|
||||
"PUSHARGB 5",
|
||||
"PUSHARGB 6",
|
||||
"PUSHARGB 7",
|
||||
"PUSHARGB 0"
|
||||
};
|
||||
|
||||
const char * const LSCRIPTTypePush[LST_EOF] = /*Flawfinder: ignore*/
|
||||
{
|
||||
"INVALID",
|
||||
"PUSHE",
|
||||
"PUSHE",
|
||||
"PUSHE",
|
||||
"PUSHE",
|
||||
"PUSHEV",
|
||||
"PUSHEQ",
|
||||
"PUSHE",
|
||||
"undefined"
|
||||
};
|
||||
|
||||
const char * const LSCRIPTTypeReturn[LST_EOF] = /*Flawfinder: ignore*/
|
||||
{
|
||||
"INVALID",
|
||||
"LOADP -12",
|
||||
"LOADP -12",
|
||||
"STORES -12\nPOP",
|
||||
"STORES -12\nPOP",
|
||||
"LOADVP -20",
|
||||
"LOADQP -24",
|
||||
"LOADLP -12",
|
||||
"undefined"
|
||||
};
|
||||
|
||||
const char * const LSCRIPTTypePop[LST_EOF] = /*Flawfinder: ignore*/
|
||||
{
|
||||
"INVALID",
|
||||
"POP",
|
||||
"POP",
|
||||
"POPS",
|
||||
"POPS",
|
||||
"POPV",
|
||||
"POPQ",
|
||||
"POPL",
|
||||
"undefined"
|
||||
};
|
||||
|
||||
const char * const LSCRIPTTypeDuplicate[LST_EOF] = /*Flawfinder: ignore*/
|
||||
{
|
||||
"INVALID",
|
||||
"DUP",
|
||||
"DUP",
|
||||
"DUPS",
|
||||
"DUPS",
|
||||
"DUPV",
|
||||
"DUPQ",
|
||||
"DUPL",
|
||||
"undefined"
|
||||
};
|
||||
|
||||
const char * const LSCRIPTTypeLocalStore[LST_EOF] = /*Flawfinder: ignore*/
|
||||
{
|
||||
"INVALID",
|
||||
"STORE ",
|
||||
"STORE ",
|
||||
"STORES ",
|
||||
"STORES ",
|
||||
"STOREV ",
|
||||
"STOREQ ",
|
||||
"STOREL ",
|
||||
"undefined"
|
||||
};
|
||||
|
||||
const char * const LSCRIPTTypeLocalDeclaration[LST_EOF] = /*Flawfinder: ignore*/
|
||||
{
|
||||
"INVALID",
|
||||
"STOREP ",
|
||||
"STOREP ",
|
||||
"STORESP ",
|
||||
"STORESP ",
|
||||
"STOREVP ",
|
||||
"STOREQP ",
|
||||
"STORELP ",
|
||||
"undefined"
|
||||
};
|
||||
|
||||
const char * const LSCRIPTTypeGlobalStore[LST_EOF] = /*Flawfinder: ignore*/
|
||||
{
|
||||
"INVALID",
|
||||
"STOREG ",
|
||||
"STOREG ",
|
||||
"STORESG ",
|
||||
"STORESG ",
|
||||
"STOREGV ",
|
||||
"STOREGQ ",
|
||||
"STORELG ",
|
||||
"undefined"
|
||||
};
|
||||
|
||||
const char * const LSCRIPTTypeLocalPush[LST_EOF] = /*Flawfinder: ignore*/
|
||||
{
|
||||
"INVALID",
|
||||
"PUSH ",
|
||||
"PUSH ",
|
||||
"PUSHS ",
|
||||
"PUSHS ",
|
||||
"PUSHV ",
|
||||
"PUSHQ ",
|
||||
"PUSHL ",
|
||||
"undefined"
|
||||
};
|
||||
|
||||
const char * const LSCRIPTTypeLocalPush1[LST_EOF] = /*Flawfinder: ignore*/
|
||||
{
|
||||
"INVALID",
|
||||
"PUSHARGI 1",
|
||||
"PUSHARGF 1",
|
||||
"undefined",
|
||||
"undefined",
|
||||
"undefined",
|
||||
"undefined",
|
||||
"undefined",
|
||||
"undefined"
|
||||
};
|
||||
|
||||
const char * const LSCRIPTTypeGlobalPush[LST_EOF] = /*Flawfinder: ignore*/
|
||||
{
|
||||
"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); /*Flawfinder: ignore*/
|
||||
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); /*Flawfinder: ignore*/
|
||||
char *temp = new char[count + 2];
|
||||
memcpy(temp, mString, count); /*Flawfinder: ignore*/
|
||||
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); /*Flawfinder: ignore*/
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *mString;
|
||||
};
|
||||
|
||||
class LLScriptScopeEntry
|
||||
{
|
||||
public:
|
||||
LLScriptScopeEntry(const 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() {}
|
||||
|
||||
const 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(const char *identifier, LSCRIPTIdentifierType idtype, LSCRIPTType type)
|
||||
{
|
||||
const 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(const char *identifier)
|
||||
{
|
||||
const char *name = mSTable->addString(identifier);
|
||||
if (mEntryMap.checkData(name))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// identifier already exists at this scope
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
LLScriptScopeEntry *findEntry(const char *identifier)
|
||||
{
|
||||
const 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(const char *identifier, LSCRIPTIdentifierType idtype)
|
||||
{
|
||||
const 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<const char *, LLScriptScopeEntry *> mEntryMap;
|
||||
LLScriptScope *mParentScope;
|
||||
LLStringTable *mSTable;
|
||||
S32 mFunctionCount;
|
||||
S32 mStateCount;
|
||||
};
|
||||
|
||||
extern LLStringTable *gScopeStringTable;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user