Fix proc groups from import names

This commit is contained in:
gingerBill
2017-12-10 11:35:11 +00:00
parent 3703ca4df4
commit 3c6f90e552
11 changed files with 91 additions and 55 deletions
+3 -3
View File
@@ -477,13 +477,13 @@ new_clone :: inline proc(data: $T, loc := #caller_location) -> ^T {
} }
free_string :: proc(str: string, loc := #caller_location) { free_string :: proc(str: string, loc := #caller_location) {
free_ptr((^raw.String)(&str).data, loc); free_ptr(raw.data(str), loc);
} }
free_dynamic_array :: proc(array: $T/[dynamic]$E, loc := #caller_location) { free_dynamic_array :: proc(array: $T/[dynamic]$E, loc := #caller_location) {
free_ptr((^raw.Dynamic_Array)(&array).data, loc); free_ptr(raw.data(array), loc);
} }
free_slice :: proc(array: $T/[]$E, loc := #caller_location) { free_slice :: proc(array: $T/[]$E, loc := #caller_location) {
free_ptr((^raw.Slice)(&array).data, loc); free_ptr(raw.data(array), loc);
} }
free_map :: proc(m: $T/map[$K]$V, loc := #caller_location) { free_map :: proc(m: $T/map[$K]$V, loc := #caller_location) {
raw := cast(^raw.Map)&m; raw := cast(^raw.Map)&m;
+2 -2
View File
@@ -399,11 +399,11 @@ quat_mulf :: proc(q: Quat, f: f32) -> Quat { return Quat{q.x*f, q.y*f, q.z*f, q.
quat_divf :: proc(q: Quat, f: f32) -> Quat { return Quat{q.x/f, q.y/f, q.z/f, q.w/f}; } quat_divf :: proc(q: Quat, f: f32) -> Quat { return Quat{q.x/f, q.y/f, q.z/f, q.w/f}; }
quat_div :: proc(q0, q1: Quat) -> Quat { return mul(q0, quat_inverse(q1)); } quat_div :: proc(q0, q1: Quat) -> Quat { return mul(q0, quat_inverse(q1)); }
quat_inverse :: proc(q: Quat) -> Quat { return div(conj(q), quat_dot(q, q)); } quat_inverse :: proc(q: Quat) -> Quat { return div(conj(q), dot(q, q)); }
quat_dot :: proc(q0, q1: Quat) -> f32 { return q0.x*q1.x + q0.y*q1.y + q0.z*q1.z + q0.w*q1.w; } quat_dot :: proc(q0, q1: Quat) -> f32 { return q0.x*q1.x + q0.y*q1.y + q0.z*q1.z + q0.w*q1.w; }
quat_norm :: proc(q: Quat) -> Quat { quat_norm :: proc(q: Quat) -> Quat {
m := sqrt(quat_dot(q, q)); m := sqrt(dot(q, q));
return div(q, m); return div(q, m);
} }
+13 -1
View File
@@ -4,7 +4,7 @@ Any :: struct #ordered {
} }
String :: struct #ordered { String :: struct #ordered {
data: ^u8, data: ^byte,
len: int, len: int,
} }
@@ -25,3 +25,15 @@ Map :: struct #ordered {
entries: Dynamic_Array, entries: Dynamic_Array,
} }
string_data :: inline proc(s: $T/string) -> ^byte {
return (^String)(&s).data;
}
slice_data :: inline proc(a: $T/[]$E) -> ^E {
return cast(^E)(^Slice)(&a).data;
}
dynamic_array_data :: inline proc(a: $T/[dynamic]$E) -> ^E {
return cast(^E)(^Dynamic_Array)(&a).data;
}
data :: proc[string_data, slice_data, dynamic_array_data];
+7 -4
View File
@@ -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) { void check_proc_group_decl(Checker *c, Entity *pg_entity, DeclInfo *d) {
GB_ASSERT(pg_entity->kind == Entity_ProcGroup); GB_ASSERT(pg_entity->kind == Entity_ProcGroup);
auto *pge = &pg_entity->ProcGroup; auto *pge = &pg_entity->ProcGroup;
String proc_group_name = pg_entity->token.string;
ast_node(pg, ProcGroup, d->init_expr); ast_node(pg, ProcGroup, d->init_expr);
array_init(&pge->entities, c->allocator, pg->args.count); array_init(&pge->entities, c->allocator, pg->args.count);
PtrSet<Entity *> entity_map = {}; PtrSet<Entity *> entity_map = {};
ptr_set_init(&entity_map, heap_allocator()); ptr_set_init(&entity_map, heap_allocator());
defer (ptr_set_destroy(&entity_map)); 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); e = check_selector(c, &o, arg, nullptr);
} }
if (e == 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; continue;
} }
if (e->kind == Entity_Variable) { if (e->kind == Entity_Variable) {
if (!is_type_proc(e->type)) { 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; continue;
} }
} else if (e->kind != Entity_Procedure) { } else if (e->kind != Entity_Procedure) {
@@ -753,7 +755,6 @@ void check_proc_group_decl(Checker *c, Entity *pg_entity, DeclInfo *d) {
continue; continue;
} }
ptr_set_add(&entity_map, e); ptr_set_add(&entity_map, e);
array_add(&pge->entities, 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) { void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
+43 -27
View File
@@ -2497,7 +2497,8 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
} }
check_entity_decl(c, entity, nullptr, nullptr); check_entity_decl(c, entity, nullptr, nullptr);
GB_ASSERT(entity->type != nullptr || entity->kind == Entity_ProcGroup); GB_ASSERT(entity->type != nullptr);
if (is_alias) { if (is_alias) {
// TODO(bill): Which scope do you search for for an 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; 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; auto *pge = &entity->ProcGroup;
Array<Entity *> procs = pge->entities; Array<Entity *> procs = pge->entities;
bool skip = false; bool skip = false;
for_array(i, procs) { 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) { if (t == t_invalid) {
continue; continue;
} }
@@ -2530,7 +2542,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
x.type = t; x.type = t;
if (type_hint != nullptr) { if (type_hint != nullptr) {
if (check_is_assignable_to(c, &x, type_hint)) { if (check_is_assignable_to(c, &x, type_hint)) {
entity = procs[i]; entity = p;
skip = true; skip = true;
break; break;
} }
@@ -2538,23 +2550,14 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
} }
if (!skip) { if (!skip) {
GB_ASSERT(e != nullptr); GB_ASSERT(entity != nullptr);
operand->mode = Addressing_ProcGroup; operand->mode = Addressing_ProcGroup;
operand->type = t_invalid; operand->type = t_invalid;
operand->expr = node; operand->expr = node;
operand->proc_group = e; operand->proc_group = entity;
return e; 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; break;
case Entity_ProcGroup: case Entity_ProcGroup:
entity->type = t_invalid; operand->mode = Addressing_ProcGroup;
operand->proc_group = entity;
break; break;
// NOTE(bill): These cases should never be hit but are here for sanity reasons // 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; 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; operand->mode = Addressing_Value;
break; break;
@@ -4370,6 +4376,8 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
} }
if (operand->mode == Addressing_ProcGroup) { if (operand->mode == Addressing_ProcGroup) {
check_entity_decl(c, operand->proc_group, nullptr, nullptr);
Array<Entity *> procs = proc_group_entities(c, *operand); Array<Entity *> procs = proc_group_entities(c, *operand);
ValidIndexAndScore *valids = gb_alloc_array(heap_allocator(), ValidIndexAndScore, procs.count); 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) { if (valid_count == 0) {
error(operand->expr, "No procedures or ambiguous call for procedure group '%s' that match with the given arguments", expr_name); 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) { for_array(i, operands) {
Operand o = operands[i]; Operand o = operands[i];
if (i > 0) gb_printf_err(", "); 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; if (t == t_invalid) continue;
GB_ASSERT(t->kind == Type_Proc); GB_ASSERT(t->kind == Type_Proc);
gbString pt; gbString pt;
defer (gb_string_free(pt));
if (t->Proc.node != nullptr) { if (t->Proc.node != nullptr) {
pt = expr_to_string(t->Proc.node); pt = expr_to_string(t->Proc.node);
} else { } else {
pt = type_to_string(t); pt = type_to_string(t);
} }
String name = proc->token.string; 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); char const *sep = "::";
gb_string_free(pt); 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) { if (procs.count > 0) {
gb_printf_err("\n"); gb_printf_err("\n");
@@ -4457,7 +4470,7 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
result_type = t_invalid; result_type = t_invalid;
} else if (valid_count > 1) { } else if (valid_count > 1) {
error(operand->expr, "Ambiguous procedure group call '%s' that match with the given arguments", expr_name); 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) { for_array(i, operands) {
Operand o = operands[i]; Operand o = operands[i];
if (i > 0) gb_printf_err(", "); 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; TokenPos pos = proc->token.pos;
Type *t = base_type(proc->type); GB_ASSERT(t->kind == Type_Proc); Type *t = base_type(proc->type); GB_ASSERT(t->kind == Type_Proc);
gbString pt; gbString pt;
defer (gb_string_free(pt));
if (t->Proc.node != nullptr) { if (t->Proc.node != nullptr) {
pt = expr_to_string(t->Proc.node); pt = expr_to_string(t->Proc.node);
} else { } else {
pt = type_to_string(t); pt = type_to_string(t);
} }
String name = proc->token.string; 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); char const *sep = "::";
gb_printf_err("\t%.*s :: %s at %.*s(%td:%td)\n", LIT(name), pt, LIT(pos.file), pos.line, pos.column); if (proc->kind == Entity_Variable) {
gb_string_free(pt); 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; result_type = t_invalid;
} else { } else {
+1 -2
View File
@@ -1225,8 +1225,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
bool detemine_type_from_operand = false; bool detemine_type_from_operand = false;
Type *specialization = nullptr; Type *specialization = nullptr;
bool is_using = (p->flags&FieldFlag_using) != 0; bool is_using = (p->flags&FieldFlag_using) != 0;
if (type_expr == nullptr) { if (type_expr == nullptr) {
if (default_value->kind == AstNode_BasicDirective && if (default_value->kind == AstNode_BasicDirective &&
+7 -7
View File
@@ -82,17 +82,17 @@ struct Entity {
i32 field_index; i32 field_index;
i32 field_src_index; i32 field_src_index;
ExactValue default_value; ExactValue default_value;
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; Entity * foreign_library;
AstNode * foreign_library_ident; AstNode * foreign_library_ident;
String link_name; String link_name;
String link_prefix; String link_prefix;
String thread_local_model;
bool default_is_nil;
bool default_is_undef;
bool default_is_location;
bool is_immutable;
bool is_foreign;
bool is_export;
} Variable; } Variable;
struct { struct {
bool is_type_alias; bool is_type_alias;
+5 -2
View File
@@ -5080,8 +5080,11 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
isize arg_count = 0; isize arg_count = 0;
for_array(i, ce->args) { for_array(i, ce->args) {
AstNode *a = ce->args[i]; AstNode *arg = ce->args[i];
Type *at = base_type(type_of_expr(proc->module->info, a)); 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) { if (at->kind == Type_Tuple) {
arg_count += at->Tuple.variables.count; arg_count += at->Tuple.variables.count;
} else { } else {
+6 -5
View File
@@ -3280,11 +3280,12 @@ AstNode *parse_proc_type(AstFile *f, Token proc_token) {
for_array(i, params->FieldList.list) { for_array(i, params->FieldList.list) {
AstNode *param = params->FieldList.list[i]; AstNode *param = params->FieldList.list[i];
ast_node(f, Field, param); ast_node(f, Field, param);
if (f->type != nullptr && if (f->type != nullptr) {
(f->type->kind == AstNode_TypeType || if (f->type->kind == AstNode_TypeType ||
f->type->kind == AstNode_PolyType)) { f->type->kind == AstNode_PolyType) {
is_generic = true; is_generic = true;
break; break;
}
} }
} }
+3 -2
View File
@@ -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_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_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> 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_remove (PtrSet<T> *s, T ptr);
template <typename T> void ptr_set_clear (PtrSet<T> *s); 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 // Returns true if it already exists
template <typename T> template <typename T>
void ptr_set_add(PtrSet<T> *s, T ptr) { T ptr_set_add(PtrSet<T> *s, T ptr) {
isize index; isize index;
PtrSetFindResult fr; PtrSetFindResult fr;
if (s->hashes.count == 0) { if (s->hashes.count == 0) {
@@ -156,6 +156,7 @@ void ptr_set_add(PtrSet<T> *s, T ptr) {
if (ptr_set__full(s)) { if (ptr_set__full(s)) {
ptr_set_grow(s); ptr_set_grow(s);
} }
return ptr;
} }
+1
View File
@@ -119,6 +119,7 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
TOKEN_KIND(Token_offset_of, "offset_of"), \ TOKEN_KIND(Token_offset_of, "offset_of"), \
TOKEN_KIND(Token_type_of, "type_of"), \ TOKEN_KIND(Token_type_of, "type_of"), \
TOKEN_KIND(Token_type_info_of, "type_info_of"), \ TOKEN_KIND(Token_type_info_of, "type_info_of"), \
TOKEN_KIND(Token_const, "const"), \
TOKEN_KIND(Token_asm, "asm"), \ TOKEN_KIND(Token_asm, "asm"), \
TOKEN_KIND(Token_yield, "yield"), \ TOKEN_KIND(Token_yield, "yield"), \
TOKEN_KIND(Token_await, "await"), \ TOKEN_KIND(Token_await, "await"), \