From e2d629f841375f73c58fcc2fd506bcdb8740ac0e Mon Sep 17 00:00:00 2001 From: Wim Hueskes Date: Mon, 18 Apr 2016 22:21:49 +0200 Subject: [PATCH 5/6] add modulo (%) operator --- panel-plugin/eval.c | 5 ++++- panel-plugin/grammar.txt | 2 +- panel-plugin/lexer.c | 2 +- panel-plugin/parser.c | 7 +++++-- panel-plugin/parsetree.h | 1 + tests/Makefile.am | 1 + tests/test-modulo.awk | 15 +++++++++++++++ 7 files changed, 28 insertions(+), 5 deletions(-) create mode 100755 tests/test-modulo.awk diff --git a/panel-plugin/eval.c b/panel-plugin/eval.c index e678e48..0d9a96a 100644 --- a/panel-plugin/eval.c +++ b/panel-plugin/eval.c @@ -103,6 +103,9 @@ static double eval(node_t *parsetree) case OP_DIV: r = left / right; break; + case OP_MODULO: + r = fmod(left, right); + break; case OP_POW: r = pow(left, right); break; @@ -118,7 +121,7 @@ static double eval(node_t *parsetree) arg = eval(parsetree->right); r = parsetree->val.fun(arg); break; - + default: g_assert_not_reached(); } diff --git a/panel-plugin/grammar.txt b/panel-plugin/grammar.txt index fa1b6f0..fb11afa 100644 --- a/panel-plugin/grammar.txt +++ b/panel-plugin/grammar.txt @@ -19,7 +19,7 @@ pow -> ( expr ) | function ( expr ) | constant | NUM add_op -> + | - -mult_op -> * | / +mult_op -> * | / | % pow_op -> ^ | ** diff --git a/panel-plugin/lexer.c b/panel-plugin/lexer.c index bd39316..a3b6c99 100644 --- a/panel-plugin/lexer.c +++ b/panel-plugin/lexer.c @@ -24,7 +24,7 @@ static gboolean isoperator(int c) { - if (c == '+' || c == '-' || c == '*' || c == '/' || c == '^') + if (c == '+' || c == '-' || c == '*' || c == '/' || c == '%' || c == '^') return TRUE; else return FALSE; diff --git a/panel-plugin/parser.c b/panel-plugin/parser.c index 5ae1bbb..cc91ec8 100644 --- a/panel-plugin/parser.c +++ b/panel-plugin/parser.c @@ -121,7 +121,7 @@ static gboolean is_mult_op(char op) /* return op[0] == '/' || (op[0] == '*' && op[1] == '\0') */ - return op == '/' || op == '*'; + return op == '/' || op == '*' || op == '%'; } /* @@ -388,8 +388,11 @@ static node_t *get_factortail(token_stack_t *stack, node_t *left_expr, GError ** case '/': op->val.op = OP_DIV; break; + case '%': + op->val.op = OP_MODULO; + break; default: - set_error(err, "Expected '*' or '/'", token); + set_error(err, "Expected '*', '/' or '%'", token); g_free(op); return left_expr; } diff --git a/panel-plugin/parsetree.h b/panel-plugin/parsetree.h index a0f8ff8..2df1c2a 100644 --- a/panel-plugin/parsetree.h +++ b/panel-plugin/parsetree.h @@ -26,6 +26,7 @@ typedef enum { NODE_OPERATOR, NODE_NUMBER, NODE_FUNCTION } node_type_t; typedef enum { OP_PLUS, OP_MINUS, OP_UMINUS, OP_TIMES, OP_DIV, + OP_MODULO, OP_POW } operator_type_t; typedef struct _node_t { diff --git a/tests/Makefile.am b/tests/Makefile.am index 1b74a74..2f11daa 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -6,6 +6,7 @@ EXTRA_DIST = \ TESTS = \ test-simple-expr.awk \ test-minus.awk \ + test-modulo.awk \ test-e-notation.awk \ test-abs.awk \ test-sqrt.awk \ diff --git a/tests/test-modulo.awk b/tests/test-modulo.awk new file mode 100755 index 0000000..792f2ef --- /dev/null +++ b/tests/test-modulo.awk @@ -0,0 +1,15 @@ +#!/usr/bin/awk -f + +function abs(x) { + return (x < 0) ? -x : x +} + +BEGIN{ + expr = "'1 + 27 % 5 * 3 + -3 % 2'" + "../panel-plugin/calctest " expr | getline res + if (abs(res - 6) > 1.0e-14) { + print res + exit 1 + } else + exit 0 +} -- 2.1.4