Cleanup compile time variables from generated code
This commit is contained in:
@@ -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; }
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -328,5 +328,51 @@ Ast_Decl *get_or_instantiate_polymorph_type(Token *pos, Ast_Decl *poly, Array<As
|
||||
return result;
|
||||
}
|
||||
|
||||
// Ast_Decl *get_or_instantiate_polymorph_lambda(Token *pos, Ast_Decl *poly, Array<Ast_Call_Item *> params, Ast_Scope *field_access_scope) {
|
||||
// }
|
||||
Ast_Decl *get_or_instantiate_polymorph_lambda(Token *pos, Ast_Decl *poly, Array<Ast_Call_Item *> 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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user