all repos — mgba @ 4638e4a0170795799e9adc8cf97184d969ba417b

mGBA Game Boy Advance Emulator

Add parenthesis support
Jeffrey Pfau jeffrey@endrift.com
Sat, 12 Jul 2014 17:58:03 -0700
commit

4638e4a0170795799e9adc8cf97184d969ba417b

parent

a58f8f8675209df00bd06aada55fb14a270a1e6b

3 files changed, 66 insertions(+), 3 deletions(-)

jump to
M src/debugger/cli-debugger.csrc/debugger/cli-debugger.c

@@ -336,6 +336,7 @@ return _performOperation(tree->token.operatorValue, _evaluateParseTree(debugger, tree->lhs, dv), _evaluateParseTree(debugger, tree->rhs, dv), dv);

case TOKEN_IDENTIFIER_TYPE: return _lookupIdentifier(debugger, tree->token.identifierValue, dv); case TOKEN_ERROR_TYPE: + default: dv->type = DV_ERROR_TYPE; } return 0;
M src/debugger/parser.csrc/debugger/parser.c

@@ -25,6 +25,7 @@ lv->next = lvNext;

lv = lvNext; lvNext = malloc(sizeof(struct LexVector)); lvNext->next = lv->next; + lvNext->token.type = TOKEN_ERROR_TYPE; lv->next = lvNext; return lvNext; }

@@ -39,6 +40,7 @@ size_t adjusted = 0;

enum LexState state = LEX_ROOT; const char* tokenStart = 0; + struct LexVector* lvNext; while (length > 0 && string[0] && string[0] != ' ' && state != LEX_ERROR) { char token = string[0];

@@ -68,6 +70,15 @@ case '$':

state = LEX_EXPECT_HEX; next = 0; 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: if (tolower(token) >= 'a' && tolower(token <= 'z')) { state = LEX_EXPECT_IDENTIFIER;

@@ -87,6 +98,11 @@ lv->token.type = TOKEN_IDENTIFIER_TYPE;

lv->token.identifierValue = strndup(tokenStart, string - tokenStart - 1); lv = _lexOperator(lv, token); state = LEX_ROOT; + break; + case ')': + lv->token.type = TOKEN_IDENTIFIER_TYPE; + lv->token.identifierValue = strndup(tokenStart, string - tokenStart - 1); + state = LEX_EXPECT_OPERATOR; break; default: break;

@@ -117,6 +133,11 @@ lv->token.uintValue = next;

lv = _lexOperator(lv, token); state = LEX_ROOT; break; + case ')': + lv->token.type = TOKEN_UINT_TYPE; + lv->token.uintValue = next; + state = LEX_EXPECT_OPERATOR; + break; default: state = LEX_ERROR; }

@@ -166,6 +187,11 @@ lv->token.uintValue = next;

lv = _lexOperator(lv, token); state = LEX_ROOT; break; + case ')': + lv->token.type = TOKEN_UINT_TYPE; + lv->token.uintValue = next; + state = LEX_EXPECT_OPERATOR; + break; default: state = LEX_ERROR; break;

@@ -183,6 +209,23 @@ state = LEX_ERROR;

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: // This shouldn't be reached break;

@@ -198,6 +241,12 @@ break;

case LEX_EXPECT_IDENTIFIER: lv->token.type = TOKEN_IDENTIFIER_TYPE; lv->token.identifierValue = strndup(tokenStart, string - tokenStart); + 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: default:

@@ -222,7 +271,7 @@ tree->lhs = 0;

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; while (lv) { int newPrecedence;

@@ -237,6 +286,16 @@ tree->token.type = TOKEN_ERROR_TYPE;

return 0; } 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: newPrecedence = _operatorPrecedence[lv->token.operatorValue]; if (newPrecedence < precedence) {

@@ -245,7 +304,7 @@ *newTree = *tree;

tree->lhs = newTree; tree->rhs = _parseTreeCreate(); 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) { tree->token.type = TOKEN_ERROR_TYPE; }

@@ -271,7 +330,7 @@ tree->token.type = TOKEN_ERROR_TYPE;

tree->lhs = 0; tree->rhs = 0; - _parseExpression(tree, lv, _operatorPrecedence[OP_ASSIGN]); + _parseExpression(tree, lv, _operatorPrecedence[OP_ASSIGN], 0); } void lexFree(struct LexVector* lv) {
M src/debugger/parser.hsrc/debugger/parser.h

@@ -11,6 +11,7 @@ LEX_EXPECT_IDENTIFIER,

LEX_EXPECT_DECIMAL, LEX_EXPECT_HEX, LEX_EXPECT_PREFIX, + LEX_EXPECT_OPERATOR }; enum Operation {

@@ -27,6 +28,8 @@ TOKEN_ERROR_TYPE,

TOKEN_UINT_TYPE, TOKEN_IDENTIFIER_TYPE, TOKEN_OPERATOR_TYPE, + TOKEN_OPEN_PAREN_TYPE, + TOKEN_CLOSE_PAREN_TYPE, } type; union { uint32_t uintValue;