diff options
| author | gingerBill <ginger.bill.22@gmail.com> | 2016-07-11 00:10:15 +0100 |
|---|---|---|
| committer | gingerBill <ginger.bill.22@gmail.com> | 2016-07-11 00:10:15 +0100 |
| commit | 9f90ff50cf4f93e6c6bb622bc2098dc7cea7f240 (patch) | |
| tree | dbc084bf93b054808dfdf1582cfaaf279537cee9 /src/checker/statements.cpp | |
| parent | f7a669d342c96451a3e0be84e2e51af8631f90ec (diff) | |
Tags, enclosed proc results and better error handling
Diffstat (limited to 'src/checker/statements.cpp')
| -rw-r--r-- | src/checker/statements.cpp | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/src/checker/statements.cpp b/src/checker/statements.cpp index a7c72d7f0..a967ff742 100644 --- a/src/checker/statements.cpp +++ b/src/checker/statements.cpp @@ -385,6 +385,12 @@ void check_statement(Checker *c, AstNode *node) { } } break; + case AstNode_TagStatement: + // TODO(bill): Tag Statements + print_checker_error(c, ast_node_token(node), "Tag statements are not supported yet"); + check_statement(c, node->tag_statement.statement); + break; + case AstNode_IncDecStatement: { Token op = {}; auto *s = &node->inc_dec_statement; @@ -653,7 +659,7 @@ void check_statement(Checker *c, AstNode *node) { case AstNode_ProcedureDeclaration: { auto *pd = &node->procedure_declaration; - GB_ASSERT_MSG(pd->kind == Declaration_Immutable, "Mutable/temp procedures are not yet implemented"); + GB_ASSERT_MSG(pd->kind == Declaration_Immutable, "Mutable/temp/anonymous procedures are not yet implemented"); Entity *e = make_entity_procedure(c, c->curr_scope, pd->name->identifier.token, NULL); add_entity(c, c->curr_scope, pd->name, e); @@ -667,9 +673,38 @@ void check_statement(Checker *c, AstNode *node) { check_open_scope(c, pd->procedure_type); { check_procedure_type(c, proc_type, pd->procedure_type); + b32 is_foreign = false; + b32 is_inline = false; + b32 is_no_inline = false; + for (AstNode *tag = pd->tag_list; tag != NULL; tag = tag->next) { + GB_ASSERT(tag->kind == AstNode_TagExpression); + + String tag_name = tag->tag_expression.name.string; + if (are_strings_equal(tag_name, make_string("foreign"))) { + is_foreign = true; + } else if (are_strings_equal(tag_name, make_string("inline"))) { + is_inline = true; + } else if (are_strings_equal(tag_name, make_string("no_inline"))) { + is_no_inline = true; + } else { + print_checker_error(c, ast_node_token(tag), "Unknown procedure tag"); + } + // TODO(bill): Other tags + } + + if (is_inline && is_no_inline) { + print_checker_error(c, ast_node_token(pd->tag_list), + "You cannot apply both `inline` and `no_inline` to a procedure"); + } + if (pd->body) { GB_ASSERT(pd->body->kind == AstNode_BlockStatement); + if (is_foreign) { + print_checker_error(c, ast_node_token(pd->body), + "A procedure tagged as `#foreign` cannot have a body"); + } + push_procedure(c, proc_type); check_statement_list(c, pd->body->block_statement.list); if (pd->procedure_type->procedure_type.result_count > 0) { @@ -678,14 +713,6 @@ void check_statement(Checker *c, AstNode *node) { } } pop_procedure(c); - } else if (pd->tag) { - GB_ASSERT(pd->tag->kind == AstNode_TagExpression); - - String tag_name = pd->tag->tag_expression.name.string; - if (are_strings_equal(tag_name, make_string("foreign"))) { - // NOTE(bill): Foreign procedure (linking stage) - } - // TODO(bill): Other tags } } check_close_scope(c); |