Updated the parser to better handle parameters, sort of and including a string length assembly program to use as a test for the whole assembler.

This commit is contained in:
2022-10-03 21:26:28 +00:00
parent 706f480e31
commit be91e3c112
5 changed files with 76 additions and 73 deletions
+47 -45
View File
@@ -10,19 +10,14 @@ int CurrentToken = 0;
//int HeapStart = 4; // zero indexed, used for declared variables.
//int BinaryEnd = 4; // Zero indexed (binary starts with a 4 byte header)
//IROpcode* CreateIROpcode(Mnemonic mnemonic);
void PrintSymbols(void);
void HandleOperation(void);
void HandleAssemblerDirective(void);
void AdvanceParser(void);
void IgnoreParserLine(void);
Token* PeekToken(void);
int ParserAtEnd(void);
int Expect(int, ...);
//List* SymbolsTable;
// unsigned int HeapTop = 4;
// unsigned int ProgramCounter = 0;
// unsigned char Heap[HIGHMEMORY];
// unsigned char Memory[HIGHMEMORY];
IRState MachineState;
IRState* ParseTokens(List* tokens) {
@@ -40,9 +35,8 @@ IRState* ParseTokens(List* tokens) {
Token* t = PeekToken();
switch(t->Class) {
case DirectiveClass:
//HandleAssemblerDirective();
//while(!ParserAtEnd() && (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation != NewLine)) AdvanceParser();
case DirectiveClass: //Maybe these should be ignored, let another process handle that.
IgnoreParserLine();
break;
case MnemonicClass:
HandleOperation();
@@ -50,7 +44,7 @@ IRState* ParseTokens(List* tokens) {
case LabelClass:
printf("%s: \n", t->Lemexe);
AddSymbolToTable(t->Lemexe, NULL, strlen(t->Lemexe), MachineState.SymbolsTable);
//AddSymbol(t, 2, ProgramCounter, 1);
AdvanceParser(); //Consume the NewLine
break;
default:
fprintf(stderr, "[Error] Line %d: Syntax error, expected start of expression, got '%c' [%d].\n", t->LineNumber, t->Value.Punctuation, t->Class);
@@ -161,45 +155,43 @@ void HandleOperation() {
AdvanceParser();
while(!ParserAtEnd()) {
if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) {
break;
}
ins->ParameterOneType = GetParameterType(&token);
if (ins->ParameterOneType == NoParameter) {
AdvanceParser(); //Comsume the line end
break;
}
if (PeekToken()->Class == PunctuationClass) {
if (PeekToken()->Value.Punctuation == NewLine) {
AdvanceParser(); //Comsume end line.
break;
}
else if (PeekToken()->Value.Punctuation != Comma) {
fprintf(stderr, "[Error] Line %d: comma need for %s\n", token->LineNumber, mn);
exit(1);
}
} else {
fprintf(stderr, "[Error] Line %d: comma needed for %s\n", token->LineNumber, mn);
exit(1);
}
AdvanceParser(); //Comsume the comma
ins->ParameterTwoType = GetParameterType(&token);
AdvanceParser();//comsume the end line.
break;
//AdvanceParser();
//No parameters here, we have a line break.
if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) {
goto InsertInstruction;
}
ins->ParameterOneType = GetParameterType(&token);
if (ins->ParameterOneType == 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;
}
if (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.\n", token->LineNumber);
exit(1);
}
AdvanceParser(); //Consume the comma
ins->ParameterTwoType = GetParameterType(&token);
InsertInstruction:
AddListItem(ins, sizeof(Instruction), MachineState.Instructions);
AdvanceParser(); //Consume the line break
free(ins);
}
@@ -651,4 +643,14 @@ int ParserAtEnd(void) {
Token* PeekToken(void) {
return TokensList->content[CurrentToken];
}
void IgnoreParserLine(void) {
while(!ParserAtEnd()) {
if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) break;
if (PeekToken()->EndOfFile) break;
AdvanceParser();
}
}