diff options
Diffstat (limited to 'src/parse.c')
| -rw-r--r-- | src/parse.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/parse.c b/src/parse.c index 507a56e..b56223e 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1493,6 +1493,8 @@ static int eval(AstNode* e) { int v = eval(e->node_operand); if (e->node_op == TokenKind_not) { return !v; + } else if (e->node_op == TokenKind_minus) { + return -v; } else { unimplemented(); } @@ -1503,9 +1505,44 @@ static int eval(AstNode* e) { return v1 && v2; } else if (e->node_op == TokenKind_oror) { return v1 || v2; + } else if (e->node_op == TokenKind_plus) { + return v1 + v2; + } else if (e->node_op == TokenKind_minus) { + return v1 - v2; + } else if (e->node_op == TokenKind_star) { + return v1 * v2; + } else if (e->node_op == TokenKind_slash) { + if (v2 == 0) { + fatal_error("eval: division by zero"); + } + return v1 / v2; + } else if (e->node_op == TokenKind_percent) { + if (v2 == 0) { + fatal_error("eval: division by zero"); + } + return v1 % v2; + } else if (e->node_op == TokenKind_eq) { + return v1 == v2; + } else if (e->node_op == TokenKind_ne) { + return v1 != v2; + } else if (e->node_op == TokenKind_lt) { + return v1 < v2; + } else if (e->node_op == TokenKind_le) { + return v1 <= v2; + } else if (e->node_op == TokenKind_lshift) { + return v1 << v2; + } else if (e->node_op == TokenKind_rshift) { + return v1 >> v2; } else { unimplemented(); } + } else if (e->kind == AstNodeKind_cond_expr) { + int cond = eval(e->node_cond); + if (cond) { + return eval(e->node_then); + } else { + return eval(e->node_else); + } } else { unimplemented(); } |
