simple B compiler
This commit is contained in:
@@ -5,7 +5,6 @@ abstract_class CBLexerWord: public IBLexerWord
|
|||||||
public:
|
public:
|
||||||
virtual int GetType() override;
|
virtual int GetType() override;
|
||||||
|
|
||||||
CUtlVector<ILexerWord*> m_children;
|
|
||||||
EBWordType m_eType;
|
EBWordType m_eType;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -14,18 +13,6 @@ int CBLexerWord::GetType()
|
|||||||
return m_eType;
|
return m_eType;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t CBLexerWord::GetNumChildren()
|
|
||||||
{
|
|
||||||
return m_children.GetSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
ILexerWord **CBLexerWord::GetChildren()
|
|
||||||
{
|
|
||||||
return m_children.GetData();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CBLexer: public ILexer
|
class CBLexer: public ILexer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -3,6 +3,127 @@
|
|||||||
#include "tier2/ifilesystem.h"
|
#include "tier2/ifilesystem.h"
|
||||||
|
|
||||||
|
|
||||||
|
class CTokenParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const char *PeekToken();
|
||||||
|
bool IsToken( const char *szString );
|
||||||
|
const char *PeekStringLiteral();
|
||||||
|
bool Continue();
|
||||||
|
|
||||||
|
Token_t *m_pTokens;
|
||||||
|
Token_t *m_pTokensEnd;
|
||||||
|
Token_t *m_pCurrentToken;
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *CTokenParser::PeekToken()
|
||||||
|
{
|
||||||
|
if ( m_pCurrentToken->m_bIsQuoted )
|
||||||
|
return NULL;
|
||||||
|
return m_pCurrentToken->m_szValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTokenParser::IsToken( const char *szString )
|
||||||
|
{
|
||||||
|
if ( !V_strcmp(szString, m_pCurrentToken->m_szValue))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *CTokenParser::PeekStringLiteral()
|
||||||
|
{
|
||||||
|
if ( !m_pCurrentToken->m_bIsQuoted )
|
||||||
|
return NULL;
|
||||||
|
return m_pCurrentToken->m_szValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTokenParser::Continue()
|
||||||
|
{
|
||||||
|
m_pCurrentToken++;
|
||||||
|
if ( m_pCurrentToken == m_pTokensEnd )
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompileErrorExpectedToken( Token_t *pToken, const char *szToken )
|
||||||
|
{
|
||||||
|
if (pToken->m_bIsQuoted)
|
||||||
|
V_printf("%d:%d: expected %s but got string literal\n", pToken->m_iLine, pToken->m_iCharacter, szToken);
|
||||||
|
else
|
||||||
|
V_printf("%d:%d: expected %s but got %s\n", pToken->m_iLine, pToken->m_iCharacter, szToken, pToken->m_szValue.GetString());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BExpression_t
|
||||||
|
{
|
||||||
|
enum BExpressionType
|
||||||
|
{
|
||||||
|
BEXPRESSION_TYPE_NEW,
|
||||||
|
BEXPRESSION_TYPE_ADD,
|
||||||
|
BEXPRESSION_TYPE_SUBTRACT,
|
||||||
|
} m_eType;
|
||||||
|
CUtlVector<BExpression_t> m_children;
|
||||||
|
};
|
||||||
|
|
||||||
|
BExpression_t ParseVar( CTokenParser *pParser )
|
||||||
|
{
|
||||||
|
const char *szToken = pParser->PeekToken();
|
||||||
|
|
||||||
|
return szToken;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ParseRValue( CTokenParser *pParser )
|
||||||
|
{
|
||||||
|
if (pParser->PeekToken() == "(")
|
||||||
|
{
|
||||||
|
pParser->PeekToken();
|
||||||
|
ParseRValue(pParser)
|
||||||
|
}
|
||||||
|
BVar_t var = ParseVar( pParser );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseStatement( CTokenParser *pParser )
|
||||||
|
{
|
||||||
|
if (pParser->IsToken("return"))
|
||||||
|
{
|
||||||
|
pParser->Continue();
|
||||||
|
ParseRValue( pParser );
|
||||||
|
if (!pParser->IsToken(";"))
|
||||||
|
CompileErrorExpectedToken(pParser->m_pCurrentToken, ";");
|
||||||
|
V_printf(" ret\n");
|
||||||
|
pParser->Continue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseGlobal( CTokenParser *pParser )
|
||||||
|
{
|
||||||
|
|
||||||
|
const char *szObjectName = pParser->PeekToken();
|
||||||
|
pParser->Continue();
|
||||||
|
V_printf("%s:\n", szObjectName);
|
||||||
|
|
||||||
|
if (pParser->IsToken("("))
|
||||||
|
{
|
||||||
|
pParser->Continue();
|
||||||
|
if (!pParser->IsToken(")"))
|
||||||
|
CompileErrorExpectedToken(pParser->m_pCurrentToken, ")");
|
||||||
|
pParser->Continue();
|
||||||
|
if (!pParser->IsToken("{"))
|
||||||
|
CompileErrorExpectedToken(pParser->m_pCurrentToken, "{");
|
||||||
|
pParser->Continue();
|
||||||
|
while (!pParser->IsToken("}"))
|
||||||
|
{
|
||||||
|
ParseStatement( pParser );
|
||||||
|
}
|
||||||
|
pParser->Continue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CompileErrorExpectedToken(pParser->m_pCurrentToken, "(");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int main( int argc, char **argv )
|
int main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
CommandLine()->CreateCommandLine(argc, argv);
|
CommandLine()->CreateCommandLine(argc, argv);
|
||||||
@@ -15,5 +136,13 @@ int main( int argc, char **argv )
|
|||||||
filesystem->Close(pFile);
|
filesystem->Close(pFile);
|
||||||
|
|
||||||
|
|
||||||
|
CUtlVector<Token_t> tokens = Tokenize(szFileContents);
|
||||||
|
CTokenParser parser;
|
||||||
|
parser.m_pTokens = tokens.GetData();
|
||||||
|
parser.m_pTokensEnd = tokens.GetData()+tokens.GetSize();
|
||||||
|
parser.m_pCurrentToken = tokens.GetData()-1;
|
||||||
|
parser.Continue();
|
||||||
|
ParseGlobal(&parser);
|
||||||
|
|
||||||
V_free((void*)szFileContents);
|
V_free((void*)szFileContents);
|
||||||
}
|
}
|
||||||
|
|||||||
0
asmrigs/cbld/gen.cpp
Normal file
0
asmrigs/cbld/gen.cpp
Normal file
0
asmrigs/cbld/gen.h
Normal file
0
asmrigs/cbld/gen.h
Normal file
@@ -1,4 +1,4 @@
|
|||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
return 1 + 2 * 3
|
return 1 + 2 * 3;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,17 @@ struct Token_t
|
|||||||
uint32_t m_iCharacter;
|
uint32_t m_iCharacter;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef bool( *fnIsAlphabetSymbol )( char c );
|
typedef bool( *IsAlphabetSymbolFn )( char c );
|
||||||
|
|
||||||
|
struct TokenizeProperties_t
|
||||||
|
{
|
||||||
|
IsAlphabetSymbolFn m_pfnIsAlphabetSymbol;
|
||||||
|
IsAlphabetSymbolFn m_pfnIsFirstAlphabetSymbol;
|
||||||
|
bool m_bAllowSlashToContinueString;
|
||||||
|
};
|
||||||
|
|
||||||
CUtlVector<Token_t> Tokenize( const char *szString );
|
CUtlVector<Token_t> Tokenize( const char *szString );
|
||||||
CUtlVector<Token_t> Tokenize( const char *szString, fnIsAlphabetSymbol pfnIsAlphabetSymbol );
|
CUtlVector<Token_t> Tokenize( const char *szString, IsAlphabetSymbolFn pfnIsAlphabetSymbol );
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,13 +18,14 @@ CUtlVector<Token_t> Tokenize( const char *psz )
|
|||||||
return Tokenize(psz, IsWordSymbol);
|
return Tokenize(psz, IsWordSymbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
CUtlVector<Token_t> Tokenize( const char *psz, fnIsAlphabetSymbol fnIsAlphabetSymbol )
|
CUtlVector<Token_t> Tokenize( const char *psz, IsAlphabetSymbolFn fnIsAlphabetSymbol )
|
||||||
{
|
{
|
||||||
CUtlVector<Token_t> tokens = {};
|
CUtlVector<Token_t> tokens = {};
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
char c;
|
char c;
|
||||||
uint32_t nCurrentLine = 0;
|
uint32_t nCurrentLine = 1;
|
||||||
uint32_t nCurrentCharacter = 0;
|
uint32_t nCurrentCharacter = 0;
|
||||||
|
uint32_t nStartingCharacter = 0;
|
||||||
bool bIsQuoted = false;
|
bool bIsQuoted = false;
|
||||||
bool bIsSlash = false;
|
bool bIsSlash = false;
|
||||||
CUtlString szStringValue;
|
CUtlString szStringValue;
|
||||||
@@ -32,14 +33,17 @@ CUtlVector<Token_t> Tokenize( const char *psz, fnIsAlphabetSymbol fnIsAlphabetSy
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
c = psz[i];
|
c = psz[i];
|
||||||
i++;
|
|
||||||
if (c == '\0')
|
if (c == '\0')
|
||||||
break;
|
break;
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
{
|
{
|
||||||
nCurrentCharacter = 0;
|
nCurrentCharacter = 0;
|
||||||
|
nStartingCharacter = 0;
|
||||||
nCurrentLine++;
|
nCurrentLine++;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
nCurrentCharacter++;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
|
||||||
if (bIsQuoted)
|
if (bIsQuoted)
|
||||||
@@ -91,7 +95,7 @@ CUtlVector<Token_t> Tokenize( const char *psz, fnIsAlphabetSymbol fnIsAlphabetSy
|
|||||||
bIsQuoted = false;
|
bIsQuoted = false;
|
||||||
if (szStringValue == 0)
|
if (szStringValue == 0)
|
||||||
continue;
|
continue;
|
||||||
tokens.AppendTail({szStringValue, true, nCurrentLine});
|
tokens.AppendTail({szStringValue, true, nCurrentLine, nStartingCharacter});
|
||||||
szStringValue = 0;
|
szStringValue = 0;
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
@@ -113,10 +117,12 @@ CUtlVector<Token_t> Tokenize( const char *psz, fnIsAlphabetSymbol fnIsAlphabetSy
|
|||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if (szStringValue != 0)
|
if (szStringValue != 0)
|
||||||
tokens.AppendTail({szStringValue, false, nCurrentLine});
|
tokens.AppendTail({szStringValue, false, nCurrentLine, nStartingCharacter});
|
||||||
|
|
||||||
|
nStartingCharacter = nCurrentCharacter;
|
||||||
szStringValue = 0;
|
szStringValue = 0;
|
||||||
if (V_isgraph(c) && c != '"')
|
if (V_isgraph(c) && c != '"')
|
||||||
tokens.AppendTail({CUtlString("%c", c), false, nCurrentLine});
|
tokens.AppendTail({CUtlString("%c", c), false, nCurrentLine, nStartingCharacter});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user