diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-02-26 15:14:08 +0000 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-02-26 15:14:08 +0000 |
| commit | f29e303ce7b11fbe88a4b63374c08130c6c189dd (patch) | |
| tree | a489ab17ff1e153891923c98597432dc98338827 /src/parser.c | |
| parent | 3c9143957c1726848e7f286ca6c96d410c84b585 (diff) | |
Slices now have a capacity.
Diffstat (limited to 'src/parser.c')
| -rw-r--r-- | src/parser.c | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/src/parser.c b/src/parser.c index 23053a816..160b72ef3 100644 --- a/src/parser.c +++ b/src/parser.c @@ -151,8 +151,9 @@ AST_NODE_KIND(_ExprBegin, "", i32) \ AST_NODE_KIND(DerefExpr, "dereference expression", struct { Token op; AstNode *expr; }) \ AST_NODE_KIND(SliceExpr, "slice expression", struct { \ AstNode *expr; \ - Token open, close, interval; \ - AstNode *low, *high; \ + Token open, close; \ + bool index3; \ + AstNode *low, *high, *max; \ }) \ AST_NODE_KIND(CallExpr, "call expression", struct { \ AstNode * proc; \ @@ -667,14 +668,15 @@ AstNode *ast_index_expr(AstFile *f, AstNode *expr, AstNode *index, Token open, T } -AstNode *ast_slice_expr(AstFile *f, AstNode *expr, Token open, Token close, Token interval, AstNode *low, AstNode *high) { +AstNode *ast_slice_expr(AstFile *f, AstNode *expr, Token open, Token close, bool index3, AstNode *low, AstNode *high, AstNode *max) { AstNode *result = make_ast_node(f, AstNode_SliceExpr); result->SliceExpr.expr = expr; result->SliceExpr.open = open; result->SliceExpr.close = close; - result->SliceExpr.interval = interval; + result->SliceExpr.index3 = index3; result->SliceExpr.low = low; result->SliceExpr.high = high; + result->SliceExpr.max = max; return result; } @@ -1945,7 +1947,9 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) { // TODO(bill): Handle this } Token open = {0}, close = {0}, interval = {0}; - AstNode *indices[2] = {0}; + AstNode *indices[3] = {0}; + isize ellipsis_count = 0; + Token ellipses[2] = {0}; f->expr_level++; open = expect_token(f, Token_OpenBracket); @@ -1955,23 +1959,37 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) { } bool is_index = true; - if (f->curr_token.kind == Token_Ellipsis) { - is_index = false; - interval = f->curr_token; + while (f->curr_token.kind == Token_Ellipsis && ellipsis_count < gb_count_of(ellipses)) { + ellipses[ellipsis_count++] = f->curr_token; next_token(f); - if (f->curr_token.kind != Token_CloseBracket && + if (f->curr_token.kind != Token_Ellipsis && + f->curr_token.kind != Token_CloseBracket && f->curr_token.kind != Token_EOF) { - indices[1] = parse_expr(f, false); + indices[ellipsis_count] = parse_expr(f, false); } } + f->expr_level--; close = expect_token(f, Token_CloseBracket); - if (is_index) { - operand = ast_index_expr(f, operand, indices[0], open, close); + if (ellipsis_count > 0) { + bool index3 = false; + if (ellipsis_count == 2) { + index3 = true; + // 2nd and 3rd index must be present + if (indices[1] == NULL) { + error(ellipses[0], "2nd index required in 3-index slice expression"); + indices[1] = ast_bad_expr(f, ellipses[0], ellipses[1]); + } + if (indices[2] == NULL) { + error(ellipses[1], "3rd index required in 3-index slice expression"); + indices[2] = ast_bad_expr(f, ellipses[1], close); + } + } + operand = ast_slice_expr(f, operand, open, close, index3, indices[0], indices[1], indices[2]); } else { - operand = ast_slice_expr(f, operand, open, close, interval, indices[0], indices[1]); + operand = ast_index_expr(f, operand, indices[0], open, close); } } break; |