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);
|
Symbol* ExpectIdentifier(ExpectOptions options, int expectUnresolved);
|
||||||
void ExpectCharacterClass(Symbol* symbol);
|
void ExpectCharacterClass(Symbol* symbol);
|
||||||
Token* ExpectLineEndOrFileEnd(ExpectOptions options);
|
Token* ExpectLineEndOrFileEnd(ExpectOptions options);
|
||||||
|
Token* ExpectMathOperator(ExpectOptions options);
|
||||||
|
Token* ExpectMathOperand(ExpectOptions options);
|
||||||
|
|
||||||
SymbolTable* SymbolsTable;
|
SymbolTable* SymbolsTable;
|
||||||
|
TokenNode* ParseSymbolExpression(void);
|
||||||
|
|
||||||
//int HeapSize = 0;
|
//int HeapSize = 0;
|
||||||
int PC = 0;
|
int PC = 0;
|
||||||
@@ -103,24 +106,16 @@ void HandleAssemblerDirective() {
|
|||||||
|
|
||||||
//symbol->Type = RefLiteral;
|
//symbol->Type = RefLiteral;
|
||||||
}
|
}
|
||||||
else if (PeekToken()->Class == NumberClass) {
|
else if (PeekToken()->Class == NumberClass || PeekToken()->Class == IdentifierClass) {
|
||||||
symbol->Length = 2;
|
symbol->Length = 2;
|
||||||
|
|
||||||
RemoveCurrentToken(); //Clear the number token.
|
//RemoveCurrentToken(); //Clear the number token.
|
||||||
|
|
||||||
ExpectLineEndOrFileEnd(RemoveExpected);
|
//ExpectLineEndOrFileEnd(RemoveExpected);
|
||||||
|
|
||||||
//symbol->Type = RefLiteral;
|
//symbol->Type = RefLiteral;
|
||||||
}
|
|
||||||
else if (PeekToken()->Class == IdentifierClass) {
|
|
||||||
//symbol->Type = RefExpression;
|
|
||||||
|
|
||||||
symbol = ExpectIdentifier(RemoveExpected, 0);
|
symbol->ValueExpression = ParseSymbolExpression();
|
||||||
symbol->Length = 2;
|
|
||||||
|
|
||||||
//TODO: This needs to be expanded to handle expressions, a symbol to symbol reg is not allowed.
|
|
||||||
|
|
||||||
ExpectLineEndOrFileEnd(RemoveExpected);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//HeapSize += symbol->Length;
|
//HeapSize += symbol->Length;
|
||||||
@@ -510,8 +505,10 @@ void PrintSymbols(void) {
|
|||||||
printf("-----SYMBOLS-----\n");
|
printf("-----SYMBOLS-----\n");
|
||||||
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;
|
||||||
|
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)
|
if (symbol->Token && symbol->Token->Class == MnemonicClass)
|
||||||
{
|
{
|
||||||
@@ -557,4 +554,77 @@ void IgnoreParserLine(void) {
|
|||||||
|
|
||||||
void RemoveCurrentToken(void) {
|
void RemoveCurrentToken(void) {
|
||||||
RemoveToken(CurrentToken, TokensList);
|
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 '-':
|
||||||
|
case '+':
|
||||||
|
case '*':
|
||||||
|
case '/':
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
@@ -366,6 +370,18 @@ Token* ParsePunctuation(char c) {
|
|||||||
case ',':
|
case ',':
|
||||||
punctuation = Comma;
|
punctuation = Comma;
|
||||||
break;
|
break;
|
||||||
|
case '-':
|
||||||
|
punctuation = Minus;
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
punctuation = Plus;
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
punctuation = Star;
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
punctuation = Slash;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-3
@@ -136,7 +136,6 @@ int TryGetSymbolValue(const Symbol* symbol, const SymbolTable* table, unsigned s
|
|||||||
*value = root->Token->Value.Number;
|
*value = root->Token->Value.Number;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
|
||||||
case LabelClass:
|
case LabelClass:
|
||||||
case IdentifierClass:
|
case IdentifierClass:
|
||||||
if (!TryGetSymbol(root->Token->Lemexe, table, &s)) return 0;
|
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;
|
if (!TryGetSymbolValue(s, table, value)) return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
case PunctuationClass:
|
||||||
case PunctuationClass: //TODO: ()'s need to be handled
|
|
||||||
//check for math operator
|
//check for math operator
|
||||||
if (!TryGetSymbol(root->Left->Token->Lemexe, table, &s)) return 0;
|
if (!TryGetSymbol(root->Left->Token->Lemexe, table, &s)) return 0;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user