Files
Client/CryptoSource/ScriptEngine-MCF File/SymbolTable.cpp
LGram16 dd97ddec92 Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 20:17:20 +09:00

525 lines
11 KiB
C++

#include "SymbolTable.h"
#include <assert.h>
#include <map>
#include <string>
#include <list>
#include "GMMemory.h"
///////////////////////////////////////////////////////////////////////////////////
// 전역변수
const char * DataTypeString[] = { "void", "bool", "int", "float", "string" };
///////////////////////////////////////////////////////////////////////////////////
//
SFuncType::SFuncType()
: m_data( 0 )
{
}
SFuncType::SFuncType( unsigned long data )
: m_data( data )
{
}
int SFuncType::GetArgCount()
{
int i = 0;
for( ; i < 7; i++ )
{
if( GetArgType( i ) == T_VOID )
break;
}
return i;
}
const char* SFuncType::ToString( const char * szFuncName )
{
static char szBuffer[128];
int n = sprintf( szBuffer, "%s %s(", DataTypeString[GetReturnType()], szFuncName );
char * pBuffer = szBuffer + n;
eDataType argType = GetArgType( 0 );
if( argType != T_VOID )
{
n = sprintf( pBuffer, " %s", DataTypeString[ argType ] );
pBuffer += n;
for( int i = 1; i < 7; i++ )
{
argType = GetArgType( i );
if( argType == T_VOID )
break;
n = sprintf( pBuffer, ", %s", DataTypeString[ argType ] );
pBuffer += n;
}
strcpy( pBuffer, " " );
pBuffer += 1;
}
strcpy( pBuffer, ")" );
return szBuffer;
}
struct ConstInfo
{
eDataType m_dataType;
int m_iOffset;
ConstInfo()
: m_dataType( T_VOID ), m_iOffset( 0 )
{}
ConstInfo( eDataType type )
: m_dataType( type ), m_iOffset( 0 )
{}
ConstInfo( eDataType type, int offset )
: m_dataType( type ), m_iOffset( offset )
{}
};
struct VarInfo
{
eDataType m_dataType;
int m_iCount; //변수의 개수. 일반 변수는 1이고 배열일 경우 배열 개수.
int m_iOffset;
VarInfo()
: m_dataType( T_VOID ), m_iCount( 0 ), m_iOffset( 0 )
{}
VarInfo( eDataType dataType, int count )
: m_dataType( dataType ), m_iCount( count ), m_iOffset( 0 )
{}
VarInfo( eDataType dataType, int count, int offset )
: m_dataType( dataType ), m_iCount( count ), m_iOffset( offset )
{}
};
typedef CSymbolTable::VAR_CONTAINER VAR_CONTAINER;
typedef VAR_CONTAINER::value_type Value_Type;
typedef struct SLocalVarInfo
{
int m_iFuncID;
VAR_CONTAINER m_ArgContainer;
VAR_CONTAINER m_VarContainer;
SLocalVarInfo()
: m_iFuncID( 0 )
{}
} LOCALVARINFO;
///////////////////////////////////////////////////////////////////////////////////
//
CSymbolTable::CSymbolTable()
: m_pConstants( new CONST_CONTAINER )
, m_pGlobalVar( new VAR_CONTAINER )
, m_pLocalVars( new LOCALVAR_CONTAINER )
, m_pCurNameSpace( m_pGlobalVar )
, m_pNameSpace2( NULL )
, m_pFunctions( new FUNC_CONTAINER )
, m_eCurrentType( T_VOID )
, m_pCurrentLocalVar( NULL )
, m_iVarOffset( 0 )
, m_iVarOffsetGlobal( 0 )
, m_iOffsetFactor( 4 )
, m_iStringOffset( 0 )
{
}
CSymbolTable::~CSymbolTable()
{
delete m_pConstants;
delete m_pGlobalVar;
delete m_pLocalVars;
delete m_pFunctions;
}
void CSymbolTable::Create()
{
}
void CSymbolTable::Destroy()
{
m_pConstants->clear();
m_pGlobalVar->clear();
m_pLocalVars->clear();
m_pFunctions->clear();
m_eCurrentType = T_VOID;
}
int CSymbolTable::AddConst( const char * szName, eDataType type )
{
int finded = FindConst( szName );
if( finded != 0 )
return finded;
pair< CONST_CONTAINER::iterator, bool > result;
if( type == T_STRING )
{
result = m_pConstants->insert( CONST_CONTAINER::value_type( szName, ConstInfo( type, m_iStringOffset ) ) );
m_iStringOffset += strlen( szName ) + 1;
}
else
result = m_pConstants->insert( CONST_CONTAINER::value_type( szName, type ) );
return int(&(*result.first));
}
int CSymbolTable::AddArrVar( const char * szName, eDataType type, int nArray )
{
pair< VAR_CONTAINER::iterator, bool > result;
if( m_pCurrentLocalVar == NULL )
{
result = m_pCurNameSpace->insert( VAR_CONTAINER::value_type( szName, VARINFO( type, nArray, m_iVarOffset ) ) );
m_iVarOffset += m_iOffsetFactor * nArray;
}
else
{
m_iVarOffset += m_iOffsetFactor * nArray;
result = m_pCurNameSpace->insert( VAR_CONTAINER::value_type( szName, VARINFO( type, nArray, m_iVarOffset ) ) );
}
if( !result.second )
return 0;
return int(&(*result.first));
}
int CSymbolTable::AddFunc( bool hasDef, const char * szName, SFuncType type )
{
typedef FUNC_CONTAINER::value_type value_type;
int finded = FindFunc( szName, type );
if( hasDef )
{
if( finded != 0 )
{
if( IsFuncDefined( finded ) )
{
return 0;
}
else
{
value_type * pValue = (value_type*)finded;
pValue->second.second = true;
return finded;
}
}
else
{
FUNC_CONTAINER::iterator result = m_pFunctions->insert( FUNC_CONTAINER::value_type( szName, FUNCINFO( type, true ) ) );
return int(&(*result));
}
}
else
{
if( finded == 0 )
{
FUNC_CONTAINER::iterator result = m_pFunctions->insert( FUNC_CONTAINER::value_type( szName, FUNCINFO( type, false ) ) );
return int(&(*result));
}
else
return finded;
}
}
int CSymbolTable::FindConst( const char * szName )
{
CONST_CONTAINER::iterator result = m_pConstants->find( szName );
if( result == m_pConstants->end() )
return 0;
return int(&(*result));
}
int CSymbolTable::FindVar( const char * szName )
{
VAR_CONTAINER::iterator result = m_pCurNameSpace->find( szName );
if( result == m_pCurNameSpace->end() )
{
if( m_pNameSpace2 )
{
result = m_pNameSpace2->find( szName );
if( result == m_pNameSpace2->end() )
{
if( m_pCurNameSpace != m_pGlobalVar )
{
result = m_pGlobalVar->find( szName );
if( result == m_pGlobalVar->end() )
return 0;
}
else
return 0;
}
}
else
{
return 0;
}
}
return int(&(*result));
}
int CSymbolTable::FindFunc( const char * szName, SFuncType type )
{
typedef FUNC_CONTAINER::iterator iterator;
pair< iterator, iterator > result = m_pFunctions->equal_range( szName );
while( result.first != result.second )
{
if( result.first->second.first == type )
return int(&(*result.first));
result.first++;
}
return 0;
}
const char* CSymbolTable::GetNameOfConst( int symbolID )
{
typedef CONST_CONTAINER::value_type value_type;
value_type * pValue = (value_type*)symbolID;
return pValue->first.c_str();
}
eDataType CSymbolTable::GetTypeOfConst( int symbolID )
{
typedef CONST_CONTAINER::value_type value_type;
value_type * pValue = (value_type*)symbolID;
return pValue->second.m_dataType;
}
int CSymbolTable::GetOffsetOfConst( int symbolID )
{
typedef CONST_CONTAINER::value_type value_type;
value_type * pValue = (value_type*)symbolID;
return pValue->second.m_iOffset;
}
const char* CSymbolTable::GetNameOfVar( int symbolID )
{
typedef VAR_CONTAINER::value_type value_type;
value_type * pValue = (value_type*)symbolID;
return pValue->first.c_str();
}
eDataType CSymbolTable::GetTypeOfVar( int symbolID )
{
typedef VAR_CONTAINER::value_type value_type;
value_type * pValue = (value_type*)symbolID;
return pValue->second.m_dataType;
}
int CSymbolTable::GetCountOfVar( int symbolID )
{
typedef VAR_CONTAINER::value_type value_type;
value_type * pValue = (value_type*)symbolID;
return pValue->second.m_iCount;
}
int CSymbolTable::GetOffsetOfVar( int varID )
{
typedef VAR_CONTAINER::value_type value_type;
value_type * pValue = (value_type*)varID;
return pValue->second.m_iOffset;
}
const char* CSymbolTable::GetNameOfFunc( int symbolID )
{
typedef FUNC_CONTAINER::value_type value_type;
value_type * pValue = (value_type*)symbolID;
return pValue->first.c_str();
}
const char* CSymbolTable::GetTypeStringOfFunc( int symbolID )
{
SFuncType type = GetTypeOfFunc( symbolID );
return type.ToString( GetNameOfFunc( symbolID ) );
}
SFuncType CSymbolTable::GetTypeOfFunc( int symbolID )
{
typedef FUNC_CONTAINER::value_type value_type;
value_type * pValue = (value_type*)symbolID;
return pValue->second.first;
}
bool CSymbolTable::IsFuncDefined( int symbolID )
{
typedef FUNC_CONTAINER::value_type value_type;
value_type * pValue = (value_type*)symbolID;
return pValue->second.second;
}
void CSymbolTable::BeginLocalNameSpace()
{
m_pLocalVars->push_back( LOCALVARINFO() );
m_pCurrentLocalVar = &m_pLocalVars->back();
m_pCurNameSpace = &m_pCurrentLocalVar->m_ArgContainer;
m_pNameSpace2 = &m_pCurrentLocalVar->m_VarContainer;
m_iVarOffsetGlobal = m_iVarOffset;
m_iVarOffset = 4;
m_iOffsetFactor = 4;
}
void CSymbolTable::EndLocalNameSpace( int FuncID )
{
m_pCurNameSpace = m_pGlobalVar;
m_pNameSpace2 = NULL;
m_pCurrentLocalVar = NULL;
if( FuncID )
{
m_pLocalVars->back().m_iFuncID = FuncID;
}
else
m_pLocalVars->pop_back();
m_iVarOffset = m_iVarOffsetGlobal;
m_iOffsetFactor = 4;
}
void CSymbolTable::EndArgument()
{
if( m_pCurrentLocalVar )
{
m_pCurNameSpace = &m_pCurrentLocalVar->m_VarContainer;
m_pNameSpace2 = &m_pCurrentLocalVar->m_ArgContainer;
m_iVarOffset = 0;
m_iOffsetFactor = -4;
}
}
int CSymbolTable::GetLocalVarSize( int FuncID )
{
int size = 0;
VAR_CONTAINER * pNameSpace = NULL;
for( LOCALVAR_CONTAINER::iterator i = m_pLocalVars->begin(); i != m_pLocalVars->end(); i++ )
{
if( i->m_iFuncID == FuncID )
{
pNameSpace = &(i->m_VarContainer);
break;
}
}
if( pNameSpace == NULL )
{
ScriptSystemError( "지정한 이름 공간을 찾을 수 없습니다. (CSymbolTable::GetLocalVarSize)" );
return 0;
}
for( VAR_CONTAINER::iterator j = pNameSpace->begin(); j != pNameSpace->end(); j++ )
{
size += j->second.m_iCount * 4;
}
return size;
}
int CSymbolTable::GetGlobalVarSize()
{
int size = 0;
for( VAR_CONTAINER::iterator i = m_pGlobalVar->begin(); i != m_pGlobalVar->end(); i++ )
{
size += i->second.m_iCount * 4;
}
return size;
}
int CSymbolTable::GetStringBufferSize()
{
return m_iStringOffset;
}
void CSymbolTable::StringBuffer( void * pBuffer )
{
char * pBuf = (char*)pBuffer;
for( CONST_CONTAINER::iterator i = m_pConstants->begin(); i != m_pConstants->end(); i++ )
{
if( i->second.m_dataType == T_STRING )
{
strcpy( pBuf + i->second.m_iOffset, i->first.c_str() );
}
}
}
void ShowVariables( CSymbolTable::VAR_CONTAINER & Container, MESSAGE_FUNCTION2 Print )
{
for( CSymbolTable::VAR_CONTAINER::iterator i = Container.begin(); i!= Container.end(); i++ )
{
Print( i->first.c_str() );
if( i->second.m_iCount != 1 )
{
Print( "[%d]", i->second.m_iCount );
}
Print( " : %s <%d>\n", DataTypeString[ i->second.m_dataType ], i->second.m_iOffset );
}
}
void CSymbolTable::Show( MESSAGE_FUNCTION2 Print )
{
const char * DataTypeString[] = { "void", "bool", "int", "float", "string" };
Print( "--Constants--\n" );
for( CONST_CONTAINER::iterator i = m_pConstants->begin(); i!= m_pConstants->end(); i++ )
{
Print( "%s : %s <%d>\n", i->first.c_str(), DataTypeString[ i->second.m_dataType ], i->second.m_iOffset );
}
Print( "--Global Variables--\n" );
ShowVariables( *m_pGlobalVar, Print );
Print( "--Local Variables--\n" );
for( LOCALVAR_CONTAINER::iterator l = m_pLocalVars->begin(); l != m_pLocalVars->end(); l++ )
{
Print( "<%s>\n", this->GetNameOfFunc( l->m_iFuncID ) );
ShowVariables( l->m_ArgContainer, Print );
ShowVariables( l->m_VarContainer, Print );
}
Print( "--Functions--\n" );
for( FUNC_CONTAINER::iterator k = m_pFunctions->begin(); k != m_pFunctions->end(); k++ )
{
Print( GetTypeStringOfFunc( int(&(*k)) ) );
Print( "\n" );
}
}
///////////////////////////////////////////////////////////////////////////////////
//