From 738d16f2fcdb79850cca82efe2f855745e54efb9 Mon Sep 17 00:00:00 2001 From: Matthieu Bessat Date: Sun, 15 May 2022 21:16:34 +0200 Subject: [PATCH] feat(Evaluator): add modulus operator --- README.md | 2 +- examples/sandbox.ltor | 2 ++ src/evaluator.h | 2 +- src/operate.c | 5 +++++ src/utils.c | 16 ++++++++++++++++ src/utils.h | 2 ++ tests/test.c | 2 +- tests/test_evaluation.c | 8 ++++++++ tests/test_utils.c | 3 +++ 9 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 examples/sandbox.ltor diff --git a/README.md b/README.md index 28a1ed5..b078218 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ ToDo List: - [X] add unit tests - [X] allow to set variables - [X] read line comments -- [ ] add modulus operator '%' +- [X] add modulus operator '%' - [ ] add support for multiple characters operators - [ ] add inclusive operators like '!=', '>=', '<=' - [ ] add input_number() std function diff --git a/examples/sandbox.ltor b/examples/sandbox.ltor new file mode 100644 index 0000000..ba642e2 --- /dev/null +++ b/examples/sandbox.ltor @@ -0,0 +1,2 @@ +# test modulus operator +print_number(20.2 % 10) diff --git a/src/evaluator.h b/src/evaluator.h index 6748bf8..40a8424 100644 --- a/src/evaluator.h +++ b/src/evaluator.h @@ -2,7 +2,7 @@ #ifndef EVALUATOR_H_ #define EVALUATOR_H_ -#define EVALUATOR_DEBUG_LEVEL 1 +#define EVALUATOR_DEBUG_LEVEL 0 int evaluate(struct StateContainer* state, char* inputStr, int* resultPtr, unsigned char* typePtr); diff --git a/src/operate.c b/src/operate.c index 309841b..b3ee816 100644 --- a/src/operate.c +++ b/src/operate.c @@ -8,6 +8,7 @@ int is_operator(char candidate) { return ( candidate == '*' || candidate == '/' || + candidate == '%' || candidate == '+' || candidate == '-' || candidate == '^' || @@ -81,6 +82,8 @@ int operate( res = a*b; } else if (operator == '/') { res = a/b; + } else if (operator == '%') { + res = m_float_modulus(a, b); } else if (operator == '^') { res = m_float_pow(a, b); } else if (operator == '=') { @@ -109,6 +112,8 @@ int operate( res = aRepr*bRepr; } else if (operator == '^') { res = integer_pow(aRepr, bRepr); + } else if (operator == '%') { + res = (aRepr % bRepr); } else if (operator == '=') { res = (int) (aRepr == bRepr); } else if (operator == '<') { diff --git a/src/utils.c b/src/utils.c index 9a73776..9c9a5d9 100644 --- a/src/utils.c +++ b/src/utils.c @@ -84,6 +84,22 @@ float m_float_pow(float base, int exponent) return r; } +float m_float_modulus(float a, float b) +{ + // find the remainder + float t = a; + float res = 0; + int i = 0; + while (i < 1000) { + t = t - b; + if (t < 0) { + return t+b; + } + i++; + } + return -1; +} + int m_factorial(int x) { if (x == 0 || x == 1) { diff --git a/src/utils.h b/src/utils.h index e8134ee..10cd57b 100644 --- a/src/utils.h +++ b/src/utils.h @@ -20,6 +20,8 @@ int integer_pow(int base, int exponent); int float_almost_equal(float a, float b); +float m_float_modulus(float a, float mod); + int m_factorial(int x); float m_float_pow(float base, int exponent); diff --git a/tests/test.c b/tests/test.c index eb0ac15..eb907c4 100644 --- a/tests/test.c +++ b/tests/test.c @@ -8,9 +8,9 @@ int main() { printf("== UNIT TESTS == \n"); + test_utils(); test_var_store(); test_stack(); - test_utils(); test_evaluation(); test_line_processing(); } diff --git a/tests/test_evaluation.c b/tests/test_evaluation.c index 8a8ae3f..bd0bbfb 100644 --- a/tests/test_evaluation.c +++ b/tests/test_evaluation.c @@ -133,4 +133,12 @@ void test_evaluation() evaluate(state, "5 > 0", &resVal, &resType); assert(resType == TYPE_INT); assert(1 == resVal); + + evaluate(state, "5 % 10", &resVal, &resType); + assert(resType == TYPE_INT); + assert(5 == resVal); + + evaluate(state, "5.3 % 10", &resVal, &resType); + assert(resType == TYPE_FLOAT); + assert(float_almost_equal(5.3, get_float_from_int_rep(resVal))); } diff --git a/tests/test_utils.c b/tests/test_utils.c index 7653637..fa7ab7c 100644 --- a/tests/test_utils.c +++ b/tests/test_utils.c @@ -39,6 +39,9 @@ void test_utils() assert(m_factorial(3) == 6); assert(m_factorial(4) == 2*3*4); + assert(float_almost_equal(2.22, m_float_modulus(2.22, 10))); + assert(float_almost_equal(28.619, m_float_modulus(200.22, 34.32))); + assert(float_almost_equal(2.7182, m_exp(1.0))); assert(float_almost_equal(1, m_exp(0)));