aboutsummaryrefslogtreecommitdiff
path: root/src/ir.c
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-04-21 00:13:20 +0100
committerGinger Bill <bill@gingerbill.org>2017-04-21 00:13:20 +0100
commit9a1566d665319b8b9eb917c0849ef4b7e1b8f849 (patch)
tree2111368ce7e7df2f37465d9492b358a9e142d5dc /src/ir.c
parenta713e3300786199510e525aa9f90ee8d91aa862a (diff)
Interval expressions for match statements
Diffstat (limited to 'src/ir.c')
-rw-r--r--src/ir.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/ir.c b/src/ir.c
index aaddaf84a..4e1e942b4 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -6191,8 +6191,24 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
for_array(j, cc->list) {
AstNode *expr = cc->list.e[j];
next_cond = ir_new_block(proc, clause, "match.case.next");
-
- irValue *cond = ir_emit_comp(proc, Token_CmpEq, tag, ir_build_expr(proc, expr));
+ irValue *cond = v_false;
+ if (expr->kind == AstNode_IntervalExpr) {
+ ast_node(ie, IntervalExpr, expr);
+ TokenKind op = {0};
+ switch (ie->op.kind) {
+ case Token_Ellipsis: op = Token_LtEq; break;
+ case Token_HalfClosed: op = Token_Lt; break;
+ default: GB_PANIC("Invalid interval operator"); break;
+ }
+ irValue *lhs = ir_build_expr(proc, ie->left);
+ irValue *rhs = ir_build_expr(proc, ie->right);
+ // TODO(bill): do short circuit here
+ irValue *cond_lhs = ir_emit_comp(proc, Token_LtEq, lhs, tag);
+ irValue *cond_rhs = ir_emit_comp(proc, op, tag, rhs);
+ cond = ir_emit_arith(proc, Token_And, cond_lhs, cond_rhs, t_bool);
+ } else {
+ cond = ir_emit_comp(proc, Token_CmpEq, tag, ir_build_expr(proc, expr));
+ }
ir_emit_if(proc, cond, body, next_cond);
ir_start_block(proc, next_cond);
}