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);
void FreeSymbolTable(SymbolTable* table);
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);
#endif
+8 -30
View File
@@ -59,31 +59,25 @@ void ParseTokens(TokenList* tokens, SymbolTable** symbols) {
Symbol* 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);
exit(1);
}
if (!found) symbol = AddSymbolToTable(t->Lemexe, PC, SymbolsTable);
// else
// {
symbol->Address = PC;
//symbol->Type = RefPointer;
//symbol->Token = t;
//}
RemoveCurrentToken(); //label
ExpectLineEndOrFileEnd(RemoveExpected);
//symbol->Value.Mnemonic = ExpectMnemonic();
symbol->Token = ExpectMnemonic();
}
break;
default:
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();
break;
}
}
@@ -103,22 +97,12 @@ void HandleAssemblerDirective() {
if (PeekToken()->Class == CharacterClass) {
ExpectCharacterClass(symbol);
//symbol->Type = RefLiteral;
}
else if (PeekToken()->Class == NumberClass || PeekToken()->Class == IdentifierClass) {
symbol->Length = 2;
//RemoveCurrentToken(); //Clear the number token.
//ExpectLineEndOrFileEnd(RemoveExpected);
//symbol->Type = RefLiteral;
symbol->ValueExpression = ParseSymbolExpression();
}
//HeapSize += symbol->Length;
}
break;
default:
@@ -425,22 +409,14 @@ Symbol* ExpectIdentifier(ExpectOptions options, int expectUnresolved) {
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);
exit(4);
}
if (!found) {
//symbol->Resolved = resolved || symbol->Resolved(symbol);
symbol = AddSymbolToTable(token->Lemexe, PC, SymbolsTable);
}
if (!found) symbol = AddSymbolToTable(token->Lemexe, PC, SymbolsTable);
if (expectUnresolved) symbol->Token = token;
// else {
// symbol = AddSymbolToTable(token->Lemexe, PC, SymbolsTable);
// }
if (options & RemoveExpected) RemoveCurrentToken();
if (options & ForwardParser) AdvanceParser();
@@ -456,6 +432,7 @@ void ExpectCharacterClass(Symbol* symbol) {
}
symbol->Length = strlen(token->Lemexe);
symbol->Token = token;
RemoveCurrentToken(); //Remove the string declared by this DB command.
@@ -506,7 +483,9 @@ void PrintSymbols(void) {
for(int i = 0; i < SymbolsTable->Size; i++) {
Symbol* symbol = SymbolsTable->Symbols[i];
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);
@@ -621,7 +600,6 @@ Token* ExpectMathOperand(ExpectOptions options) {
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();
+49 -30
View File
@@ -3,21 +3,16 @@
#include <stdlib.h>
#include <string.h>
int SymbolResolved(const Symbol* symbol) {
int SymbolResolved(const Symbol* symbol, const SymbolTable* table) {
if (!symbol) return 0;
return symbol->Token != NULL;
const Token* token = symbol->Token;
// switch (symbol->Type) {
// case RefLiteral:
// return 1;
// case RefExpression:
// return 0;
// case RefPointer:
// return symbol->Value.Mnemonic != 0;
// default:
// return 0;
// }
if (!token) return 0;
if (token->Class == LabelClass || token->Class == CharacterClass || token->Class == MnemonicClass) return 1;
return TryGetSymbolValue(symbol, table, NULL);
}
SymbolTable* CreateSymbolTable(void){
@@ -120,53 +115,59 @@ void FreeSymbol(Symbol* symbol) {
}
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) {
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;
Symbol* s = NULL;
if (value) *value = 0;
if (!root || !root->Token) return 0;
switch (root->Token->Class) {
case NumberClass:
*value = root->Token->Value.Number;
if (value) *value = root->Token->Value.Number;
return 1;
case LabelClass:
case IdentifierClass:
if (!TryGetSymbol(root->Token->Lemexe, table, &s)) return 0;
if (!TryGetSymbolValue(s, table, value)) return 0;
return 1;
return TryGetTokenNodeValue(s->ValueExpression, table, value);
case PunctuationClass:
if (!TryGetTokenNodeValue(root->Left, table, &left)) return 0;
if (!TryGetTokenNodeValue(root->Right, table, &right)) return 0;
*value = left + right;
break;
return TryGetTokenNodeValue(root, table, value);
default:
return 0;
}
return 1;
}
int TryGetTokenNodeValue(const TokenNode* node, const SymbolTable* table, unsigned short* value) {
const Token* token = node->Token;
Symbol* symbol = { 0 };
if (token->Class == NumberClass) {
*value = token->Value.Number;
if (value) *value = token->Value.Number;
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){
@@ -181,3 +182,21 @@ TokenNode* CreateTokenNode(const Token* token){
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;
}