Updated the parser to create an expression tree for symbols declared via .db directives. Scanner now see some math operators as 'punctuation'.

This commit is contained in:
2023-08-31 23:27:33 -05:00
parent 9e178ca3da
commit b810d7803c
3 changed files with 100 additions and 16 deletions
+83 -13
View File
@@ -24,8 +24,11 @@ void ExpectRegister(void);
Symbol* ExpectIdentifier(ExpectOptions options, int expectUnresolved);
void ExpectCharacterClass(Symbol* symbol);
Token* ExpectLineEndOrFileEnd(ExpectOptions options);
Token* ExpectMathOperator(ExpectOptions options);
Token* ExpectMathOperand(ExpectOptions options);
SymbolTable* SymbolsTable;
TokenNode* ParseSymbolExpression(void);
//int HeapSize = 0;
int PC = 0;
@@ -103,24 +106,16 @@ void HandleAssemblerDirective() {
//symbol->Type = RefLiteral;
}
else if (PeekToken()->Class == NumberClass) {
else if (PeekToken()->Class == NumberClass || PeekToken()->Class == IdentifierClass) {
symbol->Length = 2;
RemoveCurrentToken(); //Clear the number token.
//RemoveCurrentToken(); //Clear the number token.
ExpectLineEndOrFileEnd(RemoveExpected);
//ExpectLineEndOrFileEnd(RemoveExpected);
//symbol->Type = RefLiteral;
}
else if (PeekToken()->Class == IdentifierClass) {
//symbol->Type = RefExpression;
symbol = ExpectIdentifier(RemoveExpected, 0);
symbol->Length = 2;
//TODO: This needs to be expanded to handle expressions, a symbol to symbol reg is not allowed.
ExpectLineEndOrFileEnd(RemoveExpected);
symbol->ValueExpression = ParseSymbolExpression();
}
//HeapSize += symbol->Length;
@@ -510,8 +505,10 @@ void PrintSymbols(void) {
printf("-----SYMBOLS-----\n");
for(int i = 0; i < SymbolsTable->Size; i++) {
Symbol* symbol = SymbolsTable->Symbols[i];
unsigned short value = 0;
int resolved = TryGetSymbolValue(symbol, SymbolsTable, &value);
printf("[%s] %s [Width: %d]", SymbolResolved(symbol) == 0 ? "Unresolved" : "Resolved", symbol->Name, symbol->Length);
printf("[%s] %s [Value: %d]", resolved == 0 ? "Unresolved" : "Resolved", symbol->Name, value);
if (symbol->Token && symbol->Token->Class == MnemonicClass)
{
@@ -557,4 +554,77 @@ void IgnoreParserLine(void) {
void RemoveCurrentToken(void) {
RemoveToken(CurrentToken, TokensList);
}
TokenNode* ParseSymbolExpression(void) {
TokenNode* root = CreateTokenNode(ExpectMathOperand(RemoveExpected));
while(!ParserAtEnd()) {
if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) {
ExpectPuncuation(NewLine, RemoveExpected);
break;
}
TokenNode* value = CreateTokenNode(ExpectMathOperand(RemoveExpected));
TokenNode* operation = CreateTokenNode(ExpectMathOperator(RemoveExpected));
operation->Left = root;
operation->Right = value;
root = operation;
}
return root;
}
Token* ExpectMathOperator(ExpectOptions options) {
if (ParserAtEnd()) {
fprintf(stderr, "Syntax error, expected math operator but found unexpected end of file.\n");
exit (1);
}
Token* current = PeekToken();
if (current->Class != PunctuationClass) {
fprintf(stderr, "[Line %d] Syntax error, expected math operator.\n", current->LineNumber);
exit (1);
}
switch (current->Value.Punctuation) {
case Plus:
case Minus:
case Star:
case Slash:
case Power:
break;
default:
fprintf(stderr, "[Line %d] Syntax error, expected math operator 2.\n", current->LineNumber);
exit(1);
}
if (options & RemoveExpected) RemoveCurrentToken();
if (options & ForwardParser) AdvanceParser();
return current;
}
Token* ExpectMathOperand(ExpectOptions options) {
if (ParserAtEnd()) {
fprintf(stderr, "Syntax error, expected math operand but found unexpected end of file.\n");
exit (1);
}
Token* token = PeekToken();
if (token->Class != NumberClass && token->Class != IdentifierClass) {
fprintf(stderr, "[Line %d] Syntax error, expected a number or identifier.\n", token->LineNumber);
exit (1);
}
//TODO: handle symbols.
if (options & RemoveExpected) RemoveCurrentToken();
if (options & ForwardParser) AdvanceParser();
return token;
}
+16
View File
@@ -328,6 +328,10 @@ int IsPunctuation(char c) {
case '(':
case ')':
case ',':
case '-':
case '+':
case '*':
case '/':
return 1;
default:
return 0;
@@ -366,6 +370,18 @@ Token* ParsePunctuation(char c) {
case ',':
punctuation = Comma;
break;
case '-':
punctuation = Minus;
break;
case '+':
punctuation = Plus;
break;
case '*':
punctuation = Star;
break;
case '/':
punctuation = Slash;
break;
default:
return NULL;
}
+1 -3
View File
@@ -136,7 +136,6 @@ int TryGetSymbolValue(const Symbol* symbol, const SymbolTable* table, unsigned s
*value = root->Token->Value.Number;
return 1;
break;
case LabelClass:
case IdentifierClass:
if (!TryGetSymbol(root->Token->Lemexe, table, &s)) return 0;
@@ -144,8 +143,7 @@ int TryGetSymbolValue(const Symbol* symbol, const SymbolTable* table, unsigned s
if (!TryGetSymbolValue(s, table, value)) return 0;
return 1;
break;
case PunctuationClass: //TODO: ()'s need to be handled
case PunctuationClass:
//check for math operator
if (!TryGetSymbol(root->Left->Token->Lemexe, table, &s)) return 0;