diff --git a/misc/test.asm b/misc/test.asm index e200780..640f12d 100644 --- a/misc/test.asm +++ b/misc/test.asm @@ -6,6 +6,7 @@ ;load r2, label something_insance: +load r1, unknown_symbol load byte r1, r3 -load r1, r3 -load r1, 5 \ No newline at end of file +load r1, 5 +load r3, r4 \ No newline at end of file diff --git a/src/parser.c b/src/parser.c index e347e8b..3078882 100644 --- a/src/parser.c +++ b/src/parser.c @@ -11,21 +11,19 @@ List* TokensList; int CurrentToken = 0; void PrintSymbols(void); -void HandleOperation(void); void RemoveCurrentToken(void); void HandleAssemblerDirective(void); -void HandleAssemblerDirective(void); void AdvanceParser(void); void IgnoreParserLine(void); Token* PeekToken(void); int ParserAtEnd(void); -int Expect(TokenClass class, void* value); IRState MachineState; void ExpectPuncuation(TokenPunctuation punctuation, ExpectOptions options); void ExpectRegister(void); Symbol* ExpectIdentifier(int resolved, ExpectOptions options); -//int ExpectIdentifier(); +void ExpectCharacterClass(Symbol* symbol); +void ExpectLineEndOrFileEnd(ExpectOptions options); int HeapSize = 0; int PC = 0; @@ -41,7 +39,6 @@ IRState* ParseTokens(List* tokens) { while(!ParserAtEnd()) { Token* t = PeekToken(); if (!t || t->EndOfFile) break; - Symbol* tmp; switch(t->Class) { case DirectiveClass: @@ -52,18 +49,20 @@ IRState* ParseTokens(List* tokens) { break; case LabelClass: { - int found = TryGetSymbol(t->Lemexe, MachineState.SymbolsTable, &tmp); + Symbol* symbol; + int found = TryGetSymbol(t->Lemexe, MachineState.SymbolsTable, &symbol); - if (found && tmp->Resolved) { + if (found && symbol->Resolved) { fprintf(stderr, "[Error] Line %d: Redefinition of symbol '%s'\n", t->LineNumber, t->Lemexe); exit(1); } if (!found) AddSymbolToTable(t->Lemexe, HeapSize, 1, MachineState.SymbolsTable); - else tmp->Resolved = 1; + else symbol->Resolved = 1; RemoveCurrentToken(); //label - RemoveCurrentToken(); //newline + + ExpectLineEndOrFileEnd(RemoveExpected); } break; default: @@ -72,11 +71,6 @@ IRState* ParseTokens(List* tokens) { //IgnoreParserLine(); break; } - - // if (last == CurrentToken) { - // printf("Failed %d\n", CurrentToken); - // exit(90); - // } } PrintSymbols(); @@ -94,39 +88,18 @@ void HandleAssemblerDirective() { Symbol* symbol = ExpectIdentifier(1, RemoveExpected); - Token* value = PeekToken(); - - if (value->Class == CharacterClass) { - symbol->Length = strlen(value->Lemexe); - - RemoveCurrentToken(); //Remove the string declared by this DB command. - - if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == Comma) { - ExpectPuncuation(Comma, RemoveExpected); - - if (PeekToken()->Class != NumberClass) { - fprintf(stderr, "Syntax error line %d: Expected terminating byte.\n", PeekToken()->LineNumber); - exit(1); - } - - RemoveCurrentToken(); //Remove terminating byte - - symbol->Length++; - } - else if (PeekToken()->Class != PunctuationClass || PeekToken()->Value.Punctuation != NewLine) { - fprintf(stderr, "Syntax error line %d: Expected COMMA.", PeekToken()->LineNumber); - exit(1); - } + if (PeekToken()->Class == CharacterClass) { + ExpectCharacterClass(symbol); } else if (PeekToken()->Class == NumberClass) { symbol->Length = 2; RemoveCurrentToken(); //Clear the number token. + + ExpectLineEndOrFileEnd(RemoveExpected); } HeapSize += symbol->Length; - - RemoveCurrentToken(); //Wipe the line end token } break; case Load: @@ -135,7 +108,7 @@ void HandleAssemblerDirective() { Token* reg = PeekToken(); if (reg->Class != RegisterClass && reg->Class != DirectiveClass) { - fprintf(stderr, "Syntax error line %d: Expected register or directive 'byte', got %d.", reg->LineNumber, reg->Class); + fprintf(stderr, "[Line %d] Syntax error, expected register or keyword 'byte'.\n", reg->LineNumber); exit(1); } @@ -153,23 +126,25 @@ void HandleAssemblerDirective() { directive->Class = MnemonicClass; directive->Value.Mnemonic = LODWI; directive->Lemexe = "LODWI"; + AdvanceParser(); //Number, register or identifier } else if (PeekToken()->Class == RegisterClass) { directive->Class = MnemonicClass; directive->Value.Mnemonic = LODW; directive->Lemexe = "LODW"; + AdvanceParser(); //Number, register or identifier } else { + ExpectIdentifier(0, ForwardParser); + directive->Class = MnemonicClass; directive->Value.Mnemonic = LAA; directive->Lemexe = "LAA"; } - - AdvanceParser(); //Number, register or identifier } else if (reg->Class == DirectiveClass) { if (reg->Value.Directive != Byte) { - fprintf(stderr, "Syntax error: Line %d expected keyword 'byte'.\n", reg->LineNumber); + fprintf(stderr, "[Line %d] Syntax error, expected keyword 'byte'.\n", reg->LineNumber); exit(3); } @@ -186,7 +161,7 @@ void HandleAssemblerDirective() { directive->Lemexe = "LODB"; } - AdvanceParser(); //Line end + ExpectLineEndOrFileEnd(ForwardParser); } break; @@ -255,6 +230,57 @@ Symbol* ExpectIdentifier(int resolved, ExpectOptions options) { return symbol; } +void ExpectCharacterClass(Symbol* symbol) { + Token* token = PeekToken(); + + if (token->Class != CharacterClass) { + fprintf(stderr, "[Line %d] Syntax error, expected character string.\n", token->LineNumber); + exit(5); + } + + symbol->Length = strlen(token->Lemexe); + + RemoveCurrentToken(); //Remove the string declared by this DB command. + + token = PeekToken(); + + if (token->EndOfFile) return; + + if (token->Class == PunctuationClass && token->Value.Punctuation == NewLine) { + RemoveCurrentToken(); + return; + } + + ExpectPuncuation(Comma, RemoveExpected); + + token = PeekToken(); + + if (token->Class != NumberClass) { + fprintf(stderr, "[Line %d] Syntax error, expected terminating byte.\n", token->LineNumber); + exit(7); + } + + RemoveCurrentToken(); //Remove terminating byte. + //TODO: add the raw value of the byte to the end of the string, but for now just pretend all numbers are zero. + symbol->Length++; + + ExpectLineEndOrFileEnd(RemoveExpected); +} + +void ExpectLineEndOrFileEnd(ExpectOptions options) { + Token* token = PeekToken(); + + if (token->EndOfFile) return; + + if (token->Class != PunctuationClass || token->Value.Punctuation != NewLine) { + fprintf(stderr, "[Line %d] Syntax error, expected line break.\n", token->LineNumber); + exit(9); + } + + if (options & RemoveExpected) RemoveCurrentToken(); + if (options & ForwardParser) AdvanceParser(); +} + void PrintSymbols(void) { //char mn[12]; printf("-----SYMBOLS-----\n");