diff options
| author | gingerBill <bill@gingerbill.org> | 2017-12-10 11:35:11 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2017-12-10 11:35:11 +0000 |
| commit | 3c6f90e5524d38bdd30750eb04441a1897bcd8dd (patch) | |
| tree | 50dc37f196b7a2d0c40e1382950511654d1333a2 /src | |
| parent | 3703ca4df47134e0c274cf5096d14c9323331ff0 (diff) | |
Fix proc groups from import names
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_decl.cpp | 11 | ||||
| -rw-r--r-- | src/check_expr.cpp | 70 | ||||
| -rw-r--r-- | src/check_type.cpp | 3 | ||||
| -rw-r--r-- | src/entity.cpp | 10 | ||||
| -rw-r--r-- | src/ir.cpp | 7 | ||||
| -rw-r--r-- | src/parser.cpp | 11 | ||||
| -rw-r--r-- | src/ptr_set.cpp | 5 | ||||
| -rw-r--r-- | src/tokenizer.cpp | 1 |
8 files changed, 71 insertions, 47 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 817377baf..97acc20cd 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -715,12 +715,12 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count void check_proc_group_decl(Checker *c, Entity *pg_entity, DeclInfo *d) { GB_ASSERT(pg_entity->kind == Entity_ProcGroup); auto *pge = &pg_entity->ProcGroup; + String proc_group_name = pg_entity->token.string; ast_node(pg, ProcGroup, d->init_expr); array_init(&pge->entities, c->allocator, pg->args.count); - PtrSet<Entity *> entity_map = {}; ptr_set_init(&entity_map, heap_allocator()); defer (ptr_set_destroy(&entity_map)); @@ -735,12 +735,14 @@ void check_proc_group_decl(Checker *c, Entity *pg_entity, DeclInfo *d) { e = check_selector(c, &o, arg, nullptr); } if (e == nullptr) { - error(arg, "Expected a valid entity name in procedure group"); + error(arg, "Expected a valid entity name in procedure group, got %.*s", LIT(ast_node_strings[arg->kind])); continue; } if (e->kind == Entity_Variable) { if (!is_type_proc(e->type)) { - error(arg, "Expected a procedure variable"); + gbString s = type_to_string(e->type); + defer (gb_string_free(s)); + error(arg, "Expected a procedure, got %s", s); continue; } } else if (e->kind != Entity_Procedure) { @@ -753,7 +755,6 @@ void check_proc_group_decl(Checker *c, Entity *pg_entity, DeclInfo *d) { continue; } ptr_set_add(&entity_map, e); - array_add(&pge->entities, e); } @@ -816,6 +817,8 @@ void check_proc_group_decl(Checker *c, Entity *pg_entity, DeclInfo *d) { } } } + + pg_entity->type = t_invalid; } void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 0c3292fb8..9b33dabcd 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -2497,7 +2497,8 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h } check_entity_decl(c, entity, nullptr, nullptr); - GB_ASSERT(entity->type != nullptr || entity->kind == Entity_ProcGroup); + GB_ASSERT(entity->type != nullptr); + if (is_alias) { // TODO(bill): Which scope do you search for for an alias? @@ -2514,13 +2515,24 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h is_not_exported = true; } - if (is_not_exported && entity->kind == Entity_ProcGroup) { - check_entity_decl(c, entity, nullptr, nullptr); + + + if (is_not_exported) { + gbString sel_str = expr_to_string(selector); + error(op_expr, "'%s' is not exported by '%.*s'", sel_str, LIT(import_name)); + gb_string_free(sel_str); + operand->mode = Addressing_Invalid; + operand->expr = node; + return nullptr; + } + + if (entity->kind == Entity_ProcGroup) { auto *pge = &entity->ProcGroup; Array<Entity *> procs = pge->entities; bool skip = false; for_array(i, procs) { - Type *t = base_type(procs[i]->type); + Entity *p = procs[i]; + Type *t = base_type(p->type); if (t == t_invalid) { continue; } @@ -2530,7 +2542,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h x.type = t; if (type_hint != nullptr) { if (check_is_assignable_to(c, &x, type_hint)) { - entity = procs[i]; + entity = p; skip = true; break; } @@ -2538,23 +2550,14 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h } if (!skip) { - GB_ASSERT(e != nullptr); + GB_ASSERT(entity != nullptr); operand->mode = Addressing_ProcGroup; operand->type = t_invalid; operand->expr = node; - operand->proc_group = e; - return e; + operand->proc_group = entity; + return entity; } } - - if (is_not_exported) { - gbString sel_str = expr_to_string(selector); - error(op_expr, "'%s' is not exported by '%.*s'", sel_str, LIT(import_name)); - gb_string_free(sel_str); - operand->mode = Addressing_Invalid; - operand->expr = node; - return nullptr; - } } } @@ -2693,7 +2696,8 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h break; case Entity_ProcGroup: - entity->type = t_invalid; + operand->mode = Addressing_ProcGroup; + operand->proc_group = entity; break; // NOTE(bill): These cases should never be hit but are here for sanity reasons @@ -3330,7 +3334,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id return false; } - operand->type = make_type_array(c->allocator, elem_type, arg_count); + if (arg_count < max_count) { + operand->type = make_type_array(c->allocator, elem_type, arg_count); + } operand->mode = Addressing_Value; break; @@ -4370,6 +4376,8 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t } if (operand->mode == Addressing_ProcGroup) { + check_entity_decl(c, operand->proc_group, nullptr, nullptr); + Array<Entity *> procs = proc_group_entities(c, *operand); ValidIndexAndScore *valids = gb_alloc_array(heap_allocator(), ValidIndexAndScore, procs.count); @@ -4421,7 +4429,7 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t if (valid_count == 0) { error(operand->expr, "No procedures or ambiguous call for procedure group '%s' that match with the given arguments", expr_name); - gb_printf_err("\tGiven argument types -> ("); + gb_printf_err("\tGiven argument types: ("); for_array(i, operands) { Operand o = operands[i]; if (i > 0) gb_printf_err(", "); @@ -4441,15 +4449,20 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t if (t == t_invalid) continue; GB_ASSERT(t->kind == Type_Proc); gbString pt; + defer (gb_string_free(pt)); if (t->Proc.node != nullptr) { pt = expr_to_string(t->Proc.node); } else { pt = type_to_string(t); } String name = proc->token.string; - gb_printf_err("\t%.*s :: %s at %.*s(%td:%td) with score %lld\n", LIT(name), pt, LIT(pos.file), pos.line, pos.column, cast(long long)valids[i].score); - // gb_printf_err("\t%.*s :: %s at %.*s(%td:%td)\n", LIT(name), pt, LIT(pos.file), pos.line, pos.column); - gb_string_free(pt); + + char const *sep = "::"; + if (proc->kind == Entity_Variable) { + sep = ":="; + } + // gb_printf_err("\t%.*s %s %s at %.*s(%td:%td) with score %lld\n", LIT(name), sep, pt, LIT(pos.file), pos.line, pos.column, cast(long long)valids[i].score); + gb_printf_err("\t%.*s %s %s at %.*s(%td:%td)\n", LIT(name), sep, pt, LIT(pos.file), pos.line, pos.column); } if (procs.count > 0) { gb_printf_err("\n"); @@ -4457,7 +4470,7 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t result_type = t_invalid; } else if (valid_count > 1) { error(operand->expr, "Ambiguous procedure group call '%s' that match with the given arguments", expr_name); - gb_printf_err("\tGiven argument types -> ("); + gb_printf_err("\tGiven argument types: ("); for_array(i, operands) { Operand o = operands[i]; if (i > 0) gb_printf_err(", "); @@ -4472,15 +4485,18 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t TokenPos pos = proc->token.pos; Type *t = base_type(proc->type); GB_ASSERT(t->kind == Type_Proc); gbString pt; + defer (gb_string_free(pt)); if (t->Proc.node != nullptr) { pt = expr_to_string(t->Proc.node); } else { pt = type_to_string(t); } String name = proc->token.string; - // gb_printf_err("\t%.*s :: %s at %.*s(%td:%td) with score %lld\n", LIT(name), pt, LIT(pos.file), pos.line, pos.column, cast(long long)valids[i].score); - gb_printf_err("\t%.*s :: %s at %.*s(%td:%td)\n", LIT(name), pt, LIT(pos.file), pos.line, pos.column); - gb_string_free(pt); + char const *sep = "::"; + if (proc->kind == Entity_Variable) { + sep = ":="; + } + gb_printf_err("\t%.*s %s %s at %.*s(%td:%td)\n", LIT(name), sep, pt, LIT(pos.file), pos.line, pos.column); } result_type = t_invalid; } else { diff --git a/src/check_type.cpp b/src/check_type.cpp index 5c9654a2d..7153bbfa1 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1225,8 +1225,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari bool detemine_type_from_operand = false; Type *specialization = nullptr; - bool is_using = (p->flags&FieldFlag_using) != 0; - + bool is_using = (p->flags&FieldFlag_using) != 0; if (type_expr == nullptr) { if (default_value->kind == AstNode_BasicDirective && diff --git a/src/entity.cpp b/src/entity.cpp index ff3fd5c20..3f81a066d 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -82,17 +82,17 @@ struct Entity { i32 field_index; i32 field_src_index; ExactValue default_value; + Entity * foreign_library; + AstNode * foreign_library_ident; + String link_name; + String link_prefix; + String thread_local_model; bool default_is_nil; bool default_is_undef; bool default_is_location; bool is_immutable; - String thread_local_model; bool is_foreign; bool is_export; - Entity * foreign_library; - AstNode * foreign_library_ident; - String link_name; - String link_prefix; } Variable; struct { bool is_type_alias; diff --git a/src/ir.cpp b/src/ir.cpp index c869e550b..bf0378743 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -5080,8 +5080,11 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { isize arg_count = 0; for_array(i, ce->args) { - AstNode *a = ce->args[i]; - Type *at = base_type(type_of_expr(proc->module->info, a)); + AstNode *arg = ce->args[i]; + TypeAndValue tav = type_and_value_of_expr(proc->module->info, arg); + GB_ASSERT_MSG(tav.mode != Addressing_Invalid, "%s", expr_to_string(arg)); + GB_ASSERT_MSG(tav.mode != Addressing_ProcGroup, "%s", expr_to_string(arg)); + Type *at = tav.type; if (at->kind == Type_Tuple) { arg_count += at->Tuple.variables.count; } else { diff --git a/src/parser.cpp b/src/parser.cpp index 704833170..8dd5881a2 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3280,11 +3280,12 @@ AstNode *parse_proc_type(AstFile *f, Token proc_token) { for_array(i, params->FieldList.list) { AstNode *param = params->FieldList.list[i]; ast_node(f, Field, param); - if (f->type != nullptr && - (f->type->kind == AstNode_TypeType || - f->type->kind == AstNode_PolyType)) { - is_generic = true; - break; + if (f->type != nullptr) { + if (f->type->kind == AstNode_TypeType || + f->type->kind == AstNode_PolyType) { + is_generic = true; + break; + } } } diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp index d87a86811..ac055f41d 100644 --- a/src/ptr_set.cpp +++ b/src/ptr_set.cpp @@ -19,7 +19,7 @@ struct PtrSet { template <typename T> void ptr_set_init (PtrSet<T> *s, gbAllocator a, isize capacity = 16); template <typename T> void ptr_set_destroy (PtrSet<T> *s); -template <typename T> void ptr_set_add (PtrSet<T> *s, T ptr); +template <typename T> T ptr_set_add (PtrSet<T> *s, T ptr); template <typename T> bool ptr_set_exists (PtrSet<T> *s, T ptr); template <typename T> void ptr_set_remove (PtrSet<T> *s, T ptr); template <typename T> void ptr_set_clear (PtrSet<T> *s); @@ -136,7 +136,7 @@ gb_inline bool ptr_set_exists(PtrSet<T> *s, T ptr) { // Returns true if it already exists template <typename T> -void ptr_set_add(PtrSet<T> *s, T ptr) { +T ptr_set_add(PtrSet<T> *s, T ptr) { isize index; PtrSetFindResult fr; if (s->hashes.count == 0) { @@ -156,6 +156,7 @@ void ptr_set_add(PtrSet<T> *s, T ptr) { if (ptr_set__full(s)) { ptr_set_grow(s); } + return ptr; } diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index a8bfb6ee8..b85c62d4b 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -119,6 +119,7 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \ TOKEN_KIND(Token_offset_of, "offset_of"), \ TOKEN_KIND(Token_type_of, "type_of"), \ TOKEN_KIND(Token_type_info_of, "type_info_of"), \ + TOKEN_KIND(Token_const, "const"), \ TOKEN_KIND(Token_asm, "asm"), \ TOKEN_KIND(Token_yield, "yield"), \ TOKEN_KIND(Token_await, "await"), \ |