Refactored the code and added expect functions to make the code flow a bit nicer.

This commit is contained in:
2023-03-29 12:41:53 -05:00
parent fa12a04bb3
commit ee60d14570
2 changed files with 73 additions and 46 deletions
+2 -1
View File
@@ -6,6 +6,7 @@
;load r2, label ;load r2, label
something_insance: something_insance:
load r1, unknown_symbol
load byte r1, r3 load byte r1, r3
load r1, r3
load r1, 5 load r1, 5
load r3, r4
+70 -44
View File
@@ -11,21 +11,19 @@ List* TokensList;
int CurrentToken = 0; int CurrentToken = 0;
void PrintSymbols(void); void PrintSymbols(void);
void HandleOperation(void);
void RemoveCurrentToken(void); void RemoveCurrentToken(void);
void HandleAssemblerDirective(void); void HandleAssemblerDirective(void);
void HandleAssemblerDirective(void);
void AdvanceParser(void); void AdvanceParser(void);
void IgnoreParserLine(void); void IgnoreParserLine(void);
Token* PeekToken(void); Token* PeekToken(void);
int ParserAtEnd(void); int ParserAtEnd(void);
int Expect(TokenClass class, void* value);
IRState MachineState; IRState MachineState;
void ExpectPuncuation(TokenPunctuation punctuation, ExpectOptions options); void ExpectPuncuation(TokenPunctuation punctuation, ExpectOptions options);
void ExpectRegister(void); void ExpectRegister(void);
Symbol* ExpectIdentifier(int resolved, ExpectOptions options); Symbol* ExpectIdentifier(int resolved, ExpectOptions options);
//int ExpectIdentifier(); void ExpectCharacterClass(Symbol* symbol);
void ExpectLineEndOrFileEnd(ExpectOptions options);
int HeapSize = 0; int HeapSize = 0;
int PC = 0; int PC = 0;
@@ -41,7 +39,6 @@ IRState* ParseTokens(List* tokens) {
while(!ParserAtEnd()) { while(!ParserAtEnd()) {
Token* t = PeekToken(); Token* t = PeekToken();
if (!t || t->EndOfFile) break; if (!t || t->EndOfFile) break;
Symbol* tmp;
switch(t->Class) { switch(t->Class) {
case DirectiveClass: case DirectiveClass:
@@ -52,18 +49,20 @@ IRState* ParseTokens(List* tokens) {
break; break;
case LabelClass: 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); fprintf(stderr, "[Error] Line %d: Redefinition of symbol '%s'\n", t->LineNumber, t->Lemexe);
exit(1); exit(1);
} }
if (!found) AddSymbolToTable(t->Lemexe, HeapSize, 1, MachineState.SymbolsTable); if (!found) AddSymbolToTable(t->Lemexe, HeapSize, 1, MachineState.SymbolsTable);
else tmp->Resolved = 1; else symbol->Resolved = 1;
RemoveCurrentToken(); //label RemoveCurrentToken(); //label
RemoveCurrentToken(); //newline
ExpectLineEndOrFileEnd(RemoveExpected);
} }
break; break;
default: default:
@@ -72,11 +71,6 @@ IRState* ParseTokens(List* tokens) {
//IgnoreParserLine(); //IgnoreParserLine();
break; break;
} }
// if (last == CurrentToken) {
// printf("Failed %d\n", CurrentToken);
// exit(90);
// }
} }
PrintSymbols(); PrintSymbols();
@@ -94,39 +88,18 @@ void HandleAssemblerDirective() {
Symbol* symbol = ExpectIdentifier(1, RemoveExpected); Symbol* symbol = ExpectIdentifier(1, RemoveExpected);
Token* value = PeekToken(); if (PeekToken()->Class == CharacterClass) {
ExpectCharacterClass(symbol);
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);
}
} }
else if (PeekToken()->Class == NumberClass) { else if (PeekToken()->Class == NumberClass) {
symbol->Length = 2; symbol->Length = 2;
RemoveCurrentToken(); //Clear the number token. RemoveCurrentToken(); //Clear the number token.
ExpectLineEndOrFileEnd(RemoveExpected);
} }
HeapSize += symbol->Length; HeapSize += symbol->Length;
RemoveCurrentToken(); //Wipe the line end token
} }
break; break;
case Load: case Load:
@@ -135,7 +108,7 @@ void HandleAssemblerDirective() {
Token* reg = PeekToken(); Token* reg = PeekToken();
if (reg->Class != RegisterClass && reg->Class != DirectiveClass) { 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); exit(1);
} }
@@ -153,23 +126,25 @@ void HandleAssemblerDirective() {
directive->Class = MnemonicClass; directive->Class = MnemonicClass;
directive->Value.Mnemonic = LODWI; directive->Value.Mnemonic = LODWI;
directive->Lemexe = "LODWI"; directive->Lemexe = "LODWI";
AdvanceParser(); //Number, register or identifier
} }
else if (PeekToken()->Class == RegisterClass) { else if (PeekToken()->Class == RegisterClass) {
directive->Class = MnemonicClass; directive->Class = MnemonicClass;
directive->Value.Mnemonic = LODW; directive->Value.Mnemonic = LODW;
directive->Lemexe = "LODW"; directive->Lemexe = "LODW";
AdvanceParser(); //Number, register or identifier
} }
else { else {
ExpectIdentifier(0, ForwardParser);
directive->Class = MnemonicClass; directive->Class = MnemonicClass;
directive->Value.Mnemonic = LAA; directive->Value.Mnemonic = LAA;
directive->Lemexe = "LAA"; directive->Lemexe = "LAA";
} }
AdvanceParser(); //Number, register or identifier
} }
else if (reg->Class == DirectiveClass) { else if (reg->Class == DirectiveClass) {
if (reg->Value.Directive != Byte) { 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); exit(3);
} }
@@ -186,7 +161,7 @@ void HandleAssemblerDirective() {
directive->Lemexe = "LODB"; directive->Lemexe = "LODB";
} }
AdvanceParser(); //Line end ExpectLineEndOrFileEnd(ForwardParser);
} }
break; break;
@@ -255,6 +230,57 @@ Symbol* ExpectIdentifier(int resolved, ExpectOptions options) {
return symbol; 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) { void PrintSymbols(void) {
//char mn[12]; //char mn[12];
printf("-----SYMBOLS-----\n"); printf("-----SYMBOLS-----\n");