diff options
| author | gingerBill <bill@gingerbill.org> | 2019-08-31 20:13:28 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2019-08-31 20:13:28 +0100 |
| commit | b9d3129fb3a4ba7ef49cea69d086a7f705819f2e (patch) | |
| tree | d985a8be38dc2bbf05ea13d13e700ab5074b87ed /src/parser.cpp | |
| parent | b311540b1672129e87a7249650a19cf11d2fccef (diff) | |
`where` clauses for procedure literals
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index e92489020..8490b0e00 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -144,6 +144,7 @@ Ast *clone_ast(Ast *node) { case Ast_ProcLit: n->ProcLit.type = clone_ast(n->ProcLit.type); n->ProcLit.body = clone_ast(n->ProcLit.body); + n->ProcLit.where_clauses = clone_ast_array(n->ProcLit.where_clauses); break; case Ast_CompoundLit: n->CompoundLit.type = clone_ast(n->CompoundLit.type); @@ -612,11 +613,13 @@ Ast *ast_proc_group(AstFile *f, Token token, Token open, Token close, Array<Ast return result; } -Ast *ast_proc_lit(AstFile *f, Ast *type, Ast *body, u64 tags) { +Ast *ast_proc_lit(AstFile *f, Ast *type, Ast *body, u64 tags, Token where_token, Array<Ast *> const &where_clauses) { Ast *result = alloc_ast_node(f, Ast_ProcLit); result->ProcLit.type = type; result->ProcLit.body = body; result->ProcLit.tags = tags; + result->ProcLit.where_token = where_token; + result->ProcLit.where_clauses = where_clauses; return result; } @@ -1827,15 +1830,41 @@ Ast *parse_operand(AstFile *f, bool lhs) { } Ast *type = parse_proc_type(f, token); + Token where_token = {}; + Array<Ast *> where_clauses = {}; + u64 tags = 0; + + if (f->curr_token.kind == Token_where) { + where_token = expect_token(f, Token_where); + isize prev_level = f->expr_level; + f->expr_level = -1; + where_clauses = parse_rhs_expr_list(f); + f->expr_level = prev_level; + } + + parse_proc_tags(f, &tags); + if ((tags & ProcTag_require_results) != 0) { + syntax_error(f->curr_token, "#require_results has now been replaced as an attribute @(require_results) on the declaration"); + tags &= ~ProcTag_require_results; + } + GB_ASSERT(type->kind == Ast_ProcType); + type->ProcType.tags = tags; if (f->allow_type && f->expr_level < 0) { + if (tags != 0) { + syntax_error(token, "A procedure type cannot have suffix tags"); + } + if (where_token.kind != Token_Invalid) { + syntax_error(where_token, "'where' clauses are not allowed on procedure types"); + } return type; } - u64 tags = type->ProcType.tags; - if (allow_token(f, Token_Undef)) { - return ast_proc_lit(f, type, nullptr, tags); + if (where_token.kind != Token_Invalid) { + syntax_error(where_token, "'where' clauses are not allowed on procedure literals without a defined body (replaced with ---)"); + } + return ast_proc_lit(f, type, nullptr, tags, where_token, where_clauses); } else if (f->curr_token.kind == Token_OpenBrace) { Ast *curr_proc = f->curr_proc; Ast *body = nullptr; @@ -1843,7 +1872,7 @@ Ast *parse_operand(AstFile *f, bool lhs) { body = parse_body(f); f->curr_proc = curr_proc; - return ast_proc_lit(f, type, body, tags); + return ast_proc_lit(f, type, body, tags, where_token, where_clauses); } else if (allow_token(f, Token_do)) { Ast *curr_proc = f->curr_proc; Ast *body = nullptr; @@ -1851,12 +1880,15 @@ Ast *parse_operand(AstFile *f, bool lhs) { body = convert_stmt_to_body(f, parse_stmt(f)); f->curr_proc = curr_proc; - return ast_proc_lit(f, type, body, tags); + return ast_proc_lit(f, type, body, tags, where_token, where_clauses); } if (tags != 0) { syntax_error(token, "A procedure type cannot have suffix tags"); } + if (where_token.kind != Token_Invalid) { + syntax_error(where_token, "'where' clauses are not allowed on procedure types"); + } return type; } @@ -2827,12 +2859,6 @@ Ast *parse_proc_type(AstFile *f, Token proc_token) { results = parse_results(f, &diverging); u64 tags = 0; - parse_proc_tags(f, &tags); - if ((tags & ProcTag_require_results) != 0) { - syntax_error(f->curr_token, "#require_results has now been replaced as an attribute @(require_results) on the declaration"); - tags &= ~ProcTag_require_results; - } - bool is_generic = false; for_array(i, params->FieldList.list) { |