diff --git a/includes/symbols_table.h b/includes/symbols_table.h index 5c55735..4e74cc7 100644 --- a/includes/symbols_table.h +++ b/includes/symbols_table.h @@ -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); diff --git a/includes/token.h b/includes/token.h index a26acdd..cf3f5e2 100644 --- a/includes/token.h +++ b/includes/token.h @@ -24,7 +24,9 @@ typedef enum { typedef enum { DB, Include, - Byte + Byte, + Load, + Store } Directive; typedef enum { diff --git a/misc/test.asm b/misc/test.asm index 7bc3d3a..3ffc897 100644 --- a/misc/test.asm +++ b/misc/test.asm @@ -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 diff --git a/src/main.c b/src/main.c index 0753371..ab85657 100644 --- a/src/main.c +++ b/src/main.c @@ -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); } \ No newline at end of file diff --git a/src/parser.c b/src/parser.c index a83e615..703c0e1 100644 --- a/src/parser.c +++ b/src/parser.c @@ -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"); } diff --git a/src/scanner.c b/src/scanner.c index f3c5011..bd27284 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -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); diff --git a/src/symbols_table.c b/src/symbols_table.c index bcd2a18..1013e94 100644 --- a/src/symbols_table.c +++ b/src/symbols_table.c @@ -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++;