aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2017-12-09 18:11:36 +0000
committergingerBill <bill@gingerbill.org>2017-12-09 18:11:36 +0000
commit3703ca4df47134e0c274cf5096d14c9323331ff0 (patch)
treea01aab633bf3d25aba33357cb8d181537e9c841b /src
parent41b8281c7355eea7c4a2022027769df8a519ae7a (diff)
Explicit procedure group; Remove implicit procedure overloading
Diffstat (limited to 'src')
-rw-r--r--src/build_settings.cpp2
-rw-r--r--src/check_decl.cpp98
-rw-r--r--src/check_expr.cpp221
-rw-r--r--src/check_stmt.cpp313
-rw-r--r--src/checker.cpp166
-rw-r--r--src/entity.cpp8
-rw-r--r--src/ir.cpp21
-rw-r--r--src/main.cpp1
-rw-r--r--src/map.cpp7
-rw-r--r--src/parser.cpp28
10 files changed, 346 insertions, 519 deletions
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index 95c418839..7d7634806 100644
--- a/src/build_settings.cpp
+++ b/src/build_settings.cpp
@@ -308,7 +308,7 @@ String get_fullpath_core(gbAllocator a, String path) {
}
-String const ODIN_VERSION = str_lit("0.7.1");
+String const ODIN_VERSION = str_lit("0.8.0-dev");
String cross_compile_target = str_lit("");
String cross_compile_lib_dir = str_lit("");
diff --git a/src/check_decl.cpp b/src/check_decl.cpp
index 7b01c259e..817377baf 100644
--- a/src/check_decl.cpp
+++ b/src/check_decl.cpp
@@ -23,9 +23,9 @@ Type *check_init_variable(Checker *c, Entity *e, Operand *operand, String contex
}
- if (operand->mode == Addressing_Overload) {
+ if (operand->mode == Addressing_ProcGroup) {
if (e->type == nullptr) {
- error(operand->expr, "Cannot determine type from overloaded procedure '%.*s'", LIT(operand->overload_entities[0]->token.string));
+ error(operand->expr, "Cannot determine type from overloaded procedure '%.*s'", LIT(operand->proc_group->token.string));
} else {
check_assignment(c, operand, e->type, str_lit("variable assignment"));
if (operand->mode != Addressing_Type) {
@@ -275,11 +275,15 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init,
e->type = t_invalid;
return;
- case Addressing_Overload:
- e->kind = Entity_Alias;
- e->Alias.base = operand.overload_entities[0];
+ case Addressing_ProcGroup: {
+ GB_ASSERT(operand.proc_group != nullptr);
+ GB_ASSERT(operand.proc_group->kind == Entity_ProcGroup);
+
+ e->kind = Entity_ProcGroup;
e->type = t_invalid;
+ gb_memcopy(&e->ProcGroup, &operand.proc_group->ProcGroup, gb_size_of(e->ProcGroup));
return;
+ }
#endif
}
#if 1
@@ -708,11 +712,11 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count
check_init_variables(c, entities, entity_count, init_expr_list, context_name);
}
-void check_proc_grouping_decl(Checker *c, Entity *pg_entity, DeclInfo *d) {
- GB_ASSERT(pg_entity->kind == Entity_ProcedureGrouping);
- auto *pge = &pg_entity->ProcedureGrouping;
+void check_proc_group_decl(Checker *c, Entity *pg_entity, DeclInfo *d) {
+ GB_ASSERT(pg_entity->kind == Entity_ProcGroup);
+ auto *pge = &pg_entity->ProcGroup;
- ast_node(pg, ProcGrouping, d->init_expr);
+ ast_node(pg, ProcGroup, d->init_expr);
array_init(&pge->entities, c->allocator, pg->args.count);
@@ -731,22 +735,87 @@ void check_proc_grouping_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 grouping");
+ error(arg, "Expected a valid entity name in procedure group");
continue;
}
- if (e->kind != Entity_Procedure) {
+ if (e->kind == Entity_Variable) {
+ if (!is_type_proc(e->type)) {
+ error(arg, "Expected a procedure variable");
+ continue;
+ }
+ } else if (e->kind != Entity_Procedure) {
error(arg, "Expected a procedure entity");
continue;
}
if (ptr_set_exists(&entity_map, e)) {
- error(arg, "Previous use of `%.*s` in procedure grouping", LIT(e->token.string));
+ error(arg, "Previous use of `%.*s` in procedure group", LIT(e->token.string));
continue;
}
ptr_set_add(&entity_map, e);
array_add(&pge->entities, e);
}
+
+ for_array(j, pge->entities) {
+ Entity *p = pge->entities[j];
+ if (p->type == t_invalid) {
+ // NOTE(bill): This invalid overload has already been handled
+ continue;
+ }
+
+ String name = p->token.string;
+
+ for (isize k = j+1; k < pge->entities.count; k++) {
+ Entity *q = pge->entities[k];
+ GB_ASSERT(p != q);
+
+ bool is_invalid = false;
+
+ TokenPos pos = q->token.pos;
+
+ if (q->type == nullptr || q->type == t_invalid) {
+ continue;
+ }
+
+ ProcTypeOverloadKind kind = are_proc_types_overload_safe(p->type, q->type);
+ switch (kind) {
+ case ProcOverload_Identical:
+ error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in this scope", LIT(name));
+ is_invalid = true;
+ break;
+ // case ProcOverload_CallingConvention:
+ // error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in this scope", LIT(name));
+ // is_invalid = true;
+ // break;
+ case ProcOverload_ParamVariadic:
+ error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in this scope", LIT(name));
+ is_invalid = true;
+ break;
+ case ProcOverload_ResultCount:
+ case ProcOverload_ResultTypes:
+ error(p->token, "Overloaded procedure '%.*s' as the same parameters but different results in this scope", LIT(name));
+ is_invalid = true;
+ break;
+ case ProcOverload_Polymorphic:
+ #if 0
+ error(p->token, "Overloaded procedure '%.*s' has a polymorphic counterpart in this scope which is not allowed", LIT(name));
+ is_invalid = true;
+ #endif
+ break;
+ case ProcOverload_ParamCount:
+ case ProcOverload_ParamTypes:
+ // This is okay :)
+ break;
+
+ }
+
+ if (is_invalid) {
+ gb_printf_err("\tprevious procedure at %.*s(%td:%td)\n", LIT(pos.file), pos.line, pos.column);
+ q->type = t_invalid;
+ }
+ }
+ }
}
void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
@@ -787,9 +856,8 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
check_proc_decl(c, e, d);
break;
- case Entity_ProcedureGrouping:
- // error(e->token, "Procedure groupings are not yet supported");
- check_proc_grouping_decl(c, e, d);
+ case Entity_ProcGroup:
+ check_proc_group_decl(c, e, d);
break;
}
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index a81022d87..0c3292fb8 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -127,14 +127,6 @@ void check_scope_decls(Checker *c, Array<AstNode *> nodes, isize reserve_size) {
check_entity_decl(c, e, d, nullptr);
}
}
-
- for_array(i, s->elements.entries) {
- Entity *e = s->elements.entries[i].value;
- if (e->kind != Entity_Procedure) {
- continue;
- }
- check_procedure_overloading(c, e);
- }
}
@@ -659,18 +651,16 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
return;
}
- if (operand->mode == Addressing_Overload) {
+ if (operand->mode == Addressing_ProcGroup) {
// GB_PANIC("HERE!\n");
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
defer (gb_temp_arena_memory_end(tmp));
- Entity **procs = operand->overload_entities;
- isize overload_count = operand->overload_count;
-
+ Array<Entity *> procs = proc_group_entities(c, *operand);
bool good = false;
// NOTE(bill): These should be done
- for (isize i = 0; i < overload_count; i++) {
+ for_array(i, procs) {
Type *t = base_type(procs[i]->type);
if (t == t_invalid) {
continue;
@@ -783,7 +773,10 @@ bool is_polymorphic_type_assignable(Checker *c, Type *poly, Type *source, bool c
return false;
case Type_Array:
if (source->kind == Type_Array) {
- if (poly->Array.generic_type && modify_type) {
+
+ // IMPORTANT TODO(bill): Which is correct?
+ // if (poly->Array.generic_type != nullptr && modify_type) {
+ if (poly->Array.generic_type != nullptr) {
Type *gt = poly->Array.generic_type;
GB_ASSERT(gt->kind == Type_Generic);
Entity *e = scope_lookup_entity(gt->Generic.scope, gt->Generic.name);
@@ -808,8 +801,6 @@ bool is_polymorphic_type_assignable(Checker *c, Type *poly, Type *source, bool c
} else {
return false;
}
-
- return is_polymorphic_type_assignable(c, poly->Array.elem, source->Array.elem, true, modify_type);
}
if (poly->Array.count == source->Array.count) {
return is_polymorphic_type_assignable(c, poly->Array.elem, source->Array.elem, true, modify_type);
@@ -936,10 +927,6 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
return nullptr;
}
}
-
- bool is_overloaded = false;
- isize overload_count = 0;
-
bool is_alias = false;
while (e->kind == Entity_Alias) {
GB_ASSERT(e->Alias.base != nullptr);
@@ -949,63 +936,14 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
HashKey key = hash_string(e->token.string);
-
- if (e->kind == Entity_Procedure) {
- // NOTE(bill): Overloads are only allowed with the same scope
- Scope *s = e->scope;
- overload_count = multi_map_count(&s->elements, key);
- if (overload_count > 1) {
- is_overloaded = true;
- }
- }
-
- if (is_overloaded) {
- Scope *s = e->scope;
- bool skip = false;
-
- Entity **procs = gb_alloc_array(heap_allocator(), Entity *, overload_count);
- multi_map_get_all(&s->elements, key, procs);
- if (type_hint != nullptr) {
- gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
- defer (gb_temp_arena_memory_end(tmp));
-
- // NOTE(bill): These should be done
- for (isize i = 0; i < overload_count; i++) {
- Type *t = base_type(procs[i]->type);
- if (t == t_invalid) {
- continue;
- }
- Operand x = {};
- x.mode = Addressing_Value;
- x.type = t;
- if (check_is_assignable_to(c, &x, type_hint)) {
- e = procs[i];
- add_entity_use(c, n, e);
- skip = true;
- break;
- }
- }
- }
-
- if (!skip) {
- o->mode = Addressing_Overload;
- o->type = t_invalid;
- o->overload_count = overload_count;
- o->overload_entities = procs;
- return nullptr;
- }
- gb_free(heap_allocator(), procs);
- }
-
- if (e->kind == Entity_ProcedureGrouping) {
- auto *pge = &e->ProcedureGrouping;
+ if (e->kind == Entity_ProcGroup) {
+ auto *pge = &e->ProcGroup;
DeclInfo *d = decl_info_of_entity(&c->info, e);
check_entity_decl(c, e, d, nullptr);
- Entity **procs = pge->entities.data;
- isize overload_count = pge->entities.count;
+ Array<Entity *> procs = pge->entities;
bool skip = false;
if (type_hint != nullptr) {
@@ -1013,7 +951,7 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
defer (gb_temp_arena_memory_end(tmp));
// NOTE(bill): These should be done
- for (isize i = 0; i < overload_count; i++) {
+ for_array(i, procs) {
Type *t = base_type(procs[i]->type);
if (t == t_invalid) {
continue;
@@ -1031,10 +969,9 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
}
if (!skip) {
- o->mode = Addressing_Overload;
- o->type = t_invalid;
- o->overload_count = overload_count;
- o->overload_entities = procs;
+ o->mode = Addressing_ProcGroup;
+ o->type = t_invalid;
+ o->proc_group = e;
return nullptr;
}
}
@@ -1550,13 +1487,13 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
}
} else {
gbString xt, yt;
- if (x->mode == Addressing_Overload) {
- xt = gb_string_make(heap_allocator(), "overloaded procedure");
+ if (x->mode == Addressing_ProcGroup) {
+ xt = gb_string_make(heap_allocator(), "procedure group");
} else {
xt = type_to_string(x->type);
}
- if (y->mode == Addressing_Overload) {
- yt = gb_string_make(heap_allocator(), "overloaded procedure");
+ if (y->mode == Addressing_ProcGroup) {
+ yt = gb_string_make(heap_allocator(), "procedure group");
} else {
yt = type_to_string(y->type);
}
@@ -2483,18 +2420,6 @@ bool check_index_value(Checker *c, bool open_range, AstNode *index_value, i64 ma
return true;
}
-isize entity_overload_count(Scope *s, String name) {
- Entity *e = scope_lookup_entity(s, name);
- if (e == nullptr) {
- return 0;
- }
- if (e->kind == Entity_Procedure) {
- // NOTE(bill): Overloads are only allowed with the same scope
- return multi_map_count(&s->elements, hash_string(e->token.string));
- }
- return 1;
-}
-
Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_hint) {
ast_node(se, SelectorExpr, node);
@@ -2572,7 +2497,7 @@ 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_ProcedureGrouping);
+ GB_ASSERT(entity->type != nullptr || entity->kind == Entity_ProcGroup);
if (is_alias) {
// TODO(bill): Which scope do you search for for an alias?
@@ -2580,46 +2505,26 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
entity_name = entity->token.string;
}
- isize overload_count = entity_overload_count(import_scope, entity_name);
- bool is_overloaded = overload_count > 1;
bool implicit_is_found = is_entity_implicitly_imported(e, entity);
bool is_not_exported = !is_entity_exported(entity);
if (entity->kind == Entity_ImportName) {
is_not_exported = true;
} else if (implicit_is_found) {
- is_not_exported = !is_overloaded;
- }
-
-
- Entity **procs = nullptr;
-
- if (is_overloaded) {
- HashKey key = hash_string(entity_name);
- procs = gb_alloc_array(heap_allocator(), Entity *, overload_count);
- multi_map_get_all(&import_scope->elements, key, procs);
- } else if (entity->kind == Entity_ProcedureGrouping) {
- is_overloaded = true;
- procs = entity->ProcedureGrouping.entities.data;
- overload_count = entity->ProcedureGrouping.entities.count;
+ is_not_exported = true;
}
- if (is_overloaded) {
+ if (is_not_exported && entity->kind == Entity_ProcGroup) {
+ check_entity_decl(c, entity, nullptr, nullptr);
+ auto *pge = &entity->ProcGroup;
+ Array<Entity *> procs = pge->entities;
bool skip = false;
- for (isize i = 0; i < overload_count; i++) {
+ for_array(i, procs) {
Type *t = base_type(procs[i]->type);
if (t == t_invalid) {
continue;
}
- // NOTE(bill): Check to see if it's imported
- if (is_entity_implicitly_imported(e, procs[i])) {
- gb_swap(Entity *, procs[i], procs[overload_count-1]);
- overload_count--;
- i--; // NOTE(bill): Counteract the post event
- continue;
- }
-
Operand x = {};
x.mode = Addressing_Value;
x.type = t;
@@ -2633,16 +2538,12 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
}
if (!skip) {
- if (overload_count > 0) {
- operand->mode = Addressing_Overload;
- operand->type = t_invalid;
- operand->expr = node;
- operand->overload_count = overload_count;
- operand->overload_entities = procs;
- return procs[0];
- } else {
- is_not_exported = true;
- }
+ GB_ASSERT(e != nullptr);
+ operand->mode = Addressing_ProcGroup;
+ operand->type = t_invalid;
+ operand->expr = node;
+ operand->proc_group = e;
+ return e;
}
}
@@ -2791,7 +2692,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
operand->builtin_id = cast(BuiltinProcId)entity->Builtin.id;
break;
- case Entity_ProcedureGrouping:
+ case Entity_ProcGroup:
entity->type = t_invalid;
break;
@@ -4439,7 +4340,6 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) {
return err;
}
-
CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode *call) {
ast_node(ce, CallExpr, call);
@@ -4469,31 +4369,19 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
check_unpack_arguments(c, nullptr, -1, &operands, ce->args, false);
}
- if (operand->mode == Addressing_Overload) {
- // GB_ASSERT_MSG(operand->overload_entities != nullptr &&
- // operand->overload_count > 0,
- // "%p %td", operand->overload_entities, operand->overload_count);
- isize overload_count = operand->overload_count;
- Entity ** procs = operand->overload_entities;
- ValidIndexAndScore *valids = gb_alloc_array(heap_allocator(), ValidIndexAndScore, overload_count);
- isize valid_count = 0;
+ if (operand->mode == Addressing_ProcGroup) {
+ Array<Entity *> procs = proc_group_entities(c, *operand);
- defer (gb_free(heap_allocator(), procs));
+ ValidIndexAndScore *valids = gb_alloc_array(heap_allocator(), ValidIndexAndScore, procs.count);
+ isize valid_count = 0;
defer (gb_free(heap_allocator(), valids));
gbString expr_name = expr_to_string(operand->expr);
defer (gb_string_free(expr_name));
- for (isize i = 0; i < overload_count; i++) {
- Entity *e = procs[i];
- // GB_ASSERT(e->token.string == name);
- DeclInfo *d = decl_info_of_entity(&c->info, e);
- GB_ASSERT(d != nullptr);
- check_entity_decl(c, e, d, nullptr);
- }
-
- for (isize i = 0; i < overload_count; i++) {
+ for_array(i, procs) {
Entity *p = procs[i];
+ check_entity_decl(c, p, nullptr, nullptr);
Type *pt = base_type(p->type);
if (pt != nullptr && is_type_proc(pt)) {
CallArgumentError err = CallArgumentError_None;
@@ -4502,6 +4390,7 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
defer (c->context = prev_context);
c->context.no_polymorphic_errors = true;
c->context.allow_polymorphic_types = is_type_polymorphic(pt);
+
err = call_checker(c, call, pt, p, operands, CallArgumentMode_NoErrors, &data);
if (err == CallArgumentError_None) {
@@ -4531,7 +4420,7 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
if (valid_count == 0) {
- error(operand->expr, "No overloads or ambiguous call for '%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 -> (");
for_array(i, operands) {
Operand o = operands[i];
@@ -4542,10 +4431,10 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
}
gb_printf_err(")\n");
- if (overload_count > 0) {
+ if (procs.count > 0) {
gb_printf_err("Did you mean to use one of the following:\n");
}
- for (isize i = 0; i < overload_count; i++) {
+ for_array(i, procs) {
Entity *proc = procs[i];
TokenPos pos = proc->token.pos;
Type *t = base_type(proc->type);
@@ -4562,12 +4451,12 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
// 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);
}
- if (overload_count > 0) {
+ if (procs.count > 0) {
gb_printf_err("\n");
}
result_type = t_invalid;
} else if (valid_count > 1) {
- error(operand->expr, "Ambiguous procedure call '%s' tha 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 -> (");
for_array(i, operands) {
Operand o = operands[i];
@@ -4606,11 +4495,8 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
proc_type = e->type;
CallArgumentData data = {};
CallArgumentError err = call_checker(c, call, proc_type, e, operands, CallArgumentMode_ShowErrors, &data);
- if (data.gen_entity != nullptr) {
- add_entity_use(c, ident, data.gen_entity);
- } else {
- add_entity_use(c, ident, e);
- }
+ Entity *entity_to_use = data.gen_entity != nullptr ? data.gen_entity : e;
+ add_entity_use(c, ident, entity_to_use);
return data;
}
} else {
@@ -4623,11 +4509,8 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
Entity *e = entity_of_ident(&c->info, ident);
CallArgumentData data = {};
CallArgumentError err = call_checker(c, call, proc_type, e, operands, CallArgumentMode_ShowErrors, &data);
- if (data.gen_entity != nullptr) {
- add_entity_use(c, ident, data.gen_entity);
- } else {
- add_entity_use(c, ident, e);
- }
+ Entity *entity_to_use = data.gen_entity != nullptr ? data.gen_entity : e;
+ add_entity_use(c, ident, entity_to_use);
return data;
}
@@ -4953,7 +4836,7 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
}
Type *proc_type = base_type(operand->type);
- if (operand->mode != Addressing_Overload) {
+ if (operand->mode != Addressing_ProcGroup) {
bool valid_type = (proc_type != nullptr) && is_type_proc(proc_type);
bool valid_mode = is_operand_value(*operand);
if (!valid_type || !valid_mode) {
@@ -5206,8 +5089,8 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
o->mode = Addressing_Constant;
case_end;
- case_ast_node(pg, ProcGrouping, node);
- error(node, "Illegal use of a procedure grouping");
+ case_ast_node(pg, ProcGroup, node);
+ error(node, "Illegal use of a procedure group");
o->mode = Addressing_Invalid;
case_end;
@@ -6205,7 +6088,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
str = gb_string_appendc(str, "---");
case_end;
- case_ast_node(pg, ProcGrouping, node);
+ case_ast_node(pg, ProcGroup, node);
str = gb_string_appendc(str, "proc[");
for_array(i, pg->args) {
if (i > 0) str = gb_string_appendc(str, ", ");
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp
index 6dd2bcdaa..17d50fb6d 100644
--- a/src/check_stmt.cpp
+++ b/src/check_stmt.cpp
@@ -30,7 +30,7 @@ void check_stmt_list(Checker *c, Array<AstNode *> stmts, u32 flags) {
if (i+1 < max) {
switch (n->kind) {
case AstNode_ReturnStmt:
- error(n, "Statements after this 'return' are never executed");
+ error(n, "Statements after this 'return' are never execu");
break;
case AstNode_BranchStmt:
@@ -182,7 +182,7 @@ Type *check_assignment_variable(Checker *c, Operand *lhs, Operand *rhs) {
return nullptr;
}
if (rhs->type == t_invalid &&
- rhs->mode != Addressing_Overload &&
+ rhs->mode != Addressing_ProcGroup &&
rhs->mode != Addressing_Builtin) {
return nullptr;
}
@@ -203,17 +203,16 @@ Type *check_assignment_variable(Checker *c, Operand *lhs, Operand *rhs) {
bool used = false;
if (lhs->mode == Addressing_Invalid ||
- (lhs->type == t_invalid && lhs->mode != Addressing_Overload)) {
+ (lhs->type == t_invalid && lhs->mode != Addressing_ProcGroup)) {
return nullptr;
}
- if (rhs->mode == Addressing_Overload) {
- isize overload_count = rhs->overload_count;
- Entity **procs = rhs->overload_entities;
- GB_ASSERT(procs != nullptr && overload_count > 0);
+ if (rhs->mode == Addressing_ProcGroup) {
+ Array<Entity *> procs = proc_group_entities(c, *rhs);
+ GB_ASSERT(procs.count > 0);
// NOTE(bill): These should be done
- for (isize i = 0; i < overload_count; i++) {
+ for_array(i, procs) {
Type *t = base_type(procs[i]->type);
if (t == t_invalid) {
continue;
@@ -232,8 +231,7 @@ Type *check_assignment_variable(Checker *c, Operand *lhs, Operand *rhs) {
// HACK TODO(bill): Should the entities be freed as it's technically a leak
rhs->mode = Addressing_Value;
rhs->type = e->type;
- rhs->overload_count = 0;
- rhs->overload_entities = nullptr;
+ rhs->proc_group = nullptr;
}
} else {
if (node->kind == AstNode_Ident) {
@@ -1680,176 +1678,177 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
case_end;
case_ast_node(vd, ValueDecl, node);
- if (!vd->is_mutable) {
- break;
- }
- Entity **entities = gb_alloc_array(c->allocator, Entity *, vd->names.count);
- isize entity_count = 0;
-
- for_array(i, vd->names) {
- AstNode *name = vd->names[i];
- Entity *entity = nullptr;
- if (name->kind != AstNode_Ident) {
- error(name, "A variable declaration must be an identifier");
- } else {
- Token token = name->Ident.token;
- String str = token.string;
- Entity *found = nullptr;
- // NOTE(bill): Ignore assignments to '_'
- if (!is_blank_ident(str)) {
- found = current_scope_lookup_entity(c->context.scope, str);
- }
- if (found == nullptr) {
- entity = make_entity_variable(c->allocator, c->context.scope, token, nullptr, false);
- entity->identifier = name;
-
- AstNode *fl = c->context.foreign_context.curr_library;
- if (fl != nullptr) {
- GB_ASSERT(fl->kind == AstNode_Ident);
- entity->Variable.is_foreign = true;
- entity->Variable.foreign_library_ident = fl;
- }
+ if (vd->is_mutable) {
+ Entity **entities = gb_alloc_array(c->allocator, Entity *, vd->names.count);
+ isize entity_count = 0;
+
+ for_array(i, vd->names) {
+ AstNode *name = vd->names[i];
+ Entity *entity = nullptr;
+ if (name->kind != AstNode_Ident) {
+ error(name, "A variable declaration must be an identifier");
} else {
- TokenPos pos = found->token.pos;
- error(token,
- "Redeclaration of '%.*s' in this scope\n"
- "\tat %.*s(%td:%td)",
- LIT(str), LIT(pos.file), pos.line, pos.column);
- entity = found;
+ Token token = name->Ident.token;
+ String str = token.string;
+ Entity *found = nullptr;
+ // NOTE(bill): Ignore assignments to '_'
+ if (!is_blank_ident(str)) {
+ found = current_scope_lookup_entity(c->context.scope, str);
+ }
+ if (found == nullptr) {
+ entity = make_entity_variable(c->allocator, c->context.scope, token, nullptr, false);
+ entity->identifier = name;
+
+ AstNode *fl = c->context.foreign_context.curr_library;
+ if (fl != nullptr) {
+ GB_ASSERT(fl->kind == AstNode_Ident);
+ entity->Variable.is_foreign = true;
+ entity->Variable.foreign_library_ident = fl;
+ }
+ } else {
+ TokenPos pos = found->token.pos;
+ error(token,
+ "Redeclaration of '%.*s' in this scope\n"
+ "\tat %.*s(%td:%td)",
+ LIT(str), LIT(pos.file), pos.line, pos.column);
+ entity = found;
+ }
+ }
+ if (entity == nullptr) {
+ entity = make_entity_dummy_variable(c->allocator, c->global_scope, ast_node_token(name));
+ }
+ entity->parent_proc_decl = c->context.curr_proc_decl;
+ entities[entity_count++] = entity;
+ }
+
+ Type *init_type = nullptr;
+ if (vd->type != nullptr) {
+ init_type = check_type(c, vd->type, nullptr);
+ if (init_type == nullptr) {
+ init_type = t_invalid;
+ } else if (is_type_polymorphic(base_type(init_type))) {
+ gbString str = type_to_string(init_type);
+ error(vd->type, "Invalid use of a polymorphic type '%s' in variable declaration", str);
+ gb_string_free(str);
+ init_type = t_invalid;
+ } else if (is_type_empty_union(init_type)) {
+ gbString str = type_to_string(init_type);
+ error(vd->type, "An empty union '%s' cannot be instantiated in variable declaration", str);
+ gb_string_free(str);
+ init_type = t_invalid;
}
}
- if (entity == nullptr) {
- entity = make_entity_dummy_variable(c->allocator, c->global_scope, ast_node_token(name));
- }
- entity->parent_proc_decl = c->context.curr_proc_decl;
- entities[entity_count++] = entity;
- }
-
- Type *init_type = nullptr;
- if (vd->type != nullptr) {
- init_type = check_type(c, vd->type, nullptr);
- if (init_type == nullptr) {
- init_type = t_invalid;
- } else if (is_type_polymorphic(base_type(init_type))) {
- gbString str = type_to_string(init_type);
- error(vd->type, "Invalid use of a polymorphic type '%s' in variable declaration", str);
- gb_string_free(str);
- init_type = t_invalid;
- } else if (is_type_empty_union(init_type)) {
- gbString str = type_to_string(init_type);
- error(vd->type, "An empty union '%s' cannot be instantiated in variable declaration", str);
- gb_string_free(str);
- init_type = t_invalid;
- }
- }
- // TODO NOTE(bill): This technically checks things multple times
- AttributeContext ac = make_attribute_context(c->context.foreign_context.link_prefix);
- check_decl_attributes(c, vd->attributes, var_decl_attribute, &ac);
+ // TODO NOTE(bill): This technically checks things multple times
+ AttributeContext ac = make_attribute_context(c->context.foreign_context.link_prefix);
+ check_decl_attributes(c, vd->attributes, var_decl_attribute, &ac);
- for (isize i = 0; i < entity_count; i++) {
- Entity *e = entities[i];
- GB_ASSERT(e != nullptr);
- if (e->flags & EntityFlag_Visited) {
- e->type = t_invalid;
- continue;
- }
- e->flags |= EntityFlag_Visited;
+ for (isize i = 0; i < entity_count; i++) {
+ Entity *e = entities[i];
+ GB_ASSERT(e != nullptr);
+ if (e->flags & EntityFlag_Visited) {
+ e->type = t_invalid;
+ continue;
+ }
+ e->flags |= EntityFlag_Visited;
- if (e->type == nullptr) {
- e->type = init_type;
- }
- ac.link_name = handle_link_name(c, e->token, ac.link_name, ac.link_prefix);
- e->Variable.thread_local_model = ac.thread_local_model;
+ if (e->type == nullptr) {
+ e->type = init_type;
+ }
+ ac.link_name = handle_link_name(c, e->token, ac.link_name, ac.link_prefix);
+ e->Variable.thread_local_model = ac.thread_local_model;
- if (ac.link_name.len > 0) {
- e->Variable.link_name = ac.link_name;
+ if (ac.link_name.len > 0) {
+ e->Variable.link_name = ac.link_name;
+ }
}
- }
-
- check_arity_match(c, vd);
- check_init_variables(c, entities, entity_count, vd->values, str_lit("variable declaration"));
- for (isize i = 0; i < entity_count; i++) {
- Entity *e = entities[i];
- if (e->Variable.is_foreign) {
- if (vd->values.count > 0) {
- error(e->token, "A foreign variable declaration cannot have a default value");
- }
+ check_arity_match(c, vd);
+ check_init_variables(c, entities, entity_count, vd->values, str_lit("variable declaration"));
- String name = e->token.string;
- if (e->Variable.link_name.len > 0) {
- name = e->Variable.link_name;
- }
+ for (isize i = 0; i < entity_count; i++) {
+ Entity *e = entities[i];
+ if (e->Variable.is_foreign) {
+ if (vd->values.count > 0) {
+ error(e->token, "A foreign variable declaration cannot have a default value");
+ }
- if (vd->values.count > 0) {
- error(e->token, "A foreign variable declaration cannot have a default value");
- }
- init_entity_foreign_library(c, e);
+ String name = e->token.string;
+ if (e->Variable.link_name.len > 0) {
+ name = e->Variable.link_name;
+ }
- auto *fp = &c->info.foreigns;
- HashKey key = hash_string(name);
- Entity **found = map_get(fp, key);
- if (found) {
- Entity *f = *found;
- TokenPos pos = f->token.pos;
- Type *this_type = base_type(e->type);
- Type *other_type = base_type(f->type);
- if (!are_types_identical(this_type, other_type)) {
- error(e->token,
- "Foreign entity '%.*s' previously declared elsewhere with a different type\n"
- "\tat %.*s(%td:%td)",
- LIT(name), LIT(pos.file), pos.line, pos.column);
+ if (vd->values.count > 0) {
+ error(e->token, "A foreign variable declaration cannot have a default value");
+ }
+ init_entity_foreign_library(c, e);
+
+ auto *fp = &c->info.foreigns;
+ HashKey key = hash_string(name);
+ Entity **found = map_get(fp, key);
+ if (found) {
+ Entity *f = *found;
+ TokenPos pos = f->token.pos;
+ Type *this_type = base_type(e->type);
+ Type *other_type = base_type(f->type);
+ if (!are_types_identical(this_type, other_type)) {
+ error(e->token,
+ "Foreign entity '%.*s' previously declared elsewhere with a different type\n"
+ "\tat %.*s(%td:%td)",
+ LIT(name), LIT(pos.file), pos.line, pos.column);
+ }
+ } else {
+ map_set(fp, key, e);
}
- } else {
- map_set(fp, key, e);
}
- }
- add_entity(c, c->context.scope, e->identifier, e);
- }
-
- if (vd->is_using != 0) {
- Token token = ast_node_token(node);
- if (vd->type != nullptr && entity_count > 1) {
- error(token, "'using' can only be applied to one variable of the same type");
- // TODO(bill): Should a 'continue' happen here?
+ add_entity(c, c->context.scope, e->identifier, e);
}
- for (isize entity_index = 0; entity_index < entity_count; entity_index++) {
- Entity *e = entities[entity_index];
- if (e == nullptr) {
- continue;
+ if (vd->is_using != 0) {
+ Token token = ast_node_token(node);
+ if (vd->type != nullptr && entity_count > 1) {
+ error(token, "'using' can only be applied to one variable of the same type");
+ // TODO(bill): Should a 'continue' happen here?
}
- if (e->kind != Entity_Variable) {
- continue;
- }
- bool is_immutable = e->Variable.is_immutable;
- String name = e->token.string;
- Type *t = base_type(type_deref(e->type));
-
- if (is_blank_ident(name)) {
- error(token, "'using' cannot be applied variable declared as '_'");
- } else if (is_type_struct(t) || is_type_raw_union(t)) {
- Scope *scope = scope_of_node(&c->info, t->Struct.node);
- for_array(i, scope->elements.entries) {
- Entity *f = scope->elements.entries[i].value;
- if (f->kind == Entity_Variable) {
- Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type);
- uvar->Variable.is_immutable = is_immutable;
- Entity *prev = scope_insert_entity(c->context.scope, uvar);
- if (prev != nullptr) {
- error(token, "Namespace collision while 'using' '%.*s' of: %.*s", LIT(name), LIT(prev->token.string));
- return;
+
+ for (isize entity_index = 0; entity_index < entity_count; entity_index++) {
+ Entity *e = entities[entity_index];
+ if (e == nullptr) {
+ continue;
+ }
+ if (e->kind != Entity_Variable) {
+ continue;
+ }
+ bool is_immutable = e->Variable.is_immutable;
+ String name = e->token.string;
+ Type *t = base_type(type_deref(e->type));
+
+ if (is_blank_ident(name)) {
+ error(token, "'using' cannot be applied variable declared as '_'");
+ } else if (is_type_struct(t) || is_type_raw_union(t)) {
+ Scope *scope = scope_of_node(&c->info, t->Struct.node);
+ for_array(i, scope->elements.entries) {
+ Entity *f = scope->elements.entries[i].value;
+ if (f->kind == Entity_Variable) {
+ Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type);
+ uvar->Variable.is_immutable = is_immutable;
+ Entity *prev = scope_insert_entity(c->context.scope, uvar);
+ if (prev != nullptr) {
+ error(token, "Namespace collision while 'using' '%.*s' of: %.*s", LIT(name), LIT(prev->token.string));
+ return;
+ }
}
}
+ } else {
+ // NOTE(bill): skip the rest to remove extra errors
+ error(token, "'using' can only be applied to variables of type struct or raw_union");
+ return;
}
- } else {
- // NOTE(bill): skip the rest to remove extra errors
- error(token, "'using' can only be applied to variables of type struct or raw_union");
- return;
}
}
+ } else {
+ // constant value declarations
}
case_end;
}
diff --git a/src/checker.cpp b/src/checker.cpp
index 7c9f20135..16bc32ca1 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -120,7 +120,7 @@ enum AddressingMode {
Addressing_Constant, // constant
Addressing_Type, // type
Addressing_Builtin, // built-in procedure
- Addressing_Overload, // overloaded procedure
+ Addressing_ProcGroup, // procedure group (overloaded procedure)
Addressing_MapIndex, // map index expression -
// lhs: acts like a Variable
// rhs: acts like OptionalOk
@@ -138,8 +138,7 @@ struct Operand {
ExactValue value;
AstNode * expr;
BuiltinProcId builtin_id;
- isize overload_count;
- Entity ** overload_entities;
+ Entity * proc_group;
};
struct TypeAndValue {
@@ -166,6 +165,8 @@ bool is_operand_undef(Operand o) {
return o.mode == Addressing_Value && o.type == t_untyped_undef;
}
+
+
struct BlockLabel {
String name;
AstNode *label; // AstNode_Label;
@@ -780,28 +781,10 @@ Entity *scope_insert_entity(Scope *s, Entity *entity) {
HashKey key = hash_string(name);
Entity **found = map_get(&s->elements, key);
-#ifndef DISABLE_PROCEDURE_OVERLOADING
- // IMPORTANT NOTE(bill): Procedure overloading code
- Entity *prev = nullptr;
- if (found) {
- prev = *found;
- if (prev->kind != Entity_Procedure ||
- entity->kind != Entity_Procedure) {
- return prev;
- }
- }
-
- if (prev != nullptr && entity->kind == Entity_Procedure) {
- multi_map_insert(&s->elements, key, entity);
- } else {
- map_set(&s->elements, key, entity);
- }
-#else
if (found) {
return *found;
}
map_set(&s->elements, key, entity);
-#endif
if (entity->scope == nullptr) {
entity->scope = s;
}
@@ -1620,6 +1603,18 @@ Type *find_core_type(Checker *c, String name) {
void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type);
+Array<Entity *> proc_group_entities(Checker *c, Operand o) {
+ Array<Entity *> procs = {};
+ if (o.mode == Addressing_ProcGroup) {
+ GB_ASSERT(o.proc_group != nullptr);
+ if (o.proc_group->kind == Entity_ProcGroup) {
+ check_entity_decl(c, o.proc_group, nullptr, nullptr);
+ return o.proc_group->ProcGroup.entities;
+ }
+ }
+ return procs;
+}
+
void init_preload(Checker *c) {
if (t_type_info == nullptr) {
Entity *type_info_entity = find_core_entity(c, str_lit("Type_Info"));
@@ -1736,118 +1731,6 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes);
void check_collect_entities_from_when_stmt(Checker *c, AstNodeWhenStmt *ws);
void check_delayed_file_import_entity(Checker *c, AstNode *decl);
-bool check_is_entity_overloaded(Entity *e) {
- if (e->kind != Entity_Procedure) {
- return false;
- }
- Scope *s = e->scope;
- HashKey key = hash_string(e->token.string);
- isize overload_count = multi_map_count(&s->elements, key);
- return overload_count > 1;
-}
-
-void check_procedure_overloading(Checker *c, Entity *e) {
- GB_ASSERT(e->kind == Entity_Procedure);
- if (e->type == t_invalid) {
- return;
- }
- if (e->Procedure.overload_kind != Overload_Unknown) {
- // NOTE(bill): The overloading has already been handled
- return;
- }
-
-
- // NOTE(bill): Procedures call only overload other procedures in the same scope
-
- String name = e->token.string;
- HashKey key = hash_string(name);
- Scope *s = e->scope;
- isize overload_count = multi_map_count(&s->elements, key);
- GB_ASSERT(overload_count >= 1);
- if (overload_count == 1) {
- e->Procedure.overload_kind = Overload_No;
- return;
- }
- GB_ASSERT(overload_count > 1);
-
-
- gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
- Entity **procs = gb_alloc_array(c->tmp_allocator, Entity *, overload_count);
- multi_map_get_all(&s->elements, key, procs);
-
- for (isize j = 0; j < overload_count; j++) {
- Entity *p = procs[j];
- if (p->type == t_invalid) {
- // NOTE(bill): This invalid overload has already been handled
- continue;
- }
-
- String name = p->token.string;
-
- GB_ASSERT(p->kind == Entity_Procedure);
- for (isize k = j+1; k < overload_count; k++) {
- Entity *q = procs[k];
- GB_ASSERT(p != q);
-
- bool is_invalid = false;
- GB_ASSERT(q->kind == Entity_Procedure);
-
- TokenPos pos = q->token.pos;
-
- if (q->type == nullptr || q->type == t_invalid) {
- continue;
- }
-
- ProcTypeOverloadKind kind = are_proc_types_overload_safe(p->type, q->type);
- switch (kind) {
- case ProcOverload_Identical:
- error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in this scope", LIT(name));
- is_invalid = true;
- break;
- // case ProcOverload_CallingConvention:
- // error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in this scope", LIT(name));
- // is_invalid = true;
- // break;
- case ProcOverload_ParamVariadic:
- error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in this scope", LIT(name));
- is_invalid = true;
- break;
- case ProcOverload_ResultCount:
- case ProcOverload_ResultTypes:
- error(p->token, "Overloaded procedure '%.*s' as the same parameters but different results in this scope", LIT(name));
- is_invalid = true;
- break;
- case ProcOverload_Polymorphic:
- #if 0
- error(p->token, "Overloaded procedure '%.*s' has a polymorphic counterpart in this scope which is not allowed", LIT(name));
- is_invalid = true;
- #endif
- break;
- case ProcOverload_ParamCount:
- case ProcOverload_ParamTypes:
- // This is okay :)
- break;
-
- }
-
- if (is_invalid) {
- gb_printf_err("\tprevious procedure at %.*s(%td:%td)\n", LIT(pos.file), pos.line, pos.column);
- q->type = t_invalid;
- }
- }
- }
-
- for (isize j = 0; j < overload_count; j++) {
- Entity *p = procs[j];
- if (p->type != t_invalid) {
- p->Procedure.overload_kind = Overload_Yes;
- }
- }
-
- gb_temp_arena_memory_end(tmp);
-}
-
-
struct AttributeContext {
String link_name;
String link_prefix;
@@ -2259,11 +2142,11 @@ void check_collect_value_decl(Checker *c, AstNode *decl) {
}
d->proc_lit = init;
d->type_expr = pl->type;
- } else if (init->kind == AstNode_ProcGrouping) {
- ast_node(pg, ProcGrouping, init);
- e = make_entity_procedure_grouping(c->allocator, d->scope, token, nullptr);
+ } else if (init->kind == AstNode_ProcGroup) {
+ ast_node(pg, ProcGroup, init);
+ e = make_entity_proc_group(c->allocator, d->scope, token, nullptr);
if (fl != nullptr) {
- error(name, "Procedure groupings are not allowed within a foreign block");
+ error(name, "Procedure groups are not allowed within a foreign block");
}
d->init_expr = init;
} else {
@@ -2447,15 +2330,6 @@ void check_all_global_entities(Checker *c) {
init_preload(c);
}
}
-
- for_array(i, c->info.entities.entries) {
- auto *entry = &c->info.entities.entries[i];
- Entity *e = cast(Entity *)entry->key.ptr;
- if (e->kind != Entity_Procedure) {
- continue;
- }
- check_procedure_overloading(c, e);
- }
}
diff --git a/src/entity.cpp b/src/entity.cpp
index ef49c4d0e..ff3fd5c20 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -10,7 +10,7 @@ struct DeclInfo;
ENTITY_KIND(Variable) \
ENTITY_KIND(TypeName) \
ENTITY_KIND(Procedure) \
- ENTITY_KIND(ProcedureGrouping) \
+ ENTITY_KIND(ProcGroup) \
ENTITY_KIND(Builtin) \
ENTITY_KIND(Alias) \
ENTITY_KIND(ImportName) \
@@ -110,7 +110,7 @@ struct Entity {
} Procedure;
struct {
Array<Entity *> entities;
- } ProcedureGrouping;
+ } ProcGroup;
struct {
i32 id;
} Builtin;
@@ -248,8 +248,8 @@ Entity *make_entity_procedure(gbAllocator a, Scope *scope, Token token, Type *si
return entity;
}
-Entity *make_entity_procedure_grouping(gbAllocator a, Scope *scope, Token token, Type *type) {
- Entity *entity = alloc_entity(a, Entity_ProcedureGrouping, scope, token, type);
+Entity *make_entity_proc_group(gbAllocator a, Scope *scope, Token token, Type *type) {
+ Entity *entity = alloc_entity(a, Entity_ProcGroup, scope, token, type);
return entity;
}
diff --git a/src/ir.cpp b/src/ir.cpp
index f1b6a5ee0..c869e550b 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -3620,7 +3620,7 @@ String ir_mangle_name(irGen *s, String path, Entity *e) {
isize base_len = ext-1-base;
isize max_len = base_len + 1 + 1 + 10 + 1 + name.len;
- bool require_suffix_id = check_is_entity_overloaded(e) || is_type_polymorphic(e->type);
+ bool require_suffix_id = is_type_polymorphic(e->type);
if (require_suffix_id) {
max_len += 21;
}
@@ -8304,19 +8304,22 @@ void ir_gen_tree(irGen *s) {
}
for_array(i, info->entities.entries) {
- auto *entry = &info->entities.entries[i];
- Entity *e = cast(Entity *)entry->key.ptr;
- String name = e->token.string;
- DeclInfo *decl = entry->value;
- Scope *scope = e->scope;
+ auto * entry = &info->entities.entries[i];
+ Entity * e = cast(Entity *)entry->key.ptr;
+ String name = e->token.string;
+ DeclInfo *decl = entry->value;
+ Scope * scope = e->scope;
if (!scope->is_file) {
continue;
}
- if (e->kind == Entity_Variable || e->kind == Entity_ProcedureGrouping) {
+ switch (e->kind) {
+ case Entity_Variable:
// NOTE(bill): Handled above as it requires a specific load order
continue;
+ case Entity_ProcGroup:
+ continue;
}
bool polymorphic_struct = false;
@@ -8341,8 +8344,6 @@ void ir_gen_tree(irGen *s) {
} else {
name = ir_mangle_name(s, e->token.pos.file, e);
}
- } else if (check_is_entity_overloaded(e)) {
- name = ir_mangle_name(s, e->token.pos.file, e);
}
ir_add_entity_name(m, e, name);
@@ -8373,7 +8374,7 @@ void ir_gen_tree(irGen *s) {
ir_module_add_value(m, e, p);
HashKey hash_name = hash_string(name);
if (map_get(&m->members, hash_name) == nullptr) {
- multi_map_insert(&m->members, hash_name, p);
+ map_set(&m->members, hash_name, p);
}
break;
}
diff --git a/src/main.cpp b/src/main.cpp
index 7f24a7d4d..5df246e7f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,5 +1,4 @@
#define ALLOW_ARRAY_PROGRAMMING
-// #define DISABLE_PROCEDURE_OVERLOADING
// #define NO_ARRAY_BOUNDS_CHECK
diff --git a/src/map.cpp b/src/map.cpp
index 92840a480..152b8cb39 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -2,6 +2,8 @@
// with the use of the `multi_*` procedures.
// TODO(bill): I should probably allow the `multi_map_*` stuff to be #ifdefed out
+#define MAP_ENABLE_MULTI_MAP 1
+
#ifndef MAP_UTIL_STUFF
#define MAP_UTIL_STUFF
// NOTE(bill): This util stuff is the same for every `Map`
@@ -110,6 +112,7 @@ template <typename T> void map_clear (Map<T> *h);
template <typename T> void map_grow (Map<T> *h);
template <typename T> void map_rehash (Map<T> *h, isize new_count);
+#if MAP_ENABLE_MULTI_MAP
// Mutlivalued map procedure
template <typename T> MapEntry<T> * multi_map_find_first(Map<T> *h, HashKey key);
template <typename T> MapEntry<T> * multi_map_find_next (Map<T> *h, MapEntry<T> *e);
@@ -119,7 +122,7 @@ template <typename T> void multi_map_get_all (Map<T> *h, HashKey key, T *item
template <typename T> void multi_map_insert (Map<T> *h, HashKey key, T const &value);
template <typename T> void multi_map_remove (Map<T> *h, HashKey key, MapEntry<T> *e);
template <typename T> void multi_map_remove_all(Map<T> *h, HashKey key);
-
+#endif
template <typename T>
gb_inline void map_init(Map<T> *h, gbAllocator a, isize capacity) {
@@ -291,7 +294,7 @@ gb_inline void map_clear(Map<T> *h) {
}
-#if 1
+#if MAP_ENABLE_MULTI_MAP
template <typename T>
MapEntry<T> *multi_map_find_first(Map<T> *h, HashKey key) {
isize i = map__find(h, key).entry_index;
diff --git a/src/parser.cpp b/src/parser.cpp
index 189e13f32..704833170 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -164,7 +164,7 @@ Array<AstNode *> make_ast_node_array(AstFile *f, isize init_capacity = 8) {
Token token; \
AstNode *expr; \
}) \
- AST_NODE_KIND(ProcGrouping, "procedure grouping", struct { \
+ AST_NODE_KIND(ProcGroup, "procedure group", struct { \
Token token; \
Token open; \
Token close; \
@@ -540,7 +540,7 @@ Token ast_node_token(AstNode *node) {
case AstNode_Undef: return node->Undef;
case AstNode_BasicLit: return node->BasicLit;
case AstNode_BasicDirective: return node->BasicDirective.token;
- case AstNode_ProcGrouping: return node->ProcGrouping.token;
+ case AstNode_ProcGroup: return node->ProcGroup.token;
case AstNode_ProcLit: return ast_node_token(node->ProcLit.type);
case AstNode_CompoundLit:
if (node->CompoundLit.type != nullptr) {
@@ -669,8 +669,8 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
case AstNode_Ellipsis:
n->Ellipsis.expr = clone_ast_node(a, n->Ellipsis.expr);
break;
- case AstNode_ProcGrouping:
- n->ProcGrouping.args = clone_ast_node_array(a, n->ProcGrouping.args);
+ case AstNode_ProcGroup:
+ n->ProcGroup.args = clone_ast_node_array(a, n->ProcGroup.args);
break;
case AstNode_ProcLit:
n->ProcLit.type = clone_ast_node(a, n->ProcLit.type);
@@ -1121,12 +1121,12 @@ AstNode *ast_ellipsis(AstFile *f, Token token, AstNode *expr) {
}
-AstNode *ast_proc_grouping(AstFile *f, Token token, Token open, Token close, Array<AstNode *> args) {
- AstNode *result = make_ast_node(f, AstNode_ProcGrouping);
- result->ProcGrouping.token = token;
- result->ProcGrouping.open = open;
- result->ProcGrouping.close = close;
- result->ProcGrouping.args = args;
+AstNode *ast_proc_group(AstFile *f, Token token, Token open, Token close, Array<AstNode *> args) {
+ AstNode *result = make_ast_node(f, AstNode_ProcGroup);
+ result->ProcGroup.token = token;
+ result->ProcGroup.open = open;
+ result->ProcGroup.close = close;
+ result->ProcGroup.args = args;
return result;
}
@@ -2266,11 +2266,11 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
return expr;
} break;
- // Parse Procedure Type or Literal or Grouping
+ // Parse Procedure Type or Literal or Group
case Token_proc: {
Token token = expect_token(f, Token_proc);
- if (f->curr_token.kind == Token_OpenBracket) { // ProcGrouping
+ if (f->curr_token.kind == Token_OpenBracket) { // ProcGroup
Token open = expect_token(f, Token_OpenBracket);
Array<AstNode *> args = {};
@@ -2289,10 +2289,10 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
Token close = expect_token(f, Token_CloseBracket);
if (args.count == 0) {
- syntax_error(token, "Expected a least 1 argument in a procedure grouping");
+ syntax_error(token, "Expected a least 1 argument in a procedure group");
}
- return ast_proc_grouping(f, token, open, close, args);
+ return ast_proc_group(f, token, open, close, args);
}
AstNode *type = parse_proc_type(f, token);