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
+3 -2
View File
@@ -6,6 +6,7 @@
;load r2, label
something_insance:
load r1, unknown_symbol
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;
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");