mirror of https://github.com/mgba-emu/mgba.git
Debugger: Add segment parsing
This commit is contained in:
parent
0241952133
commit
819062a9a5
|
@ -428,36 +428,49 @@ static uint32_t _performOperation(enum Operation operation, uint32_t current, ui
|
|||
return current;
|
||||
}
|
||||
|
||||
static uint32_t _lookupIdentifier(struct mDebugger* debugger, const char* name, struct CLIDebugVector* dv) {
|
||||
static void _lookupIdentifier(struct mDebugger* debugger, const char* name, struct CLIDebugVector* dv) {
|
||||
struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger;
|
||||
if (cliDebugger->system) {
|
||||
uint32_t value = cliDebugger->system->lookupPlatformIdentifier(cliDebugger->system, name, dv);
|
||||
if (dv->type != CLIDV_ERROR_TYPE) {
|
||||
return value;
|
||||
dv->intValue = value;
|
||||
return;
|
||||
}
|
||||
dv->type = CLIDV_INT_TYPE;
|
||||
value = cliDebugger->system->lookupIdentifier(cliDebugger->system, name, dv);
|
||||
if (dv->type != CLIDV_ERROR_TYPE) {
|
||||
return value;
|
||||
dv->intValue = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
dv->type = CLIDV_ERROR_TYPE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t _evaluateParseTree(struct mDebugger* debugger, struct ParseTree* tree, struct CLIDebugVector* dv) {
|
||||
static void _evaluateParseTree(struct mDebugger* debugger, struct ParseTree* tree, struct CLIDebugVector* dv) {
|
||||
int32_t lhs, rhs;
|
||||
switch (tree->token.type) {
|
||||
case TOKEN_UINT_TYPE:
|
||||
return tree->token.uintValue;
|
||||
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:
|
||||
return _performOperation(tree->token.operatorValue, _evaluateParseTree(debugger, tree->lhs, dv), _evaluateParseTree(debugger, tree->rhs, dv), dv);
|
||||
_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:
|
||||
return _lookupIdentifier(debugger, tree->token.identifierValue, dv);
|
||||
_lookupIdentifier(debugger, tree->token.identifierValue, dv);
|
||||
break;
|
||||
case TOKEN_ERROR_TYPE:
|
||||
default:
|
||||
dv->type = CLIDV_ERROR_TYPE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct CLIDebugVector* CLIDVParse(struct CLIDebugger* debugger, const char* string, size_t length) {
|
||||
|
@ -465,7 +478,7 @@ struct CLIDebugVector* CLIDVParse(struct CLIDebugger* debugger, const char* stri
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct CLIDebugVector dvTemp = { .type = CLIDV_INT_TYPE };
|
||||
struct CLIDebugVector dvTemp = { .type = CLIDV_INT_TYPE, .segmentValue = -1 };
|
||||
|
||||
struct LexVector lv = { .next = 0 };
|
||||
size_t adjusted = lexExpression(&lv, string, length);
|
||||
|
@ -479,7 +492,7 @@ struct CLIDebugVector* CLIDVParse(struct CLIDebugger* debugger, const char* stri
|
|||
if (tree.token.type == TOKEN_ERROR_TYPE) {
|
||||
dvTemp.type = CLIDV_ERROR_TYPE;
|
||||
} else {
|
||||
dvTemp.intValue = _evaluateParseTree(&debugger->d, &tree, &dvTemp);
|
||||
_evaluateParseTree(&debugger->d, &tree, &dvTemp);
|
||||
}
|
||||
|
||||
parseFree(tree.lhs);
|
||||
|
|
|
@ -20,11 +20,14 @@ struct CLIDebugVector {
|
|||
enum CLIDVType {
|
||||
CLIDV_ERROR_TYPE,
|
||||
CLIDV_INT_TYPE,
|
||||
CLIDV_CHAR_TYPE
|
||||
CLIDV_CHAR_TYPE,
|
||||
} type;
|
||||
union {
|
||||
int32_t intValue;
|
||||
char* charValue;
|
||||
struct {
|
||||
int32_t intValue;
|
||||
int segmentValue;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -222,6 +222,17 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) {
|
|||
lv = _lexOperator(lv, token);
|
||||
state = LEX_ROOT;
|
||||
break;
|
||||
case ':':
|
||||
lv->token.type = TOKEN_SEGMENT_TYPE;
|
||||
lv->token.uintValue = next;
|
||||
lvNext = malloc(sizeof(struct LexVector));
|
||||
lvNext->next = lv->next;
|
||||
lvNext->token.type = TOKEN_UINT_TYPE;
|
||||
lv->next = lvNext;
|
||||
lv = lvNext;
|
||||
next = 0;
|
||||
state = LEX_EXPECT_HEX;
|
||||
break;
|
||||
case ')':
|
||||
lv->token.type = TOKEN_UINT_TYPE;
|
||||
lv->token.uintValue = next;
|
||||
|
@ -355,6 +366,17 @@ static struct LexVector* _parseExpression(struct ParseTree* tree, struct LexVect
|
|||
return 0;
|
||||
}
|
||||
break;
|
||||
case TOKEN_SEGMENT_TYPE:
|
||||
tree->lhs = _parseTreeCreate();
|
||||
tree->lhs->token.type = TOKEN_UINT_TYPE;
|
||||
tree->lhs->token.uintValue = lv->token.uintValue;
|
||||
tree->rhs = _parseTreeCreate();
|
||||
tree->token.type = TOKEN_SEGMENT_TYPE;
|
||||
lv = _parseExpression(tree->rhs, lv->next, precedence, openParens);
|
||||
if (tree->token.type == TOKEN_ERROR_TYPE) {
|
||||
tree->token.type = TOKEN_ERROR_TYPE;
|
||||
}
|
||||
break;
|
||||
case TOKEN_OPEN_PAREN_TYPE:
|
||||
lv = _parseExpression(tree, lv->next, INT_MAX, openParens + 1);
|
||||
break;
|
||||
|
|
|
@ -36,6 +36,7 @@ struct Token {
|
|||
TOKEN_OPERATOR_TYPE,
|
||||
TOKEN_OPEN_PAREN_TYPE,
|
||||
TOKEN_CLOSE_PAREN_TYPE,
|
||||
TOKEN_SEGMENT_TYPE,
|
||||
} type;
|
||||
union {
|
||||
uint32_t uintValue;
|
||||
|
|
Loading…
Reference in New Issue