Core: Fix assigning to arrays

This commit is contained in:
Krzosa Karol
2023-04-21 09:45:57 +02:00
parent ef243724dc
commit 51cebbf4d0
3 changed files with 53 additions and 48 deletions

View File

@@ -305,6 +305,49 @@ gen_pointer(Ast_Expr *expr) {
}
}
CORE_Static void gen_try_any_or_slice(Ast_Expr *expr, Ast_Type *decl_type);
CORE_Static void
gen_compound(Ast *ast, bool generate_compound_decl = true) {
assert(ast->kind == AST_COMPOUND);
auto node = (Ast_Call *)ast;
bool generated_anything = false;
bool is_global_variable = node->parent_scope->kind == AST_FILE;
if (!is_global_variable && generate_compound_decl) {
gen("(");
gen_simple_decl(node->resolved_type);
gen(")");
}
gen("{");
// We need to double wrap it because Any is a pointer
// We need to pass it a compound array
if (is_slice(node->resolved_type)) {
generated_anything = true;
gen(".len = %d, ", node->exprs.len);
gen(".data = (");
gen_simple_decl(node->resolved_type->base);
gen("[]");
gen(")");
gen("{");
}
For(node->exprs) {
generated_anything = true;
if (is_struct(node->resolved_type) || is_union(node->resolved_type))
gen(".%Q = ", it->resolved_name);
else if (is_array(node->resolved_type))
gen("[%d] = ", (int)it->resolved_index);
gen_try_any_or_slice(it->item, it->resolved_type);
if (!node->exprs.is_last(it)) gen(", ");
}
if (is_slice(node->resolved_type)) gen("}");
if (!generated_anything) gen("0");
gen("}");
}
CORE_Static void
gen_try_any_or_slice(Ast_Expr *expr, Ast_Type *decl_type) {
// We want normal values to get boxed as Any pointers
@@ -328,6 +371,7 @@ gen_try_any_or_slice(Ast_Expr *expr, Ast_Type *decl_type) {
CORE_Static void
gen_var(Ast_Decl *decl, B32 emit_value, B32 scope_names) {
if (decl->name == pctx->internf("HERE_IT_IS")) __debugbreak();
if (is_flag_set(decl->flags, AST_FOREIGN)) gen("extern ");
gen_simple_decl(decl->type, decl->name);
if (is_flag_set(decl->flags, AST_FOREIGN)) return;
@@ -337,8 +381,13 @@ gen_var(Ast_Decl *decl, B32 emit_value, B32 scope_names) {
}
if (decl->expr) {
gen(" = ");
gen_try_any_or_slice(decl->expr, decl->type);
if (is_array(decl->type)) {
gen_compound((Ast_Call *)decl->expr, false);
}
else {
gen(" = ");
gen_try_any_or_slice(decl->expr, decl->type);
}
}
else { // Default zero
if (is_numeric(decl->type)) {
@@ -505,41 +554,7 @@ gen_expr(Ast_Expr *ast) {
}
CASE(COMPOUND, Call) {
bool generated_anything = false;
bool is_global_variable = node->parent_scope->kind == AST_FILE;
if (!is_global_variable) {
gen("(");
gen_simple_decl(node->resolved_type);
gen(")");
}
gen("{");
// We need to double wrap it because Any is a pointer
// We need to pass it a compound array
if (is_slice(node->resolved_type)) {
generated_anything = true;
gen(".len = %d, ", node->exprs.len);
gen(".data = (");
gen_simple_decl(node->resolved_type->base);
gen("[]");
gen(")");
gen("{");
}
For(node->exprs) {
generated_anything = true;
if (is_struct(node->resolved_type) || is_union(node->resolved_type))
gen(".%Q = ", it->resolved_name);
else if (is_array(node->resolved_type))
gen("[%d] = ", (int)it->resolved_index);
gen_try_any_or_slice(it->item, it->resolved_type);
if (!node->exprs.is_last(it)) gen(", ");
}
if (is_slice(node->resolved_type)) gen("}");
if (!generated_anything) gen("0");
gen("}");
gen_compound(node);
BREAK();
}