diff --git a/src/tilde_backend.cpp b/src/tilde_backend.cpp index 0572e2fd0..97f92e3db 100644 --- a/src/tilde_backend.cpp +++ b/src/tilde_backend.cpp @@ -446,295 +446,6 @@ struct cgGlobalVariable { bool is_initialized; }; - -gb_internal TB_FunctionPrototype *cg_procedure_type_as_prototype(cgModule *m, Type *type) { - GB_ASSERT(type != nullptr); - type = base_type(type); - GB_ASSERT(type->kind == Type_Proc); - TypeProc *pt = &type->Proc; - - auto params = array_make(heap_allocator(), 0, pt->param_count); - if (pt->params) for (Entity *e : pt->params->Tuple.variables) { - TB_PrototypeParam param = {}; - - Type *t = core_type(e->type); - i64 sz = type_size_of(t); - switch (t->kind) { - case Type_Basic: - switch (t->Basic.kind) { - case Basic_bool: - case Basic_b8: - case Basic_b16: - case Basic_b32: - case Basic_b64: - case Basic_i8: - case Basic_u8: - case Basic_i16: - case Basic_u16: - case Basic_i32: - case Basic_u32: - case Basic_i64: - case Basic_u64: - case Basic_i128: - case Basic_u128: - case Basic_rune: - case Basic_int: - case Basic_uint: - case Basic_uintptr: - param.dt = TB_TYPE_INTN(cast(u16)(8*sz)); - break; - - case Basic_f16: param.dt = TB_TYPE_I16; break; - case Basic_f32: param.dt = TB_TYPE_F32; break; - case Basic_f64: param.dt = TB_TYPE_F64; break; - - case Basic_complex32: - case Basic_complex64: - case Basic_complex128: - case Basic_quaternion64: - case Basic_quaternion128: - case Basic_quaternion256: - param.dt = TB_TYPE_PTR; - break; - - - case Basic_rawptr: - param.dt = TB_TYPE_PTR; - break; - case Basic_string: // ^u8 + int - param.dt = TB_TYPE_PTR; - break; - case Basic_cstring: // ^u8 - param.dt = TB_TYPE_PTR; - break; - case Basic_any: // rawptr + ^Type_Info - param.dt = TB_TYPE_PTR; - break; - - case Basic_typeid: - param.dt = TB_TYPE_INTN(cast(u16)(8*sz)); - break; - - // Endian Specific Types - case Basic_i16le: - case Basic_u16le: - case Basic_i32le: - case Basic_u32le: - case Basic_i64le: - case Basic_u64le: - case Basic_i128le: - case Basic_u128le: - case Basic_i16be: - case Basic_u16be: - case Basic_i32be: - case Basic_u32be: - case Basic_i64be: - case Basic_u64be: - case Basic_i128be: - case Basic_u128be: - param.dt = TB_TYPE_INTN(cast(u16)(8*sz)); - break; - - case Basic_f16le: param.dt = TB_TYPE_I16; break; - case Basic_f32le: param.dt = TB_TYPE_F32; break; - case Basic_f64le: param.dt = TB_TYPE_F64; break; - - case Basic_f16be: param.dt = TB_TYPE_I16; break; - case Basic_f32be: param.dt = TB_TYPE_F32; break; - case Basic_f64be: param.dt = TB_TYPE_F64; break; - } - - case Type_Pointer: - case Type_MultiPointer: - case Type_Proc: - param.dt = TB_TYPE_PTR; - break; - - default: - switch (sz) { - case 1: param.dt = TB_TYPE_I8; break; - case 2: param.dt = TB_TYPE_I16; break; - case 4: param.dt = TB_TYPE_I32; break; - case 8: param.dt = TB_TYPE_I64; break; - default: - param.dt = TB_TYPE_PTR; - break; - } - } - - if (param.dt.width != 0) { - if (is_blank_ident(e->token)) { - param.name = alloc_cstring(temporary_allocator(), e->token.string); - } - array_add(¶ms, param); - } - } - - auto results = array_make(heap_allocator(), 0, pt->result_count); - // if (pt->results) for (Entity *e : pt->params->Tuple.variables) { - // // TODO(bill): - // } - - - return tb_prototype_create(m->mod, TB_CDECL, params.count, params.data, results.count, results.data, pt->c_vararg); -} - -gb_internal cgProcedure *cg_procedure_create(cgModule *m, Entity *entity, bool ignore_body=false) { - GB_ASSERT(entity != nullptr); - GB_ASSERT(entity->kind == Entity_Procedure); - if (!entity->Procedure.is_foreign) { - if ((entity->flags & EntityFlag_ProcBodyChecked) == 0) { - GB_PANIC("%.*s :: %s (was parapoly: %d %d)", LIT(entity->token.string), type_to_string(entity->type), is_type_polymorphic(entity->type, true), is_type_polymorphic(entity->type, false)); - } - } - - String link_name = cg_get_entity_name(m, entity); - - cgProcedure *p = nullptr; - { - StringHashKey key = string_hash_string(link_name); - cgValue *found = string_map_get(&m->members, key); - if (found) { - cg_add_entity(m, entity, *found); - p = string_map_must_get(&m->procedures, key); - if (!ignore_body && p->func != nullptr) { - return nullptr; - } - } - } - - if (p == nullptr) { - p = gb_alloc_item(permanent_allocator(), cgProcedure); - } - - p->module = m; - p->entity = entity; - p->name = link_name; - - DeclInfo *decl = entity->decl_info; - - ast_node(pl, ProcLit, decl->proc_lit); - Type *pt = base_type(entity->type); - GB_ASSERT(pt->kind == Type_Proc); - - p->type = entity->type; - p->type_expr = decl->type_expr; - p->body = pl->body; - p->inlining = pl->inlining; - p->is_foreign = entity->Procedure.is_foreign; - p->is_export = entity->Procedure.is_export; - p->is_entry_point = false; - - gbAllocator a = heap_allocator(); - p->children.allocator = a; - // p->defer_stmts.allocator = a; - // p->blocks.allocator = a; - // p->branch_blocks.allocator = a; - // p->context_stack.allocator = a; - // p->scope_stack.allocator = a; - // map_init(&p->tuple_fix_map, 0); - - TB_Linkage linkage = TB_LINKAGE_PRIVATE; - if (p->is_export) { - linkage = TB_LINKAGE_PUBLIC; - } else if (p->is_foreign || ignore_body) { - if (ignore_body) { - linkage = TB_LINKAGE_PUBLIC; - } - p->symbol = cast(TB_Symbol *)tb_extern_create(m->mod, link_name.len, cast(char const *)link_name.text, TB_EXTERNAL_SO_LOCAL); - } - - if (p->symbol == nullptr) { - p->func = tb_function_create(m->mod, link_name.len, cast(char const *)link_name.text, linkage, TB_COMDAT_NONE); - tb_function_set_prototype(p->func, cg_procedure_type_as_prototype(m, p->type), tb_default_arena()); - p->symbol = cast(TB_Symbol *)p->func; - } - - cgValue proc_value = cg_value(p->symbol, p->type); - cg_add_entity(m, entity, proc_value); - cg_add_member(m, p->name, proc_value); - cg_add_procedure_value(m, p); - - - return p; -} - -gb_internal cgProcedure *cg_procedure_create_dummy(cgModule *m, String const &link_name, Type *type) { - auto *prev_found = string_map_get(&m->members, link_name); - GB_ASSERT_MSG(prev_found == nullptr, "failed to create dummy procedure for: %.*s", LIT(link_name)); - - cgProcedure *p = gb_alloc_item(permanent_allocator(), cgProcedure); - - p->module = m; - p->name = link_name; - - p->type = type; - p->type_expr = nullptr; - p->body = nullptr; - p->tags = 0; - p->inlining = ProcInlining_none; - p->is_foreign = false; - p->is_export = false; - p->is_entry_point = false; - - gbAllocator a = heap_allocator(); - p->children.allocator = a; - // p->defer_stmts.allocator = a; - // p->blocks.allocator = a; - // p->branch_blocks.allocator = a; - // p->context_stack.allocator = a; - // map_init(&p->tuple_fix_map, 0); - - - TB_Linkage linkage = TB_LINKAGE_PRIVATE; - - p->func = tb_function_create(m->mod, link_name.len, cast(char const *)link_name.text, linkage, TB_COMDAT_NONE); - tb_function_set_prototype(p->func, cg_procedure_type_as_prototype(m, p->type), tb_default_arena()); - p->symbol = cast(TB_Symbol *)p->func; - - cgValue proc_value = cg_value(p->symbol, p->type); - cg_add_member(m, p->name, proc_value); - cg_add_procedure_value(m, p); - - return p; -} - -gb_internal void cg_procedure_begin(cgProcedure *p) { - if (p == nullptr || p->func == nullptr) { - return; - } -} - -gb_internal void cg_procedure_end(cgProcedure *p) { - if (p == nullptr || p->func == nullptr) { - return; - } - tb_inst_ret(p->func, 0, nullptr); - if (p->name == "main") { - TB_Arena *arena = tb_default_arena(); - defer (arena->free(arena)); - TB_FuncOpt *opt = tb_funcopt_enter(p->func, arena); - defer (tb_funcopt_exit(opt)); - tb_funcopt_print(opt); - } - tb_module_compile_function(p->module->mod, p->func, TB_ISEL_FAST); -} - -gb_internal void cg_procedure_generate(cgProcedure *p) { - if (p->body == nullptr) { - return; - } - cg_procedure_begin(p); - defer (cg_procedure_end(p)); - - if (p->name != "bug.main" && - p->name != "main") { - return; - } - cg_build_stmt(p, p->body); -} - - #include "tilde_const.cpp" #include "tilde_expr.cpp" #include "tilde_proc.cpp" diff --git a/src/tilde_backend.hpp b/src/tilde_backend.hpp index 6c17f8ba3..1f7300d73 100644 --- a/src/tilde_backend.hpp +++ b/src/tilde_backend.hpp @@ -113,7 +113,11 @@ enum cgDeferExitKind { cgDeferExit_Branch, }; - +struct cgContextData { + cgAddr ctx; + isize scope_index; + isize uses; +}; struct cgProcedure { u32 flags; @@ -144,6 +148,12 @@ struct cgProcedure { cgTargetList * target_list; Array branch_blocks; + + Scope *curr_scope; + i32 scope_index; + + Array scope_stack; + Array context_stack; }; @@ -214,4 +224,6 @@ gb_internal cgAddr cg_add_local(cgProcedure *p, Type *type, Entity *e, bool zero gb_internal cgValue cg_build_call_expr(cgProcedure *p, Ast *expr); -gb_internal cgValue cg_find_procedure_value_from_entity(cgModule *m, Entity *e); \ No newline at end of file +gb_internal cgValue cg_find_procedure_value_from_entity(cgModule *m, Entity *e); + +gb_internal TB_DebugType *cg_debug_type(cgModule *m, Type *type); \ No newline at end of file diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp index 702cb42ad..22da43cbd 100644 --- a/src/tilde_expr.cpp +++ b/src/tilde_expr.cpp @@ -1,3 +1,89 @@ +gb_internal cgContextData *cg_push_context_onto_stack(cgProcedure *p, cgAddr ctx) { + ctx.kind = cgAddr_Context; + cgContextData *cd = array_add_and_get(&p->context_stack); + cd->ctx = ctx; + cd->scope_index = p->scope_index; + return cd; +} + +gb_internal cgAddr cg_find_or_generate_context_ptr(cgProcedure *p) { + if (p->context_stack.count > 0) { + return p->context_stack[p->context_stack.count-1].ctx; + } + + Type *pt = base_type(p->type); + GB_ASSERT(pt->kind == Type_Proc); + GB_ASSERT(pt->Proc.calling_convention != ProcCC_Odin); + + cgAddr c = cg_add_local(p, t_context, nullptr, true); + tb_node_append_attrib(c.addr.node, tb_function_attrib_variable(p->func, -1, "context", cg_debug_type(p->module, t_context))); + c.kind = cgAddr_Context; + // lb_emit_init_context(p, c); + cg_push_context_onto_stack(p, c); + // lb_add_debug_context_variable(p, c); + + return c; +} + +gb_internal cgValue cg_find_value_from_entity(cgModule *m, Entity *e) { + e = strip_entity_wrapping(e); + GB_ASSERT(e != nullptr); + + GB_ASSERT(e->token.string != "_"); + + if (e->kind == Entity_Procedure) { + return cg_find_procedure_value_from_entity(m, e); + } + + cgValue *found = nullptr; + rw_mutex_shared_lock(&m->values_mutex); + found = map_get(&m->values, e); + rw_mutex_shared_unlock(&m->values_mutex); + if (found) { + return *found; + } + + // GB_PANIC("\n\tError in: %s, missing value '%.*s'\n", token_pos_to_string(e->token.pos), LIT(e->token.string)); + return {}; +} + +gb_internal cgAddr cg_build_addr_from_entity(cgProcedure *p, Entity *e, Ast *expr) { + GB_ASSERT(e != nullptr); + if (e->kind == Entity_Constant) { + Type *t = default_type(type_of_expr(expr)); + cgValue v = cg_const_value(p, t, e->Constant.value); + GB_PANIC("TODO(bill): cg_add_global_generated"); + // return cg_add_global_generated(p->module, t, v); + return {}; + } + + + cgValue v = {}; + + cgModule *m = p->module; + + rw_mutex_lock(&m->values_mutex); + cgValue *found = map_get(&m->values, e); + rw_mutex_unlock(&m->values_mutex); + if (found) { + v = *found; + } else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) { + GB_PANIC("TODO(bill): cg_get_using_variable"); + // NOTE(bill): Calculate the using variable every time + // v = cg_get_using_variable(p, e); + } else if (e->flags & EntityFlag_SoaPtrField) { + GB_PANIC("TODO(bill): cg_get_soa_variable_addr"); + // return cg_get_soa_variable_addr(p, e); + } + + + if (v.node == nullptr) { + return cg_addr(cg_find_value_from_entity(m, e)); + } + + return cg_addr(v); +} + gb_internal cgValue cg_typeid(cgModule *m, Type *t) { GB_ASSERT("TODO(bill): cg_typeid"); return {}; @@ -248,6 +334,65 @@ gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr) { } +gb_internal cgAddr cg_build_addr_internal(cgProcedure *p, Ast *expr); gb_internal cgAddr cg_build_addr(cgProcedure *p, Ast *expr) { - return {}; + expr = unparen_expr(expr); + + // IMPORTANT NOTE(bill): + // Selector Call Expressions (foo->bar(...)) + // must only evaluate `foo` once as it gets transformed into + // `foo.bar(foo, ...)` + // And if `foo` is a procedure call or something more complex, storing the value + // once is a very good idea + // If a stored value is found, it must be removed from the cache + if (expr->state_flags & StateFlag_SelectorCallExpr) { + // lbAddr *pp = map_get(&p->selector_addr, expr); + // if (pp != nullptr) { + // lbAddr res = *pp; + // map_remove(&p->selector_addr, expr); + // return res; + // } + } + cgAddr addr = cg_build_addr_internal(p, expr); + if (expr->state_flags & StateFlag_SelectorCallExpr) { + // map_set(&p->selector_addr, expr, addr); + } + return addr; } + + +gb_internal cgAddr cg_build_addr_internal(cgProcedure *p, Ast *expr) { + switch (expr->kind) { + case_ast_node(i, Implicit, expr); + cgAddr v = {}; + switch (i->kind) { + case Token_context: + v = cg_find_or_generate_context_ptr(p); + break; + } + + GB_ASSERT(v.addr.node != nullptr); + return v; + case_end; + + case_ast_node(i, Ident, expr); + if (is_blank_ident(expr)) { + cgAddr val = {}; + return val; + } + String name = i->token.string; + Entity *e = entity_of_node(expr); + return cg_build_addr_from_entity(p, e, expr); + case_end; + } + + TokenPos token_pos = ast_token(expr).pos; + GB_PANIC("Unexpected address expression\n" + "\tAst: %.*s @ " + "%s\n", + LIT(ast_strings[expr->kind]), + token_pos_to_string(token_pos)); + + + return {}; +} \ No newline at end of file diff --git a/src/tilde_proc.cpp b/src/tilde_proc.cpp index dbebae853..b60e797c3 100644 --- a/src/tilde_proc.cpp +++ b/src/tilde_proc.cpp @@ -1,3 +1,293 @@ +gb_internal TB_FunctionPrototype *cg_procedure_type_as_prototype(cgModule *m, Type *type) { + GB_ASSERT(type != nullptr); + type = base_type(type); + GB_ASSERT(type->kind == Type_Proc); + TypeProc *pt = &type->Proc; + + auto params = array_make(heap_allocator(), 0, pt->param_count); + if (pt->params) for (Entity *e : pt->params->Tuple.variables) { + TB_PrototypeParam param = {}; + + Type *t = core_type(e->type); + i64 sz = type_size_of(t); + switch (t->kind) { + case Type_Basic: + switch (t->Basic.kind) { + case Basic_bool: + case Basic_b8: + case Basic_b16: + case Basic_b32: + case Basic_b64: + case Basic_i8: + case Basic_u8: + case Basic_i16: + case Basic_u16: + case Basic_i32: + case Basic_u32: + case Basic_i64: + case Basic_u64: + case Basic_i128: + case Basic_u128: + case Basic_rune: + case Basic_int: + case Basic_uint: + case Basic_uintptr: + param.dt = TB_TYPE_INTN(cast(u16)(8*sz)); + break; + + case Basic_f16: param.dt = TB_TYPE_I16; break; + case Basic_f32: param.dt = TB_TYPE_F32; break; + case Basic_f64: param.dt = TB_TYPE_F64; break; + + case Basic_complex32: + case Basic_complex64: + case Basic_complex128: + case Basic_quaternion64: + case Basic_quaternion128: + case Basic_quaternion256: + param.dt = TB_TYPE_PTR; + break; + + + case Basic_rawptr: + param.dt = TB_TYPE_PTR; + break; + case Basic_string: // ^u8 + int + param.dt = TB_TYPE_PTR; + break; + case Basic_cstring: // ^u8 + param.dt = TB_TYPE_PTR; + break; + case Basic_any: // rawptr + ^Type_Info + param.dt = TB_TYPE_PTR; + break; + + case Basic_typeid: + param.dt = TB_TYPE_INTN(cast(u16)(8*sz)); + break; + + // Endian Specific Types + case Basic_i16le: + case Basic_u16le: + case Basic_i32le: + case Basic_u32le: + case Basic_i64le: + case Basic_u64le: + case Basic_i128le: + case Basic_u128le: + case Basic_i16be: + case Basic_u16be: + case Basic_i32be: + case Basic_u32be: + case Basic_i64be: + case Basic_u64be: + case Basic_i128be: + case Basic_u128be: + param.dt = TB_TYPE_INTN(cast(u16)(8*sz)); + break; + + case Basic_f16le: param.dt = TB_TYPE_I16; break; + case Basic_f32le: param.dt = TB_TYPE_F32; break; + case Basic_f64le: param.dt = TB_TYPE_F64; break; + + case Basic_f16be: param.dt = TB_TYPE_I16; break; + case Basic_f32be: param.dt = TB_TYPE_F32; break; + case Basic_f64be: param.dt = TB_TYPE_F64; break; + } + + case Type_Pointer: + case Type_MultiPointer: + case Type_Proc: + param.dt = TB_TYPE_PTR; + break; + + default: + switch (sz) { + case 1: param.dt = TB_TYPE_I8; break; + case 2: param.dt = TB_TYPE_I16; break; + case 4: param.dt = TB_TYPE_I32; break; + case 8: param.dt = TB_TYPE_I64; break; + default: + param.dt = TB_TYPE_PTR; + break; + } + } + + if (param.dt.width != 0) { + if (is_blank_ident(e->token)) { + param.name = alloc_cstring(temporary_allocator(), e->token.string); + } + array_add(¶ms, param); + } + } + + auto results = array_make(heap_allocator(), 0, pt->result_count); + // if (pt->results) for (Entity *e : pt->params->Tuple.variables) { + // // TODO(bill): + // } + + + return tb_prototype_create(m->mod, TB_CDECL, params.count, params.data, results.count, results.data, pt->c_vararg); +} + +gb_internal cgProcedure *cg_procedure_create(cgModule *m, Entity *entity, bool ignore_body=false) { + GB_ASSERT(entity != nullptr); + GB_ASSERT(entity->kind == Entity_Procedure); + if (!entity->Procedure.is_foreign) { + if ((entity->flags & EntityFlag_ProcBodyChecked) == 0) { + GB_PANIC("%.*s :: %s (was parapoly: %d %d)", LIT(entity->token.string), type_to_string(entity->type), is_type_polymorphic(entity->type, true), is_type_polymorphic(entity->type, false)); + } + } + + String link_name = cg_get_entity_name(m, entity); + + cgProcedure *p = nullptr; + { + StringHashKey key = string_hash_string(link_name); + cgValue *found = string_map_get(&m->members, key); + if (found) { + cg_add_entity(m, entity, *found); + p = string_map_must_get(&m->procedures, key); + if (!ignore_body && p->func != nullptr) { + return nullptr; + } + } + } + + if (p == nullptr) { + p = gb_alloc_item(permanent_allocator(), cgProcedure); + } + + p->module = m; + p->entity = entity; + p->name = link_name; + + DeclInfo *decl = entity->decl_info; + + ast_node(pl, ProcLit, decl->proc_lit); + Type *pt = base_type(entity->type); + GB_ASSERT(pt->kind == Type_Proc); + + p->type = entity->type; + p->type_expr = decl->type_expr; + p->body = pl->body; + p->inlining = pl->inlining; + p->is_foreign = entity->Procedure.is_foreign; + p->is_export = entity->Procedure.is_export; + p->is_entry_point = false; + + gbAllocator a = heap_allocator(); + p->children.allocator = a; + // p->defer_stmts.allocator = a; + // p->blocks.allocator = a; + // p->branch_blocks.allocator = a; + p->context_stack.allocator = a; + p->scope_stack.allocator = a; + // map_init(&p->tuple_fix_map, 0); + + TB_Linkage linkage = TB_LINKAGE_PRIVATE; + if (p->is_export) { + linkage = TB_LINKAGE_PUBLIC; + } else if (p->is_foreign || ignore_body) { + if (ignore_body) { + linkage = TB_LINKAGE_PUBLIC; + } + p->symbol = cast(TB_Symbol *)tb_extern_create(m->mod, link_name.len, cast(char const *)link_name.text, TB_EXTERNAL_SO_LOCAL); + } + + if (p->symbol == nullptr) { + p->func = tb_function_create(m->mod, link_name.len, cast(char const *)link_name.text, linkage, TB_COMDAT_NONE); + tb_function_set_prototype(p->func, cg_procedure_type_as_prototype(m, p->type), tb_default_arena()); + p->symbol = cast(TB_Symbol *)p->func; + } + + cgValue proc_value = cg_value(p->symbol, p->type); + cg_add_entity(m, entity, proc_value); + cg_add_member(m, p->name, proc_value); + cg_add_procedure_value(m, p); + + + return p; +} + +gb_internal cgProcedure *cg_procedure_create_dummy(cgModule *m, String const &link_name, Type *type) { + auto *prev_found = string_map_get(&m->members, link_name); + GB_ASSERT_MSG(prev_found == nullptr, "failed to create dummy procedure for: %.*s", LIT(link_name)); + + cgProcedure *p = gb_alloc_item(permanent_allocator(), cgProcedure); + + p->module = m; + p->name = link_name; + + p->type = type; + p->type_expr = nullptr; + p->body = nullptr; + p->tags = 0; + p->inlining = ProcInlining_none; + p->is_foreign = false; + p->is_export = false; + p->is_entry_point = false; + + gbAllocator a = heap_allocator(); + p->children.allocator = a; + // p->defer_stmts.allocator = a; + // p->blocks.allocator = a; + // p->branch_blocks.allocator = a; + p->scope_stack.allocator = a; + p->context_stack.allocator = a; + // map_init(&p->tuple_fix_map, 0); + + + TB_Linkage linkage = TB_LINKAGE_PRIVATE; + + p->func = tb_function_create(m->mod, link_name.len, cast(char const *)link_name.text, linkage, TB_COMDAT_NONE); + tb_function_set_prototype(p->func, cg_procedure_type_as_prototype(m, p->type), tb_default_arena()); + p->symbol = cast(TB_Symbol *)p->func; + + cgValue proc_value = cg_value(p->symbol, p->type); + cg_add_member(m, p->name, proc_value); + cg_add_procedure_value(m, p); + + return p; +} + +gb_internal void cg_procedure_begin(cgProcedure *p) { + if (p == nullptr || p->func == nullptr) { + return; + } +} + +gb_internal void cg_procedure_end(cgProcedure *p) { + if (p == nullptr || p->func == nullptr) { + return; + } + tb_inst_ret(p->func, 0, nullptr); + if (p->name == "main") { + TB_Arena *arena = tb_default_arena(); + defer (arena->free(arena)); + TB_FuncOpt *opt = tb_funcopt_enter(p->func, arena); + defer (tb_funcopt_exit(opt)); + tb_funcopt_print(opt); + } + tb_module_compile_function(p->module->mod, p->func, TB_ISEL_FAST); +} + +gb_internal void cg_procedure_generate(cgProcedure *p) { + if (p->body == nullptr) { + return; + } + cg_procedure_begin(p); + defer (cg_procedure_end(p)); + + if (p->name != "bug.main" && + p->name != "main") { + return; + } + cg_build_stmt(p, p->body); +} + + + gb_internal cgValue cg_find_procedure_value_from_entity(cgModule *m, Entity *e) { GB_ASSERT(is_type_proc(e->type)); e = strip_entity_wrapping(e); diff --git a/src/tilde_stmt.cpp b/src/tilde_stmt.cpp index 07bfc0555..7c3dfcef8 100644 --- a/src/tilde_stmt.cpp +++ b/src/tilde_stmt.cpp @@ -549,7 +549,7 @@ gb_internal void cg_build_stmt(cgProcedure *p, Ast *node) { case_end; case_ast_node(as, AssignStmt, node); - // cg_build_assign_stmt(p, as); + cg_build_assign_stmt(p, as); case_end; case_ast_node(rs, ReturnStmt, node);