Permalink
Browse files

Debugger: Expose parser evaluation

  • Loading branch information...
endrift committed Dec 29, 2017
1 parent e192973 commit c692006b9d272cebfa35c023335cd0bce2021854
Showing with 91 additions and 82 deletions.
  1. +3 −2 include/mgba/internal/debugger/parser.h
  2. +3 −80 src/debugger/cli-debugger.c
  3. +85 −0 src/debugger/parser.c
@@ -10,8 +10,6 @@
CXX_GUARD_START
-#include <mgba/debugger/debugger.h>
-
enum Operation {
OP_ASSIGN,
OP_ADD,
@@ -62,6 +60,9 @@ void parseLexedExpression(struct ParseTree* tree, struct LexVector* lv);
void lexFree(struct LexVector* lv);
void parseFree(struct ParseTree* tree);
+struct mDebugger;
+bool mDebuggerEvaluateParseTree(struct mDebugger* debugger, struct ParseTree* tree, int32_t* value, int* segment);
+
CXX_GUARD_END
#endif
@@ -538,85 +538,6 @@ static void _printStatus(struct CLIDebugger* debugger, struct CLIDebugVector* dv
debugger->system->printStatus(debugger->system);
}
-static uint32_t _performOperation(enum Operation operation, uint32_t current, uint32_t next, struct CLIDebugVector* dv) {
- switch (operation) {
- case OP_ASSIGN:
- current = next;
- break;
- case OP_ADD:
- current += next;
- break;
- case OP_SUBTRACT:
- current -= next;
- break;
- case OP_MULTIPLY:
- current *= next;
- break;
- case OP_DIVIDE:
- if (next != 0) {
- current /= next;
- } else {
- dv->type = CLIDV_ERROR_TYPE;
- return 0;
- }
- break;
- case OP_AND:
- current &= next;
- break;
- case OP_OR:
- current |= next;
- break;
- case OP_XOR:
- current ^= next;
- break;
- case OP_LESS:
- current = current < next;
- break;
- case OP_GREATER:
- current = current > next;
- break;
- case OP_EQUAL:
- current = current == next;
- break;
- case OP_LE:
- current = current <= next;
- break;
- case OP_GE:
- current = current >= next;
- break;
- }
- return current;
-}
-
-static void _evaluateParseTree(struct mDebugger* debugger, struct ParseTree* tree, struct CLIDebugVector* dv) {
- int32_t lhs, rhs;
- switch (tree->token.type) {
- case TOKEN_UINT_TYPE:
- dv->intValue = tree->token.uintValue;
- break;
- case TOKEN_SEGMENT_TYPE:
- _evaluateParseTree(debugger, tree->lhs, dv);
- dv->segmentValue = dv->intValue;
- _evaluateParseTree(debugger, tree->rhs, dv);
- break;
- case TOKEN_OPERATOR_TYPE:
- _evaluateParseTree(debugger, tree->lhs, dv);
- lhs = dv->intValue;
- _evaluateParseTree(debugger, tree->rhs, dv);
- rhs = dv->intValue;
- dv->intValue = _performOperation(tree->token.operatorValue, lhs, rhs, dv);
- break;
- case TOKEN_IDENTIFIER_TYPE:
- if (mDebuggerLookupIdentifier(debugger, tree->token.identifierValue, &dv->intValue, &dv->segmentValue)) {
- break;
- }
- // Fall through
- case TOKEN_ERROR_TYPE:
- default:
- dv->type = CLIDV_ERROR_TYPE;
- }
-}
-
struct CLIDebugVector* CLIDVParse(struct CLIDebugger* debugger, const char* string, size_t length) {
if (!string || length < 1) {
return 0;
@@ -636,7 +557,9 @@ struct CLIDebugVector* CLIDVParse(struct CLIDebugger* debugger, const char* stri
if (tree.token.type == TOKEN_ERROR_TYPE) {
dvTemp.type = CLIDV_ERROR_TYPE;
} else {
- _evaluateParseTree(&debugger->d, &tree, &dvTemp);
+ if (!mDebuggerEvaluateParseTree(&debugger->d, &tree, &dvTemp.intValue, &dvTemp.segmentValue)) {
+ dvTemp.type = CLIDV_ERROR_TYPE;
+ }
}
parseFree(tree.lhs);
View
@@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <mgba/internal/debugger/parser.h>
+#include <mgba/debugger/debugger.h>
#include <mgba-util/string.h>
enum LexState {
@@ -509,3 +510,87 @@ void parseFree(struct ParseTree* tree) {
}
free(tree);
}
+
+static bool _performOperation(enum Operation operation, int32_t current, int32_t next, int32_t* value) {
+ switch (operation) {
+ case OP_ASSIGN:
+ current = next;
+ break;
+ case OP_ADD:
+ current += next;
+ break;
+ case OP_SUBTRACT:
+ current -= next;
+ break;
+ case OP_MULTIPLY:
+ current *= next;
+ break;
+ case OP_DIVIDE:
+ if (next != 0) {
+ current /= next;
+ } else {
+ return false;
+ }
+ break;
+ case OP_AND:
+ current &= next;
+ break;
+ case OP_OR:
+ current |= next;
+ break;
+ case OP_XOR:
+ current ^= next;
+ break;
+ case OP_LESS:
+ current = current < next;
+ break;
+ case OP_GREATER:
+ current = current > next;
+ break;
+ case OP_EQUAL:
+ current = current == next;
+ break;
+ case OP_LE:
+ current = current <= next;
+ break;
+ case OP_GE:
+ current = current >= next;
+ break;
+ }
+ *value = current;
+ return true;
+}
+
+bool mDebuggerEvaluateParseTree(struct mDebugger* debugger, struct ParseTree* tree, int32_t* value, int* segment) {
+ if (!value) {
+ return false;
+ }
+ int32_t lhs, rhs;
+ switch (tree->token.type) {
+ case TOKEN_UINT_TYPE:
+ if (segment) {
+ *segment = -1;
+ }
+ *value = tree->token.uintValue;
+ return true;
+ case TOKEN_SEGMENT_TYPE:
+ if (!mDebuggerEvaluateParseTree(debugger, tree->rhs, value, segment)) {
+ return false;
+ }
+ return mDebuggerEvaluateParseTree(debugger, tree->lhs, segment, NULL);
+ case TOKEN_OPERATOR_TYPE:
+ if (!mDebuggerEvaluateParseTree(debugger, tree->lhs, &lhs, segment)) {
+ return false;
+ }
+ if (!mDebuggerEvaluateParseTree(debugger, tree->rhs, &rhs, segment)) {
+ return false;
+ }
+ return _performOperation(tree->token.operatorValue, lhs, rhs, value);
+ case TOKEN_IDENTIFIER_TYPE:
+ return mDebuggerLookupIdentifier(debugger, tree->token.identifierValue, value, segment);
+ case TOKEN_ERROR_TYPE:
+ default:
+ break;
+ }
+ return false;
+}

0 comments on commit c692006

Please sign in to comment.