Massive refactoring to simplify this whole setup. The Token List will be modified in place and reused in the Parser to normalize the list and generate a symbols table. Normalizing the token list will make sure the syntax is valid and the symbols table will have the relative offsets and length of symbol values. At least this is all the plan but one step at a time.
This commit is contained in:
+161
-173
@@ -14,6 +14,9 @@ Token* PeekToken(void);
|
||||
int ParserAtEnd(void);
|
||||
IRState MachineState;
|
||||
|
||||
int HeapSize = 0;
|
||||
int PC = 0;
|
||||
|
||||
IRState* ParseTokens(List* tokens) {
|
||||
if (!tokens) return NULL;
|
||||
|
||||
@@ -24,49 +27,53 @@ IRState* ParseTokens(List* tokens) {
|
||||
|
||||
while(!ParserAtEnd()) {
|
||||
Token* t = PeekToken();
|
||||
Symbol* tmp;
|
||||
//printf("Tyoe: %d\n", t->Class);
|
||||
|
||||
switch(t->Class) {
|
||||
case DirectiveClass: //Maybe these should be ignored, let another process handle that.
|
||||
HandleAssemblerDirective();
|
||||
//HandleAssemblerDirective();
|
||||
break;
|
||||
case MnemonicClass:
|
||||
HandleOperation();
|
||||
//HandleOperation();
|
||||
break;
|
||||
case LabelClass:
|
||||
{
|
||||
Symbol* symbol = TryGetSymbol(t->Lemexe, MachineState.SymbolsTable);
|
||||
int found = TryGetSymbol(t->Lemexe, MachineState.SymbolsTable, &tmp);
|
||||
|
||||
if (symbol && symbol->Type != UnresolvedSymbol) {
|
||||
fprintf(stderr, "[Error] Line %d: Redefinition of symbol '%s' (type: %d)\n", t->LineNumber, t->Lemexe, symbol->Type);
|
||||
if (found && tmp->Resolved) {
|
||||
fprintf(stderr, "[Error] Line %d: Redefinition of symbol '%s'\n", t->LineNumber, t->Lemexe);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
AdvanceParser(); //Consume the label token
|
||||
|
||||
if (!symbol) symbol = AddSymbolToTable(t->Lemexe, InstructionPointerSymbol, MachineState.SymbolsTable);
|
||||
else symbol->Type = InstructionPointerSymbol;
|
||||
if (!found) AddSymbolToTable(t->Lemexe, HeapSize, 1, MachineState.SymbolsTable);
|
||||
else tmp->Resolved = 1;
|
||||
|
||||
AdvanceParser(); //Consume the NewLine
|
||||
|
||||
Instruction* ins = HandleOperation();
|
||||
//Instruction* ins = HandleOperation();
|
||||
|
||||
if (!ins) {
|
||||
fprintf(stderr, "[Error] Line %d: Expected instruction following label '%s'.\n", t->LineNumber, t->Lemexe);
|
||||
exit(1);
|
||||
}
|
||||
// if (!ins) {
|
||||
// fprintf(stderr, "[Error] Line %d: Expected instruction following label '%s'.\n", t->LineNumber, t->Lemexe);
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
symbol->Value.Instruction = ins;
|
||||
//symbol->Value.Instruction = ins;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "[Warning] Line %d: Syntax error, expected start of expression, got '%c' [%d].\n", t->LineNumber, t->Value.Punctuation, t->Class);
|
||||
//fprintf(stderr, "[Warning] Line %d: Syntax error, expected start of expression, got '%c' [%d].\n", t->LineNumber, t->Value.Punctuation, t->Class);
|
||||
//exit(1);
|
||||
IgnoreParserLine();
|
||||
//IgnoreParserLine();
|
||||
break;
|
||||
}
|
||||
|
||||
AdvanceParser();
|
||||
}
|
||||
|
||||
if (MachineState.SymbolsTable->Size > 0) PrintSymbols();
|
||||
PrintSymbols();
|
||||
|
||||
return &MachineState;
|
||||
}
|
||||
@@ -94,12 +101,10 @@ void HandleAssemblerDirective() {
|
||||
|
||||
if (token->Class == NumberClass) {
|
||||
//Delcaring a numeric value.
|
||||
Symbol* s = AddSymbolToTable(symbolname, NumericSymbol, MachineState.SymbolsTable);
|
||||
|
||||
s->Value.Number = token->Value.Number;
|
||||
Symbol* s = AddSymbolToTable(symbolname, HeapSize, 1, MachineState.SymbolsTable);
|
||||
}
|
||||
else if (token->Class == CharacterClass) {
|
||||
Symbol* s = AddSymbolToTable(symbolname, StringSymbol, MachineState.SymbolsTable);
|
||||
Symbol* s = AddSymbolToTable(symbolname, HeapSize, 1, MachineState.SymbolsTable);
|
||||
char* string = token->Lemexe;
|
||||
|
||||
AdvanceParser();
|
||||
@@ -119,213 +124,196 @@ void HandleAssemblerDirective() {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
s->Value.String = CreateSymbolString(string, 1);
|
||||
s->Value.String->TerminatingByte = token->Value.Number;
|
||||
//s->Value.String = CreateSymbolString(string, 1);
|
||||
//s->Value.String->TerminatingByte = token->Value.Number;
|
||||
}
|
||||
else s->Value.String = CreateSymbolString(string, 0);
|
||||
//else s->Value.String = CreateSymbolString(string, 0);
|
||||
}
|
||||
|
||||
IgnoreParserLine();
|
||||
}
|
||||
|
||||
Parameter* GetParameterType() {
|
||||
Token* token = PeekToken();
|
||||
Symbol* symbol = NULL;
|
||||
Parameter* param = CreateParameter(NoParameter);
|
||||
// Parameter* GetParameterType() {
|
||||
// Token* token = PeekToken();
|
||||
// Symbol* symbol = NULL;
|
||||
// int found = 0;
|
||||
// //Parameter* param = CreateParameter(NoParameter);
|
||||
|
||||
switch(token->Class) {
|
||||
case RegisterClass:
|
||||
param->ParameterType = RegisterParameter;
|
||||
param->InterpretedAs = RegisterParameter;
|
||||
// switch(token->Class) {
|
||||
// // case RegisterClass:
|
||||
// // param->ParameterType = RegisterParameter;
|
||||
// // param->InterpretedAs = RegisterParameter;
|
||||
|
||||
param->Value.Register = token->Value.Register;
|
||||
// // param->Value.Register = token->Value.Register;
|
||||
|
||||
AdvanceParser();
|
||||
// // AdvanceParser();
|
||||
|
||||
return param;
|
||||
//case LabelClass:
|
||||
case IdentifierClass:
|
||||
param->ParameterType = AddressParameter;
|
||||
//param->InterpretedAs = AddressParameter;
|
||||
// // return param;
|
||||
// //case LabelClass:
|
||||
// case IdentifierClass:
|
||||
// found = TryGetSymbol(token->Lemexe, MachineState.SymbolsTable, &symbol);
|
||||
|
||||
symbol = TryGetSymbol(token->Lemexe, MachineState.SymbolsTable);
|
||||
// if (!found) {
|
||||
// AddSymbolToTable(token->Lemexe, HeapSize, 0, MachineState.SymbolsTable);
|
||||
// }
|
||||
|
||||
if (!symbol) {
|
||||
symbol = AddSymbolToTable(token->Lemexe, UnresolvedSymbol, MachineState.SymbolsTable);
|
||||
param->InterpretedAs = UnresolvedParameter;
|
||||
}
|
||||
else {
|
||||
switch(symbol->Type) {
|
||||
case InstructionPointerSymbol:
|
||||
case StringSymbol:
|
||||
param->InterpretedAs = AddressParameter;
|
||||
break;
|
||||
case NumericSymbol:
|
||||
param->InterpretedAs = ConstantParameter;
|
||||
break;
|
||||
default:
|
||||
param->InterpretedAs = UnresolvedParameter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// //param->Value.Symbol = symbol->Name;
|
||||
|
||||
param->Value.Symbol = symbol->Name;
|
||||
// AdvanceParser();
|
||||
|
||||
AdvanceParser();
|
||||
// //return param;
|
||||
// case PunctuationClass:
|
||||
// if (token->Value.Punctuation != LBracket) {
|
||||
// fprintf(stderr, "[Error] Line %d: Expected opening bracket\n", token->LineNumber);
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
return param;
|
||||
case PunctuationClass:
|
||||
if (token->Value.Punctuation != LBracket) {
|
||||
fprintf(stderr, "[Error] Line %d: Expected opening bracket\n", token->LineNumber);
|
||||
exit(1);
|
||||
}
|
||||
// AdvanceParser(); // [
|
||||
|
||||
AdvanceParser(); // [
|
||||
// token = PeekToken();
|
||||
|
||||
token = PeekToken();
|
||||
// if (token->Class == NumberClass) {
|
||||
// param->ParameterType = ConstantParameter;
|
||||
// param->InterpretedAs = AddressParameter;
|
||||
// param->Value.Number = token->Value.Number;
|
||||
// }
|
||||
// else if (token->Class == RegisterClass) {
|
||||
// param->ParameterType = RegisterParameter;
|
||||
// param->InterpretedAs = AddressParameter;
|
||||
// param->Value.Register = token->Value.Register;
|
||||
// }
|
||||
// else if (token->Class & AddressClass) {
|
||||
// param->ParameterType = AddressParameter;
|
||||
// param->InterpretedAs = AddressParameter;
|
||||
|
||||
if (token->Class == NumberClass) {
|
||||
param->ParameterType = ConstantParameter;
|
||||
param->InterpretedAs = AddressParameter;
|
||||
param->Value.Number = token->Value.Number;
|
||||
}
|
||||
else if (token->Class == RegisterClass) {
|
||||
param->ParameterType = RegisterParameter;
|
||||
param->InterpretedAs = AddressParameter;
|
||||
param->Value.Register = token->Value.Register;
|
||||
}
|
||||
else if (token->Class & AddressClass) {
|
||||
param->ParameterType = AddressParameter;
|
||||
param->InterpretedAs = AddressParameter;
|
||||
// symbol = TryGetSymbol(token->Lemexe, MachineState.SymbolsTable);
|
||||
|
||||
symbol = TryGetSymbol(token->Lemexe, MachineState.SymbolsTable);
|
||||
// if (!symbol) symbol = AddSymbolToTable(token->Lemexe, UnresolvedSymbol, MachineState.SymbolsTable);
|
||||
|
||||
if (!symbol) symbol = AddSymbolToTable(token->Lemexe, UnresolvedSymbol, MachineState.SymbolsTable);
|
||||
// param->Value.Symbol = symbol->Name;
|
||||
// }
|
||||
// else {
|
||||
// fprintf(stderr, "[Error] Line %d: Expected identifier, constant number or register.\n", token->LineNumber);
|
||||
// IgnoreParserLine();
|
||||
// //return NULL;
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
param->Value.Symbol = symbol->Name;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "[Error] Line %d: Expected identifier, constant number or register.\n", token->LineNumber);
|
||||
IgnoreParserLine();
|
||||
//return NULL;
|
||||
exit(1);
|
||||
}
|
||||
// AdvanceParser(); //Consume the parameter it self.
|
||||
|
||||
AdvanceParser(); //Consume the parameter it self.
|
||||
// token = PeekToken();
|
||||
|
||||
token = PeekToken();
|
||||
// if (token->Class != PunctuationClass || token->Value.Punctuation != RBracket) {
|
||||
// fprintf(stderr, "[Error] Line %d: Expected closing bracket.\n", token->LineNumber);
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
if (token->Class != PunctuationClass || token->Value.Punctuation != RBracket) {
|
||||
fprintf(stderr, "[Error] Line %d: Expected closing bracket.\n", token->LineNumber);
|
||||
exit(1);
|
||||
}
|
||||
// AdvanceParser(); // ]
|
||||
|
||||
AdvanceParser(); // ]
|
||||
// return param;
|
||||
// case NumberClass:
|
||||
// param->ParameterType = ConstantParameter;
|
||||
// param->InterpretedAs = ConstantParameter;
|
||||
|
||||
return param;
|
||||
case NumberClass:
|
||||
param->ParameterType = ConstantParameter;
|
||||
param->InterpretedAs = ConstantParameter;
|
||||
// param->Value.Number = token->Value.Number;
|
||||
|
||||
param->Value.Number = token->Value.Number;
|
||||
// AdvanceParser();
|
||||
|
||||
AdvanceParser();
|
||||
// return param;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
|
||||
return param;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// return param;
|
||||
// }
|
||||
|
||||
return param;
|
||||
}
|
||||
// Instruction* HandleOperation() {
|
||||
// if (ParserAtEnd()) {
|
||||
// //fprintf(stderr, "[Error] Expected instruction mnemonic\n");
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
Instruction* HandleOperation() {
|
||||
if (ParserAtEnd()) {
|
||||
//fprintf(stderr, "[Error] Expected instruction mnemonic\n");
|
||||
return NULL;
|
||||
}
|
||||
// Token* token = PeekToken();
|
||||
// //char mn[12];
|
||||
|
||||
Token* token = PeekToken();
|
||||
//char mn[12];
|
||||
// if (token->Class != MnemonicClass) {
|
||||
// fprintf(stderr, "[Error] Line %d: Expected instruction mnemonic\n", token->LineNumber);
|
||||
// IgnoreParserLine();
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
if (token->Class != MnemonicClass) {
|
||||
fprintf(stderr, "[Error] Line %d: Expected instruction mnemonic\n", token->LineNumber);
|
||||
IgnoreParserLine();
|
||||
return NULL;
|
||||
}
|
||||
// Instruction* ins = CreateInstruction(token->Value.Mnemonic);
|
||||
|
||||
Instruction* ins = CreateInstruction(token->Value.Mnemonic);
|
||||
// //GetMnemonicText(ins->Mnemonic, mn);
|
||||
|
||||
//GetMnemonicText(ins->Mnemonic, mn);
|
||||
// AdvanceParser();
|
||||
|
||||
AdvanceParser();
|
||||
// //No parameters here, we have a line break.
|
||||
// if (PeekToken()->EndOfFile || (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine)) {
|
||||
// goto InsertInstruction;
|
||||
// }
|
||||
|
||||
//No parameters here, we have a line break.
|
||||
if (PeekToken()->EndOfFile || (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine)) {
|
||||
goto InsertInstruction;
|
||||
}
|
||||
// ins->ParameterOne = GetParameterType();
|
||||
|
||||
ins->ParameterOne = GetParameterType();
|
||||
// if (ins->ParameterOne->ParameterType == 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);
|
||||
// }
|
||||
|
||||
if (ins->ParameterOne->ParameterType == 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;
|
||||
// }
|
||||
|
||||
goto InsertInstruction;
|
||||
}
|
||||
// if (PeekToken()->EndOfFile || (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine)) {
|
||||
// goto InsertInstruction;
|
||||
// }
|
||||
|
||||
if (PeekToken()->EndOfFile || (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 got %d.\n", token->LineNumber, token->Class);
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
if (PeekToken()->Class != PunctuationClass || PeekToken()->Value.Punctuation != Comma) {
|
||||
//Syntax error
|
||||
fprintf(stderr, "[Error] Line %d: Expected comma got %d.\n", token->LineNumber, token->Class);
|
||||
exit(1);
|
||||
}
|
||||
// AdvanceParser(); //Consume the comma
|
||||
|
||||
AdvanceParser(); //Consume the comma
|
||||
// ins->ParameterTwo = GetParameterType();
|
||||
|
||||
ins->ParameterTwo = GetParameterType();
|
||||
// InsertInstruction:
|
||||
|
||||
InsertInstruction:
|
||||
// AddListItem(ins, MachineState.Instructions);
|
||||
|
||||
AddListItem(ins, MachineState.Instructions);
|
||||
// AdvanceParser(); //Consume the line break
|
||||
|
||||
AdvanceParser(); //Consume the line break
|
||||
|
||||
return ins;
|
||||
}
|
||||
// return ins;
|
||||
// }
|
||||
|
||||
void PrintSymbols(void) {
|
||||
char mn[12];
|
||||
//char mn[12];
|
||||
printf("-----SYMBOLS-----\n");
|
||||
for(int i = 0; i < MachineState.SymbolsTable->Size; i++) {
|
||||
Symbol* symbol = MachineState.SymbolsTable->Symbols[i];
|
||||
|
||||
printf("[%s] ", symbol->Type == UnresolvedSymbol ? "Unresolved" : "Resolved");
|
||||
printf("[%s] %s", symbol->Resolved == 0 ? "Unresolved" : "Resolved", symbol->Name);
|
||||
|
||||
switch(symbol->Type) {
|
||||
case InstructionPointerSymbol:
|
||||
GetMnemonicText(symbol->Value.Instruction->Mnemonic, mn);
|
||||
printf("%s -> %s", symbol->Name, mn);
|
||||
break;
|
||||
case NumericSymbol:
|
||||
printf("[N] %s Value: %d", symbol->Name, symbol->Value.Number);
|
||||
break;
|
||||
case StringSymbol:
|
||||
if (symbol->Value.String->Terminated)
|
||||
printf("[S] %s {%s}, %d", symbol->Name, symbol->Value.String->String, symbol->Value.String->TerminatingByte);
|
||||
else
|
||||
printf("[S] %s {%s}", symbol->Name, symbol->Value.String->String);
|
||||
break;
|
||||
case UnresolvedSymbol:
|
||||
printf("[U] %s", symbol->Name);
|
||||
break;
|
||||
}
|
||||
// switch(symbol->Type) {
|
||||
// case InstructionPointerSymbol:
|
||||
// GetMnemonicText(symbol->Value.Instruction->Mnemonic, mn);
|
||||
// printf("%s -> %s", symbol->Name, mn);
|
||||
// break;
|
||||
// case NumericSymbol:
|
||||
// printf("[N] %s Value: %d", symbol->Name, symbol->Value.Number);
|
||||
// break;
|
||||
// case StringSymbol:
|
||||
// if (symbol->Value.String->Terminated)
|
||||
// printf("[S] %s {%s}, %d", symbol->Name, symbol->Value.String->String, symbol->Value.String->TerminatingByte);
|
||||
// else
|
||||
// printf("[S] %s {%s}", symbol->Name, symbol->Value.String->String);
|
||||
// break;
|
||||
// case UnresolvedSymbol:
|
||||
// printf("[U] %s", symbol->Name);
|
||||
// break;
|
||||
// }
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user