Massive refactoring to simplify this whole setup. The Token List will be modified in place and reused in the Parser to normalize the list and generate a symbols table. Normalizing the token list will make sure the syntax is valid and the symbols table will have the relative offsets and length of symbol values. At least this is all the plan but one step at a time.
This commit is contained in:
@@ -11,28 +11,11 @@
|
||||
|
||||
#define SYMBOLSTABLE_DEFAULT_CAPACITY 128
|
||||
|
||||
typedef enum {
|
||||
StringSymbol,
|
||||
NumericSymbol,
|
||||
InstructionPointerSymbol,
|
||||
UnresolvedSymbol
|
||||
} SymbolType;
|
||||
|
||||
typedef struct {
|
||||
char* String;
|
||||
int Terminated;
|
||||
u_int8_t TerminatingByte;
|
||||
} SymbolString;
|
||||
|
||||
typedef struct {
|
||||
char* Name;
|
||||
SymbolType Type;
|
||||
|
||||
union {
|
||||
SymbolString* String;
|
||||
int Number;
|
||||
Instruction* Instruction;
|
||||
} Value;
|
||||
int Address;
|
||||
int Resolved;
|
||||
int Length;
|
||||
} Symbol;
|
||||
|
||||
typedef struct {
|
||||
@@ -42,9 +25,8 @@ typedef struct {
|
||||
} SymbolTable;
|
||||
|
||||
SymbolTable* CreateSymbolTable(void);
|
||||
Symbol* TryGetSymbol(char* name, SymbolTable* table);
|
||||
Symbol* AddSymbolToTable(char* name, SymbolType type, SymbolTable* table);
|
||||
SymbolString* CreateSymbolString(char* string, int terminated);
|
||||
int TryGetSymbol(char* name, SymbolTable* table, Symbol** outSymbol);
|
||||
Symbol* AddSymbolToTable(char* name, int address, int resolved, SymbolTable* table);
|
||||
void FreeSymbolTable(SymbolTable* table);
|
||||
void FreeSymbol(Symbol* symbol);
|
||||
|
||||
|
||||
+3
-1
@@ -24,7 +24,9 @@ typedef enum {
|
||||
typedef enum {
|
||||
DB,
|
||||
Include,
|
||||
Byte
|
||||
Byte,
|
||||
Load,
|
||||
Store
|
||||
} Directive;
|
||||
|
||||
typedef enum {
|
||||
|
||||
+4
-3
@@ -1,4 +1,4 @@
|
||||
.include "/another_test.asm"
|
||||
.include "./another_test.asm"
|
||||
|
||||
.db video_start 0xF37F
|
||||
.db msg "Hello, world!", 0
|
||||
@@ -13,12 +13,13 @@ load r1, msg ; Because the lod* instructions can't load an address
|
||||
;Out: Length in R2
|
||||
|
||||
string_length:
|
||||
loadb r3, [r1] ; Load the byte from the address in R1, into R3
|
||||
load byte r3, [r1] ; Load the byte from the address in R1, into R3
|
||||
load r2, 0 ; String length
|
||||
cmp r3, null_byte ; Is R3 a null byte?
|
||||
je end
|
||||
inc r2
|
||||
|
||||
start:
|
||||
inc r1
|
||||
start:
|
||||
inc r1 ; next char
|
||||
loadb r3, [r1] ; Load the next character byte into R3
|
||||
|
||||
+6
-7
@@ -6,6 +6,7 @@
|
||||
#include "../includes/list.h"
|
||||
#include "../includes/futil.h"
|
||||
#include "../includes/scanner.h"
|
||||
#include "../includes/parser.h"
|
||||
|
||||
int main(int argc, char* args[]) {
|
||||
if (argc == 1) {
|
||||
@@ -31,20 +32,16 @@ int main(int argc, char* args[]) {
|
||||
|
||||
if (t->Class == PunctuationClass){
|
||||
if(t->Value.Punctuation == NewLine) {
|
||||
printf("\n");
|
||||
printf("<%d>\n", t->LineNumber);
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("<%d>", t->LineNumber);
|
||||
|
||||
printf("%c ", t->Value.Punctuation);
|
||||
printf(" %c ", t->Value.Punctuation);
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("<%d>", t->LineNumber);
|
||||
|
||||
if (t->Class == LabelClass) {
|
||||
printf("[L]%s* ", t->Lemexe);
|
||||
printf("[L]%s*", t->Lemexe);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -79,5 +76,7 @@ int main(int argc, char* args[]) {
|
||||
}
|
||||
}
|
||||
|
||||
ParseTokens(list);
|
||||
|
||||
free(source_code);
|
||||
}
|
||||
+161
-173
@@ -14,6 +14,9 @@ Token* PeekToken(void);
|
||||
int ParserAtEnd(void);
|
||||
IRState MachineState;
|
||||
|
||||
int HeapSize = 0;
|
||||
int PC = 0;
|
||||
|
||||
IRState* ParseTokens(List* tokens) {
|
||||
if (!tokens) return NULL;
|
||||
|
||||
@@ -24,49 +27,53 @@ IRState* ParseTokens(List* tokens) {
|
||||
|
||||
while(!ParserAtEnd()) {
|
||||
Token* t = PeekToken();
|
||||
Symbol* tmp;
|
||||
//printf("Tyoe: %d\n", t->Class);
|
||||
|
||||
switch(t->Class) {
|
||||
case DirectiveClass: //Maybe these should be ignored, let another process handle that.
|
||||
HandleAssemblerDirective();
|
||||
//HandleAssemblerDirective();
|
||||
break;
|
||||
case MnemonicClass:
|
||||
HandleOperation();
|
||||
//HandleOperation();
|
||||
break;
|
||||
case LabelClass:
|
||||
{
|
||||
Symbol* symbol = TryGetSymbol(t->Lemexe, MachineState.SymbolsTable);
|
||||
int found = TryGetSymbol(t->Lemexe, MachineState.SymbolsTable, &tmp);
|
||||
|
||||
if (symbol && symbol->Type != UnresolvedSymbol) {
|
||||
fprintf(stderr, "[Error] Line %d: Redefinition of symbol '%s' (type: %d)\n", t->LineNumber, t->Lemexe, symbol->Type);
|
||||
if (found && tmp->Resolved) {
|
||||
fprintf(stderr, "[Error] Line %d: Redefinition of symbol '%s'\n", t->LineNumber, t->Lemexe);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
AdvanceParser(); //Consume the label token
|
||||
|
||||
if (!symbol) symbol = AddSymbolToTable(t->Lemexe, InstructionPointerSymbol, MachineState.SymbolsTable);
|
||||
else symbol->Type = InstructionPointerSymbol;
|
||||
if (!found) AddSymbolToTable(t->Lemexe, HeapSize, 1, MachineState.SymbolsTable);
|
||||
else tmp->Resolved = 1;
|
||||
|
||||
AdvanceParser(); //Consume the NewLine
|
||||
|
||||
Instruction* ins = HandleOperation();
|
||||
//Instruction* ins = HandleOperation();
|
||||
|
||||
if (!ins) {
|
||||
fprintf(stderr, "[Error] Line %d: Expected instruction following label '%s'.\n", t->LineNumber, t->Lemexe);
|
||||
exit(1);
|
||||
}
|
||||
// if (!ins) {
|
||||
// fprintf(stderr, "[Error] Line %d: Expected instruction following label '%s'.\n", t->LineNumber, t->Lemexe);
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
symbol->Value.Instruction = ins;
|
||||
//symbol->Value.Instruction = ins;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "[Warning] Line %d: Syntax error, expected start of expression, got '%c' [%d].\n", t->LineNumber, t->Value.Punctuation, t->Class);
|
||||
//fprintf(stderr, "[Warning] Line %d: Syntax error, expected start of expression, got '%c' [%d].\n", t->LineNumber, t->Value.Punctuation, t->Class);
|
||||
//exit(1);
|
||||
IgnoreParserLine();
|
||||
//IgnoreParserLine();
|
||||
break;
|
||||
}
|
||||
|
||||
AdvanceParser();
|
||||
}
|
||||
|
||||
if (MachineState.SymbolsTable->Size > 0) PrintSymbols();
|
||||
PrintSymbols();
|
||||
|
||||
return &MachineState;
|
||||
}
|
||||
@@ -94,12 +101,10 @@ void HandleAssemblerDirective() {
|
||||
|
||||
if (token->Class == NumberClass) {
|
||||
//Delcaring a numeric value.
|
||||
Symbol* s = AddSymbolToTable(symbolname, NumericSymbol, MachineState.SymbolsTable);
|
||||
|
||||
s->Value.Number = token->Value.Number;
|
||||
Symbol* s = AddSymbolToTable(symbolname, HeapSize, 1, MachineState.SymbolsTable);
|
||||
}
|
||||
else if (token->Class == CharacterClass) {
|
||||
Symbol* s = AddSymbolToTable(symbolname, StringSymbol, MachineState.SymbolsTable);
|
||||
Symbol* s = AddSymbolToTable(symbolname, HeapSize, 1, MachineState.SymbolsTable);
|
||||
char* string = token->Lemexe;
|
||||
|
||||
AdvanceParser();
|
||||
@@ -119,213 +124,196 @@ void HandleAssemblerDirective() {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
s->Value.String = CreateSymbolString(string, 1);
|
||||
s->Value.String->TerminatingByte = token->Value.Number;
|
||||
//s->Value.String = CreateSymbolString(string, 1);
|
||||
//s->Value.String->TerminatingByte = token->Value.Number;
|
||||
}
|
||||
else s->Value.String = CreateSymbolString(string, 0);
|
||||
//else s->Value.String = CreateSymbolString(string, 0);
|
||||
}
|
||||
|
||||
IgnoreParserLine();
|
||||
}
|
||||
|
||||
Parameter* GetParameterType() {
|
||||
Token* token = PeekToken();
|
||||
Symbol* symbol = NULL;
|
||||
Parameter* param = CreateParameter(NoParameter);
|
||||
// Parameter* GetParameterType() {
|
||||
// Token* token = PeekToken();
|
||||
// Symbol* symbol = NULL;
|
||||
// int found = 0;
|
||||
// //Parameter* param = CreateParameter(NoParameter);
|
||||
|
||||
switch(token->Class) {
|
||||
case RegisterClass:
|
||||
param->ParameterType = RegisterParameter;
|
||||
param->InterpretedAs = RegisterParameter;
|
||||
// switch(token->Class) {
|
||||
// // case RegisterClass:
|
||||
// // param->ParameterType = RegisterParameter;
|
||||
// // param->InterpretedAs = RegisterParameter;
|
||||
|
||||
param->Value.Register = token->Value.Register;
|
||||
// // param->Value.Register = token->Value.Register;
|
||||
|
||||
AdvanceParser();
|
||||
// // AdvanceParser();
|
||||
|
||||
return param;
|
||||
//case LabelClass:
|
||||
case IdentifierClass:
|
||||
param->ParameterType = AddressParameter;
|
||||
//param->InterpretedAs = AddressParameter;
|
||||
// // return param;
|
||||
// //case LabelClass:
|
||||
// case IdentifierClass:
|
||||
// found = TryGetSymbol(token->Lemexe, MachineState.SymbolsTable, &symbol);
|
||||
|
||||
symbol = TryGetSymbol(token->Lemexe, MachineState.SymbolsTable);
|
||||
// if (!found) {
|
||||
// AddSymbolToTable(token->Lemexe, HeapSize, 0, MachineState.SymbolsTable);
|
||||
// }
|
||||
|
||||
if (!symbol) {
|
||||
symbol = AddSymbolToTable(token->Lemexe, UnresolvedSymbol, MachineState.SymbolsTable);
|
||||
param->InterpretedAs = UnresolvedParameter;
|
||||
}
|
||||
else {
|
||||
switch(symbol->Type) {
|
||||
case InstructionPointerSymbol:
|
||||
case StringSymbol:
|
||||
param->InterpretedAs = AddressParameter;
|
||||
break;
|
||||
case NumericSymbol:
|
||||
param->InterpretedAs = ConstantParameter;
|
||||
break;
|
||||
default:
|
||||
param->InterpretedAs = UnresolvedParameter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// //param->Value.Symbol = symbol->Name;
|
||||
|
||||
param->Value.Symbol = symbol->Name;
|
||||
// AdvanceParser();
|
||||
|
||||
AdvanceParser();
|
||||
// //return param;
|
||||
// case PunctuationClass:
|
||||
// if (token->Value.Punctuation != LBracket) {
|
||||
// fprintf(stderr, "[Error] Line %d: Expected opening bracket\n", token->LineNumber);
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
return param;
|
||||
case PunctuationClass:
|
||||
if (token->Value.Punctuation != LBracket) {
|
||||
fprintf(stderr, "[Error] Line %d: Expected opening bracket\n", token->LineNumber);
|
||||
exit(1);
|
||||
}
|
||||
// AdvanceParser(); // [
|
||||
|
||||
AdvanceParser(); // [
|
||||
// token = PeekToken();
|
||||
|
||||
token = PeekToken();
|
||||
// if (token->Class == NumberClass) {
|
||||
// param->ParameterType = ConstantParameter;
|
||||
// param->InterpretedAs = AddressParameter;
|
||||
// param->Value.Number = token->Value.Number;
|
||||
// }
|
||||
// else if (token->Class == RegisterClass) {
|
||||
// param->ParameterType = RegisterParameter;
|
||||
// param->InterpretedAs = AddressParameter;
|
||||
// param->Value.Register = token->Value.Register;
|
||||
// }
|
||||
// else if (token->Class & AddressClass) {
|
||||
// param->ParameterType = AddressParameter;
|
||||
// param->InterpretedAs = AddressParameter;
|
||||
|
||||
if (token->Class == NumberClass) {
|
||||
param->ParameterType = ConstantParameter;
|
||||
param->InterpretedAs = AddressParameter;
|
||||
param->Value.Number = token->Value.Number;
|
||||
}
|
||||
else if (token->Class == RegisterClass) {
|
||||
param->ParameterType = RegisterParameter;
|
||||
param->InterpretedAs = AddressParameter;
|
||||
param->Value.Register = token->Value.Register;
|
||||
}
|
||||
else if (token->Class & AddressClass) {
|
||||
param->ParameterType = AddressParameter;
|
||||
param->InterpretedAs = AddressParameter;
|
||||
// symbol = TryGetSymbol(token->Lemexe, MachineState.SymbolsTable);
|
||||
|
||||
symbol = TryGetSymbol(token->Lemexe, MachineState.SymbolsTable);
|
||||
// if (!symbol) symbol = AddSymbolToTable(token->Lemexe, UnresolvedSymbol, MachineState.SymbolsTable);
|
||||
|
||||
if (!symbol) symbol = AddSymbolToTable(token->Lemexe, UnresolvedSymbol, MachineState.SymbolsTable);
|
||||
// param->Value.Symbol = symbol->Name;
|
||||
// }
|
||||
// else {
|
||||
// fprintf(stderr, "[Error] Line %d: Expected identifier, constant number or register.\n", token->LineNumber);
|
||||
// IgnoreParserLine();
|
||||
// //return NULL;
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
param->Value.Symbol = symbol->Name;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "[Error] Line %d: Expected identifier, constant number or register.\n", token->LineNumber);
|
||||
IgnoreParserLine();
|
||||
//return NULL;
|
||||
exit(1);
|
||||
}
|
||||
// AdvanceParser(); //Consume the parameter it self.
|
||||
|
||||
AdvanceParser(); //Consume the parameter it self.
|
||||
// token = PeekToken();
|
||||
|
||||
token = PeekToken();
|
||||
// if (token->Class != PunctuationClass || token->Value.Punctuation != RBracket) {
|
||||
// fprintf(stderr, "[Error] Line %d: Expected closing bracket.\n", token->LineNumber);
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
if (token->Class != PunctuationClass || token->Value.Punctuation != RBracket) {
|
||||
fprintf(stderr, "[Error] Line %d: Expected closing bracket.\n", token->LineNumber);
|
||||
exit(1);
|
||||
}
|
||||
// AdvanceParser(); // ]
|
||||
|
||||
AdvanceParser(); // ]
|
||||
// return param;
|
||||
// case NumberClass:
|
||||
// param->ParameterType = ConstantParameter;
|
||||
// param->InterpretedAs = ConstantParameter;
|
||||
|
||||
return param;
|
||||
case NumberClass:
|
||||
param->ParameterType = ConstantParameter;
|
||||
param->InterpretedAs = ConstantParameter;
|
||||
// param->Value.Number = token->Value.Number;
|
||||
|
||||
param->Value.Number = token->Value.Number;
|
||||
// AdvanceParser();
|
||||
|
||||
AdvanceParser();
|
||||
// return param;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
|
||||
return param;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// return param;
|
||||
// }
|
||||
|
||||
return param;
|
||||
}
|
||||
// Instruction* HandleOperation() {
|
||||
// if (ParserAtEnd()) {
|
||||
// //fprintf(stderr, "[Error] Expected instruction mnemonic\n");
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
Instruction* HandleOperation() {
|
||||
if (ParserAtEnd()) {
|
||||
//fprintf(stderr, "[Error] Expected instruction mnemonic\n");
|
||||
return NULL;
|
||||
}
|
||||
// Token* token = PeekToken();
|
||||
// //char mn[12];
|
||||
|
||||
Token* token = PeekToken();
|
||||
//char mn[12];
|
||||
// if (token->Class != MnemonicClass) {
|
||||
// fprintf(stderr, "[Error] Line %d: Expected instruction mnemonic\n", token->LineNumber);
|
||||
// IgnoreParserLine();
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
if (token->Class != MnemonicClass) {
|
||||
fprintf(stderr, "[Error] Line %d: Expected instruction mnemonic\n", token->LineNumber);
|
||||
IgnoreParserLine();
|
||||
return NULL;
|
||||
}
|
||||
// Instruction* ins = CreateInstruction(token->Value.Mnemonic);
|
||||
|
||||
Instruction* ins = CreateInstruction(token->Value.Mnemonic);
|
||||
// //GetMnemonicText(ins->Mnemonic, mn);
|
||||
|
||||
//GetMnemonicText(ins->Mnemonic, mn);
|
||||
// AdvanceParser();
|
||||
|
||||
AdvanceParser();
|
||||
// //No parameters here, we have a line break.
|
||||
// if (PeekToken()->EndOfFile || (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine)) {
|
||||
// goto InsertInstruction;
|
||||
// }
|
||||
|
||||
//No parameters here, we have a line break.
|
||||
if (PeekToken()->EndOfFile || (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine)) {
|
||||
goto InsertInstruction;
|
||||
}
|
||||
// ins->ParameterOne = GetParameterType();
|
||||
|
||||
ins->ParameterOne = GetParameterType();
|
||||
// if (ins->ParameterOne->ParameterType == NoParameter) {
|
||||
// //This would be an error if the next token isn't a line break.
|
||||
// if (PeekToken()->Class != PunctuationClass || PeekToken()->Value.Punctuation != NewLine) {
|
||||
// fprintf(stderr, "[Error] Line %d: Syntax error, expected line break but got %s.\n", token->LineNumber, token->Lemexe);
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
if (ins->ParameterOne->ParameterType == NoParameter) {
|
||||
//This would be an error if the next token isn't a line break.
|
||||
if (PeekToken()->Class != PunctuationClass || PeekToken()->Value.Punctuation != NewLine) {
|
||||
fprintf(stderr, "[Error] Line %d: Syntax error, expected line break but got %s.\n", token->LineNumber, token->Lemexe);
|
||||
exit(1);
|
||||
}
|
||||
// goto InsertInstruction;
|
||||
// }
|
||||
|
||||
goto InsertInstruction;
|
||||
}
|
||||
// if (PeekToken()->EndOfFile || (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine)) {
|
||||
// goto InsertInstruction;
|
||||
// }
|
||||
|
||||
if (PeekToken()->EndOfFile || (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine)) {
|
||||
goto InsertInstruction;
|
||||
}
|
||||
// if (PeekToken()->Class != PunctuationClass || PeekToken()->Value.Punctuation != Comma) {
|
||||
// //Syntax error
|
||||
// fprintf(stderr, "[Error] Line %d: Expected comma got %d.\n", token->LineNumber, token->Class);
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
if (PeekToken()->Class != PunctuationClass || PeekToken()->Value.Punctuation != Comma) {
|
||||
//Syntax error
|
||||
fprintf(stderr, "[Error] Line %d: Expected comma got %d.\n", token->LineNumber, token->Class);
|
||||
exit(1);
|
||||
}
|
||||
// AdvanceParser(); //Consume the comma
|
||||
|
||||
AdvanceParser(); //Consume the comma
|
||||
// ins->ParameterTwo = GetParameterType();
|
||||
|
||||
ins->ParameterTwo = GetParameterType();
|
||||
// InsertInstruction:
|
||||
|
||||
InsertInstruction:
|
||||
// AddListItem(ins, MachineState.Instructions);
|
||||
|
||||
AddListItem(ins, MachineState.Instructions);
|
||||
// AdvanceParser(); //Consume the line break
|
||||
|
||||
AdvanceParser(); //Consume the line break
|
||||
|
||||
return ins;
|
||||
}
|
||||
// return ins;
|
||||
// }
|
||||
|
||||
void PrintSymbols(void) {
|
||||
char mn[12];
|
||||
//char mn[12];
|
||||
printf("-----SYMBOLS-----\n");
|
||||
for(int i = 0; i < MachineState.SymbolsTable->Size; i++) {
|
||||
Symbol* symbol = MachineState.SymbolsTable->Symbols[i];
|
||||
|
||||
printf("[%s] ", symbol->Type == UnresolvedSymbol ? "Unresolved" : "Resolved");
|
||||
printf("[%s] %s", symbol->Resolved == 0 ? "Unresolved" : "Resolved", symbol->Name);
|
||||
|
||||
switch(symbol->Type) {
|
||||
case InstructionPointerSymbol:
|
||||
GetMnemonicText(symbol->Value.Instruction->Mnemonic, mn);
|
||||
printf("%s -> %s", symbol->Name, mn);
|
||||
break;
|
||||
case NumericSymbol:
|
||||
printf("[N] %s Value: %d", symbol->Name, symbol->Value.Number);
|
||||
break;
|
||||
case StringSymbol:
|
||||
if (symbol->Value.String->Terminated)
|
||||
printf("[S] %s {%s}, %d", symbol->Name, symbol->Value.String->String, symbol->Value.String->TerminatingByte);
|
||||
else
|
||||
printf("[S] %s {%s}", symbol->Name, symbol->Value.String->String);
|
||||
break;
|
||||
case UnresolvedSymbol:
|
||||
printf("[U] %s", symbol->Name);
|
||||
break;
|
||||
}
|
||||
// switch(symbol->Type) {
|
||||
// case InstructionPointerSymbol:
|
||||
// GetMnemonicText(symbol->Value.Instruction->Mnemonic, mn);
|
||||
// printf("%s -> %s", symbol->Name, mn);
|
||||
// break;
|
||||
// case NumericSymbol:
|
||||
// printf("[N] %s Value: %d", symbol->Name, symbol->Value.Number);
|
||||
// break;
|
||||
// case StringSymbol:
|
||||
// if (symbol->Value.String->Terminated)
|
||||
// printf("[S] %s {%s}, %d", symbol->Name, symbol->Value.String->String, symbol->Value.String->TerminatingByte);
|
||||
// else
|
||||
// printf("[S] %s {%s}", symbol->Name, symbol->Value.String->String);
|
||||
// break;
|
||||
// case UnresolvedSymbol:
|
||||
// printf("[U] %s", symbol->Name);
|
||||
// break;
|
||||
// }
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@@ -283,6 +283,14 @@ Token* ParseIdentifier(void) {
|
||||
|
||||
return token;
|
||||
}
|
||||
if (strcmp(lexeme, "load") == 0) {
|
||||
Token* token = CreateToken(Line, DirectiveClass);
|
||||
|
||||
token->Lemexe = lexeme;
|
||||
token->Value.Directive = Load;
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
Token* token = CreateToken(Line, IdentifierClass);
|
||||
|
||||
|
||||
+14
-25
@@ -25,7 +25,7 @@ SymbolTable* CreateSymbolTable(void){
|
||||
return table;
|
||||
}
|
||||
|
||||
Symbol* CreateSymbol(char* name, SymbolType type) {
|
||||
Symbol* CreateSymbol(char* name, int address, int resolved) {
|
||||
Symbol* symbol = calloc(1, sizeof(Symbol));
|
||||
|
||||
if (!symbol) {
|
||||
@@ -34,40 +34,29 @@ Symbol* CreateSymbol(char* name, SymbolType type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
symbol->Type = type;
|
||||
symbol->Address = address;
|
||||
symbol->Name = name;
|
||||
symbol->Resolved = resolved;
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
SymbolString* CreateSymbolString(char* string, int terminated) {
|
||||
if (!string) return NULL;
|
||||
int TryGetSymbol(char* name, SymbolTable* table, Symbol** outSymbol) {
|
||||
*outSymbol = 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;
|
||||
if (!name || !table) return 0;
|
||||
|
||||
for(int i = 0; i < table->Size; i++) {
|
||||
if (strcmp(table->Symbols[i]->Name, name) == 0) return table->Symbols[i];
|
||||
if (strcmp(table->Symbols[i]->Name, name) == 0) {
|
||||
*outSymbol = table->Symbols[i];
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Symbol* AddSymbolToTable(char* name, SymbolType type, SymbolTable* table) {
|
||||
Symbol* AddSymbolToTable(char* name, int address, int resolved, SymbolTable* table) {
|
||||
//if (!name || !value || !table || length == 0) return NULL;
|
||||
|
||||
for(int i = 0; i < table->Size; i++) {
|
||||
@@ -79,7 +68,7 @@ Symbol* AddSymbolToTable(char* name, SymbolType type, SymbolTable* table) {
|
||||
}
|
||||
|
||||
if (table->Capacity < table->Size + 1) {
|
||||
Symbol** newBlock = realloc(table->Symbols, sizeof(Symbol*) * table->Capacity * 2);//calloc(table->Size * 2, sizeof(Symbol*));
|
||||
Symbol** newBlock = realloc(table->Symbols, sizeof(Symbol*) * table->Capacity * 2);
|
||||
|
||||
if (!newBlock) {
|
||||
fprintf(stderr, "Failed to realloc space for a new symbol '%s'. %s.\n", name, strerror(errno));
|
||||
@@ -91,7 +80,7 @@ Symbol* AddSymbolToTable(char* name, SymbolType type, SymbolTable* table) {
|
||||
table->Symbols = newBlock;
|
||||
}
|
||||
|
||||
Symbol* symbol = CreateSymbol(name, type);
|
||||
Symbol* symbol = CreateSymbol(name, address, resolved);
|
||||
|
||||
table->Symbols[table->Size] = symbol;
|
||||
table->Size++;
|
||||
|
||||
Reference in New Issue
Block a user