diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-04-21 00:13:20 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-04-21 00:13:20 +0100 |
| commit | 9a1566d665319b8b9eb917c0849ef4b7e1b8f849 (patch) | |
| tree | 2111368ce7e7df2f37465d9492b358a9e142d5dc /src/ir.c | |
| parent | a713e3300786199510e525aa9f90ee8d91aa862a (diff) | |
Interval expressions for match statements
Diffstat (limited to 'src/ir.c')
| -rw-r--r-- | src/ir.c | 20 |
1 files changed, 18 insertions, 2 deletions
@@ -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); } |