Updated the parser to handle treating variables as expressions. Updated the symbols table to handle computing the values of variables.

This commit is contained in:
2023-09-07 21:29:58 -05:00
parent 21c2bf046e
commit c95d739e16
3 changed files with 62 additions and 65 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ int TryGetSymbol(const char* name, const SymbolTable* table, Symbol** outSymbol)
Symbol* AddSymbolToTable(const char* name, int address, SymbolTable* table); Symbol* AddSymbolToTable(const char* name, int address, SymbolTable* table);
void FreeSymbolTable(SymbolTable* table); void FreeSymbolTable(SymbolTable* table);
void FreeSymbol(Symbol* symbol); void FreeSymbol(Symbol* symbol);
int SymbolResolved(const Symbol* symbol); int SymbolResolved(const Symbol* symbol, const SymbolTable* table);
int TryGetSymbolValue(const Symbol* symbol, const SymbolTable* table, unsigned short* value); int TryGetSymbolValue(const Symbol* symbol, const SymbolTable* table, unsigned short* value);
#endif #endif
+8 -30
View File
@@ -59,31 +59,25 @@ void ParseTokens(TokenList* tokens, SymbolTable** symbols) {
Symbol* symbol; Symbol* symbol;
int found = TryGetSymbol(t->Lemexe, SymbolsTable, &symbol); int found = TryGetSymbol(t->Lemexe, SymbolsTable, &symbol);
if (found && SymbolResolved(symbol)) { if (found && SymbolResolved(symbol, SymbolsTable)) {
fprintf(stderr, "[Error] Line %d: Redefinition of symbol '%s'\n", t->LineNumber, t->Lemexe); fprintf(stderr, "[Error] Line %d: Redefinition of symbol '%s'\n", t->LineNumber, t->Lemexe);
exit(1); exit(1);
} }
if (!found) symbol = AddSymbolToTable(t->Lemexe, PC, SymbolsTable); if (!found) symbol = AddSymbolToTable(t->Lemexe, PC, SymbolsTable);
// else
// {
symbol->Address = PC; symbol->Address = PC;
//symbol->Type = RefPointer;
//symbol->Token = t;
//}
RemoveCurrentToken(); //label RemoveCurrentToken(); //label
ExpectLineEndOrFileEnd(RemoveExpected); ExpectLineEndOrFileEnd(RemoveExpected);
//symbol->Value.Mnemonic = ExpectMnemonic();
symbol->Token = ExpectMnemonic(); symbol->Token = ExpectMnemonic();
} }
break; break;
default: 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); exit(1);
//IgnoreParserLine();
break; break;
} }
} }
@@ -103,22 +97,12 @@ void HandleAssemblerDirective() {
if (PeekToken()->Class == CharacterClass) { if (PeekToken()->Class == CharacterClass) {
ExpectCharacterClass(symbol); ExpectCharacterClass(symbol);
//symbol->Type = RefLiteral;
} }
else if (PeekToken()->Class == NumberClass || PeekToken()->Class == IdentifierClass) { else if (PeekToken()->Class == NumberClass || PeekToken()->Class == IdentifierClass) {
symbol->Length = 2; symbol->Length = 2;
//RemoveCurrentToken(); //Clear the number token.
//ExpectLineEndOrFileEnd(RemoveExpected);
//symbol->Type = RefLiteral;
symbol->ValueExpression = ParseSymbolExpression(); symbol->ValueExpression = ParseSymbolExpression();
} }
//HeapSize += symbol->Length;
} }
break; break;
default: default:
@@ -425,22 +409,14 @@ Symbol* ExpectIdentifier(ExpectOptions options, int expectUnresolved) {
int found = TryGetSymbol(token->Lemexe, SymbolsTable, &symbol); int found = TryGetSymbol(token->Lemexe, SymbolsTable, &symbol);
if (found && SymbolResolved(symbol) && expectUnresolved) { if (found && TryGetSymbolValue(symbol, SymbolsTable, NULL) && expectUnresolved) {
fprintf(stderr, "[Line %d] Redefinition of symbol '%s'.\n", token->LineNumber, token->Lemexe); fprintf(stderr, "[Line %d] Redefinition of symbol '%s'.\n", token->LineNumber, token->Lemexe);
exit(4); exit(4);
} }
if (!found) { if (!found) symbol = AddSymbolToTable(token->Lemexe, PC, SymbolsTable);
//symbol->Resolved = resolved || symbol->Resolved(symbol);
symbol = AddSymbolToTable(token->Lemexe, PC, SymbolsTable);
}
if (expectUnresolved) symbol->Token = token; if (expectUnresolved) symbol->Token = token;
// else {
// symbol = AddSymbolToTable(token->Lemexe, PC, SymbolsTable);
// }
if (options & RemoveExpected) RemoveCurrentToken(); if (options & RemoveExpected) RemoveCurrentToken();
if (options & ForwardParser) AdvanceParser(); if (options & ForwardParser) AdvanceParser();
@@ -456,6 +432,7 @@ void ExpectCharacterClass(Symbol* symbol) {
} }
symbol->Length = strlen(token->Lemexe); symbol->Length = strlen(token->Lemexe);
symbol->Token = token;
RemoveCurrentToken(); //Remove the string declared by this DB command. RemoveCurrentToken(); //Remove the string declared by this DB command.
@@ -506,7 +483,9 @@ void PrintSymbols(void) {
for(int i = 0; i < SymbolsTable->Size; i++) { for(int i = 0; i < SymbolsTable->Size; i++) {
Symbol* symbol = SymbolsTable->Symbols[i]; Symbol* symbol = SymbolsTable->Symbols[i];
unsigned short value = 0; unsigned short value = 0;
int resolved = TryGetSymbolValue(symbol, SymbolsTable, &value); int resolved = SymbolResolved(symbol, SymbolsTable);
if (resolved) TryGetSymbolValue(symbol, SymbolsTable, &value);
printf("[%s] %s [Value: %d]", resolved == 0 ? "Unresolved" : "Resolved", symbol->Name, value); printf("[%s] %s [Value: %d]", resolved == 0 ? "Unresolved" : "Resolved", symbol->Name, value);
@@ -621,7 +600,6 @@ Token* ExpectMathOperand(ExpectOptions options) {
fprintf(stderr, "[Line %d] Syntax error, expected a number or identifier.\n", token->LineNumber); fprintf(stderr, "[Line %d] Syntax error, expected a number or identifier.\n", token->LineNumber);
exit (1); exit (1);
} }
//TODO: handle symbols.
if (options & RemoveExpected) RemoveCurrentToken(); if (options & RemoveExpected) RemoveCurrentToken();
if (options & ForwardParser) AdvanceParser(); if (options & ForwardParser) AdvanceParser();
+49 -30
View File
@@ -3,21 +3,16 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
int SymbolResolved(const Symbol* symbol) { int SymbolResolved(const Symbol* symbol, const SymbolTable* table) {
if (!symbol) return 0; if (!symbol) return 0;
return symbol->Token != NULL; const Token* token = symbol->Token;
// switch (symbol->Type) { if (!token) return 0;
// case RefLiteral:
// return 1; if (token->Class == LabelClass || token->Class == CharacterClass || token->Class == MnemonicClass) return 1;
// case RefExpression:
// return 0; return TryGetSymbolValue(symbol, table, NULL);
// case RefPointer:
// return symbol->Value.Mnemonic != 0;
// default:
// return 0;
// }
} }
SymbolTable* CreateSymbolTable(void){ SymbolTable* CreateSymbolTable(void){
@@ -120,53 +115,59 @@ void FreeSymbol(Symbol* symbol) {
} }
int TryGetTokenNodeValue(const TokenNode* node, const SymbolTable* table, unsigned short* value); int TryGetTokenNodeValue(const TokenNode* node, const SymbolTable* table, unsigned short* value);
unsigned short DoOp(unsigned short left, unsigned short right, TokenPunctuation op);
int TryGetSymbolValue(const Symbol* symbol, const SymbolTable* table, unsigned short* value) { int TryGetSymbolValue(const Symbol* symbol, const SymbolTable* table, unsigned short* value) {
if (!symbol || !symbol->Token || !table) return 0; if (!symbol || !symbol->Token || !table) return 0;
if (symbol->Token->Class == CharacterClass) return 0;
unsigned short left = 0;
unsigned short right = 0;
TokenNode* root = symbol->ValueExpression; TokenNode* root = symbol->ValueExpression;
Symbol* s = NULL; Symbol* s = NULL;
if (value) *value = 0;
if (!root || !root->Token) return 0; if (!root || !root->Token) return 0;
switch (root->Token->Class) { switch (root->Token->Class) {
case NumberClass: case NumberClass:
*value = root->Token->Value.Number; if (value) *value = root->Token->Value.Number;
return 1; return 1;
case LabelClass:
case IdentifierClass: case IdentifierClass:
if (!TryGetSymbol(root->Token->Lemexe, table, &s)) return 0; if (!TryGetSymbol(root->Token->Lemexe, table, &s)) return 0;
if (!TryGetSymbolValue(s, table, value)) return 0; return TryGetTokenNodeValue(s->ValueExpression, table, value);
return 1;
case PunctuationClass: case PunctuationClass:
if (!TryGetTokenNodeValue(root->Left, table, &left)) return 0; return TryGetTokenNodeValue(root, table, value);
if (!TryGetTokenNodeValue(root->Right, table, &right)) return 0;
*value = left + right;
break;
default: default:
return 0; return 0;
} }
return 1;
} }
int TryGetTokenNodeValue(const TokenNode* node, const SymbolTable* table, unsigned short* value) { int TryGetTokenNodeValue(const TokenNode* node, const SymbolTable* table, unsigned short* value) {
const Token* token = node->Token; const Token* token = node->Token;
Symbol* symbol = { 0 };
if (token->Class == NumberClass) { if (token->Class == NumberClass) {
*value = token->Value.Number; if (value) *value = token->Value.Number;
return 1; return 1;
} }
return 0; if (token->Class == IdentifierClass) {
if (!TryGetSymbol(token->Lemexe, table, &symbol)) return 0;
return TryGetTokenNodeValue(symbol->ValueExpression, table, value);
}
if (token->Class != PunctuationClass) return 0;
unsigned short left = 0;
unsigned short right = 0;
if (!TryGetTokenNodeValue(node->Left, table, &left)) return 0;
if (!TryGetTokenNodeValue(node->Right, table, &right)) return 0;
if (value) *value = DoOp(left, right, token->Value.Punctuation);
return 1;
} }
TokenNode* CreateTokenNode(const Token* token){ TokenNode* CreateTokenNode(const Token* token){
@@ -181,3 +182,21 @@ TokenNode* CreateTokenNode(const Token* token){
return node; return node;
} }
unsigned short DoOp(unsigned short left, unsigned short right, TokenPunctuation op) {
switch (op) {
case Plus:
return left + right;
case Minus:
return left - right;
case Star:
return left * right;
case Slash:
return left / right;
default:
break;
}
return 0;
}