aboutsummaryrefslogtreecommitdiff
path: root/src/parser.c
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-01-03 18:02:13 +0000
committerGinger Bill <bill@gingerbill.org>2017-01-03 18:02:13 +0000
commita86896e4d30b118287cf2111cd2fbec00ed2be70 (patch)
tree15198095de38744739e239bfac3c160dfa936d58 /src/parser.c
parenta3883a178c1e4e10058089a2832004a6ce1521e2 (diff)
Interval expressions in `range`
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c52
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) {