holy shit thats a lot of changed to asmrigs
This commit is contained in:
@@ -1,48 +1,35 @@
|
||||
#include "brb.h"
|
||||
#include "asmrigs/tokenparser.h"
|
||||
#include "tier0/commandline.h"
|
||||
#include "tier2/ifilesystem.h"
|
||||
|
||||
IBGenerator *g_pGenerator;
|
||||
|
||||
class CTokenParser
|
||||
class CBGenerator: public IBGenerator
|
||||
{
|
||||
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;
|
||||
virtual void AddExternSymbol( const char *szName ) override;
|
||||
virtual void DefineFunction( const char *szName ) override;
|
||||
virtual CUtlString GetAssembly() override;
|
||||
CUtlVector<CUtlString> m_externalSymbols;
|
||||
CUtlString m_szAssembly;
|
||||
};
|
||||
EXPOSE_INTERFACE(CBGenerator, IBGenerator, B_GENERATOR_INTERFACE_VERSION);
|
||||
|
||||
const char *CTokenParser::PeekToken()
|
||||
void CBGenerator::AddExternSymbol( const char *szName )
|
||||
{
|
||||
if ( m_pCurrentToken->m_bIsQuoted )
|
||||
return NULL;
|
||||
return m_pCurrentToken->m_szValue;
|
||||
m_externalSymbols.AppendTail(szName);
|
||||
}
|
||||
|
||||
bool CTokenParser::IsToken( const char *szString )
|
||||
void CBGenerator::DefineFunction( const char *szName )
|
||||
{
|
||||
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;
|
||||
m_szAssembly.AppendTail(CUtlString("public %s\n", szName));
|
||||
m_szAssembly.AppendTail(CUtlString("%s:\n", szName));
|
||||
}
|
||||
|
||||
bool CTokenParser::Continue()
|
||||
CUtlString CBGenerator::GetAssembly()
|
||||
{
|
||||
m_pCurrentToken++;
|
||||
if ( m_pCurrentToken == m_pTokensEnd )
|
||||
return false;
|
||||
return true;
|
||||
return m_szAssembly;
|
||||
}
|
||||
|
||||
void CompileErrorExpectedToken( Token_t *pToken, const char *szToken )
|
||||
@@ -54,32 +41,235 @@ void CompileErrorExpectedToken( Token_t *pToken, const char *szToken )
|
||||
exit(1);
|
||||
}
|
||||
|
||||
struct BExpression_t
|
||||
void CompileErrorUnexpectedToken( Token_t *pToken )
|
||||
{
|
||||
enum BExpressionType
|
||||
{
|
||||
BEXPRESSION_TYPE_NEW,
|
||||
BEXPRESSION_TYPE_ADD,
|
||||
BEXPRESSION_TYPE_SUBTRACT,
|
||||
} m_eType;
|
||||
CUtlVector<BExpression_t> m_children;
|
||||
if (pToken->m_bIsQuoted)
|
||||
V_printf("%d:%d: unexpected string literal\n", pToken->m_iLine, pToken->m_iCharacter );
|
||||
else
|
||||
V_printf("%d:%d: unexpected %s\n", pToken->m_iLine, pToken->m_iCharacter, pToken->m_szValue.GetString());
|
||||
exit(1);
|
||||
}
|
||||
void CompileErrorGotRValue( Token_t *pToken )
|
||||
{
|
||||
V_printf("%d:%d: got rvalue when expected lvalue\n", pToken->m_iLine, pToken->m_iCharacter );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
enum EBValueType
|
||||
{
|
||||
EBVALUE_TYPE_UNKNOWN,
|
||||
EBVALUE_TYPE_INT_LITERAL,
|
||||
EBVALUE_TYPE_VARIABLE,
|
||||
};
|
||||
|
||||
BExpression_t ParseVar( CTokenParser *pParser )
|
||||
struct BValue_t
|
||||
{
|
||||
enum EBValueType m_eType;
|
||||
int m_iLiteral;
|
||||
const char *m_szVarName;
|
||||
};
|
||||
|
||||
enum EBValueNodeOp
|
||||
{
|
||||
EBVALUE_OP_NOTHING,
|
||||
EBVALUE_OP_VALUE,
|
||||
EBVALUE_OP_READ_PTR,
|
||||
EBVALUE_OP_GET_PTR,
|
||||
EBVALUE_OP_ADD,
|
||||
EBVALUE_OP_SUB,
|
||||
EBVALUE_OP_MUL,
|
||||
EBVALUE_OP_DIV,
|
||||
EBVALUE_OP_PARENTHESIS,
|
||||
EBVALUE_OP_NEG,
|
||||
EBVALUE_OP_NOT,
|
||||
};
|
||||
|
||||
struct Node_t
|
||||
{
|
||||
BValue_t m_value;
|
||||
struct Node_t *m_pLeftValue;
|
||||
struct Node_t *m_pRightValue;
|
||||
EBValueNodeOp m_eOp;
|
||||
};
|
||||
|
||||
struct ScopeVariable_t
|
||||
{
|
||||
const char *szName;
|
||||
};
|
||||
|
||||
|
||||
BValue_t ParseVar( CTokenParser *pParser )
|
||||
{
|
||||
const char *szToken = pParser->PeekToken();
|
||||
|
||||
return szToken;
|
||||
if (V_isdigit(szToken[0]))
|
||||
{
|
||||
pParser->Continue();
|
||||
return {EBVALUE_TYPE_INT_LITERAL, atoi(szToken)};
|
||||
}
|
||||
pParser->Continue();
|
||||
return {EBVALUE_TYPE_VARIABLE, 0, szToken};
|
||||
};
|
||||
Node_t *ParseExpr( CTokenParser *pParser );
|
||||
void ParseRValue( CTokenParser *pParser );
|
||||
Node_t *ParsePrimary( CTokenParser *pParser )
|
||||
{
|
||||
Node_t *pNode;
|
||||
if (pParser->IsToken("("))
|
||||
{
|
||||
pParser->Continue();
|
||||
pNode = ParseExpr(pParser);
|
||||
if (!pParser->IsToken(")"))
|
||||
CompileErrorExpectedToken(pParser->m_pCurrentToken, ")");
|
||||
pParser->Continue();
|
||||
goto lvalue;
|
||||
}
|
||||
pNode = new Node_t();
|
||||
pNode->m_eOp = EBVALUE_OP_VALUE;
|
||||
pNode->m_value = ParseVar( pParser );
|
||||
lvalue:
|
||||
if (pParser->IsToken("="))
|
||||
{
|
||||
if (pNode->m_eOp == EBVALUE_OP_VALUE)
|
||||
{
|
||||
if ( pNode->m_value.m_eType == EBVALUE_TYPE_VARIABLE )
|
||||
goto confirmedlvalue;
|
||||
};
|
||||
CompileErrorGotRValue(pParser->m_pCurrentToken);
|
||||
confirmedlvalue:
|
||||
pParser->Continue();
|
||||
ParseRValue(pParser);
|
||||
};
|
||||
|
||||
return pNode;
|
||||
}
|
||||
Node_t *ParseUnary( CTokenParser *pParser )
|
||||
{
|
||||
return ParsePrimary(pParser);
|
||||
}
|
||||
Node_t *ParseTerm( CTokenParser *pParser )
|
||||
{
|
||||
Node_t *pNode;
|
||||
Node_t *pNewNode;
|
||||
|
||||
EBValueNodeOp eOp = EBVALUE_OP_NOTHING;
|
||||
pNode = new Node_t();
|
||||
for (;;)
|
||||
{
|
||||
if (pParser->IsToken("*"))
|
||||
{
|
||||
pParser->Continue();
|
||||
eOp = EBVALUE_OP_MUL;
|
||||
}
|
||||
else if (pParser->IsToken("/"))
|
||||
{
|
||||
pParser->Continue();
|
||||
eOp = EBVALUE_OP_DIV;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNode->m_eOp = eOp;
|
||||
if (pNode->m_pLeftValue == NULL)
|
||||
pNode->m_pLeftValue = ParseUnary(pParser);
|
||||
else
|
||||
{
|
||||
if (eOp == EBVALUE_OP_NOTHING)
|
||||
break;
|
||||
eOp = EBVALUE_OP_NOTHING;
|
||||
pNode->m_pRightValue = ParseUnary(pParser);
|
||||
pNewNode = new Node_t();
|
||||
pNewNode->m_pLeftValue = pNode;
|
||||
pNode = pNewNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pNode->m_pRightValue == NULL)
|
||||
{
|
||||
pNewNode = pNode->m_pLeftValue;
|
||||
delete pNode;
|
||||
return pNewNode;
|
||||
}
|
||||
return pNode;
|
||||
}
|
||||
|
||||
Node_t *ParseExpr( CTokenParser *pParser )
|
||||
{
|
||||
Node_t *pNode;
|
||||
Node_t *pNewNode;
|
||||
|
||||
EBValueNodeOp eOp = EBVALUE_OP_NOTHING;
|
||||
pNode = new Node_t();
|
||||
for (;;)
|
||||
{
|
||||
if (pParser->IsToken("+"))
|
||||
{
|
||||
pParser->Continue();
|
||||
eOp = EBVALUE_OP_ADD;
|
||||
}
|
||||
else if (pParser->IsToken("-"))
|
||||
{
|
||||
pParser->Continue();
|
||||
eOp = EBVALUE_OP_SUB;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNode->m_eOp = eOp;
|
||||
if (pNode->m_pLeftValue == NULL)
|
||||
pNode->m_pLeftValue = ParseTerm(pParser);
|
||||
else
|
||||
{
|
||||
if (eOp == EBVALUE_OP_NOTHING)
|
||||
break;
|
||||
eOp = EBVALUE_OP_NOTHING;
|
||||
pNode->m_pRightValue = ParseTerm(pParser);
|
||||
pNewNode = new Node_t();
|
||||
pNewNode->m_pLeftValue = pNode;
|
||||
pNode = pNewNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pNode->m_pRightValue == NULL)
|
||||
{
|
||||
pNewNode = pNode->m_pLeftValue;
|
||||
delete pNode;
|
||||
return pNewNode;
|
||||
}
|
||||
return pNode;
|
||||
}
|
||||
|
||||
void PrintExpr( Node_t *pNode )
|
||||
{
|
||||
if ( pNode->m_eOp == EBVALUE_OP_VALUE )
|
||||
{
|
||||
switch ( pNode->m_value.m_eType )
|
||||
{
|
||||
case EBVALUE_TYPE_INT_LITERAL:
|
||||
V_printf("%i\n", pNode->m_value.m_iLiteral);
|
||||
break;
|
||||
case EBVALUE_TYPE_VARIABLE:
|
||||
V_printf("%s\n", pNode->m_value.m_szVarName);
|
||||
break;
|
||||
|
||||
}
|
||||
} else {
|
||||
if (pNode->m_pLeftValue)
|
||||
PrintExpr(pNode->m_pLeftValue);
|
||||
if (pNode->m_pRightValue)
|
||||
PrintExpr(pNode->m_pRightValue);
|
||||
if (pNode->m_eOp == EBVALUE_OP_ADD)
|
||||
V_printf("+\n");
|
||||
if (pNode->m_eOp == EBVALUE_OP_SUB)
|
||||
V_printf("-\n");
|
||||
if (pNode->m_eOp == EBVALUE_OP_MUL)
|
||||
V_printf("*\n");
|
||||
if (pNode->m_eOp == EBVALUE_OP_DIV)
|
||||
V_printf("/\n");
|
||||
}
|
||||
}
|
||||
|
||||
void ParseRValue( CTokenParser *pParser )
|
||||
{
|
||||
if (pParser->PeekToken() == "(")
|
||||
{
|
||||
pParser->PeekToken();
|
||||
ParseRValue(pParser)
|
||||
}
|
||||
BVar_t var = ParseVar( pParser );
|
||||
PrintExpr(ParseExpr( pParser ));
|
||||
}
|
||||
|
||||
void ParseStatement( CTokenParser *pParser )
|
||||
@@ -93,34 +283,89 @@ void ParseStatement( CTokenParser *pParser )
|
||||
V_printf(" ret\n");
|
||||
pParser->Continue();
|
||||
}
|
||||
else if (pParser->IsToken("extrn"))
|
||||
{
|
||||
pParser->Continue();
|
||||
for (;;)
|
||||
{
|
||||
const char *szName = pParser->PeekToken();
|
||||
pParser->Continue();
|
||||
if (pParser->IsToken(","))
|
||||
{
|
||||
pParser->Continue();
|
||||
continue;
|
||||
}
|
||||
if (pParser->IsToken(";"))
|
||||
{
|
||||
pParser->Continue();
|
||||
break;
|
||||
}
|
||||
CompileErrorUnexpectedToken(pParser->m_pCurrentToken);
|
||||
};
|
||||
}
|
||||
else if (pParser->IsToken("auto"))
|
||||
{
|
||||
pParser->Continue();
|
||||
for (;;)
|
||||
{
|
||||
const char *szName = pParser->PeekToken();
|
||||
pParser->Continue();
|
||||
if (pParser->IsToken(","))
|
||||
{
|
||||
pParser->Continue();
|
||||
continue;
|
||||
}
|
||||
if (pParser->IsToken(";"))
|
||||
{
|
||||
pParser->Continue();
|
||||
break;
|
||||
}
|
||||
CompileErrorUnexpectedToken(pParser->m_pCurrentToken);
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseRValue(pParser);
|
||||
if (!pParser->IsToken(";"))
|
||||
CompileErrorExpectedToken(pParser->m_pCurrentToken, ";");
|
||||
pParser->Continue();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void ParseGlobal( CTokenParser *pParser )
|
||||
{
|
||||
|
||||
const char *szObjectName = pParser->PeekToken();
|
||||
pParser->Continue();
|
||||
V_printf("%s:\n", szObjectName);
|
||||
for (;;)
|
||||
{
|
||||
if (pParser->IsEOF())
|
||||
break;
|
||||
const char *szObjectName = pParser->PeekToken();
|
||||
pParser->Continue();
|
||||
|
||||
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("}"))
|
||||
if (pParser->IsToken("("))
|
||||
{
|
||||
ParseStatement( pParser );
|
||||
pParser->Continue();
|
||||
if (!pParser->IsToken(")"))
|
||||
CompileErrorExpectedToken(pParser->m_pCurrentToken, ")");
|
||||
pParser->Continue();
|
||||
g_pGenerator->DefineFunction(szObjectName);
|
||||
|
||||
if (!pParser->IsToken("{"))
|
||||
CompileErrorExpectedToken(pParser->m_pCurrentToken, "{");
|
||||
pParser->Continue();
|
||||
while (!pParser->IsToken("}"))
|
||||
{
|
||||
ParseStatement( pParser );
|
||||
}
|
||||
pParser->Continue();
|
||||
}
|
||||
else
|
||||
{
|
||||
CompileErrorExpectedToken(pParser->m_pCurrentToken, "(");
|
||||
}
|
||||
pParser->Continue();
|
||||
}
|
||||
else
|
||||
{
|
||||
CompileErrorExpectedToken(pParser->m_pCurrentToken, "(");
|
||||
}
|
||||
V_printf("%s\n", g_pGenerator->GetAssembly().GetString());
|
||||
};
|
||||
|
||||
|
||||
@@ -135,6 +380,8 @@ int main( int argc, char **argv )
|
||||
const char *szFileContents = filesystem->ReadString(pFile);
|
||||
filesystem->Close(pFile);
|
||||
|
||||
g_pGenerator = (IBGenerator*)CreateInterface(B_GENERATOR_INTERFACE_VERSION, NULL);
|
||||
|
||||
|
||||
CUtlVector<Token_t> tokens = Tokenize(szFileContents);
|
||||
CTokenParser parser;
|
||||
|
||||
Reference in New Issue
Block a user