Permalink
Browse files

Debugger: Add modulo operator

  • Loading branch information...
endrift committed Dec 29, 2017
1 parent 49675d7 commit 5d98f9c963100c5f369b653d843b89456057b3db
Showing with 50 additions and 13 deletions.
  1. +1 −0 include/mgba/internal/debugger/parser.h
  2. +27 −13 src/debugger/parser.c
  3. +22 −0 src/debugger/test/lexer.c
@@ -18,6 +18,7 @@ enum Operation {
OP_SUBTRACT,
OP_MULTIPLY,
OP_DIVIDE,
+ OP_MODULO,
OP_AND,
OP_OR,
OP_XOR,
View
@@ -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;
View
@@ -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),

0 comments on commit 5d98f9c

Please sign in to comment.