feat(Evaluator): add modulus operator

This commit is contained in:
Matthieu Bessat 2022-05-15 21:16:34 +02:00
parent 7700e61019
commit 738d16f2fc
9 changed files with 39 additions and 3 deletions

View file

@ -26,7 +26,7 @@ ToDo List:
- [X] add unit tests - [X] add unit tests
- [X] allow to set variables - [X] allow to set variables
- [X] read line comments - [X] read line comments
- [ ] add modulus operator '%' - [X] add modulus operator '%'
- [ ] add support for multiple characters operators - [ ] add support for multiple characters operators
- [ ] add inclusive operators like '!=', '>=', '<=' - [ ] add inclusive operators like '!=', '>=', '<='
- [ ] add input_number() std function - [ ] add input_number() std function

2
examples/sandbox.ltor Normal file
View file

@ -0,0 +1,2 @@
# test modulus operator
print_number(20.2 % 10)

View file

@ -2,7 +2,7 @@
#ifndef EVALUATOR_H_ #ifndef EVALUATOR_H_
#define 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); int evaluate(struct StateContainer* state, char* inputStr, int* resultPtr, unsigned char* typePtr);

View file

@ -8,6 +8,7 @@ int is_operator(char candidate) {
return ( return (
candidate == '*' || candidate == '*' ||
candidate == '/' || candidate == '/' ||
candidate == '%' ||
candidate == '+' || candidate == '+' ||
candidate == '-' || candidate == '-' ||
candidate == '^' || candidate == '^' ||
@ -81,6 +82,8 @@ int operate(
res = a*b; res = a*b;
} else if (operator == '/') { } else if (operator == '/') {
res = a/b; res = a/b;
} else if (operator == '%') {
res = m_float_modulus(a, b);
} else if (operator == '^') { } else if (operator == '^') {
res = m_float_pow(a, b); res = m_float_pow(a, b);
} else if (operator == '=') { } else if (operator == '=') {
@ -109,6 +112,8 @@ int operate(
res = aRepr*bRepr; res = aRepr*bRepr;
} else if (operator == '^') { } else if (operator == '^') {
res = integer_pow(aRepr, bRepr); res = integer_pow(aRepr, bRepr);
} else if (operator == '%') {
res = (aRepr % bRepr);
} else if (operator == '=') { } else if (operator == '=') {
res = (int) (aRepr == bRepr); res = (int) (aRepr == bRepr);
} else if (operator == '<') { } else if (operator == '<') {

View file

@ -84,6 +84,22 @@ float m_float_pow(float base, int exponent)
return r; 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) int m_factorial(int x)
{ {
if (x == 0 || x == 1) { if (x == 0 || x == 1) {

View file

@ -20,6 +20,8 @@ int integer_pow(int base, int exponent);
int float_almost_equal(float a, float b); int float_almost_equal(float a, float b);
float m_float_modulus(float a, float mod);
int m_factorial(int x); int m_factorial(int x);
float m_float_pow(float base, int exponent); float m_float_pow(float base, int exponent);

View file

@ -8,9 +8,9 @@
int main() int main()
{ {
printf("== UNIT TESTS == \n"); printf("== UNIT TESTS == \n");
test_utils();
test_var_store(); test_var_store();
test_stack(); test_stack();
test_utils();
test_evaluation(); test_evaluation();
test_line_processing(); test_line_processing();
} }

View file

@ -133,4 +133,12 @@ void test_evaluation()
evaluate(state, "5 > 0", &resVal, &resType); evaluate(state, "5 > 0", &resVal, &resType);
assert(resType == TYPE_INT); assert(resType == TYPE_INT);
assert(1 == resVal); 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)));
} }

View file

@ -39,6 +39,9 @@ void test_utils()
assert(m_factorial(3) == 6); assert(m_factorial(3) == 6);
assert(m_factorial(4) == 2*3*4); 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(2.7182, m_exp(1.0)));
assert(float_almost_equal(1, m_exp(0))); assert(float_almost_equal(1, m_exp(0)));