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:
+83
-13
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user