diff --git a/includes/symbols_table.h b/includes/symbols_table.h index a4e1959..5c55735 100644 --- a/includes/symbols_table.h +++ b/includes/symbols_table.h @@ -1,10 +1,12 @@ #ifndef SYMBOLSTABLE_H #define SYMBOLSTABLE_H +#include #include #include #include #include +#include #include "opcodes.h" #define SYMBOLSTABLE_DEFAULT_CAPACITY 128 @@ -16,12 +18,18 @@ typedef enum { UnresolvedSymbol } SymbolType; +typedef struct { + char* String; + int Terminated; + u_int8_t TerminatingByte; +} SymbolString; + typedef struct { char* Name; SymbolType Type; union { - char* Text; + SymbolString* String; int Number; Instruction* Instruction; } Value; @@ -36,6 +44,7 @@ typedef struct { SymbolTable* CreateSymbolTable(void); Symbol* TryGetSymbol(char* name, SymbolTable* table); Symbol* AddSymbolToTable(char* name, SymbolType type, SymbolTable* table); +SymbolString* CreateSymbolString(char* string, int terminated); void FreeSymbolTable(SymbolTable* table); void FreeSymbol(Symbol* symbol); diff --git a/src/parser.c b/src/parser.c index a418c7a..323cfe7 100644 --- a/src/parser.c +++ b/src/parser.c @@ -100,13 +100,34 @@ void HandleAssemblerDirective() { } else if (token->Class == CharacterClass) { Symbol* s = AddSymbolToTable(symbolname, StringSymbol, MachineState.SymbolsTable); + char* string = token->Lemexe; - s->Value.Text = token->Lemexe; + AdvanceParser(); - IgnoreParserLine(); + if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == Comma) { + AdvanceParser(); + + token = PeekToken(); + + if (token->Class != NumberClass) { + fprintf(stderr, "[Error] Line %d: Expected terminating byte.\n", token->LineNumber); + IgnoreParserLine(); + return; + } + + if (token->Value.Number > 255) { + fprintf(stderr, "[Error] Line %d: Number must fit within a byte.\n", token->LineNumber); + IgnoreParserLine(); + return; + } + + s->Value.String = CreateSymbolString(string, 1); + s->Value.String->TerminatingByte = token->Value.Number; + } + else s->Value.String = CreateSymbolString(string, 0); } - else IgnoreParserLine(); - + + IgnoreParserLine(); } Parameter* GetParameterType() { @@ -273,10 +294,13 @@ void PrintSymbols(void) { printf("%s -> %s", symbol->Name, mn); break; case NumericSymbol: - printf("[N] %s", symbol->Name); + printf("[N] %s Value: %d", symbol->Name, symbol->Value.Number); break; case StringSymbol: - printf("[S] %s", symbol->Name); + if (symbol->Value.String->Terminated) + printf("[S] %s, %d", symbol->Name, symbol->Value.String->TerminatingByte); + else + printf("[S] %s", symbol->Value.String->String); break; case UnresolvedSymbol: printf("[U] %s", symbol->Name); diff --git a/src/symbols_table.c b/src/symbols_table.c index 373ac51..bcd2a18 100644 --- a/src/symbols_table.c +++ b/src/symbols_table.c @@ -40,6 +40,23 @@ Symbol* CreateSymbol(char* name, SymbolType type) { return symbol; } +SymbolString* CreateSymbolString(char* string, int terminated) { + if (!string) return NULL; + + SymbolString* s = calloc(1, sizeof(SymbolString)); + + if (!s) { + fprintf(stderr, "Failed to calloc string for symbol. %s.\n", strerror(errno)); + + return NULL; + } + + s->String = string; + s->Terminated = terminated; + + return s; +} + Symbol* TryGetSymbol(char* name, SymbolTable* table) { if (!name || !table) return NULL;