diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-01-03 18:02:13 +0000 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-01-03 18:02:13 +0000 |
| commit | a86896e4d30b118287cf2111cd2fbec00ed2be70 (patch) | |
| tree | 15198095de38744739e239bfac3c160dfa936d58 /src/parser.c | |
| parent | a3883a178c1e4e10058089a2832004a6ce1521e2 (diff) | |
Interval expressions in `range`
Diffstat (limited to 'src/parser.c')
| -rw-r--r-- | src/parser.c | 52 |
1 files changed, 35 insertions, 17 deletions
diff --git a/src/parser.c b/src/parser.c index da87a6c7c..1332fd929 100644 --- a/src/parser.c +++ b/src/parser.c @@ -160,6 +160,7 @@ AST_NODE_KIND(_ExprBegin, "", i32) \ AstNode *body; \ AstNode *else_expr; \ }) \ + AST_NODE_KIND(IntervalExpr, "interval expression", struct { Token op; AstNode *left, *right; }) \ AST_NODE_KIND(_ExprEnd, "", i32) \ AST_NODE_KIND(_StmtBegin, "", i32) \ AST_NODE_KIND(BadStmt, "bad statement", struct { Token begin, end; }) \ @@ -205,11 +206,11 @@ AST_NODE_KIND(_ComplexStmtBegin, "", i32) \ AstNode *body; \ }) \ AST_NODE_KIND(RangeStmt, "range statement", struct { \ - Token token; \ - AstNode * key; \ - AstNode * value; \ - AstNode * expr; \ - AstNode * body; \ + Token token; \ + AstNode *value; \ + AstNode *index; \ + AstNode *expr; \ + AstNode *body; \ }) \ AST_NODE_KIND(CaseClause, "case clause", struct { \ Token token; \ @@ -451,6 +452,8 @@ Token ast_node_token(AstNode *node) { return node->GiveExpr.token; case AstNode_IfExpr: return node->IfExpr.token; + case AstNode_IntervalExpr: + return ast_node_token(node->IntervalExpr.left); case AstNode_BadStmt: return node->BadStmt.begin; @@ -700,6 +703,18 @@ AstNode *make_demaybe_expr(AstFile *f, AstNode *expr, Token op) { return result; } +AstNode *make_interval_expr(AstFile *f, Token op, AstNode *left, AstNode *right) { + AstNode *result = make_node(f, AstNode_IntervalExpr); + + result->IntervalExpr.op = op; + result->IntervalExpr.left = left; + result->IntervalExpr.right = right; + + return result; +} + + + AstNode *make_basic_lit(AstFile *f, Token basic_lit) { AstNode *result = make_node(f, AstNode_BasicLit); @@ -854,12 +869,12 @@ AstNode *make_for_stmt(AstFile *f, Token token, AstNode *init, AstNode *cond, As result->ForStmt.body = body; return result; } -AstNode *make_range_stmt(AstFile *f, Token token, AstNode *key, AstNode *value, AstNode *expr, AstNode *body) { +AstNode *make_range_stmt(AstFile *f, Token token, AstNode *value, AstNode *index, AstNode *expr, AstNode *body) { AstNode *result = make_node(f, AstNode_RangeStmt); result->RangeStmt.token = token; - result->RangeStmt.key = key; result->RangeStmt.value = value; - result->RangeStmt.expr = expr; + result->RangeStmt.index = index; + result->RangeStmt.expr = expr; result->RangeStmt.body = body; return result; } @@ -2791,28 +2806,31 @@ AstNode *parse_range_stmt(AstFile *f) { isize prev_level = f->expr_level; f->expr_level = -1; AstNode *expr = parse_expr(f, false); + if (f->curr_token.kind == Token_Interval) { + Token op = expect_token(f, Token_Interval); + AstNode *right = parse_expr(f, false); + expr = make_interval_expr(f, op, expr, right); + } f->expr_level = prev_level; - AstNode *key = NULL; AstNode *value = NULL; - AstNode *body = parse_block_stmt(f, false); + AstNode *index = NULL; + AstNode *body = parse_block_stmt(f, false); switch (names.count) { - case 0: - break; case 1: - key = names.e[0]; + value = names.e[0]; break; case 2: - key = names.e[0]; - value = names.e[1]; + value = names.e[0]; + index = names.e[1]; break; default: - error_node(names.e[names.count-1], "Expected at most 2 expressions"); + error(token, "Expected at 1 or 2 identifiers"); return make_bad_stmt(f, token, f->curr_token); } - return make_range_stmt(f, token, key, value, expr, body); + return make_range_stmt(f, token, value, index, expr, body); } AstNode *parse_case_clause(AstFile *f) { |