mirror of https://github.com/mgba-emu/mgba.git
Debugger: Add modulo operator
This commit is contained in:
parent
49675d7c58
commit
5d98f9c963
|
@ -18,6 +18,7 @@ enum Operation {
|
||||||
OP_SUBTRACT,
|
OP_SUBTRACT,
|
||||||
OP_MULTIPLY,
|
OP_MULTIPLY,
|
||||||
OP_DIVIDE,
|
OP_DIVIDE,
|
||||||
|
OP_MODULO,
|
||||||
OP_AND,
|
OP_AND,
|
||||||
OP_OR,
|
OP_OR,
|
||||||
OP_XOR,
|
OP_XOR,
|
||||||
|
|
|
@ -39,6 +39,9 @@ static void _lexOperator(struct LexVector* lv, char operator) {
|
||||||
case '/':
|
case '/':
|
||||||
lvNext->operatorValue = OP_DIVIDE;
|
lvNext->operatorValue = OP_DIVIDE;
|
||||||
break;
|
break;
|
||||||
|
case '%':
|
||||||
|
lvNext->operatorValue = OP_MODULO;
|
||||||
|
break;
|
||||||
case '&':
|
case '&':
|
||||||
lvNext->operatorValue = OP_AND;
|
lvNext->operatorValue = OP_AND;
|
||||||
break;
|
break;
|
||||||
|
@ -68,6 +71,7 @@ static void _lexValue(struct LexVector* lv, char token, uint32_t next, enum LexS
|
||||||
case '-':
|
case '-':
|
||||||
case '*':
|
case '*':
|
||||||
case '/':
|
case '/':
|
||||||
|
case '%':
|
||||||
case '&':
|
case '&':
|
||||||
case '|':
|
case '|':
|
||||||
case '^':
|
case '^':
|
||||||
|
@ -158,6 +162,7 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) {
|
||||||
case '-':
|
case '-':
|
||||||
case '*':
|
case '*':
|
||||||
case '/':
|
case '/':
|
||||||
|
case '%':
|
||||||
case '&':
|
case '&':
|
||||||
case '|':
|
case '|':
|
||||||
case '^':
|
case '^':
|
||||||
|
@ -304,6 +309,7 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) {
|
||||||
case '-':
|
case '-':
|
||||||
case '*':
|
case '*':
|
||||||
case '/':
|
case '/':
|
||||||
|
case '%':
|
||||||
case '&':
|
case '&':
|
||||||
case '|':
|
case '|':
|
||||||
case '^':
|
case '^':
|
||||||
|
@ -356,19 +362,20 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int _operatorPrecedence[] = {
|
static const int _operatorPrecedence[] = {
|
||||||
14,
|
[OP_ASSIGN] = 14,
|
||||||
4,
|
[OP_ADD] = 4,
|
||||||
4,
|
[OP_SUBTRACT] = 4,
|
||||||
3,
|
[OP_MULTIPLY] = 3,
|
||||||
3,
|
[OP_DIVIDE] = 3,
|
||||||
8,
|
[OP_MODULO] = 3,
|
||||||
10,
|
[OP_AND] = 8,
|
||||||
9,
|
[OP_OR] = 10,
|
||||||
6,
|
[OP_XOR] = 9,
|
||||||
6,
|
[OP_LESS] = 6,
|
||||||
7,
|
[OP_GREATER] = 6,
|
||||||
6,
|
[OP_EQUAL] = 7,
|
||||||
6
|
[OP_LE] = 6,
|
||||||
|
[OP_GE] = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ParseTree* _parseTreeCreate() {
|
static struct ParseTree* _parseTreeCreate() {
|
||||||
|
@ -508,6 +515,13 @@ static bool _performOperation(enum Operation operation, int32_t current, int32_t
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case OP_MODULO:
|
||||||
|
if (next != 0) {
|
||||||
|
current %= next;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case OP_AND:
|
case OP_AND:
|
||||||
current &= next;
|
current &= next;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -230,6 +230,26 @@ M_TEST_DEFINE(lexIdentifierDivOperator) {
|
||||||
assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_DIVIDE);
|
assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_DIVIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexModOperator) {
|
||||||
|
LEX("1%");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(lv), 2);
|
||||||
|
assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1);
|
||||||
|
assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_MODULO);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexIdentifierModOperator) {
|
||||||
|
LEX("x%");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(lv), 2);
|
||||||
|
assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE);
|
||||||
|
assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x");
|
||||||
|
assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_MODULO);
|
||||||
|
}
|
||||||
|
|
||||||
M_TEST_DEFINE(lexAndOperator) {
|
M_TEST_DEFINE(lexAndOperator) {
|
||||||
LEX("1&");
|
LEX("1&");
|
||||||
|
|
||||||
|
@ -428,6 +448,8 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(Lexer,
|
||||||
cmocka_unit_test(lexIdentifierMulOperator),
|
cmocka_unit_test(lexIdentifierMulOperator),
|
||||||
cmocka_unit_test(lexDivOperator),
|
cmocka_unit_test(lexDivOperator),
|
||||||
cmocka_unit_test(lexIdentifierDivOperator),
|
cmocka_unit_test(lexIdentifierDivOperator),
|
||||||
|
cmocka_unit_test(lexModOperator),
|
||||||
|
cmocka_unit_test(lexIdentifierModOperator),
|
||||||
cmocka_unit_test(lexAndOperator),
|
cmocka_unit_test(lexAndOperator),
|
||||||
cmocka_unit_test(lexIdentifierAndOperator),
|
cmocka_unit_test(lexIdentifierAndOperator),
|
||||||
cmocka_unit_test(lexOrOperator),
|
cmocka_unit_test(lexOrOperator),
|
||||||
|
|
Loading…
Reference in New Issue