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>
This commit is contained in:
2025-11-29 20:17:20 +09:00
parent 5d3cd64a25
commit dd97ddec92
11602 changed files with 1446576 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
#ifndef _BaseDef_H_
#define _BaseDef_H_
#define MACHINECODEFILEEXT ".mcf" //Machine Code File
#define INTCODEFILEEXT ".imc" //InterMediate Code
#define SCRIPTFILEEXT ".gsf" //Gama Script File
///////////////////////////////////////////////////////////////////////////////////
//
typedef void * ANY_FUNCTION;
enum eDataType
{
T_VOID = 0,
T_BOOL,
T_INT,
T_FLOAT,
T_STRING = 4
};
typedef int BOOL;
#define TRUE 1
#define FALSE 0
///////////////////////////////////////////////////////////////////////////////////
//
struct ScriptFunc
{
void * pFunc;
long Type;
ScriptFunc( void *, long );
};
typedef ScriptFunc SE_FUNC;
///////////////////////////////////////////////////////////////////////////////////
//
union AnyData
{
int intValue;
float floatValue;
const char* stringValue;
AnyData( int n )
: intValue( n )
{}
AnyData( float f )
: floatValue( f )
{}
AnyData( const char * pszStr )
: stringValue( pszStr )
{}
AnyData( void * p )
: stringValue( (const char *)p )
{
}
AnyData & operator=( int n )
{
intValue = n;
return *this;
}
};
///////////////////////////////////////////////////////////////////////////////////
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
#ifndef _IMCodeGen_H_
#define _IMCodeGen_H_
#include "STL.h"
class CSyntaxTree;
class IOPCode;
typedef list<IOPCode*> IMCODES;
typedef map<int, IMCODES*> FUNCTIONS;
void GenerateCode( CSyntaxTree &, IMCODES &, FUNCTIONS & );
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,641 @@
#ifndef _IMCodeUnits_H_
#define _IMCodeUnits_H_
#include "BaseDef.h"
#include "Message.h"
#include "STL.h"
class CSymbolTable;
class CRelocTable;
typedef map<int, long> FUNCTABLE;
///////////////////////////////////////////////////////////////////////////////////
//
void SetSymbolTable( CSymbolTable * );
void SetFuncTable( FUNCTABLE * );
void SetRelocTable( CRelocTable * );
///////////////////////////////////////////////////////////////////////////////////
//
typedef unsigned char byte;
enum eRegister
{
EAX = 0,
ECX,
EDX,
EBX,
ESP,
EBP,
ESI,
EDI = 7,
NONE = 8
};
enum eCondition
{
G = 0, //Greater
GE, //Greater or Equal
L, //Less
LE, //Less or Equal
E, //Equal
NE = 5 //Not Equal
};
typedef struct _VAR_* VAR;
typedef struct _CONST_* CONST;
typedef struct _FUNC_* FUNC;
///////////////////////////////////////////////////////////////////////////////////
//
class IOPCode
{
public:
long m_lAddress;
public:
virtual ~IOPCode() {} //ToMachineCode 호출 전에 Addressing이 반드시 되어 있어야 한다.
virtual int ToMachineCode( byte * ) = 0; //넘겨받은 주소에 기계어 코드를 쓰고 index를 증가시킨다.
virtual long Addressing( long ) = 0; //현재 주소를 받고, 다음 instruction의 주소를 리턴한다.
virtual void Show( MESSAGE_FUNCTION2 ) = 0;
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_call : public IOPCode
{
FUNC m_funcID;
int m_iLine;
public:
COP_call( FUNC, int line );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_mov : public IOPCode
{
byte m_Type;
FUNC m_funcID;
union
{
VAR m_leftVarID;
eRegister m_leftReg;
};
union
{
int m_midArrayIndex;
eRegister m_midIndexReg;
};
union
{
eRegister m_rightReg;
CONST m_rightConstID;
VAR m_rightVarID;
int m_rightValue;
float m_rightValuef;
};
public:
COP_mov( FUNC, VAR, eRegister reg );
COP_mov( eRegister reg, FUNC, VAR );
COP_mov( eRegister reg, CONST constID );
COP_mov( FUNC, VAR, float valuef );
COP_mov( eRegister lreg, eRegister rreg );
COP_mov( eRegister lreg, int value );
COP_mov( FUNC, VAR, int arrayIndex, eRegister rreg );
COP_mov( eRegister lreg, FUNC, VAR, eRegister indexReg );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_nop : public IOPCode
{
public:
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_add : public IOPCode
{
byte m_Type;
eRegister m_leftReg;
union
{
int m_iValue;
eRegister m_rightReg;
};
public:
COP_add( eRegister reg, int value );
COP_add( eRegister lreg, eRegister rreg );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_sub : public IOPCode
{
byte m_Type;
eRegister m_leftReg;
union
{
eRegister m_rightReg;
int m_iValue;
};
public:
COP_sub( eRegister reg, int value );
COP_sub( eRegister lreg, eRegister rreg );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_imul : public IOPCode
{
eRegister m_leftReg;
eRegister m_rightReg;
public:
COP_imul( eRegister lreg, eRegister rreg );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_idiv : public IOPCode
{
eRegister m_rightReg;
public:
COP_idiv( eRegister rreg );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_push : public IOPCode
{
eRegister m_Reg;
public:
COP_push( eRegister reg );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_pop : public IOPCode
{
eRegister m_Reg;
public:
COP_pop( eRegister reg );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_jmp : public IOPCode
{
public:
IOPCode * m_pJumpTarget;
public:
COP_jmp();
COP_jmp( IOPCode * pJmpTarget );
virtual ~COP_jmp();
virtual int ToMachineCode( byte * );
virtual long Addressing( long addr );
virtual void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_jcc : public COP_jmp
{
eCondition m_Condition;
public:
COP_jcc( eCondition condition );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_jmpmark : public IOPCode
{
public:
IOPCode * m_pJumpSrc;
public:
COP_jmpmark();
COP_jmpmark( COP_jmp * pOPjmp );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_cmp : public IOPCode
{
byte m_Type;
FUNC m_funcID;
union
{
VAR m_leftVarID;
eRegister m_leftReg;
};
union
{
byte m_rightValue;
CONST m_rightConstID;
eRegister m_rightReg;
};
public:
COP_cmp( FUNC, VAR lvarID, CONST rconstID );
COP_cmp( eRegister lreg, byte value );
COP_cmp( eRegister lreg, eRegister rreg );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_ret : public IOPCode
{
public:
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
class COP_xor : public IOPCode
{
eRegister m_leftReg;
eRegister m_rightReg;
public:
COP_xor( eRegister lreg, eRegister rreg );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_setcc : public IOPCode
{
eCondition m_Condition;
eRegister m_Reg;
public:
COP_setcc( eCondition condition, eRegister lreg );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_int3 : public IOPCode
{
public:
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_fld : public IOPCode
{
FUNC m_funcID;
VAR m_varID;
public:
COP_fld( FUNC, VAR );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_fadd : public IOPCode
{
FUNC m_funcID;
VAR m_varID;
public:
COP_fadd( FUNC, VAR );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_fsub : public IOPCode
{
FUNC m_funcID;
VAR m_varID;
public:
COP_fsub( FUNC, VAR );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_fmul : public IOPCode
{
FUNC m_funcID;
VAR m_varID;
public:
COP_fmul( FUNC, VAR );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_fdiv : public IOPCode
{
FUNC m_funcID;
VAR m_varID;
public:
COP_fdiv( FUNC, VAR );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_fstp : public IOPCode
{
FUNC m_funcID;
VAR m_varID;
bool m_bDouble;
public:
COP_fstp( FUNC, VAR, bool = false );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_fcomp : public IOPCode
{
FUNC m_funcID;
VAR m_varID;
public:
COP_fcomp( FUNC, VAR );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_fnstsw_ax : public IOPCode
{
public:
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_test_ah : public IOPCode
{
byte m_Value8;
public:
COP_test_ah( byte );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_itoa : public IOPCode
{
eRegister m_leftReg;
FUNC m_funcID;
VAR m_StringBuffer;
public:
COP_itoa( eRegister, VAR );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_ftoa : public IOPCode
{
eRegister m_freeReg;
VAR m_DoubleVar;
VAR m_StringBuffer;
public:
COP_ftoa( eRegister, VAR, VAR );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
//할당된 메모리의 주소가 EAX에 들어간다.
class COP_malloc : public IOPCode
{
eRegister m_Reg;
public:
COP_malloc( eRegister );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_free : public IOPCode
{
FUNC m_funcID;
VAR m_varID;
public:
COP_free( FUNC, VAR );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
class COP_strcpy : public IOPCode
{
int m_type;
eRegister m_leftReg;
FUNC m_funcID;
union
{
eRegister m_rightReg;
VAR m_varID;
};
public:
COP_strcpy( eRegister, eRegister );
COP_strcpy( eRegister, FUNC, VAR );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
//ptr[leftReg]과 ptr[rightReg]의 문자열을 비교해서 결과값을 eax에 넣는다.
class COP_strcmp : public IOPCode
{
eRegister m_leftReg;
eRegister m_rightReg;
public:
COP_strcmp( eRegister lreg, eRegister rreg );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
//
//ptr [rightReg] 에 있는 문자열의 길이를 세서 leftReg에 넣는다.
class COP_strlen : public IOPCode
{
int m_type;
FUNC m_funcID;
union
{
eRegister m_Reg;
VAR m_varID;
};
public:
COP_strlen( eRegister reg );
COP_strlen( FUNC, VAR );
int ToMachineCode( byte * );
long Addressing( long addr );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -0,0 +1,160 @@
#include "IntermediateCode.h"
#include "IMCodeGen.h"
#include "IMCodeUnits.h"
#include "SymbolTable.h"
#include <list>
#include <map>
#include "RelocTable.h"
#include <stdlib.h>
#include <string>
///////////////////////////////////////////////////////////////////////////////////
//
CIntermediateCode::CIntermediateCode()
: m_pCodes( new IMCODES )
, m_pFunctions( new FUNCTIONS )
, m_pFuncTable( new FUNCTABLE )
{
}
CIntermediateCode::~CIntermediateCode()
{
Destroy();
delete m_pCodes;
delete m_pFunctions;
delete m_pFuncTable;
}
void CIntermediateCode::Create( CSyntaxTree & rSyntaxTree )
{
GenerateCode( rSyntaxTree, *m_pCodes, *m_pFunctions );
}
void CIntermediateCode::DestroyIMCodes( IMCODES * pIMCodes )
{
for( IMCODES::iterator i = pIMCodes->begin(); i != pIMCodes->end(); i++ )
{
delete *i;
}
pIMCodes->clear();
}
void CIntermediateCode::Destroy()
{
for( FUNCTIONS::iterator i = m_pFunctions->begin(); i != m_pFunctions->end(); i++ )
{
DestroyIMCodes( i->second );
delete i->second;
}
m_pFunctions->clear();
DestroyIMCodes( m_pCodes );
}
void CIntermediateCode::Show( MESSAGE_FUNCTION2 Print, CSymbolTable * pSymbolTable )
{
const char * DataTypeString[] = { "void", "bool", "int", "float", "string" };
SetSymbolTable( pSymbolTable );
Print( "<<< void Main() >>>\n" );
for( IMCODES::iterator i = m_pCodes->begin(); i != m_pCodes->end(); i++ )
{
IOPCode * pCode = (*i);
Print( "%X :\t", pCode->m_lAddress );
pCode->Show( Print );
}
for( FUNCTIONS::iterator j = m_pFunctions->begin(); j != m_pFunctions->end(); j++ )
{
SFuncType type = pSymbolTable->GetTypeOfFunc( j->first );
Print( "<<< %s %s(", DataTypeString[type.GetReturnType()], pSymbolTable->GetNameOfFunc( j->first ) );
if( type.GetArgType( 0 ) != T_VOID )
{
Print( " " );
Print( DataTypeString[ type.GetArgType( 0 ) ] );
for( int ith = 1; ith < 8; ith++ )
{
eDataType dataType = type.GetArgType( ith );
if( dataType == T_VOID )
break;
Print( ", %s", DataTypeString[dataType] );
}
Print( " " );
}
Print( ") >>>\n" );
IMCODES * pFuncCode = j->second;
for( IMCODES::iterator i = pFuncCode->begin(); i != pFuncCode->end(); i++ )
{
Print( "%X :\t", (*i)->m_lAddress );
(*i)->Show( Print );
}
}
}
long CIntermediateCode::Addressing( long addr )
{
for( IMCODES::iterator i = m_pCodes->begin(); i != m_pCodes->end(); i++ )
{
addr = (*i)->Addressing( addr );
}
for( FUNCTIONS::iterator j = m_pFunctions->begin(); j != m_pFunctions->end(); j++ )
{
IMCODES * pFuncCode = j->second;
for( IMCODES::iterator i = pFuncCode->begin(); i != pFuncCode->end(); i++ )
{
addr = (*i)->Addressing( addr );
}
}
return addr;
}
int CIntermediateCode::ToMachineCode( void * pBuf, CRelocTable * pRelocTable )
{
Addressing( 0 );
for( FUNCTIONS::iterator k = m_pFunctions->begin(); k != m_pFunctions->end(); k++ )
{
int funcID = k->first;
int offset = k->second->front()->m_lAddress;
m_pFuncTable->insert( FUNCTABLE::value_type( funcID, offset ) );
}
SetFuncTable( m_pFuncTable );
SetRelocTable( pRelocTable );
byte * pBuffer = (byte*)pBuf;
int TotalSize = 0;
IMCODES::iterator i = m_pCodes->begin();
for( ; i != m_pCodes->end(); i++ )
{
int size = (*i)->ToMachineCode( pBuffer );
pBuffer += size;
TotalSize += size;
}
for( FUNCTIONS::iterator j = m_pFunctions->begin(); j != m_pFunctions->end(); j++ )
{
IMCODES * pFuncCode = j->second;
for( i = pFuncCode->begin(); i != pFuncCode->end(); i++ )
{
int size = (*i)->ToMachineCode( pBuffer );
pBuffer += size;
TotalSize += size;
}
}
return TotalSize;
}
///////////////////////////////////////////////////////////////////////////////////
//

View File

@@ -0,0 +1,51 @@
#ifndef _IntermediateCode_H_
#define _IntermediateCode_H_
#include "STL.h"
#include "BaseDef.h"
#include "Message.h"
///////////////////////////////////////////////////////////////////////////////////
//
class IOPCode;
class CSyntaxTree;
class CSymbolTable;
class CRelocTable;
class CIntermediateCode
{
public:
typedef list<IOPCode*> IMCODES;
typedef map<int, IMCODES*> FUNCTIONS;
typedef map<int, long> FUNCTABLE;
protected:
IMCODES * m_pCodes;
FUNCTIONS * m_pFunctions;
FUNCTABLE * m_pFuncTable;
protected:
void DestroyIMCodes( IMCODES * );
public:
CIntermediateCode();
~CIntermediateCode();
void Create( CSyntaxTree & );
void Destroy();
void Show( MESSAGE_FUNCTION2, CSymbolTable * pSymbolTable );
long Addressing( long addr ); //past endÀÇ addrÀ» ¸®ÅÏÇÔ.
int ToMachineCode( void *, CRelocTable * );
FUNCTABLE & GetFuncTable() { return *m_pFuncTable; }
};
///////////////////////////////////////////////////////////////////////////////////
//
#endif

View File

@@ -0,0 +1,110 @@
#include "Message.h"
#include <iostream>
#include <stdarg.h>
using namespace std;
void DefaultMessageFunction( const char * ErrMsg )
{
cout << ErrMsg << endl;
}
MESSAGE_FUNCTION g_pfuncCompilerMessage = DefaultMessageFunction;
void CompilerMessage( const char * szStr )
{
(*g_pfuncCompilerMessage)( szStr );
}
void CompilerMessage2( const char * szStr, ... )
{
va_list args;
va_start( args, szStr );
char szBuffer[4096];
vsprintf( szBuffer, szStr, args );
CompilerMessage( szBuffer );
}
void SetCompilerMessageFunction( MESSAGE_FUNCTION func )
{
g_pfuncCompilerMessage = func;
}
void ErrorMessage( int line, const char * Msg )
{
CompilerMessage2( "Error (line %d) : %s", line, Msg );
exit(0);
}
void ErrorMessage( const char * Msg )
{
CompilerMessage2( "Error : %s", Msg );
exit(0);
}
void ErrorMessage2( int line, const char * Msg, ... )
{
va_list args;
va_start( args, Msg );
char szBuffer[4096];
vsprintf( szBuffer, Msg, args );
CompilerMessage2( "Error (line %d) : %s", line, szBuffer );
exit(0);
}
void ErrorMessage2( const char * Msg, ... )
{
va_list args;
va_start( args, Msg );
char szBuffer[4096];
vsprintf( szBuffer, Msg, args );
CompilerMessage2( "Error : %s", szBuffer );
exit(0);
}
void WarningMessage( int line, const char * Msg )
{
CompilerMessage2( "Warning (line %d) : %s", line, Msg );
}
void WarningMessage( const char * Msg )
{
CompilerMessage2( "Warning : %s", Msg );
}
void WarningMessage2( const char * Msg, ... )
{
va_list args;
va_start( args, Msg );
char szBuffer[4096];
vsprintf( szBuffer, Msg, args );
CompilerMessage2( "Warning : %s", szBuffer );
}
void WarningMessage2( int line, const char * Msg, ... )
{
va_list args;
va_start( args, Msg );
char szBuffer[4096];
vsprintf( szBuffer, Msg, args );
CompilerMessage2( "Warning (line %d) : %s", line, szBuffer );
}
void ScriptSystemError( const char * Msg )
{
CompilerMessage2( "Script System Error : %s", Msg );
}

View File

@@ -0,0 +1,27 @@
#ifndef _Message_H_
#define _Message_H_
///////////////////////////////////////////////////////////////////////////////////
//
typedef void (*MESSAGE_FUNCTION)( const char * ErrMsg );
typedef void (*MESSAGE_FUNCTION2)( const char *, ... );
void CompilerMessage( const char * );
void CompilerMessage2( const char *, ... );
void SetCompilerMessageFunction( MESSAGE_FUNCTION );
void ErrorMessage( int line, const char * );
void ErrorMessage( const char * );
void ErrorMessage2( int line, const char *, ... );
void ErrorMessage2( const char *, ... );
void WarningMessage( int line, const char * );
void WarningMessage( const char * );
void WarningMessage2( int line, const char *, ... );
void WarningMessage2( const char *, ... );
void ScriptSystemError( const char * );
///////////////////////////////////////////////////////////////////////////////////
//
#endif

View File

@@ -0,0 +1,21 @@
========================================================================
정적 라이브러리 : ScriptEngine 프로젝트 개요
========================================================================
응용 프로그램 마법사에서 이 ScriptEngine 라이브러리 프로젝트를 만들었습니다.
프로젝트에 대해 소스 파일은 만들어지지 않았습니다.
ScriptEngine.vcproj
응용 프로그램 마법사를 사용하여 생성한 VC++ 프로젝트의 기본 프로젝트 파일입니다.
해당 파일을 생성한 Visual C++의 버전 정보를 비롯하여
응용 프로그램 마법사에서 선택한 플랫폼, 구성 및
프로젝트 기능에 대한 정보가 들어 있습니다.
/////////////////////////////////////////////////////////////////////////////
기타 참고:
응용 프로그램 마법사에서 사용하는 "TODO:" 주석은 사용자가 추가하거나 사용자 지정해야 하는
소스 코드 부분을 나타냅니다.
/////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,196 @@
#include "RelocTable.h"
#include <vector>
#include <fstream>
#include <stdio.h>
#include <windows.h>
#include "VirtualMachine.h"
CRelocTable::CRelocTable()
: m_pGlobalVarTable( new RELOCTABLE )
, m_pStringTable( new RELOCTABLE )
, m_pFuncRelocTable( new FUNCRELOCTABLE )
{
}
CRelocTable::~CRelocTable()
{
delete m_pGlobalVarTable;
delete m_pStringTable;
delete m_pFuncRelocTable;
}
void CRelocTable::Create( ifstream & file )
{
Destroy();
int GlobalVarSize;
int StringBufferSize;
int FuncBufferSize;
file.read( (char*)&GlobalVarSize, sizeof(int) );
file.read( (char*)&StringBufferSize, sizeof(int) );
file.read( (char*)&FuncBufferSize, sizeof(int) );
int Temp;
for( int i = 0; i < GlobalVarSize; i++ )
{
file.read( (char*)&Temp, sizeof(int) );
m_pGlobalVarTable->push_back( Temp );
}
for( int i = 0; i < StringBufferSize; i++ )
{
file.read( (char*)&Temp, sizeof(int) );
m_pStringTable->push_back( Temp );
}
for( int i = 0; i < FuncBufferSize; i++ )
{
eStdFunc Func;
file.read( (char*)&Func, sizeof(Func) );
file.read( (char*)&Temp, sizeof(int) );
m_pFuncRelocTable->push_back( FUNCRELOC( Func, Temp ) );
}
}
#define READ_INT( p, var ) { var = *((int*)p); p += sizeof(int); }
#define READ_STDFUNCTYPE( p, var ) { var = *((eStdFunc*)p); p+= sizeof(eStdFunc); }
const void * CRelocTable::Create( const void * pDataBuf, unsigned dataSize )
{
Destroy();
const char * pBuf = (const char *)pDataBuf;
int GlobalVarSize, StringBufferSize, FuncBufferSize, temp;
READ_INT( pBuf, GlobalVarSize );
READ_INT( pBuf, StringBufferSize );
READ_INT( pBuf, FuncBufferSize );
for( int i = 0; i < GlobalVarSize; i++ )
{
READ_INT( pBuf, temp );
m_pGlobalVarTable->push_back( temp );
}
for( int i = 0; i < StringBufferSize; i++ )
{
READ_INT( pBuf, temp );
m_pStringTable->push_back( temp );
}
for( int i = 0; i < FuncBufferSize; i++ )
{
eStdFunc Func;
READ_STDFUNCTYPE( pBuf, Func );
READ_INT( pBuf, temp );
m_pFuncRelocTable->push_back( FUNCRELOC( Func, temp ) );
}
return pBuf;
}
void CRelocTable::Destroy()
{
m_pGlobalVarTable->clear();
m_pStringTable->clear();
}
void CRelocTable::Save( ofstream & file )
{
int GlobalVarSize = m_pGlobalVarTable->size();
int StringBufferSize = m_pStringTable->size();
int FuncBufferSize = m_pFuncRelocTable->size();
file.write( (const char*)&GlobalVarSize, sizeof(int) );
file.write( (const char*)&StringBufferSize, sizeof(int) );
file.write( (const char*)&FuncBufferSize, sizeof(int) );
for( int i = 0; i < GlobalVarSize; i++ )
{
int offset = m_pGlobalVarTable->at( i );
file.write( (const char*)&offset, sizeof(int) );
}
for( int i = 0; i < StringBufferSize; i++ )
{
int offset = m_pStringTable->at( i );
file.write( (const char*)&offset, sizeof(int) );
}
for( int i = 0; i < FuncBufferSize; i++ )
{
FUNCRELOC relocFunc = m_pFuncRelocTable->at( i );
file.write( (const char*)&relocFunc.first, sizeof(relocFunc.first) );
file.write( (const char*)&relocFunc.second, sizeof(relocFunc.second) );
}
}
void CRelocTable::AddGlobalVar( int offset )
{
m_pGlobalVarTable->push_back( offset );
}
void CRelocTable::AddConstString( int offset )
{
m_pStringTable->push_back( offset );
}
void CRelocTable::AddFuncBind( eStdFunc func, int offset )
{
m_pFuncRelocTable->push_back( FUNCRELOC( func, offset ) );
}
void CRelocTable::Relocate( void * pGlobalVarBuffer, void * pStringBuffer, void * pCodeBuffer )
{
void * ArrFuncPtr[] = { itoa, gcvt, malloc, free, strcpy, strcmp,
strlen, RegisterAllocatedMemory, UnregisterAllocatedMemory };
char * pCode = (char*)pCodeBuffer;
for( RELOCTABLE::iterator i = m_pGlobalVarTable->begin(); i != m_pGlobalVarTable->end(); i++ )
{
long * pValue = (long*)(pCode + *i);
*pValue += long(pGlobalVarBuffer);
}
for( RELOCTABLE::iterator j = m_pStringTable->begin(); j != m_pStringTable->end(); j++ )
{
long * pValue = (long*)(pCode + *j);
*pValue += long(pStringBuffer);
}
for( FUNCRELOCTABLE::iterator k = m_pFuncRelocTable->begin(); k != m_pFuncRelocTable->end(); k++ )
{
long * pValue = (long*)(pCode + k->second);
*pValue = (long) ArrFuncPtr[k->first];
}
}
void CRelocTable::Unlocate( void * pGlobalVarBuffer, void * pStringBuffer, void * pCodeBuffer )
{
char * pCode = (char*)pCodeBuffer;
for( RELOCTABLE::iterator i = m_pGlobalVarTable->begin(); i != m_pGlobalVarTable->end(); i++ )
{
long * pValue = (long*)(pCode + *i);
*pValue -= long(pGlobalVarBuffer);
}
for( RELOCTABLE::iterator i = m_pStringTable->begin(); i != m_pStringTable->end(); i++ )
{
long * pValue = (long*)(pCode + *i);
*pValue -= long(pStringBuffer);
}
for( FUNCRELOCTABLE::iterator k = m_pFuncRelocTable->begin(); k != m_pFuncRelocTable->end(); k++ )
{
long * pValue = (long*)(pCode + k->second);
*pValue = 0;
}
}

View File

@@ -0,0 +1,51 @@
#ifndef _RelocTable_H_
#define _RelocTable_H_
#include "STL.h"
///////////////////////////////////////////////////////////////////////////////////
//
enum eStdFunc
{
FUNC_ITOA = 0,
FUNC_GCVT,
FUNC_MALLOC,
FUNC_FREE,
FUNC_STRCPY,
FUNC_STRCMP,
FUNC_STRLEN,
FUNC_REGISTERALLOCATEDMEMORY,
FUNC_UNREGISTERALLOCATEDMEMORY = 8
};
class CRelocTable
{
typedef vector<int> RELOCTABLE;
typedef pair<eStdFunc, int> FUNCRELOC;
typedef vector<FUNCRELOC> FUNCRELOCTABLE;
RELOCTABLE * m_pGlobalVarTable;
RELOCTABLE * m_pStringTable;
FUNCRELOCTABLE * m_pFuncRelocTable;
public:
CRelocTable();
~CRelocTable();
void Create( ifstream & );
const void * Create( const void * pDataBuf, unsigned dataSize );
void Destroy();
void Save( ofstream & );
void AddGlobalVar( int offset );
void AddConstString( int offset );
void AddFuncBind( eStdFunc, int offset );
void Relocate( void * pGlobalVarBuffer, void * pStringBuffer, void * pCodeBuffer );
void Unlocate( void * pGlobalVarBuffer, void * pStringBuffer, void * pCodeBuffer );
};
///////////////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -0,0 +1,20 @@
#ifndef _STL_H_
#define _STL_H_
#pragma warning(disable:4786) //STL의 쓸데없는 Warning을 없애기 위한..
#include <iosfwd>
#include <map>
#include <set>
#include <string>
#include <deque>
#include <queue>
#include <vector>
#include <stack>
#include <list>
#include <utility>
using namespace std;
#endif

View File

@@ -0,0 +1,123 @@
// ScriptEngine.cpp : Defines the entry point for the DLL application.
//
#include "ScriptEngine.h"
#include "SyntaxTree.h"
#include "IntermediateCode.h"
#include "VirtualMachine.h"
#include "Message.h"
#include <stdarg.h>
#include <stdio.h>
#include <windows.h>
/*
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}*/
SCRIPT _SE_Create( const char * codeFile )
{
FILE * fp = fopen( codeFile, "r" );
if( fp == NULL )
{
ErrorMessage2( "Cannot open file : %s", codeFile );
return NULL;
}
CVirtualMachine * pVM = new CVirtualMachine;
char szFilename[128];
strcpy( szFilename, codeFile );
strlwr( szFilename );
if( strstr( szFilename, MACHINECODEFILEEXT ) != 0 )
{
pVM->Create( codeFile );
}
else if( strstr( szFilename, SCRIPTFILEEXT ) != 0 )
{
CSyntaxTree SyntaxTree;
CIntermediateCode IMCode;
SyntaxTree.Create( codeFile );
IMCode.Create( SyntaxTree );
pVM->Create( IMCode, *SyntaxTree.GetSymbolTable() );
}
else
{
return NULL;
}
return pVM;
}
void _SE_Destroy( SCRIPT Script )
{
delete Script;
}
bool _SE_Save( SCRIPT Script, const char * szFilename )
{
return Script->Save( szFilename );
}
void _SE_Execute( SCRIPT Script )
{
Script->Execute();
}
void _SE_RegisterFunction( SCRIPT Script, ANY_FUNCTION FuncPtr, eDataType RetType, const char * szFuncName, ... )
{
va_list args;
va_start( args, szFuncName );
Script->RegisterFunction( FuncPtr, RetType, szFuncName, args );
}
SE_FUNC _SE_GetScriptFunction( SCRIPT Script, eDataType RetType, const char * szFuncName, ... )
{
va_list args;
va_start( args, szFuncName );
return Script->GetScriptFunction( RetType, szFuncName, args );
}
void _SE_SetMessageFunction( MESSAGE_FUNCTION func )
{
SetCompilerMessageFunction( func );
}
AnyData _SE_CallScriptFunction( SCRIPT pScript, SE_FUNC Func )
{
return pScript->CallScriptFunction( Func );
}
AnyData _SE_CallScriptFunction( SCRIPT pScript, SE_FUNC Func, AnyData arg1 )
{
return pScript->CallScriptFunction( Func, arg1 );
}
AnyData _SE_CallScriptFunction( SCRIPT pScript, SE_FUNC Func, AnyData arg1, AnyData arg2 )
{
return pScript->CallScriptFunction( Func, arg1, arg2 );
}
AnyData _SE_CallScriptFunction( SCRIPT pScript, SE_FUNC Func, AnyData arg1, AnyData arg2, AnyData arg3 )
{
return pScript->CallScriptFunction( Func, arg1, arg2, arg3 );
}
AnyData _SE_CallScriptFunction( SCRIPT pScript, SE_FUNC Func, AnyData arg1, AnyData arg2, AnyData arg3, AnyData arg4 )
{
return pScript->CallScriptFunction( Func, arg1, arg2, arg3, arg4 );
}
AnyData _SE_CallScriptFunction( SCRIPT pScript, SE_FUNC Func, AnyData args[], int nArgs )
{
return pScript->CallScriptFunction( Func, args, nArgs );
}

View File

@@ -0,0 +1,36 @@
#ifndef _ScriptEngine_H_
#define _ScriptEngine_H_
#include "BaseDef.h"
#define DllExport // __declspec( dllexport )
class CVirtualMachine;
typedef CVirtualMachine * SCRIPT;
typedef void (*MESSAGE_FUNCTION)( const char * ErrMsg );
typedef void (*MESSAGE_FUNCTION2)( const char *, ... );
typedef char * va_list;
////////////////////////////////////////////////////////////////////////////////
//
DllExport SCRIPT _SE_Create( const char * codeFile );
DllExport void _SE_Destroy( SCRIPT );
DllExport bool _SE_Save( SCRIPT, const char * );
DllExport void _SE_Execute( SCRIPT );
DllExport void _SE_RegisterFunction( SCRIPT, ANY_FUNCTION, eDataType, const char * FuncName, ... );
DllExport SE_FUNC _SE_GetScriptFunction( SCRIPT, eDataType, const char * FuncName, ... );
DllExport void _SE_SetMessageFunction( MESSAGE_FUNCTION );
DllExport AnyData _SE_CallScriptFunction( SCRIPT, SE_FUNC );
DllExport AnyData _SE_CallScriptFunction( SCRIPT, SE_FUNC, AnyData );
DllExport AnyData _SE_CallScriptFunction( SCRIPT, SE_FUNC, AnyData, AnyData );
DllExport AnyData _SE_CallScriptFunction( SCRIPT, SE_FUNC, AnyData, AnyData, AnyData );
DllExport AnyData _SE_CallScriptFunction( SCRIPT, SE_FUNC, AnyData, AnyData, AnyData, AnyData );
DllExport AnyData _SE_CallScriptFunction( SCRIPT, SE_FUNC, AnyData args[], int nArgs );
////////////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -0,0 +1,365 @@
<?xml version="1.0" encoding="ks_c_5601-1987"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="ScriptEngine"
ProjectGUID="{8EE86398-FBBB-4568-98CF-4A890DA9D636}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Library/$(ConfigurationName)"
IntermediateDirectory="../../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../MemoryManager"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/ScriptEngine.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Library/$(ConfigurationName)"
IntermediateDirectory="../../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../MemoryManager"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/ScriptEngine.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release_NoGD|Win32"
OutputDirectory="../../Library/$(ConfigurationName)"
IntermediateDirectory="../../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../MemoryManager"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/ScriptEngine.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug_NoGD|Win32"
OutputDirectory="../../Library/$(ConfigurationName)"
IntermediateDirectory="../../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../MemoryManager"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/ScriptEngine.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release_MY|Win32"
OutputDirectory="../../Library/$(ConfigurationName)"
IntermediateDirectory="../../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../MemoryManager"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/ScriptEngine.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug_MY|Win32"
OutputDirectory="../../Library/$(ConfigurationName)"
IntermediateDirectory="../../Intermediate/$(ProjectName)/$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../MemoryManager"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/ScriptEngine.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="소스 파일"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\IMCodeGen.cpp">
</File>
<File
RelativePath=".\IMCodeUnits.cpp">
</File>
<File
RelativePath=".\IntermediateCode.cpp">
</File>
<File
RelativePath=".\lex.cpp">
</File>
<File
RelativePath=".\Message.cpp">
</File>
<File
RelativePath=".\parse.cpp">
</File>
<File
RelativePath=".\RelocTable.cpp">
</File>
<File
RelativePath=".\ScriptEngine.cpp">
</File>
<File
RelativePath=".\SymbolTable.cpp">
</File>
<File
RelativePath=".\SyntaxTree.cpp">
</File>
<File
RelativePath=".\VirtualMachine.cpp">
</File>
</Filter>
<Filter
Name="헤더 파일"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\BaseDef.h">
</File>
<File
RelativePath=".\IMCodeGen.h">
</File>
<File
RelativePath=".\IMCodeUnits.h">
</File>
<File
RelativePath=".\IntermediateCode.h">
</File>
<File
RelativePath=".\lex.h">
</File>
<File
RelativePath=".\lexsymb.h">
</File>
<File
RelativePath=".\Message.h">
</File>
<File
RelativePath=".\RelocTable.h">
</File>
<File
RelativePath=".\ScriptEngine.h">
</File>
<File
RelativePath=".\STL.h">
</File>
<File
RelativePath=".\SymbolTable.h">
</File>
<File
RelativePath=".\SyntaxTree.h">
</File>
<File
RelativePath=".\unistd.h">
</File>
<File
RelativePath=".\VirtualMachine.h">
</File>
</Filter>
<Filter
Name="리소스 파일"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
<File
RelativePath=".\bison.simple">
</File>
<File
RelativePath=".\ReadMe.txt">
</File>
<File
RelativePath=".\string.l">
</File>
<File
RelativePath=".\string.y">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,258 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug_MY|Win32">
<Configuration>Debug_MY</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug_NoGD|Win32">
<Configuration>Debug_NoGD</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release_MY|Win32">
<Configuration>Release_MY</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release_NoGD|Win32">
<Configuration>Release_NoGD</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{8EE86398-FBBB-4568-98CF-4A890DA9D636}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../Library/$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../Intermediate/$(ProjectName)/$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../Library/$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../Intermediate/$(ProjectName)/$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'">../../Library/$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'">../../Intermediate/$(ProjectName)/$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'">../../Library/$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'">../../Intermediate/$(ProjectName)/$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'">../../Library/$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'">../../Intermediate/$(ProjectName)/$(Configuration)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'">../../Library/$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'">../../Intermediate/$(ProjectName)/$(Configuration)\</IntDir>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IncludePath);C:\project\trunk\Client\Library\dxx8\include</IncludePath>
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\project\trunk\Client\Library\dxx8\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../MemoryManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<OpenMPSupport>
</OpenMPSupport>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)ScriptEngine.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>../MemoryManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;NO_GAMEGUARD;_LIB;_USE_32BIT_TIME_T;</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)ScriptEngine.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_NoGD|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>../MemoryManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)ScriptEngine.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoGD|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../MemoryManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)ScriptEngine.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_MY|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>../MemoryManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)ScriptEngine.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_MY|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../MemoryManager;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)ScriptEngine.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="IMCodeGen.cpp" />
<ClCompile Include="IMCodeUnits.cpp" />
<ClCompile Include="IntermediateCode.cpp" />
<ClCompile Include="lex.cpp" />
<ClCompile Include="Message.cpp" />
<ClCompile Include="parse.cpp" />
<ClCompile Include="RelocTable.cpp" />
<ClCompile Include="ScriptEngine.cpp" />
<ClCompile Include="SymbolTable.cpp" />
<ClCompile Include="SyntaxTree.cpp" />
<ClCompile Include="VirtualMachine.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="BaseDef.h" />
<ClInclude Include="IMCodeGen.h" />
<ClInclude Include="IMCodeUnits.h" />
<ClInclude Include="IntermediateCode.h" />
<ClInclude Include="lex.h" />
<ClInclude Include="lexsymb.h" />
<ClInclude Include="Message.h" />
<ClInclude Include="RelocTable.h" />
<ClInclude Include="ScriptEngine.h" />
<ClInclude Include="STL.h" />
<ClInclude Include="SymbolTable.h" />
<ClInclude Include="SyntaxTree.h" />
<ClInclude Include="unistd.h" />
<ClInclude Include="VirtualMachine.h" />
</ItemGroup>
<ItemGroup>
<None Include="bison.simple" />
<None Include="ReadMe.txt" />
<None Include="string.l" />
<None Include="string.y" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MemoryManager\MemoryManager.vcxproj">
<Project>{7b602b2e-c629-4311-b7f6-c9177660ada1}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<Private>true</Private>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="소스 파일">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="헤더 파일">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="리소스 파일">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="IMCodeGen.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="IMCodeUnits.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="IntermediateCode.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="lex.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="Message.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="parse.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="RelocTable.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="ScriptEngine.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="SymbolTable.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="SyntaxTree.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
<ClCompile Include="VirtualMachine.cpp">
<Filter>소스 파일</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="BaseDef.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="IMCodeGen.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="IMCodeUnits.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="IntermediateCode.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="lex.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="lexsymb.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="Message.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="RelocTable.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="ScriptEngine.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="STL.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="SymbolTable.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="SyntaxTree.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="unistd.h">
<Filter>헤더 파일</Filter>
</ClInclude>
<ClInclude Include="VirtualMachine.h">
<Filter>헤더 파일</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="bison.simple" />
<None Include="ReadMe.txt" />
<None Include="string.l" />
<None Include="string.y" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>

View File

@@ -0,0 +1,524 @@
#include "SymbolTable.h"
#include <assert.h>
#include <map>
#include <string>
#include <list>
///////////////////////////////////////////////////////////////////////////////////
// 전역변수
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" );
}
}
///////////////////////////////////////////////////////////////////////////////////
//

View File

@@ -0,0 +1,121 @@
#ifndef _SymbolTable_H_
#define _SymbolTable_H_
#include "STL.h"
#include "BaseDef.h"
#include "Message.h"
#define SYSVAR_SWITCHTEMP "<SwitchTempVar>"
#define SYSVAR_FLOATUNIT "<FloatUnit>"
#define SYSVAR_FLOATTEMP "<FloatTemp>"
#define SYSVAR_TRUE "<True>"
#define SYSVAR_FALSE "<False>"
#define SYSVAR_CONVBUFFER "<ConvBuffer>"
///////////////////////////////////////////////////////////////////////////////////
// 함수의 인자는 7개를 넘어선 안된다.
struct SFuncType
{
public:
unsigned long m_data;
public:
SFuncType();
SFuncType( unsigned long );
void SetArgType( int nth, eDataType arg ) { m_data |= ( 0x0000000f & arg ) << (nth*4); }
void SetReturnType( eDataType retType ) { m_data |= ( 0x0000000f & retType ) << 28; }
eDataType GetArgType( int nth ) { return (eDataType)(m_data >> (nth*4) & 0x0000000f); }
eDataType GetReturnType() { return (eDataType)(m_data >> 28 & 0x0000000f); }
int GetArgCount();
const char* ToString( const char * szFuncName );
bool operator==( const SFuncType & rhs ) { return (m_data & 0x0fffffff) == (rhs.m_data & 0x0fffffff); }
bool operator!=( const SFuncType & rhs ) { return (m_data & 0x0fffffff) != (rhs.m_data & 0x0fffffff); }
};
///////////////////////////////////////////////////////////////////////////////////
//
class CSymbolTable
{
public:
typedef map< int, int > OFFSETMAP;
typedef unsigned char byte;
typedef struct ConstInfo CONSTINFO;
typedef map<string,CONSTINFO> CONST_CONTAINER;
typedef struct VarInfo VARINFO;
typedef map<string,VARINFO> VAR_CONTAINER;
typedef struct SLocalVarInfo LOCALVARINFO;
typedef list<LOCALVARINFO> LOCALVAR_CONTAINER;
typedef pair<SFuncType, bool> FUNCINFO;
typedef multimap<string,FUNCINFO> FUNC_CONTAINER;
protected:
CONST_CONTAINER * m_pConstants;
VAR_CONTAINER * m_pGlobalVar;
LOCALVAR_CONTAINER* m_pLocalVars;
VAR_CONTAINER * m_pCurNameSpace;
VAR_CONTAINER * m_pNameSpace2; //CurNameSpace와 쌍을 이룸( CurNameSpace가 ArgContainer일 때 이것은 VarContainer, VarContainer일 때 ArgContainer )
FUNC_CONTAINER * m_pFunctions;
LOCALVARINFO * m_pCurrentLocalVar;
eDataType m_eCurrentType;
int m_iVarOffset, m_iVarOffsetGlobal;
int m_iOffsetFactor;
int m_iStringOffset;
public:
CSymbolTable();
~CSymbolTable();
void Create();
void Destroy();
int AddConst( const char * szName, eDataType type );
int AddArrVar( const char * szName, eDataType, int nArray );
int AddArrVar( const char * szName, int nArray ) { return AddArrVar( szName, m_eCurrentType, nArray ); }
int AddVar( const char * szName, eDataType type ) { return AddArrVar( szName, type, 1 ); }
int AddVar( const char * szName ) { return AddVar( szName, m_eCurrentType ); }
int AddFunc( bool hasDef, const char * szName, SFuncType );
void SetCurrentType( eDataType type ) { m_eCurrentType = type; }
eDataType GetCurrentType() { return m_eCurrentType; }
int FindConst( const char * szName );
int FindVar( const char * szName );
int FindFunc( const char * szname, SFuncType );
void BeginLocalNameSpace();
void EndLocalNameSpace( int ); //인자로는 함수의 ID를 넘겨준다.
void EndArgument();
const char* GetNameOfConst( int );
eDataType GetTypeOfConst( int );
int GetOffsetOfConst( int );
const char* GetNameOfVar( int );
eDataType GetTypeOfVar( int );
int GetCountOfVar( int );
int GetOffsetOfVar( int ); //지역 변수일 경우 EBP를 기준으로한 오프셋을 리턴함.
//전역 변수일 경우 시작 주소에 대한 오프셋을 리턴한다.
const char* GetNameOfFunc( int );
const char* GetTypeStringOfFunc( int );
SFuncType GetTypeOfFunc( int );
bool IsFuncDefined( int );
int GetLocalVarSize( int );
int GetGlobalVarSize();
int GetStringBufferSize();
void StringBuffer( void * );
void Show( MESSAGE_FUNCTION2 Print );
};
///////////////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -0,0 +1,547 @@
#include "SyntaxTree.h"
#include "SymbolTable.h"
#include "lex.h"
#include <assert.h>
#include <set>
///////////////////////////////////////////////////////////////////////////////
// 전역변수
CSyntaxTree * g_pSynTree = 0;
CSymbolTable * g_pSymbolTable = 0;
char szBuffer[4096];
///////////////////////////////////////////////////////////////////////////////
// Parser 함수
void yyerror( char *msg )
{
CompilerMessage( msg );
}
extern "C" int yywrap(void) {
return 1;
}
////////////////////////////////////////////////////////////////////////////////
// 멤버 함수
SNode::SNode( int line, eSyntaxType type, SNode * pNode1, SNode * pNode2, SNode * pNode3 )
: m_iLine( line ), m_eType( type ), m_SymbolID( 0 ), m_eReturnType( T_VOID )
{
m_ArrPtrChilds[0] = pNode1;
m_ArrPtrChilds[1] = pNode2;
m_ArrPtrChilds[2] = pNode3;
}
const char * SyntaxTypeName[] =
{
"TYPE_STATEMENT_LIST",
"TYPE_EMPTY_STATEMENT",
"TYPE_ERROR_STATEMENT",
"TYPE_EXPRESSION",
"TYPE_IF_STATEMENT",
"TYPE_IF_ELSE_STATEMENT",
"TYPE_SWITCH_STATEMENT",
"TYPE_SWITCH_CASES",
"TYPE_CASE_ONE",
"TYPE_DEFAULT",
"TYPE_FOR_STATEMENT",
"TYPE_WHILE_STATEMENT",
"TYPE_FOR_EXPRESSION",
"TYPE_BREAK_STATEMENT",
"TYPE_CONTINUE_STATEMENT",
"TYPE_RETURN_STATEMENT",
"TYPE_DECLARATION",
"TYPE_SPECIFIER_VOID",
"TYPE_SPECIFIER_INT",
"TYPE_SPECIFIER_FLOAT",
"TYPE_SPECIFIER_BOOL",
"TYPE_SPECIFIER_STRING",
"TYPE_VARIABLE",
"TYPE_DECLARATOR_LIST",
"TYPE_INIT_DECLARATION",
"TYPE_NORMAL_DECLARATION",
"TYPE_ARRAY_INITIALIZE",
"TYPE_ARRAY_INITIALIZE2",
"TYPE_ARRAY_DECLARATION",
"TYPE_FUNCTION_DECLARATION",
"TYPE_INITIALIZER_LIST",
"TYPE_ARGUMENT_DECLARATION_LIST",
"TYPE_ARGUMENT_DECLARATION",
"TYPE_FUNCTION_DEFINITION",
"TYPE_CONSTANT_EXPRESSION",
"TYPE_EXPRESSION_LIST",
"TYPE_ASSIGNMENT_EXPESSION",
"TYPE_OR_EXPRESSION",
"TYPE_AND_EXPRESSION",
"TYPE_NOT_EXPRESSION",
"TYPE_EQUALITY_EXPRESSION",
"TYPE_NOTEQAUL_EXPRESSION",
"TYPE_LESSTHAN_EXPRESSION",
"TYPE_MORETHAN_EXPRESSION",
"TYPE_LESSTHANOREQUAL_EXPRESSION",
"TYPE_MORETHANOREQUAL_EXPRESSION",
"TYPE_ADDITION_EXPRESSION",
"TYPE_SUBTRACTION_EXPRESSION",
"TYPE_MULTIPLICATION_EXPRESSION",
"TYPE_DIVISION_EXPRESSION",
"TYPE_REMINDER_EXPRESSION",
"TYPE_COMPOUND_ADDITION",
"TYPE_COMPOUND_SUBTRACTION",
"TYPE_COMPOUND_MULTIPLICATION",
"TYPE_COMPOUND_DIVISION",
"TYPE_COMPOUND_REMINDER",
"TYPE_PREFIXINCREMENT",
"TYPE_PREFIXDECREMENT",
"TYPE_ARRAY_INDEXING",
"TYPE_FUNCTION_CALL",
"TYPE_POSTFIXINCREMENT",
"TYPE_POSTFIXDECREMENT"
};
void SNode::Show( int level, MESSAGE_FUNCTION2 Print, CSymbolTable * pSymbolTable )
{
const char * DataTypeString[] = { "void", "bool", "int", "float", "string" };
int nl = level;
if (!this) return;
if( m_eType != TYPE_STATEMENT_LIST )
{
Print( itoa( m_iLine, szBuffer, 10 ) );
Print( ": " );
for ( int i = 0; i < level; i++ )
Print( " " );
Print( SyntaxTypeName[m_eType] );
switch( m_eType )
{
case TYPE_CONSTANT_EXPRESSION :
Print( " ( " );
Print( pSymbolTable->GetNameOfConst( m_SymbolID ) );
Print( " : " );
Print( DataTypeString[ pSymbolTable->GetTypeOfConst( m_SymbolID ) ] );
Print( " )" );
break;
case TYPE_INIT_DECLARATION :
case TYPE_NORMAL_DECLARATION :
case TYPE_ARRAY_INITIALIZE :
case TYPE_ARRAY_INITIALIZE2 :
case TYPE_ARRAY_DECLARATION :
case TYPE_ARGUMENT_DECLARATION :
case TYPE_VARIABLE :
case TYPE_PREFIXINCREMENT :
case TYPE_PREFIXDECREMENT :
case TYPE_POSTFIXINCREMENT :
case TYPE_POSTFIXDECREMENT :
case TYPE_COMPOUND_ADDITION :
case TYPE_COMPOUND_SUBTRACTION :
case TYPE_COMPOUND_MULTIPLICATION :
case TYPE_COMPOUND_DIVISION :
case TYPE_COMPOUND_REMINDER :
Print( " ( " );
Print( pSymbolTable->GetNameOfVar( m_SymbolID ) );
Print( " : " );
Print( DataTypeString[ pSymbolTable->GetTypeOfVar( m_SymbolID ) ] );
Print( " )" );
break;
}
nl++;
Print("\n");
}
for( int i = 0; m_ArrPtrChilds[i] != 0 && i < 3; i++ )
m_ArrPtrChilds[i]->Show( nl, Print, pSymbolTable );
}
bool SNode::SemanticCheck( CSymbolTable * pSymbolTable )
{
static eDataType tempType, tempType2;
switch( m_eType )
{
case TYPE_ARRAY_INDEXING :
//첫번째 int일때만 유효하고, 심볼의 타입에 의해 타입이 결정됨.
if( m_ArrPtrChilds[0]->m_eReturnType != T_INT )
return false;
else
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
break;
case TYPE_EXPRESSION :
m_eReturnType = m_ArrPtrChilds[0]->m_eReturnType;
break;
case TYPE_ARRAY_DECLARATION :
//첫번째 차일드가 int일때만 유효하고, 심볼 타입에 의해 타입이 결정됨.
if( m_ArrPtrChilds[0]->m_eReturnType != T_INT )
return false;
else
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
break;
case TYPE_ARRAY_INITIALIZE2 :
//심볼 타입과 두번재 차일드의 타입이 같은지 검사하고 같을 때 심볼 타입을 리턴
//첫번째 차일드는 int형이어야 함.
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
if( m_ArrPtrChilds[0]->m_eReturnType != T_INT )
return false;
if( m_eReturnType != m_ArrPtrChilds[1]->m_eReturnType )
return false;
break;
case TYPE_ARRAY_INITIALIZE :
//심볼 타입과 첫번째 차일드의 타입이 같아야 함.
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
if( m_eReturnType != m_ArrPtrChilds[0]->m_eReturnType )
return false;
break;
case TYPE_INIT_DECLARATION :
case TYPE_ASSIGNMENT_EXPRESSION :
//심볼 타입과 첫번째 차일드의 타입이 같은지 검사하고 같을 때 심볼 타입을 리턴
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
if( m_eReturnType == T_VOID )
return false;
if( m_eReturnType != m_ArrPtrChilds[0]->m_eReturnType )
{
if( m_eReturnType != T_STRING )
return false;
}
break;
case TYPE_INITIALIZER_LIST :
m_eReturnType = m_ArrPtrChilds[0]->m_eReturnType;
if( m_eReturnType == T_STRING )
{
if( m_ArrPtrChilds[1]->m_eReturnType == T_VOID )
return false;
}
else if( m_ArrPtrChilds[1]->m_eReturnType == T_STRING )
{
if( m_eReturnType == T_VOID )
return false;
m_eReturnType = T_STRING;
}
else
{
if( m_eReturnType != m_ArrPtrChilds[1]->m_eReturnType )
break;
}
break;
case TYPE_DECLARATOR_LIST :
//첫번째 차일드와 두번째 차일드의 타입이 같은지 검사하고 같을 때 첫번째 차일드 타입 리턴
if( m_ArrPtrChilds[0]->m_eReturnType != m_ArrPtrChilds[1]->m_eReturnType )
return false;
else
m_eReturnType = m_ArrPtrChilds[0]->m_eReturnType;
break;
case TYPE_ADDITION_EXPRESSION :
m_eReturnType = m_ArrPtrChilds[0]->m_eReturnType;
if( m_eReturnType == T_STRING )
{
if( m_ArrPtrChilds[1]->m_eReturnType == T_VOID )
return false;
}
else if( m_ArrPtrChilds[1]->m_eReturnType == T_STRING )
{
if( m_eReturnType == T_VOID )
return false;
m_eReturnType = T_STRING;
}
else
{
if( m_eReturnType != m_ArrPtrChilds[1]->m_eReturnType )
return false;
}
break;
case TYPE_SUBTRACTION_EXPRESSION :
case TYPE_MULTIPLICATION_EXPRESSION :
case TYPE_DIVISION_EXPRESSION :
//첫번째 차일드와 두번째 차일드가 다를 때는 무효, int나 float형이 아닐 경우에도 무효
if( m_ArrPtrChilds[0]->m_eReturnType != m_ArrPtrChilds[1]->m_eReturnType )
{
return false;
}
m_eReturnType = m_ArrPtrChilds[0]->m_eReturnType;
if( m_eReturnType != T_INT && m_eReturnType != T_FLOAT )
return false;
break;
case TYPE_REMINDER_EXPRESSION :
//첫번째 차일드와 두번째 차일드가 다를 때는 무효, int형이 아닐 경우에도 무효
if( m_ArrPtrChilds[0]->m_eReturnType != m_ArrPtrChilds[1]->m_eReturnType )
{
return false;
break;
}
m_eReturnType = m_ArrPtrChilds[0]->m_eReturnType;
if( m_eReturnType != T_INT )
return false;
break;
case TYPE_PREFIXINCREMENT :
case TYPE_PREFIXDECREMENT :
case TYPE_POSTFIXINCREMENT :
case TYPE_POSTFIXDECREMENT :
//int와 float형이 아닌 경우에는 무효.
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
if( m_eReturnType != T_INT && m_eReturnType != T_FLOAT )
return false;
break;
case TYPE_NORMAL_DECLARATION :
case TYPE_CONSTANT_EXPRESSION :
case TYPE_VARIABLE :
//심볼의 타입이 이 노드의 타입을 결정
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
break;
case TYPE_NOT_EXPRESSION :
//첫번째 차일드가 BOOL형일 경우에만 유효함.
if( m_ArrPtrChilds[0]->m_eReturnType != T_BOOL )
return false;
else
m_eReturnType = T_BOOL;
break;
case TYPE_OR_EXPRESSION :
case TYPE_AND_EXPRESSION :
//첫번째 차일드와 두번째 차일드가 모두 bool형일 때에만 유효함.
m_eReturnType = T_BOOL;
if( m_ArrPtrChilds[0]->m_eReturnType != T_BOOL || m_ArrPtrChilds[1]->m_eReturnType != T_BOOL )
{
return false;
}
break;
case TYPE_EQUALITY_EXPRESSION :
case TYPE_NOTEQAUL_EXPRESSION :
//왼쪽과 오른쪽의 타입이 같아야 하며, void는 허용 안됨.
tempType = m_ArrPtrChilds[0]->m_eReturnType;
if( tempType != m_ArrPtrChilds[1]->m_eReturnType || tempType == T_VOID )
return false;
else
m_eReturnType = T_BOOL;
break;
case TYPE_LESSTHAN_EXPRESSION :
case TYPE_MORETHAN_EXPRESSION :
case TYPE_LESSTHANOREQUAL_EXPRESSION :
case TYPE_MORETHANOREQUAL_EXPRESSION :
tempType = m_ArrPtrChilds[0]->m_eReturnType;
//첫 번째 차일드와 두 번째 차일드가 다를 때는 무효, int, float형이 아닐 경우에도 오류
if( tempType != m_ArrPtrChilds[1]->m_eReturnType )
return false;
if( tempType != T_INT && tempType != T_FLOAT )
return false;
m_eReturnType = T_BOOL;
break;
case TYPE_COMPOUND_ADDITION :
//심볼의 타입이 이 노드의 타입을 결정
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
//int나 float, string형이 아닐 경우 무효
if( m_eReturnType != T_INT && m_eReturnType != T_FLOAT && m_eReturnType != T_STRING )
return false;
//심볼 타입과 첫번째 차일드가 다를 때는 심볼 타입이 string일 경우에만 유효
if( m_eReturnType != m_ArrPtrChilds[0]->m_eReturnType )
{
if( m_eReturnType != T_STRING )
return false;
else
{
if( m_ArrPtrChilds[0]->m_eReturnType == T_VOID )
return false;
}
}
break;
case TYPE_COMPOUND_SUBTRACTION :
case TYPE_COMPOUND_MULTIPLICATION :
case TYPE_COMPOUND_DIVISION :
//심볼의 타입이 이 노드의 타입을 결정
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
//심볼 타입과 첫번째 차일드가 다를 때는 무효, int나 float형이 아닐 경우에도 무효
if( m_eReturnType != m_ArrPtrChilds[0]->m_eReturnType )
{
return false;
}
if( m_eReturnType != T_INT && m_eReturnType != T_FLOAT )
return false;
break;
case TYPE_COMPOUND_REMINDER :
//심볼의 타입이 이 노드의 타입을 결정
m_eReturnType = pSymbolTable->GetTypeOfVar( m_SymbolID );
//심볼 타입과 첫번째 차일드가 다를 때는 무효, int형이 아닐 경우에도 무효
if( m_eReturnType != m_ArrPtrChilds[0]->m_eReturnType )
{
return false;
}
if( m_eReturnType != T_INT )
return false;
break;
case TYPE_FUNCTION_CALL :
{
SFuncType type = pSymbolTable->GetTypeOfFunc( m_SymbolID );
m_eReturnType = type.GetReturnType();
break;
}
case TYPE_SWITCH_STATEMENT :
{
if( m_ArrPtrChilds[0]->m_eReturnType != T_INT )
return false;
m_eReturnType = T_VOID;
break;
}
case TYPE_CASE_ONE :
{
if( m_ArrPtrChilds[0]->m_eReturnType != T_INT )
return false;
m_eReturnType = T_VOID;
break;
}
default :
m_eReturnType = T_VOID;
break;
}
return true;
}
CSyntaxTree::CSyntaxTree()
: m_pRoot( 0 )
, m_pSymbolTable( new CSymbolTable )
, m_pPtrStorage( new PTRSTORAGE )
{
}
CSyntaxTree::~CSyntaxTree()
{
Destroy();
delete m_pSymbolTable;
delete m_pPtrStorage;
}
void CSyntaxTree::Create( const char * szFileName )
{
FILE * fp = fopen( szFileName, "rt" );
if( fp == NULL )
return;
yylloc.first_line = 1;
Create( fp );
}
void CSyntaxTree::Create( FILE * fp )
{
yyin = fp;
g_pSynTree = this;
g_pSymbolTable = m_pSymbolTable;
g_pSymbolTable->Create();
yylloc.first_line = 1;
yyparse();
}
void CSyntaxTree::Destroy()
{
typedef PTRSTORAGE::iterator ITERATOR;
for( ITERATOR i = m_pPtrStorage->begin(); i != m_pPtrStorage->end(); i++ )
{
delete (*i);
}
m_pPtrStorage->clear();
m_pSymbolTable->Destroy();
}
int CSyntaxTree::Insert( int line, eSyntaxType SynType, int childID1, int childID2, int childID3 )
{
SNode * pNode = new SNode( line, SynType, (SNode*)childID1, (SNode*)childID2, (SNode*)childID3 );
assert( m_pPtrStorage->insert( pNode ).second );
if( pNode->SemanticCheck( m_pSymbolTable ) == false )
ErrorMessage( pNode->m_iLine, "타입이 맞지 않습니다~\n" );
return (int)pNode;
}
int CSyntaxTree::Insert( int line, int symbolID, eSyntaxType SynType, int childID1, int childID2, int childID3 )
{
SNode * pNode = new SNode( line, SynType, (SNode*)childID1, (SNode*)childID2, (SNode*)childID3 );
assert( m_pPtrStorage->insert( pNode ).second );
pNode->m_SymbolID = symbolID;
if( pNode->SemanticCheck( m_pSymbolTable ) == false )
CompilerMessage2( "Error(line %d) : 타입이 맞지 않습니다~\n", pNode->m_iLine );
return (int)pNode;
}
void CSyntaxTree::SetRoot( int nodeID )
{
if( nodeID != 0 )
{
if( m_pRoot != NULL )
{
Destroy();
}
m_pRoot = (SNode*)nodeID;
}
}
void CSyntaxTree::Show( MESSAGE_FUNCTION2 Print )
{
if( m_pRoot != NULL )
{
m_pRoot->Show( 0, Print, m_pSymbolTable );
}
}

View File

@@ -0,0 +1,135 @@
#ifndef _SyntaxTree_H_
#define _SyntaxTree_H_
#include "BaseDef.h"
#include "Message.h"
#include "STL.h"
#define MAXCHILD 3
class CSymbol;
class CSyntaxTree;
class CSymbolTable;
struct _iobuf;
typedef struct _iobuf FILE;
enum eSyntaxType
{
TYPE_STATEMENT_LIST = 0,
TYPE_EMPTY_STATEMENT,
TYPE_ERROR_STATEMENT,
TYPE_EXPRESSION,
TYPE_IF_STATEMENT,
TYPE_IF_ELSE_STATEMENT,
TYPE_SWITCH_STATEMENT,
TYPE_SWITCH_CASES,
TYPE_CASE_ONE,
TYPE_DEFAULT,
TYPE_FOR_STATEMENT,
TYPE_WHILE_STATEMENT,
TYPE_FOR_EXPRESSION,
TYPE_BREAK_STATEMENT,
TYPE_CONTINUE_STATEMENT,
TYPE_RETURN_STATEMENT,
TYPE_DECLARATION,
TYPE_SPECIFIER_VOID,
TYPE_SPECIFIER_INT,
TYPE_SPECIFIER_FLOAT,
TYPE_SPECIFIER_BOOL,
TYPE_SPECIFIER_STRING,
TYPE_VARIABLE,
TYPE_DECLARATOR_LIST,
TYPE_INIT_DECLARATION,
TYPE_NORMAL_DECLARATION,
TYPE_ARRAY_INITIALIZE,
TYPE_ARRAY_INITIALIZE2,
TYPE_ARRAY_DECLARATION,
TYPE_FUNCTION_DECLARATION,
TYPE_INITIALIZER_LIST,
TYPE_ARGUMENT_DECLARATION_LIST,
TYPE_ARGUMENT_DECLARATION,
TYPE_FUNCTION_DEFINITION,
TYPE_CONSTANT_EXPRESSION,
TYPE_EXPRESSION_LIST,
TYPE_ASSIGNMENT_EXPRESSION,
TYPE_OR_EXPRESSION,
TYPE_AND_EXPRESSION,
TYPE_NOT_EXPRESSION,
TYPE_EQUALITY_EXPRESSION,
TYPE_NOTEQAUL_EXPRESSION,
TYPE_LESSTHAN_EXPRESSION,
TYPE_MORETHAN_EXPRESSION,
TYPE_LESSTHANOREQUAL_EXPRESSION,
TYPE_MORETHANOREQUAL_EXPRESSION,
TYPE_ADDITION_EXPRESSION,
TYPE_SUBTRACTION_EXPRESSION,
TYPE_MULTIPLICATION_EXPRESSION,
TYPE_DIVISION_EXPRESSION,
TYPE_REMINDER_EXPRESSION,
TYPE_COMPOUND_ADDITION,
TYPE_COMPOUND_SUBTRACTION,
TYPE_COMPOUND_MULTIPLICATION,
TYPE_COMPOUND_DIVISION,
TYPE_COMPOUND_REMINDER,
TYPE_PREFIXINCREMENT,
TYPE_PREFIXDECREMENT,
TYPE_ARRAY_INDEXING,
TYPE_FUNCTION_CALL,
TYPE_POSTFIXINCREMENT,
TYPE_POSTFIXDECREMENT = 61,
};
///////////////////////////////////////////////////////////////////////////////////
//
struct SNode
{
int m_iLine;
eSyntaxType m_eType;
SNode * m_ArrPtrChilds[MAXCHILD];
int m_SymbolID;
eDataType m_eReturnType;
public:
SNode( int, eSyntaxType, SNode *, SNode *, SNode * );
void Show( int, MESSAGE_FUNCTION2, CSymbolTable * );
bool SemanticCheck( CSymbolTable * );
};
class CSyntaxTree
{
protected:
SNode * m_pRoot;
CSymbolTable * m_pSymbolTable;
typedef set<void *> PTRSTORAGE;
PTRSTORAGE * m_pPtrStorage;
public:
CSyntaxTree();
~CSyntaxTree();
void Create( const char * ); //특정 스크립트 화일을 읽어서 Syntax트리를 구성한다.
void Create( FILE * );
void Destroy();
int Insert( int line, eSyntaxType, int childID1 = 0, int childID2 = 0, int childID3 = 0 );
int Insert( int line, int symbolID, eSyntaxType, int childID1 = 0, int childID2 = 0, int childID3 = 0 );
void SetRoot( int nodeID );
void Show( MESSAGE_FUNCTION2 );
CSymbolTable * GetSymbolTable() { return m_pSymbolTable; }
SNode * GetRoot() { return m_pRoot; }
};
///////////////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -0,0 +1,625 @@
#include "VirtualMachine.h"
#include "IntermediateCode.h"
#include "SymbolTable.h"
#include "RelocTable.h"
#include <map>
#include <string>
#include <stdarg.h>
#include <fstream>
#include <set>
typedef unsigned char byte;
static const int xor_key_value = 0x82fac623;
///////////////////////////////////////////////////////////////////////////////////
//
CVirtualMachine::ALLOCATED * pAllocatedPtrs = NULL;
void RegisterAllocatedMemory( void * p )
{
pAllocatedPtrs->insert( p );
// CompilerMessage2( "[[[Register Allocated Memory : %d]]]", int(p) );
}
void UnregisterAllocatedMemory( void * p )
{
pAllocatedPtrs->erase( p );
// CompilerMessage2( "[[[Unregister Allocated Memory : %d]]]", int(p) );
}
///////////////////////////////////////////////////////////////////////////////////
//
ScriptFunc::ScriptFunc( void * pfunc, long type )
: pFunc( pfunc ), Type( type )
{}
CVirtualMachine::CVirtualMachine()
: m_pBuffer( NULL )
, m_pGlobalVars( NULL )
, m_pStringBuffer( NULL )
, m_pCodeBuffer( NULL )
, m_iCodeSize( 0 )
, m_pFunctionMap( new FUNCMAP )
, m_pRelocation( new CRelocTable )
, m_bRelocated( false )
, m_pAllocatedPtrs( new ALLOCATED )
, m_pSysVarBuffer( new char[32] )
{
pAllocatedPtrs = m_pAllocatedPtrs;
}
CVirtualMachine::~CVirtualMachine()
{
Destroy();
delete m_pFunctionMap;
delete m_pRelocation;
delete m_pAllocatedPtrs;
delete [] m_pSysVarBuffer;
}
///////////////////////////////////////////////////////////////////////////////////
//
void Data_XOR( char * pDataBuf, unsigned size, int keyValue )
{
int * pIntData = (int*)pDataBuf;
int IntDataSize = size/sizeof(int);
for( int i = 0; i < IntDataSize; i++ )
{
pIntData[i] = pIntData[i] ^ keyValue;
}
}
///////////////////////////////////////////////////////////////////////////////////
//
void File_XOR( const char * szSrcFilename, const char * szDstFilename, int keyValue )
{
fstream infile( szSrcFilename, ios_base::in | ios_base::binary );
if( !infile.is_open() )
{
ErrorMessage2( "화일을 열 수 없습니다.(At File_XOR) : %s", szSrcFilename );
}
fstream outfile( szDstFilename, ios_base::out | ios_base::binary );
if( !outfile.is_open() )
{
ErrorMessage2( "화일을 열 수 없습니다.(At File_XOR) : %s", szDstFilename );
}
infile.seekg( 0, ios_base::end );
unsigned filesize = infile.tellg();
infile.seekg( 0, ios_base::beg );
char * pDataBuf = new char[ filesize ];
infile.read( pDataBuf, filesize );
Data_XOR( pDataBuf, filesize, keyValue );
outfile.write( pDataBuf, filesize );
delete [] pDataBuf;
}
///////////////////////////////////////////////////////////////////////////////////
//
void CVirtualMachine::Create( const char * szFilename )
{
ifstream file( szFilename, ios::binary | ios::in );
if( !file.is_open() )
ErrorMessage2( "지정한 화일을 찾을 수 없습니다. (At CVirtualMachine::Create) : %s", szFilename );
file.seekg( 0, ios_base::end );
unsigned filesize = file.tellg();
file.seekg( 0, ios_base::beg );
char * pBuf = new char[filesize];
int xor_key_valueT = xor_key_value^0x601f1ac4;
file.read( pBuf, filesize );
Data_XOR( pBuf, filesize, xor_key_valueT );
Create( pBuf, filesize );
delete [] pBuf;
file.close();
/*
Destroy();
ifstream file( szFilename, ios::binary | ios::in );
if( !file.is_open() )
ErrorMessage2( "지정한 화일을 찾을 수 없습니다. (At CVirtualMachine::Create) : %s", szFilename );
m_pRelocation->Create( file );
int GlobalVarBufferSize, StringBufferSize, TotalBufferSize;
file.read( (char*)&GlobalVarBufferSize, sizeof(int) );
file.read( (char*)&StringBufferSize, sizeof(int) );
file.read( (char*)&m_iCodeSize, sizeof(int) );
TotalBufferSize = GlobalVarBufferSize + StringBufferSize + m_iCodeSize;
m_pGlobalVars = m_pBuffer = new char[TotalBufferSize];
m_pStringBuffer = ((byte*)m_pGlobalVars) + GlobalVarBufferSize;
m_pCodeBuffer = ((byte*)m_pStringBuffer) + StringBufferSize;
memset( m_pGlobalVars, 0, GlobalVarBufferSize );
file.read( (char*)m_pStringBuffer, StringBufferSize );
file.read( (char*)m_pCodeBuffer, m_iCodeSize );
long FuncMapSize;
file.read( (char*)&FuncMapSize, sizeof(long) );
string str;
char endChar;
long type, offset;
for( int i = 0; i < FuncMapSize; i++ )
{
file >> str;
file.read( &endChar, 1 );
file.read( (char*)&type, sizeof(long) );
file.read( (char*)&offset, sizeof(long) );
offset += long( m_pCodeBuffer );
m_pFunctionMap->insert( FUNCMAP::value_type( str, FUNCINFO( type, (void*)offset ) ) );
}
file.read( (char*)m_pSysVarOffset, sizeof(int)*4 );
file.close();
m_pRelocation->Relocate( m_pGlobalVars, m_pStringBuffer, m_pCodeBuffer );
m_bRelocated = true;
SetSysVars();
*/
}
#define READ_INT( p, var ) { var = *((int*)p); p += sizeof(int); }
#define READ_LONG( p, var ) { var = *((long*)p); p += sizeof(long); }
#define READ_CHAR( p, var ) { var = *p; p += sizeof(char); }
const char * ReadLine( const char * szBuf, char * szOut, char endChar = '\0' )
{
const char * p = szBuf;
char * pDst = szOut;
while( *p != endChar )
{
*pDst = *p;
p++, pDst++;
}
*pDst = '\0';
return p + 1;
}
void CVirtualMachine::Create( const void * pDataBuf, unsigned DataSize )
{
Destroy();
const char * pData = (const char*)m_pRelocation->Create( pDataBuf, DataSize );
int GlobalVarBufferSize, StringBufferSize, TotalBufferSize;
READ_INT( pData, GlobalVarBufferSize );
READ_INT( pData, StringBufferSize );
READ_INT( pData, m_iCodeSize );
TotalBufferSize = GlobalVarBufferSize + StringBufferSize + m_iCodeSize;
m_pGlobalVars = m_pBuffer = new char[TotalBufferSize];
m_pStringBuffer = ((byte*)m_pGlobalVars) + GlobalVarBufferSize;
m_pCodeBuffer = ((byte*)m_pStringBuffer) + StringBufferSize;
memset( m_pGlobalVars, 0, GlobalVarBufferSize );
memcpy( m_pStringBuffer, pData, StringBufferSize );
pData += StringBufferSize;
memcpy( m_pCodeBuffer, pData, m_iCodeSize );
pData += m_iCodeSize;
long FuncMapSize;
READ_LONG( pData, FuncMapSize );
long type, offset;
for( int i = 0; i < FuncMapSize; i++ )
{
char szStr[256];
pData = ReadLine( pData, szStr, '\n' );
READ_LONG( pData, type );
READ_LONG( pData, offset );
offset += long( m_pCodeBuffer );
m_pFunctionMap->insert( FUNCMAP::value_type( szStr, FUNCINFO( type, (void*)offset ) ) );
}
memcpy( m_pSysVarOffset, pData, sizeof(int)*4 );
pData += sizeof(int)*4;
m_pRelocation->Relocate( m_pGlobalVars, m_pStringBuffer, m_pCodeBuffer );
m_bRelocated = true;
SetSysVars();
}
void CVirtualMachine::Create( CIntermediateCode & IMCode, CSymbolTable & SymbolTable )
{
Destroy();
m_iCodeSize = IMCode.Addressing( 0 );
int GlobalVarsSize = SymbolTable.GetGlobalVarSize();
int StringBufferSize = SymbolTable.GetStringBufferSize();
int BufSize = GlobalVarsSize + StringBufferSize + m_iCodeSize;
m_pGlobalVars = m_pBuffer = new char[ BufSize ];
memset( m_pGlobalVars, 0, GlobalVarsSize );
m_pStringBuffer = (char*)m_pBuffer + GlobalVarsSize;
SymbolTable.StringBuffer( m_pStringBuffer );
m_pCodeBuffer = (char*)m_pStringBuffer + StringBufferSize;
if( IMCode.ToMachineCode( m_pCodeBuffer, m_pRelocation ) != m_iCodeSize )
ScriptSystemError( "계산된 코드 사이즈와 실제 코드 사이즈가 다릅니다.( at CVirtualMachine::Create )" );
//리로케이션
m_pRelocation->Relocate( m_pGlobalVars, m_pStringBuffer, m_pCodeBuffer );
m_bRelocated = true;
//함수 테이블 만들기
typedef CIntermediateCode::FUNCTABLE FUNCTABLE;
FUNCTABLE & funcTable = IMCode.GetFuncTable();
byte * pCode = (byte*)m_pCodeBuffer;
for( FUNCTABLE::iterator i = funcTable.begin(); i != funcTable.end(); i++ )
{
const char * pFuncName = SymbolTable.GetNameOfFunc( i->first );
SFuncType FuncType = SymbolTable.GetTypeOfFunc( i->first );
void * pFunc = pCode + i->second;
m_pFunctionMap->insert( FUNCMAP::value_type( pFuncName, FUNCINFO( FuncType, pFunc ) ) );
}
m_pSysVarOffset[0] = SymbolTable.GetOffsetOfVar( SymbolTable.FindVar( SYSVAR_FLOATUNIT ) );
m_pSysVarOffset[1] = SymbolTable.GetOffsetOfVar( SymbolTable.FindVar( SYSVAR_TRUE ) );
m_pSysVarOffset[2] = SymbolTable.GetOffsetOfVar( SymbolTable.FindVar( SYSVAR_FALSE ) );
m_pSysVarOffset[3] = SymbolTable.GetOffsetOfVar( SymbolTable.FindVar( SYSVAR_CONVBUFFER ) );
SetSysVars();
}
void CVirtualMachine::SetSysVars()
{
int * pVarBuffer = (int*)m_pGlobalVars;
float floatunit = 1.0f;
pVarBuffer[ m_pSysVarOffset[0]/4 ] = *((int*)&floatunit); //0x3f800000
pVarBuffer[ m_pSysVarOffset[1]/4 ] = (int)strcpy( m_pSysVarBuffer, "true" );
pVarBuffer[ m_pSysVarOffset[2]/4 ] = (int)strcpy( m_pSysVarBuffer + 5, "false" );
pVarBuffer[ m_pSysVarOffset[3]/4 ] = int(m_pSysVarBuffer + 11);
}
void CVirtualMachine::Destroy()
{
delete [] m_pBuffer;
m_pBuffer = m_pGlobalVars = m_pStringBuffer = m_pCodeBuffer = NULL;
m_iCodeSize = 0;
m_pFunctionMap->clear();
m_pRelocation->Destroy();
for( ALLOCATED::iterator i = m_pAllocatedPtrs->begin(); i != m_pAllocatedPtrs->end(); i++ )
{
free( *i );
// CompilerMessage2( "[[[free : %d]]]", int(*i) );
}
m_pAllocatedPtrs->clear();
}
///////////////////////////////////////////////////////////////////////////////////
// 화일 포맷
// 1. 전역 변수 Relocation 개수(int)
// 2. 문자열 상수 Relocation 개수(int)
// 3. 전역 변수 Relocation Table
// 4. 문자열 상수 Relocation Table
// 5. 전역변수 버퍼 크기(int)
// 6. 문자열 버퍼 크기(int)
// 7. 코드 버퍼 크기(int)
// 8. 문자열 버퍼
// 9. 코드 버퍼
// 10. 함수맵 사이즈
// 11. < 문자열, 함수 타입(long), 오프셋(long) > * 사이즈
///////////////////////////////////////////////////////////////////////////////////
bool CVirtualMachine::Save( const char * szFilename )
{
if( m_pBuffer == NULL || m_pGlobalVars == NULL || m_pStringBuffer == NULL || m_pCodeBuffer == NULL )
return false;
ofstream file( szFilename, ios::binary | ios::out );
if( !file.is_open() )
ErrorMessage2( "지정한 화일로 저장을 할 수 없습니다.(At CVirtualMachine::Save) : %s", szFilename );
if( m_bRelocated )
{
m_pRelocation->Unlocate( m_pGlobalVars, m_pStringBuffer, m_pCodeBuffer );
m_bRelocated = false;
}
m_pRelocation->Save( file );
int GlobalVarBufferSize = ((byte*)m_pStringBuffer) - ((byte*)m_pGlobalVars);
int StringBufferSize = ((byte*)m_pCodeBuffer) - ((byte*)m_pStringBuffer);
file.write( (const char*)&GlobalVarBufferSize, sizeof(int) );
file.write( (const char*)&StringBufferSize, sizeof(int) );
file.write( (const char*)&m_iCodeSize, sizeof(int) );
file.write( (const char*)m_pStringBuffer, StringBufferSize );
file.write( (const char*)m_pCodeBuffer, m_iCodeSize );
int FuncMapSize = m_pFunctionMap->size();
file.write( (const char*)&FuncMapSize, sizeof(int) );
for( FUNCMAP::iterator it = m_pFunctionMap->begin(); it != m_pFunctionMap->end(); it++ )
{
file << it->first << '\n';
file.write( (const char*)&it->second.first.m_data, sizeof(long) );
long offset = long( it->second.second ) - long(m_pCodeBuffer);
file.write( (const char*)&offset, sizeof(long) );
}
file.write( (const char*)m_pSysVarOffset, sizeof(int)*4 );
file.close();
m_pRelocation->Relocate( m_pGlobalVars, m_pStringBuffer, m_pCodeBuffer );
char tempFilename[256];
sprintf( tempFilename, "%s+", szFilename );
int xor_key_valueT = xor_key_value^0x601f1ac4;
File_XOR( szFilename, tempFilename, xor_key_valueT );
remove( szFilename );
rename( tempFilename, szFilename );
return true;
}
void __declspec(safebuffers) CVirtualMachine::Execute()
{
void * pCodeBuffer = m_pCodeBuffer;
__asm call pCodeBuffer;
}
SFuncType MakeFuncType( eDataType returnType, va_list args )
{
SFuncType type;
type.SetReturnType( returnType );
for( int i = 0; i < 7; i++ )
{
eDataType dataType = va_arg( args, eDataType );
if( dataType == T_VOID )
break;
type.SetArgType( i, dataType );
}
return type;
}
void * GetFuncPtr( CVirtualMachine::FUNCMAP & funcMap, const char * szFuncName, SFuncType funcType )
{
typedef CVirtualMachine::FUNCMAP::iterator iterator;
pair< iterator, iterator > result = funcMap.equal_range( szFuncName );
while( result.first != result.second )
{
SFuncType ftype = result.first->second.first;
if( ftype == funcType )
{
return result.first->second.second;
}
result.first++;
}
return NULL;
}
union long_byte
{
long longValue;
char byteValue[4];
};
///////////////////////////////////////////////////////////////////////////////////
//Native함수를 스크립트에 바인드 하는 방식
//
//현재 방식 : 함수를 두 번 거치게 한다. ( 실행 속도는 좀 더 느리지만 더 간단하다. )
// 1-1. 선언만 있고, 정의가 없는 함수들만 함수 코드에서 처음 부분에 5바이트 이상의 공백(nop)를 만들어둔다.
// 1-2. RegisterFunction이 호출됐을 때 1-1에서 만들어둔 공백 부분에 call <native function>과 ret를 집어넣는다.
// 얼마나 느린가? 모든 함수에 nop가 2개 이상 추가되고, native call는 이중 호출이 된다.
// Empty Function을 제거한다.
//
//다른 대안 : 등록하려는 함수를 호출하는 모든 부분의 함수 주소를 바꾼다.( 실행 속도는 빠르나 복잡하다. )
// 2-1. 모든 함수 호출 부분을 Relocation Table처럼 call table에 저장해둔다.
// 2-2. RegisterFunction이 호출되었을 때 call table을 참조해서 call하고 있는 부분을 전부 바꾼다.
// call table은? map< string, pair< SFuncType, vector<int> > >
///////////////////////////////////////////////////////////////////////////////////
void CVirtualMachine::RegisterFunction( ANY_FUNCTION FuncPtr, eDataType returnType, const char * szFuncName, ... )
{
va_list args;
va_start( args, szFuncName );
RegisterFunction( FuncPtr, returnType, szFuncName, args );
}
void CVirtualMachine::RegisterFunction( ANY_FUNCTION FuncPtr, eDataType returnType, const char * szFuncName, va_list args )
{
SFuncType funcType = MakeFuncType( returnType, args );
byte * pFunc = (byte*)GetFuncPtr( *m_pFunctionMap, szFuncName, funcType );
if( pFunc == NULL )
ErrorMessage2( "함수 등록에 실패했습니다. 함수를 찾을 수 없었습니다. : %s", funcType.ToString( szFuncName ) );
if( pFunc[3] != 0x90 ) //nop가 아닐 때
ScriptSystemError( "RegisterFunction Error!!( at CVirtualMachine::RegisterFunction )" );
int nArg = funcType.GetArgCount();
pFunc += 3;
for( int i = 0; i < nArg; i++ )
{
*(pFunc++) = 0xff;
*(pFunc++) = 0x75;
*(pFunc++) = 0xff & (8+4*i);
}
*(pFunc++) = 0xe8;
long_byte FuncOffset;
FuncOffset.longValue = long(FuncPtr) - long(pFunc+4);
*(pFunc++) = FuncOffset.byteValue[0];
*(pFunc++) = FuncOffset.byteValue[1];
*(pFunc++) = FuncOffset.byteValue[2];
*(pFunc++) = FuncOffset.byteValue[3];
}
ScriptFunc CVirtualMachine::GetScriptFunction( eDataType returnType, const char * szFuncName, ... )
{
va_list args;
va_start( args, szFuncName );
return GetScriptFunction( returnType, szFuncName, args );
}
ScriptFunc CVirtualMachine::GetScriptFunction( eDataType returnType, const char * szFuncName, va_list args )
{
SFuncType funcType = MakeFuncType( returnType, args );
void * pFunc = GetFuncPtr( *m_pFunctionMap, szFuncName, funcType );
if( pFunc == NULL )
ErrorMessage2( "스크립트 함수를 얻어오는데 실패했습니다. 함수를 찾을 수 없었습니다. : %s", funcType.ToString( szFuncName ) );
return ScriptFunc( pFunc, funcType.m_data );
}
void * CVirtualMachine::CallScriptFunction( ScriptFunc Func )
{
__asm call Func.pFunc;
}
void * CVirtualMachine::CallScriptFunction( ScriptFunc Func, AnyData arg1 )
{
__asm
{
push arg1;
call Func.pFunc;
add esp, 4;
}
}
void * CVirtualMachine::CallScriptFunction( ScriptFunc Func, AnyData arg1, AnyData arg2 )
{
__asm
{
push arg2;
push arg1;
call Func.pFunc;
add esp, 8;
}
}
void * CVirtualMachine::CallScriptFunction( ScriptFunc Func, AnyData arg1, AnyData arg2, AnyData arg3 )
{
__asm
{
push arg3;
push arg2;
push arg1;
call Func.pFunc;
add esp, 12;
}
}
void * CVirtualMachine::CallScriptFunction( ScriptFunc Func, AnyData arg1, AnyData arg2, AnyData arg3, AnyData arg4 )
{
__asm
{
push arg4;
push arg3;
push arg2;
push arg1;
call Func.pFunc;
add esp, 16;
}
}
void * CVirtualMachine::CallScriptFunction( ScriptFunc Func, AnyData args[], int nArgs )
{
for( int i = nArgs - 1; i >= 0; i-- )
__asm push args[i];
__asm call Func.pFunc;
nArgs *= 4;
__asm add esp, nArgs;
}
/*
int CVirtualMachine::CallScriptFunction( ScriptFunc Func, va_list args )
{
int nArgs = SFuncType( Func.Type ).GetArgCount();
for( int i = 0; i < nArgs; i++ )
{
AnyData data = va_arg( args, AnyData );
__asm push data;
}
void * pFunc = Func.pFunc;
int n = nArgs * 4;
__asm
{
call pFunc;
add esp, n;
}
}
int CVirtualMachine::CallScriptFunction( ScriptFunc Func, ... )
{
va_list args;
va_start( args, Func );
return CallScriptFunction( Func, args );
}
*/

View File

@@ -0,0 +1,77 @@
#ifndef _VirtualMachine_H_
#define _VirtualMachine_H_
#include "STL.h"
#include "BaseDef.h"
class CIntermediateCode;
class CSymbolTable;
struct SFuncType;
class CRelocTable;
typedef char * va_list;
///////////////////////////////////////////////////////////////////////////////////
//
void RegisterAllocatedMemory( void * );
void UnregisterAllocatedMemory( void * );
///////////////////////////////////////////////////////////////////////////////////
//
class CVirtualMachine
{
public:
typedef pair<SFuncType, void*> FUNCINFO;
typedef multimap<string, FUNCINFO> FUNCMAP;
typedef set<void*> ALLOCATED;
protected:
void * m_pBuffer;
void * m_pGlobalVars; //전역 변수 버퍼
void * m_pStringBuffer; //m_pBuffer에서 Const버퍼가 시작되는 지점
void * m_pCodeBuffer; //m_pBuffer에서 Code버퍼가 시작되는 지점
int m_iCodeSize;
FUNCMAP * m_pFunctionMap; //커스텀 함수의 이름, 인자와 함수 오프셋 간의 매핑 테이블
CRelocTable * m_pRelocation; //Relocation Table
int m_pSysVarOffset[4]; //시스템 변수들에 대한 오프셋 값들.
char * m_pSysVarBuffer;
bool m_bRelocated;
ALLOCATED * m_pAllocatedPtrs;
protected:
void SetSysVars();
public:
CVirtualMachine();
~CVirtualMachine();
void Create( const char * szFilename );
void Create( const void * pDataBuf, unsigned DataSize ); //메모리 블럭으로부터 생성
void Create( CIntermediateCode &, CSymbolTable & );
void Destroy();
bool Save( const char * szFilename );
void Execute();
//인자의 끝에 T_VOID를 꼭 넣어주어야 함!!!
void RegisterFunction( ANY_FUNCTION, eDataType returnType, const char *, ... );
void RegisterFunction( ANY_FUNCTION, eDataType, const char *, va_list );
ScriptFunc GetScriptFunction( eDataType returnType, const char *, ... );
ScriptFunc GetScriptFunction( eDataType, const char *, va_list );
void * CallScriptFunction( ScriptFunc );
void * CallScriptFunction( ScriptFunc, AnyData );
void * CallScriptFunction( ScriptFunc, AnyData, AnyData );
void * CallScriptFunction( ScriptFunc, AnyData, AnyData, AnyData );
void * CallScriptFunction( ScriptFunc, AnyData, AnyData, AnyData, AnyData );
void * CallScriptFunction( ScriptFunc, AnyData args[], int nArgs );
// int CallScriptFunction( ScriptFunc, va_list );
// int CallScriptFunction( ScriptFunc, ... );
};
///////////////////////////////////////////////////////////////////////////////////
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,167 @@
// lex.h: lexer defines & declarations
#ifndef _LEX_H_
#define _LEX_H_
#include <stdio.h>
#ifdef _LEX_CPP_
int lineno = 1; // line number count; this will be used for error messages later
#else
// Import some variables
extern int lineno;
extern FILE *yyin; // the input stream
// Function prototype
int yylex ();
#endif
int yyparse ();
#ifndef YYLTYPE
typedef
struct yyltype
{
int timestamp;
int first_line;
int first_column;
int last_line;
int last_column;
char *text;
}
yyltype;
#define YYLTYPE yyltype
#endif
extern YYLTYPE yylloc;
/*
enum {
TOKEN_BEGIN = 258,
TOKEN_INCLUDE,
TOKEN_DEFINE,
TOKEN_INTEGERVALUE,
TOKEN_FLOATVALUE,
TOKEN_BOOLVALUE,
TOKEN_STRINGVALUE,
TOKEN_VOID,
TOKEN_INT,
TOKEN_FLOAT,
TOKEN_BOOL,
TOKEN_STRING,
TOKEN_FOR,
TOKEN_WHILE,
TOKEN_IF,
TOKEN_ELSE,
TOKEN_SWITCH,
TOKEN_CASE,
TOKEN_DEFAULT,
TOKEN_CONTINUE,
TOKEN_BREAK,
TOKEN_RETURN,
TOKEN_ID,
TOKEN_ADDITION,
TOKEN_SUBTRACTION,
TOKEN_MULTIPLICATION,
TOKEN_DIVISION,
TOKEN_REMINDER,
TOKEN_ASSIGNMENT,
TOKEN_COMPOUNDADDITION,
TOKEN_COMPOUNDSUBTRACTION,
TOKEN_COMPOUNDMULTIPLICATION,
TOKEN_COMPOUNDDIVISION,
TOKEN_COMPOUNDREMINDER,
TOKEN_INCREMENT,
TOKEN_DECREMENT,
TOKEN_NOT,
TOKEN_LESSTHAN,
TOKEN_LESSTHANOREQUAL,
TOKEN_MORETHAN,
TOKEN_MORETHANOREQUAL,
TOKEN_EQUALITY,
TOKEN_NOTEQUAL,
TOKEN_AND,
TOKEN_OR,
TOKEN_ENDSTATEMENT,
TOKEN_LEFTPARENTHESIS,
TOKEN_RIGHTPARENTHESIS,
TOKEN_LEFTBRACE,
TOKEN_RIGHTBRACE,
TOKEN_LEFTBRACKET,
TOKEN_RIGHTBRACKET,
TOKEN_COMMA,
TOKEN_COLON,
TOKEN_ERROR,
TOKEN_END
};
*/
#define TOKEN_ID 258
#define TOKEN_INTEGERVALUE 259
#define TOKEN_FLOATVALUE 260
#define TOKEN_BOOLVALUE 261
#define TOKEN_STRINGVALUE 262
#define TOKEN_INT 263
#define TOKEN_FLOAT 264
#define TOKEN_BOOL 265
#define TOKEN_STRING 266
#define TOKEN_VOID 267
#define TOKEN_FOR 268
#define TOKEN_WHILE 269
#define TOKEN_IF 270
#define TOKEN_ELSE 271
#define TOKEN_SWITCH 272
#define TOKEN_CASE 273
#define TOKEN_DEFAULT 274
#define TOKEN_CONTINUE 275
#define TOKEN_BREAK 276
#define TOKEN_RETURN 277
#define TOKEN_ENDSTATEMENT 278
#define TOKEN_LEFTPARENTHESIS 279
#define TOKEN_RIGHTPARENTHESIS 280
#define TOKEN_LEFTBRACE 281
#define TOKEN_RIGHTBRACE 282
#define TOKEN_LEFTBRACKET 283
#define TOKEN_RIGHTBRACKET 284
#define TOKEN_ERROR 285
#define TOKEN_COMMA 286
#define TOKEN_COLON 287
#define TOKEN_ASSIGNMENT 288
#define TOKEN_COMPOUNDADDITION 289
#define TOKEN_COMPOUNDSUBTRACTION 290
#define TOKEN_COMPOUNDMULTIPLICATION 291
#define TOKEN_COMPOUNDDIVISION 292
#define TOKEN_COMPOUNDREMINDER 293
#define TOKEN_AND 294
#define TOKEN_OR 295
#define TOKEN_LESSTHAN 296
#define TOKEN_LESSTHANOREQUAL 297
#define TOKEN_MORETHAN 298
#define TOKEN_MORETHANOREQUAL 299
#define TOKEN_EQUALITY 300
#define TOKEN_NOTEQUAL 301
#define TOKEN_ADDITION 302
#define TOKEN_SUBTRACTION 303
#define TOKEN_MULTIPLICATION 304
#define TOKEN_DIVISION 305
#define TOKEN_REMINDER 306
#define TOKEN_NOT 307
#define PREFIXINCREMENT 308
#define PREFIXDECREMENT 309
#define TOKEN_INCREMENT 310
#define TOKEN_DECREMENT 311
#define TOKEN_INCLUDE 312
#define TOKEN_DEFINE 313
#endif

View File

@@ -0,0 +1,80 @@
typedef union {
int symbolID; // entry from symbol table
int nodeID; // node in the syntax tree
char szIdentifier[4096];
char szConstant[4096];
} YYSTYPE;
#ifndef YYLTYPE
typedef
struct yyltype
{
int timestamp;
int first_line;
int first_column;
int last_line;
int last_column;
char *text;
}
yyltype;
#define YYLTYPE yyltype
#endif
#define TOKEN_ID 258
#define TOKEN_INTEGERVALUE 259
#define TOKEN_FLOATVALUE 260
#define TOKEN_BOOLVALUE 261
#define TOKEN_STRINGVALUE 262
#define TOKEN_INT 263
#define TOKEN_FLOAT 264
#define TOKEN_BOOL 265
#define TOKEN_STRING 266
#define TOKEN_VOID 267
#define TOKEN_FOR 268
#define TOKEN_WHILE 269
#define TOKEN_IF 270
#define TOKEN_ELSE 271
#define TOKEN_SWITCH 272
#define TOKEN_CASE 273
#define TOKEN_DEFAULT 274
#define TOKEN_CONTINUE 275
#define TOKEN_BREAK 276
#define TOKEN_RETURN 277
#define TOKEN_ENDSTATEMENT 278
#define TOKEN_LEFTPARENTHESIS 279
#define TOKEN_RIGHTPARENTHESIS 280
#define TOKEN_LEFTBRACE 281
#define TOKEN_RIGHTBRACE 282
#define TOKEN_LEFTBRACKET 283
#define TOKEN_RIGHTBRACKET 284
#define TOKEN_ERROR 285
#define TOKEN_COMMA 286
#define TOKEN_COLON 287
#define TOKEN_ASSIGNMENT 288
#define TOKEN_COMPOUNDADDITION 289
#define TOKEN_COMPOUNDSUBTRACTION 290
#define TOKEN_COMPOUNDMULTIPLICATION 291
#define TOKEN_COMPOUNDDIVISION 292
#define TOKEN_COMPOUNDREMINDER 293
#define TOKEN_AND 294
#define TOKEN_OR 295
#define TOKEN_LESSTHAN 296
#define TOKEN_LESSTHANOREQUAL 297
#define TOKEN_MORETHAN 298
#define TOKEN_MORETHANOREQUAL 299
#define TOKEN_EQUALITY 300
#define TOKEN_NOTEQUAL 301
#define TOKEN_ADDITION 302
#define TOKEN_SUBTRACTION 303
#define TOKEN_MULTIPLICATION 304
#define TOKEN_DIVISION 305
#define TOKEN_REMINDER 306
#define TOKEN_NOT 307
#define PREFIXINCREMENT 308
#define PREFIXDECREMENT 309
#define TOKEN_INCREMENT 310
#define TOKEN_DECREMENT 311
extern YYSTYPE yylval;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,186 @@
%{
/* ------------------------------------------------------------------
Initial code (copied verbatim to the output file)
------------------------------------------------------------------ */
#include <io.h> // isatty
#define _LEX_CPP_ // make sure our variables get created
#include "lex.h"
#include "lexsymb.h"
#include "SymbolTable.h"
#include <string>
#ifdef MSVC
#define isatty _isatty // for some reason isatty is called _isatty in VC..
#endif
extern "C" int yywrap (); // the yywrap function is declared by the caller
void EatCComment();
void EatCppComment();
extern CSymbolTable * g_pSymbolTable;
%}
/* ------------------------------------------------------------------
Some macros (standard regular expressions)
------------------------------------------------------------------ */
LETTER [a-zA-Z_]
DIGIT [0-9]
HEXLETTER [a-fA-F0-9]
HEXVALUE 0[xX]{HEXLETTER}+
INTEGERVALUE {DIGIT}+
FLOATVALUE {DIGIT}+[.]{DIGIT}+
BOOLVALUE true|false
STRINGVALUE \"[^\"]*\"
ID {LETTER}({LETTER}|{DIGIT})*
WSPACE [ \t]+
INCLUDE "#include"{WSPACE}*{STRINGVALUE}
DEFINEoptPARAM {WSPACE}*","{WSPACE}*{ID}
DEFINEopt {WSPACE}*"("{WSPACE}*{ID}{DEFINEoptPARAM}*{WSPACE}*")"
DEFINEtokenstring {WSPACE}+{ID}
DEFINE "#define"{WSPACE}+{ID}{DEFINEopt}?{DEFINEtokenstring}?
/* ------------------------------------------------------------------
The lexer rules
------------------------------------------------------------------ */
%%
{INCLUDE} { return TOKEN_INCLUDE; }
{DEFINE} { return TOKEN_DEFINE; }
{HEXVALUE} { strcpy( yylval.szConstant, yytext );
return TOKEN_INTEGERVALUE; }
{INTEGERVALUE} { strcpy( yylval.szConstant, yytext );
return TOKEN_INTEGERVALUE; }
{FLOATVALUE} { strcpy( yylval.szConstant, yytext );
return TOKEN_FLOATVALUE; }
{BOOLVALUE} { strcpy( yylval.szConstant, yytext );
return TOKEN_BOOLVALUE; }
{STRINGVALUE} { strcpy( yylval.szConstant, yytext + 1 );
yylval.szConstant[ strlen( yylval.szConstant ) - 1 ] = '\0';
return TOKEN_STRINGVALUE; }
"void" { return TOKEN_VOID; }
"int" { return TOKEN_INT; }
"float" { return TOKEN_FLOAT; }
"bool" { return TOKEN_BOOL; }
"string" { return TOKEN_STRING; }
"for" { return TOKEN_FOR; }
"while" { return TOKEN_WHILE; }
"break" { return TOKEN_BREAK; }
"if" { return TOKEN_IF; }
"else" { return TOKEN_ELSE; }
"switch" { return TOKEN_SWITCH; }
"case" { return TOKEN_CASE; }
"default" { return TOKEN_DEFAULT; }
"continue" { return TOKEN_CONTINUE; }
"return" { return TOKEN_RETURN; }
{ID} { strcpy( yylval.szIdentifier, yytext );
return TOKEN_ID; }
"+" { return TOKEN_ADDITION; }
"-" { return TOKEN_SUBTRACTION; }
"*" { return TOKEN_MULTIPLICATION; }
"/" { return TOKEN_DIVISION; }
"%" { return TOKEN_REMINDER; }
"=" { return TOKEN_ASSIGNMENT; }
"+=" { return TOKEN_COMPOUNDADDITION; }
"-=" { return TOKEN_COMPOUNDSUBTRACTION; }
"*=" { return TOKEN_COMPOUNDMULTIPLICATION; }
"/=" { return TOKEN_COMPOUNDDIVISION; }
"%=" { return TOKEN_COMPOUNDREMINDER; }
"!" { return TOKEN_NOT; }
"<" { return TOKEN_LESSTHAN; }
"<=" { return TOKEN_LESSTHANOREQUAL; }
">" { return TOKEN_MORETHAN; }
">=" { return TOKEN_MORETHANOREQUAL; }
"==" { return TOKEN_EQUALITY; }
"!=" { return TOKEN_NOTEQUAL; }
"++" { return TOKEN_INCREMENT; }
"--" { return TOKEN_DECREMENT; }
";" { return TOKEN_ENDSTATEMENT; }
"(" { return TOKEN_LEFTPARENTHESIS; }
")" { return TOKEN_RIGHTPARENTHESIS; }
"[" { return TOKEN_LEFTBRACE; }
"]" { return TOKEN_RIGHTBRACE; }
"{" { return TOKEN_LEFTBRACKET; }
"}" { return TOKEN_RIGHTBRACKET; }
"," { return TOKEN_COMMA; }
":" { return TOKEN_COLON; }
"||" { return TOKEN_OR; }
"&&" { return TOKEN_AND; }
"//" { EatCppComment(); }
"/*" { EatCComment(); }
\n { yylloc.first_line = ++lineno; }
{WSPACE} {} //무시해버림
. { return TOKEN_ERROR; } //그 외의 것들은 모두 에러!
%%
/* ------------------------------------------------------------------
Additional code (again copied verbatim to the output file)
------------------------------------------------------------------ */
void EatCppComment()
{
char c;
while( (c = yyinput()) != '\n' && c != 0 );
yylloc.first_line = ++lineno;
}
void EatCComment()
{
char c, c0 = ' ';
while( true )
{
c = yyinput();
if( c0 == '*' && c == '/' )
break;
if( c == '\n' )
yylloc.first_line = ++lineno;
c0 = c;
}
}

View File

@@ -0,0 +1,588 @@
%{
/* ------------------------------------------------------------------
Initial code (copied verbatim to the output file)
------------------------------------------------------------------ */
#include <malloc.h> // _alloca is used by the parser
#include <string> // strcpy
#include <assert.h>
#include <stdlib.h>
#include "lex.h" // the lexer
#include "SyntaxTree.h"
#include "SymbolTable.h"
#include "BaseDef.h"
#include "Message.h"
// Some yacc (bison) defines
#define YYDEBUG 1 // Generate debug code; needed for YYERROR_VERBOSE
#define YYERROR_VERBOSE // Give a more specific parse error message
// Forward references
void yyerror (char *msg);
extern CSyntaxTree * g_pSynTree;
extern CSymbolTable * g_pSymbolTable;
SFuncType GetFunctionType( int nodeID );
SFuncType GetFunctionType( int nodeID1, int nodeID2 );
SFuncType GetFuncCallType( int nodeID );
int CountArrayElements( int nodeID );
int GetConstantValue( int nodeID );
%}
/* ------------------------------------------------------------------
Yacc declarations
------------------------------------------------------------------ */
%union {
int symbolID; // entry from symbol table
int nodeID; // node in the syntax tree
char szIdentifier[4096];
char szConstant[4096];
}
%type <symbolID> variable new_variable
%type <nodeID> program statement_list statement compound_statement expression_statement selection_statement
%type <nodeID> cases case_one default iteration_statement for_expression for_init_statement optional_expression
%type <nodeID> jump_statement declaration decl_specifiers declarator_list init_declarator
%type <nodeID> array_initializer initializer_list argument_declaration_list argument_declaration function_definition
%type <nodeID> constant_expression expression assignment_expression logical_or_expression logical_and_expression
%type <nodeID> equality_expression relational_expression additive_expression multiplicative_expression unary_expression
%type <nodeID> postfix_expression primary_expression
%type <szIdentifier> function_name
%type <nodeID> function_decl_end
%token <szIdentifier> TOKEN_ID
%token <szConstant> TOKEN_INTEGERVALUE TOKEN_FLOATVALUE TOKEN_BOOLVALUE TOKEN_STRINGVALUE
%token TOKEN_INT TOKEN_FLOAT TOKEN_BOOL TOKEN_STRING TOKEN_VOID
%token TOKEN_FOR TOKEN_WHILE TOKEN_IF TOKEN_ELSE TOKEN_SWITCH TOKEN_CASE
%token TOKEN_DEFAULT TOKEN_CONTINUE TOKEN_BREAK TOKEN_RETURN
%token TOKEN_ENDSTATEMENT TOKEN_LEFTPARENTHESIS TOKEN_RIGHTPARENTHESIS
%token TOKEN_LEFTBRACE TOKEN_RIGHTBRACE TOKEN_LEFTBRACKET TOKEN_RIGHTBRACKET
%token TOKEN_ERROR
/*밑에 있을수록 연산자 우선순위가 높음.*/
%left TOKEN_COMMA TOKEN_COLON
%right TOKEN_ASSIGNMENT TOKEN_COMPOUNDADDITION TOKEN_COMPOUNDSUBTRACTION TOKEN_COMPOUNDMULTIPLICATION TOKEN_COMPOUNDDIVISION TOKEN_COMPOUNDREMINDER
%left TOKEN_AND TOKEN_OR
%left TOKEN_LESSTHAN TOKEN_LESSTHANOREQUAL TOKEN_MORETHAN TOKEN_MORETHANOREQUAL TOKEN_EQUALITY TOKEN_NOTEQUAL
%left TOKEN_ADDITION TOKEN_SUBTRACTION
%right TOKEN_MULTIPLICATION TOKEN_DIVISION TOKEN_REMINDER
%right TOKEN_NOT
%left PREFIXINCREMENT PREFIXDECREMENT /*Context-Dependent Precedence(가짜 심볼)*/
%left TOKEN_INCREMENT TOKEN_DECREMENT
%right TOKEN_LEFTPARENTHESIS
%left TOKEN_RIGHTPARENTHESIS
%expect 1 /* shift/reduce conflict: dangling ELSE */
/* declaration */
%%
/* ------------------------------------------------------------------
Yacc grammar rules
------------------------------------------------------------------ */
program
: statement_list { assert( g_pSynTree != NULL );
g_pSynTree->SetRoot( $1 ); }
;
statement_list
: statement_list statement { $$ = g_pSynTree->Insert( @1.first_line, TYPE_STATEMENT_LIST, $1, $2 ); }
| /* empty */ { $$ = g_pSynTree->Insert( @1.first_line, TYPE_EMPTY_STATEMENT ); }
;
statement
: compound_statement { $$ = $1; }
| expression_statement { $$ = $1; }
| selection_statement { $$ = $1; }
| iteration_statement { $$ = $1; }
| jump_statement { $$ = $1; }
| error TOKEN_ENDSTATEMENT { $$ = g_pSynTree->Insert( @1.first_line, TYPE_ERROR_STATEMENT ); }
| declaration { $$ = $1; }
| function_definition { $$ = $1; }
;
compound_statement
: TOKEN_LEFTBRACKET statement_list TOKEN_RIGHTBRACKET
{ $$ = $2; }
;
expression_statement
: TOKEN_ENDSTATEMENT { $$ = g_pSynTree->Insert( @1.first_line, TYPE_EMPTY_STATEMENT ); }
| expression TOKEN_ENDSTATEMENT { $$ = g_pSynTree->Insert( @1.first_line, TYPE_EXPRESSION, $1 ); }
;
selection_statement
: TOKEN_IF TOKEN_LEFTPARENTHESIS expression TOKEN_RIGHTPARENTHESIS statement
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_IF_STATEMENT, $3, $5 ); }
| TOKEN_IF TOKEN_LEFTPARENTHESIS expression TOKEN_RIGHTPARENTHESIS statement TOKEN_ELSE statement
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_IF_ELSE_STATEMENT, $3, $5, $7 ); }
| TOKEN_SWITCH TOKEN_LEFTPARENTHESIS expression TOKEN_RIGHTPARENTHESIS
TOKEN_LEFTBRACKET cases default TOKEN_RIGHTBRACKET
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_SWITCH_STATEMENT, $3, $6, $7 ); }
;
cases
: case_one cases { $$ = g_pSynTree->Insert( @1.first_line, TYPE_SWITCH_CASES, $1, $2 ); }
| case_one { $$ = $1; }
;
case_one
: TOKEN_CASE constant_expression TOKEN_COLON statement_list
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_CASE_ONE, $2, $4 ); }
;
default
: TOKEN_DEFAULT TOKEN_COLON statement_list { $$ = g_pSynTree->Insert( @1.first_line, TYPE_DEFAULT, $3 ); }
| { $$ = 0; }
;
iteration_statement
: TOKEN_FOR TOKEN_LEFTPARENTHESIS for_expression TOKEN_RIGHTPARENTHESIS statement
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_FOR_STATEMENT, $3, $5 ); }
| TOKEN_WHILE TOKEN_LEFTPARENTHESIS expression TOKEN_RIGHTPARENTHESIS statement
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_WHILE_STATEMENT, $3, $5 ); }
;
for_expression
: for_init_statement optional_expression TOKEN_ENDSTATEMENT optional_expression
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_FOR_EXPRESSION, $1, $2, $4 ); }
;
for_init_statement
: expression_statement { $$ = $1; }
| declaration { $$ = $1; }
;
optional_expression
: expression { $$ = $1; }
| { $$ = 0; }
;
jump_statement
: TOKEN_BREAK TOKEN_ENDSTATEMENT { $$ = g_pSynTree->Insert( @1.first_line, TYPE_BREAK_STATEMENT ); }
| TOKEN_CONTINUE TOKEN_ENDSTATEMENT { $$ = g_pSynTree->Insert( @1.first_line, TYPE_CONTINUE_STATEMENT ); }
| TOKEN_RETURN optional_expression TOKEN_ENDSTATEMENT
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_RETURN_STATEMENT, $2 ); }
;
declaration
: decl_specifiers declarator_list TOKEN_ENDSTATEMENT
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_DECLARATION, $1, $2 );
g_pSymbolTable->SetCurrentType( T_VOID ); }
;
decl_specifiers
: TOKEN_VOID { $$ = g_pSynTree->Insert( @1.first_line, TYPE_SPECIFIER_VOID ); }
| TOKEN_INT { g_pSymbolTable->SetCurrentType( T_INT );
$$ = g_pSynTree->Insert( @1.first_line, TYPE_SPECIFIER_INT ); }
| TOKEN_FLOAT { g_pSymbolTable->SetCurrentType( T_FLOAT );
$$ = g_pSynTree->Insert( @1.first_line, TYPE_SPECIFIER_FLOAT ); }
| TOKEN_BOOL { g_pSymbolTable->SetCurrentType( T_BOOL );
$$ = g_pSynTree->Insert( @1.first_line, TYPE_SPECIFIER_BOOL ); }
| TOKEN_STRING { g_pSymbolTable->SetCurrentType( T_STRING );
$$ = g_pSynTree->Insert( @1.first_line, TYPE_SPECIFIER_STRING ); }
;
variable
: TOKEN_ID {
$$ = g_pSymbolTable->FindVar( $1 );
if( $$ == 0 )
ErrorMessage2( @1.first_line, "undefined symbol : %s", $1 );
}
;
new_variable
: TOKEN_ID {
$$ = g_pSymbolTable->AddVar( $1 );
if( $$ == 0 )
ErrorMessage2( @1.first_line, "이미 정의 되어 있는 심볼입니다. : %s", $1 );
}
;
declarator_list
: init_declarator { $$ = $1; }
| declarator_list TOKEN_COMMA init_declarator { $$ = g_pSynTree->Insert( @1.first_line, TYPE_DECLARATOR_LIST, $1, $3 ); }
;
init_declarator
: new_variable TOKEN_ASSIGNMENT assignment_expression { $$ = g_pSynTree->Insert( @1.first_line, $1, TYPE_INIT_DECLARATION, $3 ); }
| new_variable { $$ = g_pSynTree->Insert( @1.first_line, $1, TYPE_NORMAL_DECLARATION ); }
| TOKEN_ID TOKEN_LEFTBRACE TOKEN_RIGHTBRACE array_initializer
{ $$ = g_pSynTree->Insert( @1.first_line, g_pSymbolTable->AddArrVar( $1, CountArrayElements( $4 ) ), TYPE_ARRAY_INITIALIZE, $4 ); }
| TOKEN_ID TOKEN_LEFTBRACE constant_expression TOKEN_RIGHTBRACE array_initializer
{ $$ = g_pSynTree->Insert( @1.first_line, g_pSymbolTable->AddArrVar( $1, GetConstantValue( $3 ) ), TYPE_ARRAY_INITIALIZE2, $3, $5 ); }
| TOKEN_ID TOKEN_LEFTBRACE constant_expression TOKEN_RIGHTBRACE
{ $$ = g_pSynTree->Insert( @1.first_line, g_pSymbolTable->AddArrVar( $1, GetConstantValue( $3 ) ), TYPE_ARRAY_DECLARATION, $3 ); }
;
array_initializer
: TOKEN_ASSIGNMENT TOKEN_LEFTBRACKET initializer_list TOKEN_RIGHTBRACKET
{ $$ = $3; }
;
initializer_list
: assignment_expression { $$ = $1; }
| assignment_expression TOKEN_COMMA initializer_list
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_INITIALIZER_LIST, $1, $3 ); }
;
argument_declaration_list
: argument_declaration { $$ = $1; }
| argument_declaration TOKEN_COMMA argument_declaration_list
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_ARGUMENT_DECLARATION_LIST, $1, $3 ); }
| { $$ = 0; }
;
argument_declaration
: decl_specifiers new_variable { $$ = g_pSynTree->Insert( @1.first_line, $2, TYPE_ARGUMENT_DECLARATION, $1 ); }
| decl_specifiers { $$ = $1; }
;
function_name
: TOKEN_ID { strcpy( $$, $1 );
g_pSymbolTable->BeginLocalNameSpace(); }
;
function_decl_end
: TOKEN_ENDSTATEMENT { g_pSymbolTable->EndLocalNameSpace( 0 ); }
;
function_def_start
: TOKEN_LEFTBRACKET { g_pSymbolTable->EndArgument(); }
;
function_definition
: decl_specifiers function_name TOKEN_LEFTPARENTHESIS argument_declaration_list TOKEN_RIGHTPARENTHESIS function_def_start statement_list TOKEN_RIGHTBRACKET
{
int symbID = g_pSymbolTable->AddFunc( true, $2, GetFunctionType( $1, $4 ) );
if( symbID == 0 )
ErrorMessage( @1.first_line, "같은 함수를 중복하여 정의했습니다." );
$$ = g_pSynTree->Insert( @1.first_line, symbID, TYPE_FUNCTION_DEFINITION, $4, $7 );
g_pSymbolTable->SetCurrentType( T_VOID );
g_pSymbolTable->EndLocalNameSpace( symbID );
}
| decl_specifiers function_name TOKEN_LEFTPARENTHESIS argument_declaration_list TOKEN_RIGHTPARENTHESIS function_decl_end
{ $$ = g_pSynTree->Insert( @1.first_line, g_pSymbolTable->AddFunc( false, $2, GetFunctionType( $1, $4 ) ), TYPE_FUNCTION_DECLARATION, $4 );
g_pSymbolTable->SetCurrentType( T_VOID ); }
;
constant_expression
: TOKEN_INTEGERVALUE { $$ = g_pSynTree->Insert( @1.first_line, g_pSymbolTable->AddConst( $1, T_INT ), TYPE_CONSTANT_EXPRESSION ); }
| TOKEN_FLOATVALUE { $$ = g_pSynTree->Insert( @1.first_line, g_pSymbolTable->AddConst( $1, T_FLOAT ), TYPE_CONSTANT_EXPRESSION ); }
| TOKEN_BOOLVALUE { $$ = g_pSynTree->Insert( @1.first_line, g_pSymbolTable->AddConst( $1, T_BOOL ), TYPE_CONSTANT_EXPRESSION ); }
| TOKEN_STRINGVALUE { $$ = g_pSynTree->Insert( @1.first_line, g_pSymbolTable->AddConst( $1, T_STRING ), TYPE_CONSTANT_EXPRESSION ); }
;
expression
: assignment_expression { $$ = $1; }
| assignment_expression TOKEN_COMMA expression { $$ = g_pSynTree->Insert( @1.first_line, TYPE_EXPRESSION_LIST, $1, $3 ); }
;
assignment_expression
: logical_or_expression { $$ = $1; }
| variable TOKEN_ASSIGNMENT assignment_expression
{ $$ = g_pSynTree->Insert( @1.first_line, $1, TYPE_ASSIGNMENT_EXPRESSION, $3 ); }
| variable TOKEN_COMPOUNDADDITION assignment_expression
{ $$ = g_pSynTree->Insert( @1.first_line, $1, TYPE_COMPOUND_ADDITION, $3 ); }
| variable TOKEN_COMPOUNDSUBTRACTION assignment_expression
{ $$ = g_pSynTree->Insert( @1.first_line, $1, TYPE_COMPOUND_SUBTRACTION, $3 ); }
| variable TOKEN_COMPOUNDMULTIPLICATION assignment_expression
{ $$ = g_pSynTree->Insert( @1.first_line, $1, TYPE_COMPOUND_MULTIPLICATION, $3 ); }
| variable TOKEN_COMPOUNDDIVISION assignment_expression
{ $$ = g_pSynTree->Insert( @1.first_line, $1, TYPE_COMPOUND_DIVISION, $3 ); }
| variable TOKEN_COMPOUNDREMINDER assignment_expression
{ $$ = g_pSynTree->Insert( @1.first_line, $1, TYPE_COMPOUND_REMINDER, $3 ); }
;
logical_or_expression
: logical_and_expression { $$ = $1; }
| logical_or_expression TOKEN_OR logical_and_expression
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_OR_EXPRESSION, $1, $3 ); }
;
logical_and_expression
: equality_expression { $$ = $1; }
| logical_and_expression TOKEN_AND equality_expression
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_AND_EXPRESSION, $1, $3 ); }
;
equality_expression
: relational_expression { $$ = $1; }
| equality_expression TOKEN_EQUALITY relational_expression
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_EQUALITY_EXPRESSION, $1, $3 ); }
| equality_expression TOKEN_NOTEQUAL relational_expression
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_NOTEQAUL_EXPRESSION, $1, $3 ); }
;
relational_expression
: additive_expression { $$ = $1; }
| relational_expression TOKEN_LESSTHAN additive_expression
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_LESSTHAN_EXPRESSION, $1, $3 ); }
| relational_expression TOKEN_MORETHAN additive_expression
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_MORETHAN_EXPRESSION, $1, $3 ); }
| relational_expression TOKEN_LESSTHANOREQUAL additive_expression
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_LESSTHANOREQUAL_EXPRESSION, $1, $3 ); }
| relational_expression TOKEN_MORETHANOREQUAL additive_expression
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_MORETHANOREQUAL_EXPRESSION, $1, $3 ); }
;
additive_expression
: multiplicative_expression { $$ = $1; }
| additive_expression TOKEN_ADDITION multiplicative_expression
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_ADDITION_EXPRESSION, $1, $3 ); }
| additive_expression TOKEN_SUBTRACTION multiplicative_expression
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_SUBTRACTION_EXPRESSION, $1, $3 ); }
;
multiplicative_expression
: unary_expression { $$ = $1; }
| multiplicative_expression TOKEN_MULTIPLICATION unary_expression
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_MULTIPLICATION_EXPRESSION, $1, $3 ); }
| multiplicative_expression TOKEN_DIVISION unary_expression
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_DIVISION_EXPRESSION, $1, $3 ); }
| multiplicative_expression TOKEN_REMINDER unary_expression
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_REMINDER_EXPRESSION, $1, $3 ); }
;
unary_expression
: postfix_expression { $$ = $1; }
| TOKEN_INCREMENT variable %prec PREFIXINCREMENT
{ $$ = g_pSynTree->Insert( @1.first_line, $2, TYPE_PREFIXINCREMENT ); }
| TOKEN_DECREMENT variable %prec PREFIXDECREMENT
{ $$ = g_pSynTree->Insert( @1.first_line, $2, TYPE_PREFIXDECREMENT ); }
| TOKEN_NOT unary_expression { $$ = g_pSynTree->Insert( @1.first_line, TYPE_NOT_EXPRESSION, $2 ); }
;
postfix_expression
: primary_expression { $$ = $1; }
| variable TOKEN_LEFTBRACE expression TOKEN_RIGHTBRACE
{ $$ = g_pSynTree->Insert( @1.first_line, $1, TYPE_ARRAY_INDEXING, $3 ); }
| TOKEN_ID TOKEN_LEFTPARENTHESIS expression TOKEN_RIGHTPARENTHESIS
{
int symbolID = g_pSymbolTable->FindFunc( $1, GetFuncCallType( $3 ) );
if( symbolID == 0 )
ErrorMessage2( "Error(line %d) : 지정한 함수를 찾을 수 없습니다.\n", @1.first_line );
$$ = g_pSynTree->Insert( @1.first_line, symbolID, TYPE_FUNCTION_CALL, $3 );
}
| TOKEN_ID TOKEN_LEFTPARENTHESIS TOKEN_RIGHTPARENTHESIS
{
int symbolID = g_pSymbolTable->FindFunc( $1, 0 );
if( symbolID == 0 )
ErrorMessage2( "Error(line %d) : 지정한 함수를 찾을 수 없습니다.\n", @1.first_line );
$$ = g_pSynTree->Insert( @1.first_line, symbolID, TYPE_FUNCTION_CALL );
}
| variable TOKEN_INCREMENT { $$ = g_pSynTree->Insert( @1.first_line, $1, TYPE_POSTFIXINCREMENT ); }
| variable TOKEN_DECREMENT { $$ = g_pSynTree->Insert( @1.first_line, $1, TYPE_POSTFIXDECREMENT ); }
;
primary_expression
: constant_expression { $$ = $1; }
| TOKEN_LEFTPARENTHESIS expression TOKEN_RIGHTPARENTHESIS
{ $$ = g_pSynTree->Insert( @1.first_line, TYPE_EXPRESSION, $2 ); }
| variable { $$ = g_pSynTree->Insert( @1.first_line, $1, TYPE_VARIABLE ); }
;
%%
/* ------------------------------------------------------------------
Additional code (again copied verbatim to the output file)
------------------------------------------------------------------ */
eDataType GetType( SNode * pNode )
{
switch( pNode->m_eType )
{
case TYPE_ARGUMENT_DECLARATION :
return GetType( pNode->m_ArrPtrChilds[0] );
case TYPE_SPECIFIER_INT :
return T_INT;
case TYPE_SPECIFIER_FLOAT :
return T_FLOAT;
case TYPE_SPECIFIER_BOOL :
return T_BOOL;
case TYPE_SPECIFIER_STRING :
return T_STRING;
}
return T_VOID;
}
SFuncType GetFunctionType( eDataType retType, int nodeID )
{
SNode * pNode = (SNode*)nodeID;
SFuncType FuncType;
int i = 0;
while( pNode != NULL )
{
if( pNode->m_eType == TYPE_ARGUMENT_DECLARATION_LIST )
{
FuncType.SetArgType( i++, GetType( pNode->m_ArrPtrChilds[0] ) );
pNode = pNode->m_ArrPtrChilds[1];
}
else //TYPE_ARGUMENT_DECLARATION나 TYPE_SPECIFIER_XXX 계열일 때
{
FuncType.SetArgType( i++, GetType( pNode ) );
break;
}
}
assert( i <= 8 );
FuncType.SetReturnType( retType );
return FuncType;
}
SFuncType GetFunctionType( int nodeID )
{
return GetFunctionType( g_pSymbolTable->GetCurrentType(), nodeID );
}
SFuncType GetFunctionType( int nodeID1, int nodeID2 )
{
SNode * pNode = (SNode*)nodeID1;
if( pNode != NULL )
{
return GetFunctionType( GetType( pNode ), nodeID2 );
}
return 0;
}
SFuncType GetFuncCallType( int nodeID )
{
SNode * pNode = (SNode*)nodeID;
SFuncType FuncType;
int i = 0;
while( pNode != NULL )
{
if( pNode->m_eType == TYPE_EXPRESSION_LIST )
{
FuncType.SetArgType( i++, pNode->m_ArrPtrChilds[0]->m_eReturnType );
pNode = pNode->m_ArrPtrChilds[1];
}
else
{
FuncType.SetArgType( i++, pNode->m_eReturnType );
break;
}
}
assert( i <= 8 );
FuncType.SetReturnType( T_VOID );
return FuncType;
}
int CountArrayElements( int nodeID )
{
if( nodeID == 0 )
return 0;
SNode * pNode = (SNode*)nodeID;
//initializer_list
int i = 0;
while( pNode != NULL )
{
if( pNode->m_eType == TYPE_INITIALIZER_LIST )
{
i++;
pNode = pNode->m_ArrPtrChilds[1];
}
else
{
i++;
break;
}
}
return i;
}
int GetConstantValue( int nodeID )
{
//constant expression
SNode * pNode = (SNode*)nodeID;
if( pNode->m_eType == TYPE_CONSTANT_EXPRESSION )
{
if( g_pSymbolTable->GetTypeOfConst( pNode->m_SymbolID ) == T_INT )
{
const char * pStr = g_pSymbolTable->GetNameOfConst( pNode->m_SymbolID );
return strtol( pStr, NULL, 0 );
}
}
return 0;
}