From e8f82f643ae135fc8d1b056378fda0fcba0ce465 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sat, 1 Apr 2023 19:54:03 +0200 Subject: [PATCH] Cleanup compile time variables from generated code --- base_data_structures.cpp | 11 ++++++++ core_codegen_c_language.cpp | 1 + core_polymorph.cpp | 50 +++++++++++++++++++++++++++++++++++-- core_typechecking.cpp | 4 +-- 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/base_data_structures.cpp b/base_data_structures.cpp index c82d57e..597b7c0 100644 --- a/base_data_structures.cpp +++ b/base_data_structures.cpp @@ -117,6 +117,17 @@ struct Array { return result; } + void ordered_remove(T &item) { + assert(len > 0); + assert(&item >= begin() && &item < end()); + int index = get_index(&item); + assert(index >= 0 && index < len); + + int right_len = len - index - 1; + memmove(data + index, data + index + 1, right_len * sizeof(T)); + len -= 1; + } + force_inline B32 is_last(T *item) { return item == last(); } force_inline B32 is_first(T *item) { return item == begin(); } force_inline void clear() { len = 0; } diff --git a/core_codegen_c_language.cpp b/core_codegen_c_language.cpp index 2c1824f..a78362f 100644 --- a/core_codegen_c_language.cpp +++ b/core_codegen_c_language.cpp @@ -337,6 +337,7 @@ CORE_Static void gen_lambda(Intern_String name, Ast_Lambda *lambda, B32 generate_block = true) { gen_simple_decl(lambda->resolved_type->func.ret, name); gen("("); + if (lambda->args.len == 0) gen("void"); For(lambda->args) { gen_var(it, DONT_EMIT_VALUE, true); if (&it != (lambda->args.end() - 1)) diff --git a/core_polymorph.cpp b/core_polymorph.cpp index c6de734..942d0e7 100644 --- a/core_polymorph.cpp +++ b/core_polymorph.cpp @@ -328,5 +328,51 @@ Ast_Decl *get_or_instantiate_polymorph_type(Token *pos, Ast_Decl *poly, Array params, Ast_Scope *field_access_scope) { -// } \ No newline at end of file +Ast_Decl *get_or_instantiate_polymorph_lambda(Token *pos, Ast_Decl *poly, Array params, Ast_Scope *field_access_scope) { + if (params.len != poly->polymorph_parameters.len) compiler_error(pos, "Invalid count of polymorphic arguments"); + + int i = 0; + uint64_t hash = 91; + For(params) { + Ast_Decl *poly_decl = poly->polymorph_parameters[i++]; + resolve_decl(poly_decl); + if (poly_decl->type != pctx->type_type) compiler_error(poly_decl->pos, "Invalid type of polymorphic struct argument"); + + Operand op = resolve_expr(it->item, AST_CANT_BE_NULL, 0, field_access_scope); + if (!op.is_const) compiler_error(it->pos, "Argument is required to be compile time known"); + if (op.type != pctx->type_type) compiler_error(it->pos, "Struct argument required to be a type"); + + hash = hash_mix(hash, hash_ptr(op.type_val)); + } + + Ast_Decl *result = 0; + For(poly->polymorphs) { + if (it->polymorph_hash == hash) { + result = it; + break; + } + } + + if (!result) { + result = (Ast_Decl *)ast_copy(poly, poly->parent_scope, &poly->polymorph_parameters, ¶ms); + For(result->lambda->args) { + if (it->flags & AST_IDENT_POLYMORPH) { + result->lambda->args.ordered_remove(it); + } + } + + unset_flag(result->flags, AST_POLYMORPH); + unset_flag(result->flags, AST_PARENT_POLYMORPH); + result->polymorph_hash = hash; + + assert(result->di != poly->di); + result->name = get_unique_name_for_decl(result); + result->unique_name = result->name; + + poly->polymorphs.allocator = pctx->heap; + poly->polymorphs.add(result); + } + + resolve_decl(result); + return result; +} diff --git a/core_typechecking.cpp b/core_typechecking.cpp index 22d8005..9829a36 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -1703,8 +1703,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str } Ast_Decl *poly = name.resolved_decl; - assert(replacements.len == poly->polymorph_parameters.len); - Ast_Decl *instance = get_or_instantiate_polymorph_type(node->pos, poly, replacements, field_access_scope); + Ast_Decl *instance = get_or_instantiate_polymorph_lambda(node->pos, poly, replacements, field_access_scope); node->resolved_decl = instance; lambda = instance->lambda; } @@ -1714,6 +1713,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str For(matches) { Ast_Call_Item *item = it.call_arg; Ast_Decl *lambda_arg = it.lambda_arg; + if (lambda_arg->flags & AST_IDENT_POLYMORPH) continue; Operand expr = resolve_expr(item->item, AST_CANT_BE_NULL, lambda_arg->type, field_access_scope); make_sure_value_is_compatible_with_type(item->pos, &expr, lambda_arg->type, TYPE_AND_EXPR_REQUIRED);