mirror of https://github.com/mgba-emu/mgba.git
Add parenthesis support
This commit is contained in:
parent
a58f8f8675
commit
4638e4a017
|
@ -336,6 +336,7 @@ static uint32_t _evaluateParseTree(struct ARMDebugger* debugger, struct ParseTre
|
||||||
case TOKEN_IDENTIFIER_TYPE:
|
case TOKEN_IDENTIFIER_TYPE:
|
||||||
return _lookupIdentifier(debugger, tree->token.identifierValue, dv);
|
return _lookupIdentifier(debugger, tree->token.identifierValue, dv);
|
||||||
case TOKEN_ERROR_TYPE:
|
case TOKEN_ERROR_TYPE:
|
||||||
|
default:
|
||||||
dv->type = DV_ERROR_TYPE;
|
dv->type = DV_ERROR_TYPE;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -25,6 +25,7 @@ static struct LexVector* _lexOperator(struct LexVector* lv, char operator) {
|
||||||
lv = lvNext;
|
lv = lvNext;
|
||||||
lvNext = malloc(sizeof(struct LexVector));
|
lvNext = malloc(sizeof(struct LexVector));
|
||||||
lvNext->next = lv->next;
|
lvNext->next = lv->next;
|
||||||
|
lvNext->token.type = TOKEN_ERROR_TYPE;
|
||||||
lv->next = lvNext;
|
lv->next = lvNext;
|
||||||
return lvNext;
|
return lvNext;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +40,7 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) {
|
||||||
|
|
||||||
enum LexState state = LEX_ROOT;
|
enum LexState state = LEX_ROOT;
|
||||||
const char* tokenStart = 0;
|
const char* tokenStart = 0;
|
||||||
|
struct LexVector* lvNext;
|
||||||
|
|
||||||
while (length > 0 && string[0] && string[0] != ' ' && state != LEX_ERROR) {
|
while (length > 0 && string[0] && string[0] != ' ' && state != LEX_ERROR) {
|
||||||
char token = string[0];
|
char token = string[0];
|
||||||
|
@ -68,6 +70,15 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) {
|
||||||
state = LEX_EXPECT_HEX;
|
state = LEX_EXPECT_HEX;
|
||||||
next = 0;
|
next = 0;
|
||||||
break;
|
break;
|
||||||
|
case '(':
|
||||||
|
state = LEX_ROOT;
|
||||||
|
lv->token.type = TOKEN_OPEN_PAREN_TYPE;
|
||||||
|
lvNext = malloc(sizeof(struct LexVector));
|
||||||
|
lvNext->next = lv->next;
|
||||||
|
lvNext->token.type = TOKEN_ERROR_TYPE;
|
||||||
|
lv->next = lvNext;
|
||||||
|
lv = lvNext;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (tolower(token) >= 'a' && tolower(token <= 'z')) {
|
if (tolower(token) >= 'a' && tolower(token <= 'z')) {
|
||||||
state = LEX_EXPECT_IDENTIFIER;
|
state = LEX_EXPECT_IDENTIFIER;
|
||||||
|
@ -88,6 +99,11 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) {
|
||||||
lv = _lexOperator(lv, token);
|
lv = _lexOperator(lv, token);
|
||||||
state = LEX_ROOT;
|
state = LEX_ROOT;
|
||||||
break;
|
break;
|
||||||
|
case ')':
|
||||||
|
lv->token.type = TOKEN_IDENTIFIER_TYPE;
|
||||||
|
lv->token.identifierValue = strndup(tokenStart, string - tokenStart - 1);
|
||||||
|
state = LEX_EXPECT_OPERATOR;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -117,6 +133,11 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) {
|
||||||
lv = _lexOperator(lv, token);
|
lv = _lexOperator(lv, token);
|
||||||
state = LEX_ROOT;
|
state = LEX_ROOT;
|
||||||
break;
|
break;
|
||||||
|
case ')':
|
||||||
|
lv->token.type = TOKEN_UINT_TYPE;
|
||||||
|
lv->token.uintValue = next;
|
||||||
|
state = LEX_EXPECT_OPERATOR;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
state = LEX_ERROR;
|
state = LEX_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -166,6 +187,11 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) {
|
||||||
lv = _lexOperator(lv, token);
|
lv = _lexOperator(lv, token);
|
||||||
state = LEX_ROOT;
|
state = LEX_ROOT;
|
||||||
break;
|
break;
|
||||||
|
case ')':
|
||||||
|
lv->token.type = TOKEN_UINT_TYPE;
|
||||||
|
lv->token.uintValue = next;
|
||||||
|
state = LEX_EXPECT_OPERATOR;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
state = LEX_ERROR;
|
state = LEX_ERROR;
|
||||||
break;
|
break;
|
||||||
|
@ -183,6 +209,23 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case LEX_EXPECT_OPERATOR:
|
||||||
|
switch (token) {
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
case '*':
|
||||||
|
case '/':
|
||||||
|
lvNext = malloc(sizeof(struct LexVector));
|
||||||
|
lvNext->next = lv->next;
|
||||||
|
lvNext->token.type = TOKEN_CLOSE_PAREN_TYPE;
|
||||||
|
lv->next = lvNext;
|
||||||
|
lv = _lexOperator(lv->next, token);
|
||||||
|
state = LEX_ROOT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
state = LEX_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case LEX_ERROR:
|
case LEX_ERROR:
|
||||||
// This shouldn't be reached
|
// This shouldn't be reached
|
||||||
break;
|
break;
|
||||||
|
@ -199,6 +242,12 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) {
|
||||||
lv->token.type = TOKEN_IDENTIFIER_TYPE;
|
lv->token.type = TOKEN_IDENTIFIER_TYPE;
|
||||||
lv->token.identifierValue = strndup(tokenStart, string - tokenStart);
|
lv->token.identifierValue = strndup(tokenStart, string - tokenStart);
|
||||||
break;
|
break;
|
||||||
|
case LEX_EXPECT_OPERATOR:
|
||||||
|
lvNext = malloc(sizeof(struct LexVector));
|
||||||
|
lvNext->next = lv->next;
|
||||||
|
lvNext->token.type = TOKEN_CLOSE_PAREN_TYPE;
|
||||||
|
lv->next = lvNext;
|
||||||
|
break;
|
||||||
case LEX_ERROR:
|
case LEX_ERROR:
|
||||||
default:
|
default:
|
||||||
lv->token.type = TOKEN_ERROR_TYPE;
|
lv->token.type = TOKEN_ERROR_TYPE;
|
||||||
|
@ -222,7 +271,7 @@ static struct ParseTree* _parseTreeCreate() {
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct LexVector* _parseExpression(struct ParseTree* tree, struct LexVector* lv, int precedence) {
|
static struct LexVector* _parseExpression(struct ParseTree* tree, struct LexVector* lv, int precedence, int openParens) {
|
||||||
struct ParseTree* newTree = 0;
|
struct ParseTree* newTree = 0;
|
||||||
while (lv) {
|
while (lv) {
|
||||||
int newPrecedence;
|
int newPrecedence;
|
||||||
|
@ -237,6 +286,16 @@ static struct LexVector* _parseExpression(struct ParseTree* tree, struct LexVect
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TOKEN_OPEN_PAREN_TYPE:
|
||||||
|
lv = _parseExpression(tree, lv->next, INT_MAX, openParens + 1);
|
||||||
|
break;
|
||||||
|
case TOKEN_CLOSE_PAREN_TYPE:
|
||||||
|
if (openParens <= 0) {
|
||||||
|
tree->token.type = TOKEN_ERROR_TYPE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return lv->next;
|
||||||
|
break;
|
||||||
case TOKEN_OPERATOR_TYPE:
|
case TOKEN_OPERATOR_TYPE:
|
||||||
newPrecedence = _operatorPrecedence[lv->token.operatorValue];
|
newPrecedence = _operatorPrecedence[lv->token.operatorValue];
|
||||||
if (newPrecedence < precedence) {
|
if (newPrecedence < precedence) {
|
||||||
|
@ -245,7 +304,7 @@ static struct LexVector* _parseExpression(struct ParseTree* tree, struct LexVect
|
||||||
tree->lhs = newTree;
|
tree->lhs = newTree;
|
||||||
tree->rhs = _parseTreeCreate();
|
tree->rhs = _parseTreeCreate();
|
||||||
tree->token = lv->token;
|
tree->token = lv->token;
|
||||||
lv = _parseExpression(tree->rhs, lv->next, newPrecedence);
|
lv = _parseExpression(tree->rhs, lv->next, newPrecedence, openParens);
|
||||||
if (tree->token.type == TOKEN_ERROR_TYPE) {
|
if (tree->token.type == TOKEN_ERROR_TYPE) {
|
||||||
tree->token.type = TOKEN_ERROR_TYPE;
|
tree->token.type = TOKEN_ERROR_TYPE;
|
||||||
}
|
}
|
||||||
|
@ -271,7 +330,7 @@ void parseLexedExpression(struct ParseTree* tree, struct LexVector* lv) {
|
||||||
tree->lhs = 0;
|
tree->lhs = 0;
|
||||||
tree->rhs = 0;
|
tree->rhs = 0;
|
||||||
|
|
||||||
_parseExpression(tree, lv, _operatorPrecedence[OP_ASSIGN]);
|
_parseExpression(tree, lv, _operatorPrecedence[OP_ASSIGN], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lexFree(struct LexVector* lv) {
|
void lexFree(struct LexVector* lv) {
|
||||||
|
|
|
@ -11,6 +11,7 @@ enum LexState {
|
||||||
LEX_EXPECT_DECIMAL,
|
LEX_EXPECT_DECIMAL,
|
||||||
LEX_EXPECT_HEX,
|
LEX_EXPECT_HEX,
|
||||||
LEX_EXPECT_PREFIX,
|
LEX_EXPECT_PREFIX,
|
||||||
|
LEX_EXPECT_OPERATOR
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Operation {
|
enum Operation {
|
||||||
|
@ -27,6 +28,8 @@ struct Token {
|
||||||
TOKEN_UINT_TYPE,
|
TOKEN_UINT_TYPE,
|
||||||
TOKEN_IDENTIFIER_TYPE,
|
TOKEN_IDENTIFIER_TYPE,
|
||||||
TOKEN_OPERATOR_TYPE,
|
TOKEN_OPERATOR_TYPE,
|
||||||
|
TOKEN_OPEN_PAREN_TYPE,
|
||||||
|
TOKEN_CLOSE_PAREN_TYPE,
|
||||||
} type;
|
} type;
|
||||||
union {
|
union {
|
||||||
uint32_t uintValue;
|
uint32_t uintValue;
|
||||||
|
|
Loading…
Reference in New Issue