diff --git a/asmrigs/as/as.cpp b/asmrigs/as/as.cpp new file mode 100644 index 0000000..16ad5b2 --- /dev/null +++ b/asmrigs/as/as.cpp @@ -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 Assemble( const char *szAssembly, AsOptions_t stOptions ) +{ + CUtlVector externalFunctions; + CUtlVector publicFunctions; + CUtlVector labels; + CUtlVector 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 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 {}; +}; diff --git a/asmrigs/as/main.cpp b/asmrigs/as/main.cpp new file mode 100644 index 0000000..071aa1d --- /dev/null +++ b/asmrigs/as/main.cpp @@ -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; +} diff --git a/asmrigs/brb/brb.h b/asmrigs/brb/brb.h index 63835ef..ee24086 100644 --- a/asmrigs/brb/brb.h +++ b/asmrigs/brb/brb.h @@ -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 diff --git a/asmrigs/brb/lexer.cpp b/asmrigs/brb/lexer.cpp deleted file mode 100644 index 3f8619f..0000000 --- a/asmrigs/brb/lexer.cpp +++ /dev/null @@ -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 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 tokens ) -{ - Token_t *pCurrentToken = tokens.GetData(); - Token_t *pEndingToken = tokens.GetData() + tokens.GetSize(); - CBLexerWord *pGlobalWord = new CBLexerWord; - - - return pGlobalWord; -}; diff --git a/asmrigs/brb/main.cpp b/asmrigs/brb/main.cpp index 89e1a22..cdf6195 100644 --- a/asmrigs/brb/main.cpp +++ b/asmrigs/brb/main.cpp @@ -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 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 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 tokens = Tokenize(szFileContents); CTokenParser parser; diff --git a/asmrigs/build.cpp b/asmrigs/build.cpp index b9d6e43..6e30724 100644 --- a/asmrigs/build.cpp +++ b/asmrigs/build.cpp @@ -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; diff --git a/asmrigs/cbld/gen.h b/asmrigs/cbld/gen.h deleted file mode 100644 index e69de29..0000000 diff --git a/asmrigs/cbld/gen.cpp b/asmrigs/libbr/Makefile similarity index 100% rename from asmrigs/cbld/gen.cpp rename to asmrigs/libbr/Makefile diff --git a/asmrigs/libbr/math.s b/asmrigs/libbr/math.s new file mode 100644 index 0000000..d61e6ce --- /dev/null +++ b/asmrigs/libbr/math.s @@ -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 + diff --git a/asmrigs/spec/brb.txt b/asmrigs/spec/brb.txt deleted file mode 100644 index 25c762c..0000000 --- a/asmrigs/spec/brb.txt +++ /dev/null @@ -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 - - diff --git a/asmrigs/spec/o.txt b/asmrigs/spec/o.txt deleted file mode 100644 index d41cae7..0000000 --- a/asmrigs/spec/o.txt +++ /dev/null @@ -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 diff --git a/asmrigs/tests/001.b b/asmrigs/tests/001.b index 6dc375c..47fcd70 100644 --- a/asmrigs/tests/001.b +++ b/asmrigs/tests/001.b @@ -1,4 +1,4 @@ -main() +_tick() { } diff --git a/asmrigs/tests/001.s b/asmrigs/tests/001.s new file mode 100644 index 0000000..564452e --- /dev/null +++ b/asmrigs/tests/001.s @@ -0,0 +1,3 @@ +public _tick +_tick: + ret diff --git a/asmrigs/tests/002.b b/asmrigs/tests/002.b index c3f9756..34bea15 100644 --- a/asmrigs/tests/002.b +++ b/asmrigs/tests/002.b @@ -1,4 +1,5 @@ -main() +_tick() { - return 0; + extrn a; + a = 30; } diff --git a/asmrigs/tests/002.s b/asmrigs/tests/002.s new file mode 100644 index 0000000..564452e --- /dev/null +++ b/asmrigs/tests/002.s @@ -0,0 +1,3 @@ +public _tick +_tick: + ret diff --git a/asmrigs/tests/003.b b/asmrigs/tests/003.b index c93610b..203337e 100644 --- a/asmrigs/tests/003.b +++ b/asmrigs/tests/003.b @@ -1,4 +1,5 @@ -main() +_tick() { - return 1 + 2 * 3; + extrn a; + a = 1 + 2 * 3 * ( 4 + 5 ); } diff --git a/asmrigs/tests/004.b b/asmrigs/tests/004.b index 591b830..65dec45 100644 --- a/asmrigs/tests/004.b +++ b/asmrigs/tests/004.b @@ -1,5 +1,6 @@ main() { + extrn something; auto a, b; a = 10; b = a + 5; diff --git a/public/asmrigs/as.h b/public/asmrigs/as.h new file mode 100644 index 0000000..ad20bd2 --- /dev/null +++ b/public/asmrigs/as.h @@ -0,0 +1,14 @@ +#ifndef ASMRIGS_AS_H +#define ASMRIGS_AS_H + +#include "tier0/platform.h" +#include "tier1/utlbuffer.h" + +struct AsOptions_t +{ + +}; + +CUtlBuffer Assemble( const char *szAssembly, AsOptions_t stOptions ); + +#endif diff --git a/public/asmrigs/ld.h b/public/asmrigs/ld.h new file mode 100644 index 0000000..2c8be2e --- /dev/null +++ b/public/asmrigs/ld.h @@ -0,0 +1,6 @@ +#ifndef ASMRIGS_LD_H +#define ASMRIGS_LD_H + +#include "tier0/interface.h" + +#endif diff --git a/public/asmrigs/tokenparser.h b/public/asmrigs/tokenparser.h new file mode 100644 index 0000000..313b309 --- /dev/null +++ b/public/asmrigs/tokenparser.h @@ -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 diff --git a/public/tier1/utlbuffer.h b/public/tier1/utlbuffer.h index 0d0b525..e0ee920 100644 --- a/public/tier1/utlbuffer.h +++ b/public/tier1/utlbuffer.h @@ -76,10 +76,10 @@ CUtlBuffer::CUtlBuffer( const CUtlBuffer& buffer ) : m_nSize(buffer.m_nSiz // Constructor. //----------------------------------------------------------------------------- template -CUtlBuffer::CUtlBuffer( const CUtlResizableBuffer& buffer ) : m_nSize(buffer.m_nSize) +CUtlBuffer::CUtlBuffer( const CUtlResizableBuffer& 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