holy shit thats a lot of changed to asmrigs

This commit is contained in:
2026-01-17 23:45:36 +02:00
parent ee7735b610
commit fe1273e539
21 changed files with 645 additions and 197 deletions

132
asmrigs/as/as.cpp Normal file
View 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
View 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;
}

View File

@@ -4,24 +4,17 @@
#include "tier2/tokenizer.h" #include "tier2/tokenizer.h"
#include "tier3/lexer.h" #include "tier3/lexer.h"
#define B_LEXEL_INTERFACE_NAME "BLexer001"
abstract_class IBGenerator
enum EBWordType
{
BWORDTYPE_CONST_WORD,
BWORDTYPE_FUNCTION,
BWORDTYPE_FUNCTION_ARGS,
BWORDTYPE_FUNCTION_ARG,
BWORDTYPE_FUNCTION_SCOPE,
BWORDTYPE_RETURN,
};
abstract_class IBLexerWord: public ILexerWord
{ {
public: 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 #endif

View File

@@ -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;
};

View File

@@ -1,48 +1,35 @@
#include "brb.h" #include "brb.h"
#include "asmrigs/tokenparser.h"
#include "tier0/commandline.h" #include "tier0/commandline.h"
#include "tier2/ifilesystem.h" #include "tier2/ifilesystem.h"
IBGenerator *g_pGenerator;
class CTokenParser class CBGenerator: public IBGenerator
{ {
public: public:
const char *PeekToken(); virtual void AddExternSymbol( const char *szName ) override;
bool IsToken( const char *szString ); virtual void DefineFunction( const char *szName ) override;
const char *PeekStringLiteral(); virtual CUtlString GetAssembly() override;
bool Continue(); CUtlVector<CUtlString> m_externalSymbols;
CUtlString m_szAssembly;
Token_t *m_pTokens;
Token_t *m_pTokensEnd;
Token_t *m_pCurrentToken;
}; };
EXPOSE_INTERFACE(CBGenerator, IBGenerator, B_GENERATOR_INTERFACE_VERSION);
const char *CTokenParser::PeekToken() void CBGenerator::AddExternSymbol( const char *szName )
{ {
if ( m_pCurrentToken->m_bIsQuoted ) m_externalSymbols.AppendTail(szName);
return NULL;
return m_pCurrentToken->m_szValue;
} }
bool CTokenParser::IsToken( const char *szString ) void CBGenerator::DefineFunction( const char *szName )
{ {
if ( !V_strcmp(szString, m_pCurrentToken->m_szValue)) m_szAssembly.AppendTail(CUtlString("public %s\n", szName));
return true; m_szAssembly.AppendTail(CUtlString("%s:\n", szName));
return false;
};
const char *CTokenParser::PeekStringLiteral()
{
if ( !m_pCurrentToken->m_bIsQuoted )
return NULL;
return m_pCurrentToken->m_szValue;
} }
bool CTokenParser::Continue() CUtlString CBGenerator::GetAssembly()
{ {
m_pCurrentToken++; return m_szAssembly;
if ( m_pCurrentToken == m_pTokensEnd )
return false;
return true;
} }
void CompileErrorExpectedToken( Token_t *pToken, const char *szToken ) void CompileErrorExpectedToken( Token_t *pToken, const char *szToken )
@@ -54,32 +41,235 @@ void CompileErrorExpectedToken( Token_t *pToken, const char *szToken )
exit(1); exit(1);
} }
struct BExpression_t void CompileErrorUnexpectedToken( Token_t *pToken )
{ {
enum BExpressionType 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 )
{ {
BEXPRESSION_TYPE_NEW, V_printf("%d:%d: got rvalue when expected lvalue\n", pToken->m_iLine, pToken->m_iCharacter );
BEXPRESSION_TYPE_ADD, exit(1);
BEXPRESSION_TYPE_SUBTRACT, }
} m_eType;
CUtlVector<BExpression_t> m_children; 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(); 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 ) void ParseRValue( CTokenParser *pParser )
{ {
if (pParser->PeekToken() == "(") PrintExpr(ParseExpr( pParser ));
{
pParser->PeekToken();
ParseRValue(pParser)
}
BVar_t var = ParseVar( pParser );
} }
void ParseStatement( CTokenParser *pParser ) void ParseStatement( CTokenParser *pParser )
@@ -93,14 +283,65 @@ void ParseStatement( CTokenParser *pParser )
V_printf(" ret\n"); V_printf(" ret\n");
pParser->Continue(); 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 ) void ParseGlobal( CTokenParser *pParser )
{ {
for (;;)
{
if (pParser->IsEOF())
break;
const char *szObjectName = pParser->PeekToken(); const char *szObjectName = pParser->PeekToken();
pParser->Continue(); pParser->Continue();
V_printf("%s:\n", szObjectName);
if (pParser->IsToken("(")) if (pParser->IsToken("("))
{ {
@@ -108,6 +349,8 @@ void ParseGlobal( CTokenParser *pParser )
if (!pParser->IsToken(")")) if (!pParser->IsToken(")"))
CompileErrorExpectedToken(pParser->m_pCurrentToken, ")"); CompileErrorExpectedToken(pParser->m_pCurrentToken, ")");
pParser->Continue(); pParser->Continue();
g_pGenerator->DefineFunction(szObjectName);
if (!pParser->IsToken("{")) if (!pParser->IsToken("{"))
CompileErrorExpectedToken(pParser->m_pCurrentToken, "{"); CompileErrorExpectedToken(pParser->m_pCurrentToken, "{");
pParser->Continue(); pParser->Continue();
@@ -121,6 +364,8 @@ void ParseGlobal( CTokenParser *pParser )
{ {
CompileErrorExpectedToken(pParser->m_pCurrentToken, "("); 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); const char *szFileContents = filesystem->ReadString(pFile);
filesystem->Close(pFile); filesystem->Close(pFile);
g_pGenerator = (IBGenerator*)CreateInterface(B_GENERATOR_INTERFACE_VERSION, NULL);
CUtlVector<Token_t> tokens = Tokenize(szFileContents); CUtlVector<Token_t> tokens = Tokenize(szFileContents);
CTokenParser parser; CTokenParser parser;

View File

@@ -7,6 +7,61 @@ ADD_DEPENDENCY_BUILD_FILE(tier1, "../tier1/build.cpp")
ADD_DEPENDENCY_BUILD_FILE(tier2, "../tier2/build.cpp") ADD_DEPENDENCY_BUILD_FILE(tier2, "../tier2/build.cpp")
ADD_DEPENDENCY_BUILD_FILE(fs, "../stdfilesystems/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) DECLARE_BUILD_STAGE(brb)
{ {
CProject_t stProject = {}; CProject_t stProject = {};
@@ -15,7 +70,6 @@ DECLARE_BUILD_STAGE(brb)
stProject.m_szName = "bc"; stProject.m_szName = "bc";
stProject.files = { stProject.files = {
"brb/lexer.cpp",
"brb/main.cpp", "brb/main.cpp",
}; };
stProject.includeDirectories = { stProject.includeDirectories = {
@@ -24,6 +78,7 @@ DECLARE_BUILD_STAGE(brb)
stLink = ccompiler->Compile(&stProject); stLink = ccompiler->Compile(&stProject);
stLink.libraryObjects = { stLink.libraryObjects = {
GET_PROJECT_LIBRARY(libbras, "bras"),
GET_PROJECT_LIBRARY(tier0, "tier0"), GET_PROJECT_LIBRARY(tier0, "tier0"),
GET_PROJECT_LIBRARY(tier1, "tier1"), GET_PROJECT_LIBRARY(tier1, "tier1"),
GET_PROJECT_LIBRARY(tier2, "tier2"), GET_PROJECT_LIBRARY(tier2, "tier2"),
@@ -34,11 +89,12 @@ DECLARE_BUILD_STAGE(brb)
return 0; return 0;
}; };
DECLARE_BUILD_STAGE(brb_install) DECLARE_BUILD_STAGE(install)
{ {
CUtlString szBuildOutput = CUtlString("build/%s", Target_t::DefaultTarget().GetTriplet().GetString()); CUtlString szBuildOutput = CUtlString("build/%s", Target_t::DefaultTarget().GetTriplet().GetString());
filesystem2->MakeDirectory(szBuildOutput); filesystem2->MakeDirectory(szBuildOutput);
filesystem2->CopyFile(szBuildOutput, GET_PROJECT_OBJECT(brb, "bc")); 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(tier0, "tier0"));
filesystem2->CopyFile(szBuildOutput, GET_PROJECT_LIBRARY(filesystem_std, "fs")); filesystem2->CopyFile(szBuildOutput, GET_PROJECT_LIBRARY(filesystem_std, "fs"));
return 0; return 0;

View File

26
asmrigs/libbr/math.s Normal file
View 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

View File

@@ -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

View File

@@ -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

View File

@@ -1,4 +1,4 @@
main() _tick()
{ {
} }

3
asmrigs/tests/001.s Normal file
View File

@@ -0,0 +1,3 @@
public _tick
_tick:
ret

View File

@@ -1,4 +1,5 @@
main() _tick()
{ {
return 0; extrn a;
a = 30;
} }

3
asmrigs/tests/002.s Normal file
View File

@@ -0,0 +1,3 @@
public _tick
_tick:
ret

View File

@@ -1,4 +1,5 @@
main() _tick()
{ {
return 1 + 2 * 3; extrn a;
a = 1 + 2 * 3 * ( 4 + 5 );
} }

View File

@@ -1,5 +1,6 @@
main() main()
{ {
extrn something;
auto a, b; auto a, b;
a = 10; a = 10;
b = a + 5; b = a + 5;

14
public/asmrigs/as.h Normal file
View 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
View File

@@ -0,0 +1,6 @@
#ifndef ASMRIGS_LD_H
#define ASMRIGS_LD_H
#include "tier0/interface.h"
#endif

View 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

View File

@@ -76,10 +76,10 @@ CUtlBuffer<T>::CUtlBuffer( const CUtlBuffer<T>& buffer ) : m_nSize(buffer.m_nSiz
// Constructor. // Constructor.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> 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); m_pData = (T*)V_malloc(sizeof(T)*buffer.GetSize());
V_memcpy(m_pData,buffer.pData,sizeof(T)*buffer.nSize); V_memcpy(m_pData,buffer.GetMemory(),sizeof(T)*buffer.GetSize());
} }
template <typename T> template <typename T>