holy shit thats a lot of changed to asmrigs
This commit is contained in:
132
asmrigs/as/as.cpp
Normal file
132
asmrigs/as/as.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
#include "asmrigs/as.h"
|
||||
#include "tier2/tokenizer.h"
|
||||
#include "asmrigs/tokenparser.h"
|
||||
|
||||
struct ObjectHeader_t
|
||||
{
|
||||
uint8_t m_magic[4];
|
||||
uint32_t m_uSymbolCount;
|
||||
uint32_t m_uDatasCount;
|
||||
};
|
||||
|
||||
enum EDataFlags: uint32_t
|
||||
{
|
||||
DATA_TYPE_DECLARE,
|
||||
DATA_TYPE_USED,
|
||||
};
|
||||
|
||||
struct Data_t
|
||||
{
|
||||
uint64_t m_uDataSize;
|
||||
uint64_t m_uDataOffsetSize;
|
||||
};
|
||||
|
||||
struct Symbol_t
|
||||
{
|
||||
uint32_t m_uName;
|
||||
uint32_t m_uData;
|
||||
EDataFlags m_eDataFlags;
|
||||
};
|
||||
|
||||
enum EInstruction: uint8_t
|
||||
{
|
||||
I_NOP = 0,
|
||||
|
||||
I_PUSH = 3,
|
||||
I_POP = 4,
|
||||
|
||||
I_CMP = 5,
|
||||
|
||||
I_JUMP = 6,
|
||||
I_JZ = 7,
|
||||
I_JNZ = 8,
|
||||
I_JG = 9,
|
||||
I_JGE = 10,
|
||||
I_JLE = 11,
|
||||
|
||||
I_LOAD = 12,
|
||||
I_STORE = 13,
|
||||
I_LOADPTR = 14,
|
||||
I_STOREPTR = 15,
|
||||
I_LOADLIT = 16,
|
||||
|
||||
I_JSR = 20,
|
||||
I_RET = 21,
|
||||
};
|
||||
|
||||
CUtlBuffer<uint8_t> Assemble( const char *szAssembly, AsOptions_t stOptions )
|
||||
{
|
||||
CUtlVector<CUtlString> externalFunctions;
|
||||
CUtlVector<CUtlString> publicFunctions;
|
||||
CUtlVector<CUtlString> labels;
|
||||
CUtlVector<Token_t> tokens = Tokenize(szAssembly);
|
||||
Token_t *pTokens = tokens.GetData();
|
||||
for ( int i = 0; i < tokens.GetSize()-2; )
|
||||
{
|
||||
if ( !tokens[i].m_bIsQuoted && tokens[i].m_szValue == "/" )
|
||||
if ( !tokens[i+1].m_bIsQuoted && tokens[i+1].m_szValue == "/" )
|
||||
if ( !tokens[i+2].m_bIsQuoted && tokens[i+2].m_szValue == "/" )
|
||||
{
|
||||
tokens.RemoveAt(i, 3);
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
};
|
||||
CTokenParser parser;
|
||||
parser.m_pTokens = tokens.GetData();
|
||||
parser.m_pTokensEnd = tokens.GetData()+tokens.GetSize();
|
||||
parser.m_pCurrentToken = tokens.GetData()-1;
|
||||
parser.Continue();
|
||||
|
||||
CUtlVector<uint8_t> commandStream;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (parser.IsEOF())
|
||||
break;
|
||||
CUtlString szCommand = parser.PeekToken();
|
||||
parser.Continue();
|
||||
if ( szCommand == "extrn" )
|
||||
{
|
||||
externalFunctions.AppendTail(parser.PeekToken());
|
||||
parser.Continue();
|
||||
continue;
|
||||
}
|
||||
if ( szCommand == "public" )
|
||||
{
|
||||
publicFunctions.AppendTail(parser.PeekToken());
|
||||
parser.Continue();
|
||||
continue;
|
||||
}
|
||||
if ( szCommand == "store" )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( szCommand == "load" )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( szCommand == "jsr" )
|
||||
{
|
||||
commandStream.AppendTail(I_JSR);
|
||||
continue;
|
||||
}
|
||||
if ( szCommand == "ret" )
|
||||
{
|
||||
commandStream.AppendTail(I_RET);
|
||||
continue;
|
||||
}
|
||||
if (parser.IsEOF())
|
||||
break;
|
||||
if (!V_strcmp(parser.PeekToken(), ":"))
|
||||
{
|
||||
parser.Continue();
|
||||
labels.AppendTail("");
|
||||
}
|
||||
else
|
||||
{
|
||||
V_printf("%s is not a valid instuction or label\n", szCommand.GetString());
|
||||
}
|
||||
}
|
||||
return {};
|
||||
};
|
||||
18
asmrigs/as/main.cpp
Normal file
18
asmrigs/as/main.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "asmrigs/tokenparser.h"
|
||||
#include "asmrigs/as.h"
|
||||
#include "tier0/commandline.h"
|
||||
#include "tier2/ifilesystem.h"
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
CommandLine()->CreateCommandLine(argc, argv);
|
||||
|
||||
CreateInterfaceFn filesystemFactory = Sys_GetFactory("filesystem_std");
|
||||
filesystem = (IFileSystem*)filesystemFactory(FILESYSTEM_INTERFACE_VERSION, NULL);
|
||||
|
||||
IFileHandle *pFile = filesystem->Open(argv[1], FILEMODE_READ);
|
||||
const char *szFileContents = filesystem->ReadString(pFile);
|
||||
filesystem->Close(pFile);
|
||||
|
||||
Assemble(szFileContents, {});
|
||||
return 0;
|
||||
}
|
||||
@@ -4,24 +4,17 @@
|
||||
#include "tier2/tokenizer.h"
|
||||
#include "tier3/lexer.h"
|
||||
|
||||
#define B_LEXEL_INTERFACE_NAME "BLexer001"
|
||||
|
||||
|
||||
enum EBWordType
|
||||
{
|
||||
BWORDTYPE_CONST_WORD,
|
||||
|
||||
BWORDTYPE_FUNCTION,
|
||||
BWORDTYPE_FUNCTION_ARGS,
|
||||
BWORDTYPE_FUNCTION_ARG,
|
||||
BWORDTYPE_FUNCTION_SCOPE,
|
||||
|
||||
BWORDTYPE_RETURN,
|
||||
};
|
||||
|
||||
abstract_class IBLexerWord: public ILexerWord
|
||||
abstract_class IBGenerator
|
||||
{
|
||||
public:
|
||||
virtual void AddExternSymbol( const char *szName ) = 0;
|
||||
virtual void DefineFunction( const char *szName ) = 0;
|
||||
virtual void Load( uint8_t uRegister, int iValue ) = 0;
|
||||
virtual void Return() = 0;
|
||||
virtual CUtlString GetAssembly() = 0;
|
||||
};
|
||||
|
||||
#define B_GENERATOR_INTERFACE_VERSION "BGenerator001"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
#include "brb.h"
|
||||
|
||||
abstract_class CBLexerWord: public IBLexerWord
|
||||
{
|
||||
public:
|
||||
virtual int GetType() override;
|
||||
|
||||
EBWordType m_eType;
|
||||
};
|
||||
|
||||
int CBLexerWord::GetType()
|
||||
{
|
||||
return m_eType;
|
||||
}
|
||||
|
||||
class CBLexer: public ILexer
|
||||
{
|
||||
public:
|
||||
virtual ILexerWord *ParseTokens( CUtlVector<Token_t> tokens ) override;
|
||||
|
||||
CBLexerWord *ParseFunctionBody( Token_t *&pToken, const Token_t *pEnding );
|
||||
|
||||
bool GetExpectedToken();
|
||||
CUtlString GetStringLiteral();
|
||||
};
|
||||
|
||||
#define NEXT_TOKEN() \
|
||||
pToken++; \
|
||||
if (pToken == pEnding) \
|
||||
goto eof \
|
||||
|
||||
ILexerWord *CBLexer::ParseTokens( CUtlVector<Token_t> tokens )
|
||||
{
|
||||
Token_t *pCurrentToken = tokens.GetData();
|
||||
Token_t *pEndingToken = tokens.GetData() + tokens.GetSize();
|
||||
CBLexerWord *pGlobalWord = new CBLexerWord;
|
||||
|
||||
|
||||
return pGlobalWord;
|
||||
};
|
||||
@@ -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,14 +283,65 @@ 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 )
|
||||
{
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (pParser->IsEOF())
|
||||
break;
|
||||
const char *szObjectName = pParser->PeekToken();
|
||||
pParser->Continue();
|
||||
V_printf("%s:\n", szObjectName);
|
||||
|
||||
if (pParser->IsToken("("))
|
||||
{
|
||||
@@ -108,6 +349,8 @@ void ParseGlobal( CTokenParser *pParser )
|
||||
if (!pParser->IsToken(")"))
|
||||
CompileErrorExpectedToken(pParser->m_pCurrentToken, ")");
|
||||
pParser->Continue();
|
||||
g_pGenerator->DefineFunction(szObjectName);
|
||||
|
||||
if (!pParser->IsToken("{"))
|
||||
CompileErrorExpectedToken(pParser->m_pCurrentToken, "{");
|
||||
pParser->Continue();
|
||||
@@ -121,6 +364,8 @@ void ParseGlobal( CTokenParser *pParser )
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -7,6 +7,61 @@ ADD_DEPENDENCY_BUILD_FILE(tier1, "../tier1/build.cpp")
|
||||
ADD_DEPENDENCY_BUILD_FILE(tier2, "../tier2/build.cpp")
|
||||
ADD_DEPENDENCY_BUILD_FILE(fs, "../stdfilesystems/build.cpp")
|
||||
|
||||
|
||||
DECLARE_BUILD_STAGE(libbras)
|
||||
{
|
||||
CProject_t stProject = {};
|
||||
LinkProject_t stLink = {};
|
||||
CUtlString szBuiltFile = {};
|
||||
|
||||
stProject.m_szName = "bras";
|
||||
stProject.files = {
|
||||
"as/as.cpp",
|
||||
};
|
||||
stProject.includeDirectories = {
|
||||
"../public"
|
||||
};
|
||||
|
||||
stLink = ccompiler->Compile(&stProject);
|
||||
stLink.linkType = ELINK_STATIC_LIBRARY;
|
||||
stLink.libraryObjects = {
|
||||
GET_PROJECT_LIBRARY(tier0, "tier0"),
|
||||
GET_PROJECT_LIBRARY(tier1, "tier1"),
|
||||
GET_PROJECT_LIBRARY(tier2, "tier2"),
|
||||
};
|
||||
szBuiltFile = linker->Link(&stLink);
|
||||
ADD_OUTPUT_OBJECT("bras", szBuiltFile);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
DECLARE_BUILD_STAGE(bras)
|
||||
{
|
||||
CProject_t stProject = {};
|
||||
LinkProject_t stLink = {};
|
||||
CUtlString szBuiltFile = {};
|
||||
|
||||
stProject.m_szName = "bras";
|
||||
stProject.files = {
|
||||
"as/main.cpp",
|
||||
};
|
||||
stProject.includeDirectories = {
|
||||
"../public"
|
||||
};
|
||||
|
||||
stLink = ccompiler->Compile(&stProject);
|
||||
stLink.libraryObjects = {
|
||||
GET_PROJECT_LIBRARY(libbras, "bras"),
|
||||
GET_PROJECT_LIBRARY(tier0, "tier0"),
|
||||
GET_PROJECT_LIBRARY(tier1, "tier1"),
|
||||
GET_PROJECT_LIBRARY(tier2, "tier2"),
|
||||
};
|
||||
szBuiltFile = linker->Link(&stLink);
|
||||
ADD_OUTPUT_OBJECT("bras", szBuiltFile);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
DECLARE_BUILD_STAGE(brb)
|
||||
{
|
||||
CProject_t stProject = {};
|
||||
@@ -15,7 +70,6 @@ DECLARE_BUILD_STAGE(brb)
|
||||
|
||||
stProject.m_szName = "bc";
|
||||
stProject.files = {
|
||||
"brb/lexer.cpp",
|
||||
"brb/main.cpp",
|
||||
};
|
||||
stProject.includeDirectories = {
|
||||
@@ -24,6 +78,7 @@ DECLARE_BUILD_STAGE(brb)
|
||||
|
||||
stLink = ccompiler->Compile(&stProject);
|
||||
stLink.libraryObjects = {
|
||||
GET_PROJECT_LIBRARY(libbras, "bras"),
|
||||
GET_PROJECT_LIBRARY(tier0, "tier0"),
|
||||
GET_PROJECT_LIBRARY(tier1, "tier1"),
|
||||
GET_PROJECT_LIBRARY(tier2, "tier2"),
|
||||
@@ -34,11 +89,12 @@ DECLARE_BUILD_STAGE(brb)
|
||||
return 0;
|
||||
};
|
||||
|
||||
DECLARE_BUILD_STAGE(brb_install)
|
||||
DECLARE_BUILD_STAGE(install)
|
||||
{
|
||||
CUtlString szBuildOutput = CUtlString("build/%s", Target_t::DefaultTarget().GetTriplet().GetString());
|
||||
filesystem2->MakeDirectory(szBuildOutput);
|
||||
filesystem2->CopyFile(szBuildOutput, GET_PROJECT_OBJECT(brb, "bc"));
|
||||
filesystem2->CopyFile(szBuildOutput, GET_PROJECT_OBJECT(bras, "bras"));
|
||||
filesystem2->CopyFile(szBuildOutput, GET_PROJECT_LIBRARY(tier0, "tier0"));
|
||||
filesystem2->CopyFile(szBuildOutput, GET_PROJECT_LIBRARY(filesystem_std, "fs"));
|
||||
return 0;
|
||||
|
||||
26
asmrigs/libbr/math.s
Normal file
26
asmrigs/libbr/math.s
Normal file
@@ -0,0 +1,26 @@
|
||||
public min
|
||||
min:
|
||||
pop b
|
||||
pop c
|
||||
min a, b, c
|
||||
ret
|
||||
|
||||
public max
|
||||
max:
|
||||
pop b
|
||||
pop c
|
||||
max a, b, c
|
||||
ret
|
||||
|
||||
public abs
|
||||
abs:
|
||||
pop b
|
||||
abs a, b, c
|
||||
ret
|
||||
|
||||
public sign
|
||||
sign:
|
||||
pop b
|
||||
sign a, b
|
||||
ret
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
Brick Rigs B is a programming language made to work in the game Brick Rigs
|
||||
|
||||
1. The main issues of Brick Rigs
|
||||
|
||||
There are multiple limitations that are present in Brick Rigs:
|
||||
1. Math Bricks are updated once per frame. It limits them to be one
|
||||
time usage, which may cause some problems if you want to set the same
|
||||
brick multiple times.
|
||||
|
||||
To solve this issue we've developed multiple targets:
|
||||
1. Native Brick Rigs framed - allows to run code once per frame,
|
||||
useful for missiles and custom built-logic.
|
||||
2. Native Brick Rigs stacked - splits the code into multiple
|
||||
parts, which allows stack to occur at a cost of a single frame.
|
||||
3. Combat Advanced's virtual machine - it allows to run complex code by
|
||||
using Combat Advanced's virtual machine
|
||||
|
||||
There are multiple extensions for native Brick Rigs
|
||||
1. Combat Advanced's memory module
|
||||
2. Combat Advanced's trigonometry functions
|
||||
|
||||
2. Syntaxis
|
||||
|
||||
It can be seen in B user's guide
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
Brick Rigs math vehicle object file specification v 1.0.
|
||||
|
||||
1. Terminology
|
||||
"byte" must be 1 byte long (uint8_t in C)
|
||||
"word" must be 2 bytes long (uint16_t in C)
|
||||
"int" must be 4 bytes long (uint16_t in C)
|
||||
|
||||
2. Global header
|
||||
|
||||
First comes global header which has following structure:
|
||||
|
||||
struct
|
||||
{
|
||||
byte magic[4];
|
||||
byte architecture[2];
|
||||
word symbols_number;
|
||||
}
|
||||
|
||||
Where:
|
||||
magic must equal to 0x1 'B' 'M' 'O'
|
||||
architecture is defined per implementation
|
||||
symbols_number is the amount of symbols
|
||||
|
||||
3. Symbols
|
||||
|
||||
First comes the header:
|
||||
|
||||
struct
|
||||
{
|
||||
byte type;
|
||||
int name_offset;
|
||||
byte name_lenght;
|
||||
int data_offset;
|
||||
byte data_lenght;
|
||||
}
|
||||
|
||||
Where:
|
||||
type is equal to 0x1 which defines function or 0x2 which defines variable
|
||||
name_lenght is equal to the lenght of the name of the symbol + 1
|
||||
data_lenght is equal to the data lenght of the symbol
|
||||
|
||||
After that comes the ASCII terminated by 0x0 set of lenght of name_lenght, which defined name of the symbol
|
||||
@@ -1,4 +1,4 @@
|
||||
main()
|
||||
_tick()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
3
asmrigs/tests/001.s
Normal file
3
asmrigs/tests/001.s
Normal file
@@ -0,0 +1,3 @@
|
||||
public _tick
|
||||
_tick:
|
||||
ret
|
||||
@@ -1,4 +1,5 @@
|
||||
main()
|
||||
_tick()
|
||||
{
|
||||
return 0;
|
||||
extrn a;
|
||||
a = 30;
|
||||
}
|
||||
|
||||
3
asmrigs/tests/002.s
Normal file
3
asmrigs/tests/002.s
Normal file
@@ -0,0 +1,3 @@
|
||||
public _tick
|
||||
_tick:
|
||||
ret
|
||||
@@ -1,4 +1,5 @@
|
||||
main()
|
||||
_tick()
|
||||
{
|
||||
return 1 + 2 * 3;
|
||||
extrn a;
|
||||
a = 1 + 2 * 3 * ( 4 + 5 );
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
main()
|
||||
{
|
||||
extrn something;
|
||||
auto a, b;
|
||||
a = 10;
|
||||
b = a + 5;
|
||||
|
||||
14
public/asmrigs/as.h
Normal file
14
public/asmrigs/as.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef ASMRIGS_AS_H
|
||||
#define ASMRIGS_AS_H
|
||||
|
||||
#include "tier0/platform.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
|
||||
struct AsOptions_t
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
CUtlBuffer<uint8_t> Assemble( const char *szAssembly, AsOptions_t stOptions );
|
||||
|
||||
#endif
|
||||
6
public/asmrigs/ld.h
Normal file
6
public/asmrigs/ld.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef ASMRIGS_LD_H
|
||||
#define ASMRIGS_LD_H
|
||||
|
||||
#include "tier0/interface.h"
|
||||
|
||||
#endif
|
||||
55
public/asmrigs/tokenparser.h
Normal file
55
public/asmrigs/tokenparser.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef ASMRIGS_TOKEN_PARSER
|
||||
#define ASMRIGS_TOKEN_PARSER
|
||||
|
||||
#include "tier2/tokenizer.h"
|
||||
|
||||
class CTokenParser
|
||||
{
|
||||
public:
|
||||
bool IsEOF();
|
||||
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;
|
||||
};
|
||||
|
||||
inline const char *CTokenParser::PeekToken()
|
||||
{
|
||||
if ( m_pCurrentToken->m_bIsQuoted )
|
||||
return NULL;
|
||||
return m_pCurrentToken->m_szValue;
|
||||
}
|
||||
inline bool CTokenParser::IsEOF()
|
||||
{
|
||||
if (m_pCurrentToken == m_pTokensEnd)
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
inline bool CTokenParser::IsToken( const char *szString )
|
||||
{
|
||||
if ( !V_strcmp(szString, m_pCurrentToken->m_szValue))
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
inline const char *CTokenParser::PeekStringLiteral()
|
||||
{
|
||||
if ( !m_pCurrentToken->m_bIsQuoted )
|
||||
return NULL;
|
||||
return m_pCurrentToken->m_szValue;
|
||||
}
|
||||
|
||||
inline bool CTokenParser::Continue()
|
||||
{
|
||||
m_pCurrentToken++;
|
||||
if ( m_pCurrentToken == m_pTokensEnd )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -76,10 +76,10 @@ CUtlBuffer<T>::CUtlBuffer( const CUtlBuffer<T>& buffer ) : m_nSize(buffer.m_nSiz
|
||||
// Constructor.
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
CUtlBuffer<T>::CUtlBuffer( const CUtlResizableBuffer<T>& buffer ) : m_nSize(buffer.m_nSize)
|
||||
CUtlBuffer<T>::CUtlBuffer( const CUtlResizableBuffer<T>& buffer ) : m_nSize(buffer.GetSize())
|
||||
{
|
||||
m_pData = (T*)V_malloc(sizeof(T)*buffer.nSize);
|
||||
V_memcpy(m_pData,buffer.pData,sizeof(T)*buffer.nSize);
|
||||
m_pData = (T*)V_malloc(sizeof(T)*buffer.GetSize());
|
||||
V_memcpy(m_pData,buffer.GetMemory(),sizeof(T)*buffer.GetSize());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
||||
Reference in New Issue
Block a user