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_MULTIPLY,
|
||||
OP_DIVIDE,
|
||||
OP_MODULO,
|
||||
OP_AND,
|
||||
OP_OR,
|
||||
OP_XOR,
|
||||
|
|
|
@ -39,6 +39,9 @@ static void _lexOperator(struct LexVector* lv, char operator) {
|
|||
case '/':
|
||||
lvNext->operatorValue = OP_DIVIDE;
|
||||
break;
|
||||
case '%':
|
||||
lvNext->operatorValue = OP_MODULO;
|
||||
break;
|
||||
case '&':
|
||||
lvNext->operatorValue = OP_AND;
|
||||
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 '^':
|
||||
|
@ -158,6 +162,7 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) {
|
|||
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 '^':
|
||||
|
@ -356,19 +362,20 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) {
|
|||
}
|
||||
|
||||
static const int _operatorPrecedence[] = {
|
||||
14,
|
||||
4,
|
||||
4,
|
||||
3,
|
||||
3,
|
||||
8,
|
||||
10,
|
||||
9,
|
||||
6,
|
||||
6,
|
||||
7,
|
||||
6,
|
||||
6
|
||||
[OP_ASSIGN] = 14,
|
||||
[OP_ADD] = 4,
|
||||
[OP_SUBTRACT] = 4,
|
||||
[OP_MULTIPLY] = 3,
|
||||
[OP_DIVIDE] = 3,
|
||||
[OP_MODULO] = 3,
|
||||
[OP_AND] = 8,
|
||||
[OP_OR] = 10,
|
||||
[OP_XOR] = 9,
|
||||
[OP_LESS] = 6,
|
||||
[OP_GREATER] = 6,
|
||||
[OP_EQUAL] = 7,
|
||||
[OP_LE] = 6,
|
||||
[OP_GE] = 6
|
||||
};
|
||||
|
||||
static struct ParseTree* _parseTreeCreate() {
|
||||
|
@ -508,6 +515,13 @@ static bool _performOperation(enum Operation operation, int32_t current, int32_t
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
case OP_MODULO:
|
||||
if (next != 0) {
|
||||
current %= next;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case OP_AND:
|
||||
current &= next;
|
||||
break;
|
||||
|
|
|
@ -230,6 +230,26 @@ M_TEST_DEFINE(lexIdentifierDivOperator) {
|
|||
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) {
|
||||
LEX("1&");
|
||||
|
||||
|
@ -428,6 +448,8 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(Lexer,
|
|||
cmocka_unit_test(lexIdentifierMulOperator),
|
||||
cmocka_unit_test(lexDivOperator),
|
||||
cmocka_unit_test(lexIdentifierDivOperator),
|
||||
cmocka_unit_test(lexModOperator),
|
||||
cmocka_unit_test(lexIdentifierModOperator),
|
||||
cmocka_unit_test(lexAndOperator),
|
||||
cmocka_unit_test(lexIdentifierAndOperator),
|
||||
cmocka_unit_test(lexOrOperator),
|
||||
|
|
Loading…
Reference in New Issue