Moved some of the grunt work to their own functions to clean the code up a bit.

This commit is contained in:
2023-03-28 22:14:31 -05:00
parent 2d7aad1617
commit fa12a04bb3
+72 -59
View File
@@ -3,6 +3,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
typedef enum {
NoOptions = 0, ForwardParser = 1, RemoveExpected = 2
} ExpectOptions;
List* TokensList; List* TokensList;
int CurrentToken = 0; int CurrentToken = 0;
@@ -18,7 +22,9 @@ int ParserAtEnd(void);
int Expect(TokenClass class, void* value); int Expect(TokenClass class, void* value);
IRState MachineState; IRState MachineState;
//int ExpectPuncuation(TokenPunctuation punctuation); void ExpectPuncuation(TokenPunctuation punctuation, ExpectOptions options);
void ExpectRegister(void);
Symbol* ExpectIdentifier(int resolved, ExpectOptions options);
//int ExpectIdentifier(); //int ExpectIdentifier();
int HeapSize = 0; int HeapSize = 0;
@@ -35,7 +41,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;
int last = CurrentToken;
Symbol* tmp; Symbol* tmp;
switch(t->Class) { switch(t->Class) {
@@ -43,7 +48,7 @@ IRState* ParseTokens(List* tokens) {
HandleAssemblerDirective(); HandleAssemblerDirective();
break; break;
case MnemonicClass: case MnemonicClass:
HandleOperation(); //HandleOperation();
break; break;
case LabelClass: case LabelClass:
{ {
@@ -87,31 +92,7 @@ void HandleAssemblerDirective() {
{ {
RemoveCurrentToken(); RemoveCurrentToken();
Token* identifier = PeekToken(); Symbol* symbol = ExpectIdentifier(1, RemoveExpected);
if (identifier->Class != IdentifierClass) {
fprintf(stderr, "[Line %d] Expected Identifier '%c'\n", identifier->LineNumber, identifier->Value.Punctuation);
exit(30);
}
Symbol* symbol;
int found = TryGetSymbol(identifier->Lemexe, MachineState.SymbolsTable, &symbol);
if (found && symbol->Resolved) {
fprintf(stderr, "Redefinition of %s on line %d.\n", identifier->Lemexe, identifier->LineNumber);
exit(1);
}
if (found) {
symbol->Address = HeapSize;
symbol->Resolved = 1;
}
else {
symbol = AddSymbolToTable(identifier->Lemexe, HeapSize, 1, MachineState.SymbolsTable);
}
RemoveCurrentToken(); //Remove the Idenifier name token.
Token* value = PeekToken(); Token* value = PeekToken();
@@ -121,11 +102,7 @@ void HandleAssemblerDirective() {
RemoveCurrentToken(); //Remove the string declared by this DB command. RemoveCurrentToken(); //Remove the string declared by this DB command.
if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == Comma) { if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == Comma) {
if (PeekToken()->Value.Punctuation != Comma) { ExpectPuncuation(Comma, RemoveExpected);
fprintf(stderr, "Syntax error line %d: Expected COMMA got %c.", PeekToken()->LineNumber, PeekToken()->Value.Punctuation);
exit(1);
}
RemoveCurrentToken(); //Remove COMMA
if (PeekToken()->Class != NumberClass) { if (PeekToken()->Class != NumberClass) {
fprintf(stderr, "Syntax error line %d: Expected terminating byte.\n", PeekToken()->LineNumber); fprintf(stderr, "Syntax error line %d: Expected terminating byte.\n", PeekToken()->LineNumber);
@@ -137,7 +114,7 @@ void HandleAssemblerDirective() {
symbol->Length++; symbol->Length++;
} }
else if (PeekToken()->Class != PunctuationClass || PeekToken()->Value.Punctuation != NewLine) { else if (PeekToken()->Class != PunctuationClass || PeekToken()->Value.Punctuation != NewLine) {
fprintf(stderr, "Syntax error line %d: Expected COMMA got %c.", PeekToken()->LineNumber, PeekToken()->Value.Punctuation); fprintf(stderr, "Syntax error line %d: Expected COMMA.", PeekToken()->LineNumber);
exit(1); exit(1);
} }
} }
@@ -165,19 +142,14 @@ void HandleAssemblerDirective() {
if (reg->Class == RegisterClass) { if (reg->Class == RegisterClass) {
AdvanceParser(); AdvanceParser();
if (PeekToken()->Class != PunctuationClass || PeekToken()->Value.Punctuation != Comma) { ExpectPuncuation(Comma, ForwardParser);
exit(1); if (PeekToken()->Class != IdentifierClass && PeekToken()->Class != NumberClass && PeekToken()->Class != RegisterClass) {
} fprintf(stderr, "[Line %d] Syntax error, expected either a symbol, numeric literal or a register.\n", PeekToken()->LineNumber);
AdvanceParser(); //Save the comma
if (PeekToken()->Class != IdentifierClass && PeekToken()->Class != NumberClass && PeekToken()->Class != RegisterClass){
exit(2); exit(2);
} }
if (PeekToken()->Class == NumberClass) { if (PeekToken()->Class == NumberClass) {
printf("LODWI\n");
directive->Class = MnemonicClass; directive->Class = MnemonicClass;
directive->Value.Mnemonic = LODWI; directive->Value.Mnemonic = LODWI;
directive->Lemexe = "LODWI"; directive->Lemexe = "LODWI";
@@ -188,7 +160,6 @@ void HandleAssemblerDirective() {
directive->Lemexe = "LODW"; directive->Lemexe = "LODW";
} }
else { else {
printf("LAA\n");
directive->Class = MnemonicClass; directive->Class = MnemonicClass;
directive->Value.Mnemonic = LAA; directive->Value.Mnemonic = LAA;
directive->Lemexe = "LAA"; directive->Lemexe = "LAA";
@@ -204,23 +175,11 @@ void HandleAssemblerDirective() {
RemoveCurrentToken(); AdvanceParser(); //byte RemoveCurrentToken(); AdvanceParser(); //byte
if (PeekToken()->Class != RegisterClass) { ExpectRegister();
exit(3);
}
AdvanceParser(); //reg ExpectPuncuation(Comma, ForwardParser);
if (PeekToken()->Class != PunctuationClass) { ExpectRegister();
exit(7);
}
AdvanceParser(); //Comma
if (PeekToken()->Class != RegisterClass) {
exit(4);
}
AdvanceParser(); //Reg
directive->Class = MnemonicClass; directive->Class = MnemonicClass;
directive->Value.Mnemonic = LODB; directive->Value.Mnemonic = LODB;
@@ -230,6 +189,11 @@ void HandleAssemblerDirective() {
AdvanceParser(); //Line end AdvanceParser(); //Line end
} }
break;
case Store:
{
}
break; break;
default: default:
fprintf(stderr, "Synatx error on line %d, %s.\n", directive->LineNumber, directive->Lemexe); fprintf(stderr, "Synatx error on line %d, %s.\n", directive->LineNumber, directive->Lemexe);
@@ -237,10 +201,59 @@ void HandleAssemblerDirective() {
} }
} }
void HandleOperation(void) { void ExpectPuncuation(TokenPunctuation punctuation, ExpectOptions options) {
Token* token = PeekToken();
if (token->Class != PunctuationClass || token->Value.Punctuation != punctuation) {
fprintf(stderr, "[Line %d] Syntac error, expected %c.\n", token->LineNumber, punctuation);
exit(1);
}
if (options & RemoveExpected) RemoveCurrentToken();
if (options & ForwardParser) AdvanceParser();
} }
void ExpectRegister() {
Token* token = PeekToken();
if (token->Class != RegisterClass) {
fprintf(stderr, "[Line %d] Syntax error, expected Register.\n", token->LineNumber);
exit(2);
}
AdvanceParser();
}
Symbol* ExpectIdentifier(int resolved, ExpectOptions options) {
Token* token = PeekToken();
if (token->Class != IdentifierClass) {
fprintf(stderr, "[Line %d] Expected Identifier.\n", token->LineNumber);
exit(3);
}
Symbol* symbol;
int found = TryGetSymbol(token->Lemexe, MachineState.SymbolsTable, &symbol);
if (found && symbol->Resolved && resolved) {
fprintf(stderr, "[Line %d] Redefinition of symbol '%s'.\n", token->LineNumber, token->Lemexe);
exit(4);
}
if (found) {
symbol->Address = HeapSize;
symbol->Resolved = resolved || symbol->Resolved;
}
else {
symbol = AddSymbolToTable(token->Lemexe, HeapSize, resolved, MachineState.SymbolsTable);
}
if (options & RemoveExpected) RemoveCurrentToken();
if (options & ForwardParser) AdvanceParser();
return symbol;
}
void PrintSymbols(void) { void PrintSymbols(void) {
//char mn[12]; //char mn[12];