Skip to content

Commit

Permalink
add modulo (%) operator
Browse files Browse the repository at this point in the history
  • Loading branch information
wimh committed Apr 18, 2016
1 parent 824c138 commit e2d629f
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 5 deletions.
5 changes: 4 additions & 1 deletion panel-plugin/eval.c
Expand Up @@ -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;
Expand All @@ -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();
}
Expand Down
2 changes: 1 addition & 1 deletion panel-plugin/grammar.txt
Expand Up @@ -19,7 +19,7 @@ pow -> ( expr ) | function ( expr ) | constant | NUM

add_op -> + | -

mult_op -> * | /
mult_op -> * | / | %

pow_op -> ^ | **

Expand Down
2 changes: 1 addition & 1 deletion panel-plugin/lexer.c
Expand Up @@ -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;
Expand Down
7 changes: 5 additions & 2 deletions panel-plugin/parser.c
Expand Up @@ -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 == '%';
}

/*
Expand Down Expand Up @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions panel-plugin/parsetree.h
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions tests/Makefile.am
Expand Up @@ -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 \
Expand Down
15 changes: 15 additions & 0 deletions 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
}

0 comments on commit e2d629f

Please sign in to comment.