From cbf6ca84806337a19598d67b839c638d0349560e Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Thu, 29 Sep 2022 12:41:04 +0200 Subject: [PATCH] Restructuring --- core_compiler.cpp | 68 +++++++++- core_compiler.h | 69 +--------- core_main.cpp | 13 ++ core_typechecking.cpp | 297 +++++++++++++++++++++++++++++++++++++++++- core_typechecking.h | 297 +----------------------------------------- 5 files changed, 379 insertions(+), 365 deletions(-) diff --git a/core_compiler.cpp b/core_compiler.cpp index c48bfac..37dcfea 100644 --- a/core_compiler.cpp +++ b/core_compiler.cpp @@ -6,6 +6,72 @@ global F64 total_time; global F64 init_ctx_time_begin; global F64 init_ctx_time_end; +//----------------------------------------------------------------------------- +// Constructors +//----------------------------------------------------------------------------- +function void +lex_init(Allocator *token_string_arena, Allocator *map_allocator, Lexer *l){ + l->arena = token_string_arena; + l->tokens = array_make(token_string_arena, 1024*2); + l->interns= intern_table_make(token_string_arena, map_allocator, 1024); + + keyword_struct= l->intern("struct"_s); + keyword_union = l->intern("union"_s); + keyword_true = l->intern("true"_s); + keyword_default = l->intern("default"_s); + keyword_break = l->intern("break"_s); + keyword_false = l->intern("false"_s); + keyword_return = l->intern("return"_s); + keyword_switch = l->intern("switch"_s); + keyword_assert = l->intern("Assert"_s); + keyword_if = l->intern("if"_s); + keyword_elif = l->intern("elif"_s); + keyword_pass = l->intern("pass"_s); + keyword_else = l->intern("else"_s); + keyword_for = l->intern("for"_s); + keyword_enum = intern_string(&l->interns, "enum"_s); + l->interns.first_keyword = keyword_struct.str; + l->interns.last_keyword = keyword_enum.str; + + intern_sizeof = l->intern("SizeOf"_s); + intern_lengthof = l->intern("Length"_s); + intern_alignof = l->intern("AlignOf"_s); + intern_foreign = intern_string(&l->interns, "foreign"_s); + intern_strict = intern_string(&l->interns, "strict"_s); + intern_void = intern_string(&l->interns, "void"_s); + intern_flag = intern_string(&l->interns, "flag"_s); + intern_it = intern_string(&l->interns, "it"_s); +} + +function void +parse_init(Parse_Ctx *ctx, Allocator *perm_allocator, Allocator *heap_allocator){ + pctx = ctx; + ctx->perm = perm_allocator; + ctx->heap = heap_allocator; + ctx->gen = {ctx->heap}; + ctx->ordered_decls = {ctx->heap}; + ctx->type_map = {ctx->heap}; + ctx->modules = {ctx->heap}; + ctx->all_types = {ctx->heap}; + ctx->helper_builder= {ctx->heap}; + ctx->files = {ctx->heap}; + ctx->scope_ids = 1; + bigint_allocator = ctx->perm; + arena_init(&ctx->stage_arena, "Compiler stage arena"_s); + + lex_init(ctx->perm, ctx->heap, ctx); + init_type(); + + // Init paths + ctx->exe_folder = os_get_exe_dir(ctx->perm); + ctx->working_folder = os_get_working_dir(ctx->perm); + + ctx->module_folders = {ctx->heap}; + String main_module = string_fmt(ctx->perm, "%Q/modules", ctx->exe_folder); + ctx->module_folders.add(main_module); +} + + function void begin_compilation(){ init_ctx_time_begin = os_time(); @@ -155,8 +221,6 @@ resolve_everything_in_module(Ast_Module *module){ resolving_time_end = os_time(); } -function String compile_to_c_code(); - function String compile_file_to_string(String filename){ total_time = os_time(); diff --git a/core_compiler.h b/core_compiler.h index db2d65d..5df26b4 100644 --- a/core_compiler.h +++ b/core_compiler.h @@ -212,72 +212,9 @@ struct Parse_Ctx:Lexer{ String_Builder gen; String_Builder helper_builder; }; +thread_local Parse_Ctx *pctx; global B32 emit_line_directives; function void init_type(); - -//----------------------------------------------------------------------------- -// Constructors -//----------------------------------------------------------------------------- -thread_local Parse_Ctx *pctx; -function void -lex_init(Allocator *token_string_arena, Allocator *map_allocator, Lexer *l){ - l->arena = token_string_arena; - l->tokens = array_make(token_string_arena, 1024*2); - l->interns= intern_table_make(token_string_arena, map_allocator, 1024); - - keyword_struct= l->intern("struct"_s); - keyword_union = l->intern("union"_s); - keyword_true = l->intern("true"_s); - keyword_default = l->intern("default"_s); - keyword_break = l->intern("break"_s); - keyword_false = l->intern("false"_s); - keyword_return = l->intern("return"_s); - keyword_switch = l->intern("switch"_s); - keyword_assert = l->intern("Assert"_s); - keyword_if = l->intern("if"_s); - keyword_elif = l->intern("elif"_s); - keyword_pass = l->intern("pass"_s); - keyword_else = l->intern("else"_s); - keyword_for = l->intern("for"_s); - keyword_enum = intern_string(&l->interns, "enum"_s); - l->interns.first_keyword = keyword_struct.str; - l->interns.last_keyword = keyword_enum.str; - - intern_sizeof = l->intern("SizeOf"_s); - intern_lengthof = l->intern("Length"_s); - intern_alignof = l->intern("AlignOf"_s); - intern_foreign = intern_string(&l->interns, "foreign"_s); - intern_strict = intern_string(&l->interns, "strict"_s); - intern_void = intern_string(&l->interns, "void"_s); - intern_flag = intern_string(&l->interns, "flag"_s); - intern_it = intern_string(&l->interns, "it"_s); -} - -function void -parse_init(Parse_Ctx *ctx, Allocator *perm_allocator, Allocator *heap_allocator){ - pctx = ctx; - ctx->perm = perm_allocator; - ctx->heap = heap_allocator; - ctx->gen = {ctx->heap}; - ctx->ordered_decls = {ctx->heap}; - ctx->type_map = {ctx->heap}; - ctx->modules = {ctx->heap}; - ctx->all_types = {ctx->heap}; - ctx->helper_builder= {ctx->heap}; - ctx->files = {ctx->heap}; - ctx->scope_ids = 1; - bigint_allocator = ctx->perm; - arena_init(&ctx->stage_arena, "Compiler stage arena"_s); - - lex_init(ctx->perm, ctx->heap, ctx); - init_type(); - - // Init paths - ctx->exe_folder = os_get_exe_dir(ctx->perm); - ctx->working_folder = os_get_working_dir(ctx->perm); - - ctx->module_folders = {ctx->heap}; - String main_module = string_fmt(ctx->perm, "%Q/modules", ctx->exe_folder); - ctx->module_folders.add(main_module); -} +function void lex_init(Allocator *token_string_arena, Allocator *map_allocator, Lexer *l); +function String compile_to_c_code(); \ No newline at end of file diff --git a/core_main.cpp b/core_main.cpp index 2544c80..8c3f4bb 100644 --- a/core_main.cpp +++ b/core_main.cpp @@ -42,6 +42,19 @@ Maybe later ------------------------------------------------------------------------------- +2022.09.29 - Function overloads, operator overloads, namespaces idea + +I thought about adding function overloading but I'm not sure if that's +actually good. It seems pretty hard to implement and there are many problems +with it. It's probably better to implement descent namespacing mechanism. + +Currently I'm thinking of something like this: operator overloads are this special +additional thing. They can be overloaded cause they are handled differently. +You are not looking up names, you are looking into an array of operators +during resolution of binary expressions etc. It shouldn't complicate things, hopefully. + +------------------------------------------------------------------------------- + 2022.05.28 - On lambda expressions I think it's not wise to add the multiline lambda expressions As is the case with python it would require new alternative syntax. diff --git a/core_typechecking.cpp b/core_typechecking.cpp index 7b74272..eb19e49 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -1,6 +1,297 @@ -#define CASE(kind,type) case AST_##kind: { Ast_##type *node = (Ast_##type *)ast; -#define BREAK() } break -function String gen_string_simple_decl(Allocator *a, Ast_Type *ast, String name = {}, Ast_Scope *scope = 0, bool scope_names = true); + +function Resolve_Flag +inherit_flag(Resolve_Flag flag, B32 ast_can_be_null){ + unset_flag(flag, AST_CAN_BE_NULL); + set_flag(flag, ast_can_be_null); + return flag; +} + +//----------------------------------------------------------------------------- +// Operands +//----------------------------------------------------------------------------- +function Operand +operand(Ast_Decl *decl){ + Operand result = {}; + result.type = decl->type; + result.is_const = decl->kind != AST_VAR ? true : false; + result.is_lvalue= decl->kind == AST_CONST ? false : true; // Cant assign to const values + result.value = decl->value; + result.resolved_decl = decl; + if(decl->kind == AST_LAMBDA){ + result.is_const = false; + } + return result; +} + +function Operand +operand_type(Ast_Type *type){ + Operand result = {}; + result.type = type_type; + result.is_const = true; + result.is_lvalue = false; + result.type_val = type; + return result; +} + +function Operand +operand_int(BigInt big_int){ + Operand result = {}; + result.type = untyped_int; + result.big_int_val = bigint_copy(pctx->perm, &big_int); + result.is_const = true; + result.is_lvalue = false; + return result; +} + +function Operand +operand_str(Intern_String intern_val){ + Operand result = {}; + result.type = type_string; + result.intern_val = intern_val; + result.is_const = true; + result.is_lvalue = false; + return result; +} + +function Operand +operand_lambda(Ast_Type *type){ + Operand result = {}; + result.type = type; + result.is_const = true; + result.is_lvalue = false; + return result; +} + +function Operand +operand_const_rvalue(Value value){ + Operand result = {}; + result.is_const = true; + result.value = value; + return result; +} + +function Operand +operand_lvalue(Ast_Type *type){ + Operand result = {}; + result.type = type; + result.is_const = false; + result.is_lvalue = true; + return result; +} + +function Operand +operand_rvalue(Ast_Type *type){ + Operand result = {}; + result.type = type; + result.is_const = false; + result.is_lvalue = false; + return result; +} + +//----------------------------------------------------------------------------- +// Hash consed types +//----------------------------------------------------------------------------- +function Ast_Type * +type_new(Allocator *allocator, Ast_Type_Kind kind, SizeU size, SizeU align){ + Ast_Type *result = exp_alloc_type(allocator, Ast_Type, AF_ZeroMemory); + result->kind = kind; + result->size = size; + result->align = align; + result->type_id = pctx->type_ids++; + pctx->all_types.add(result); + return result; +} + +function Ast_Type * +type_copy(Allocator *a, Ast_Type *type){ + // @warning: This changes type id !!!! + Ast_Type *result = exp_alloc_type(a, Ast_Type); + memory_copy(result, type, sizeof(Ast_Type)); + result->type_id = pctx->type_ids++; + pctx->all_types.add(result); + return result; +} + +function Ast_Type * +type_pointer(Ast_Type *base){ + Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, (void *)base); + if(!result){ + result = type_new(pctx->perm, TYPE_POINTER, pointer_size, pointer_align); + result->base = base; + result->is_unsigned = true; + map_insert(&pctx->type_map, base, result); + } + assert(result->kind == TYPE_POINTER); + return result; +} + +function Ast_Type * +type_slice(Ast_Type *base, Ast *ast){ + U64 hash_base = hash_ptr(base); + U64 hash = hash_mix(hash_base, hash_u64(ARRAY_SIZE_SLICE)); + Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash); + if(result){ + assert(result->kind == TYPE_SLICE); + assert(result->arr.base == base); + return result; + } + + struct Slice{void *p; S64 len;}; + result = type_new(pctx->perm, TYPE_SLICE, sizeof(Slice), alignof(Slice)); + result->arr.base = base; + result->arr.slice_hash = hash; + result->ast = ast; + map_insert(&pctx->type_map, hash, result); + return result; +} + +function Ast_Type * +type_try_tupling(Array types, Ast *ast){ + if(types.len == 0) return type_void; + if(types.len == 1) return types[0]; + + U64 hash = 13; + For(types) hash = hash_mix(hash, hash_ptr(it)); + Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash); + if(result){ + assert(result->kind == TYPE_TUPLE); + assert(result->agg.members.len == types.len); + assert(result->agg.members.len > 1); + return result; + } + + // @todo alignment, offsets + result = type_new(pctx->perm, TYPE_TUPLE, 0, pointer_align); + result->agg.members = array_make(pctx->perm, types.len); + For(types){ + Ast_Resolved_Member m = {}; + m.type = it; + m.offset = 0; // @todo + result->size += it->size; + result->agg.members.add(m); + } + map_insert(&pctx->type_map, hash, result); + assert(result->agg.members.len > 1); + + return result; +} + +function Ast_Type * +type_array(Ast_Type *base, S64 size){ + U64 hash_base = hash_ptr(base); + U64 hash = hash_mix(hash_base, hash_u64(size)); + Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash); + if(result){ + assert(result->kind == TYPE_ARRAY); + assert(result->arr.size == size); + assert(result->arr.base == base); + return result; + } + + result = type_new(pctx->perm, TYPE_ARRAY, size*base->size, pointer_align); + result->arr.base = base; + result->arr.size = size; + result->arr.slice_hash = hash_mix(hash_base, hash_u64(ARRAY_SIZE_SLICE)); + map_insert(&pctx->type_map, hash, result); + return result; +} + +function Ast_Type * +type_lambda(Ast *ast, Array return_vals, Array args){ + Ast_Type *ret = type_try_tupling(return_vals, ast); + U64 hash_without_ret = 13; // @function_overloading scrap this if we changed course + For(args) hash_without_ret = hash_mix(hash_without_ret, hash_ptr(it)); + U64 hash = hash_mix(hash_ptr(ret), hash_without_ret); + Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash); + + if(result){ + assert(result->kind == TYPE_LAMBDA); + assert(result->func.args.len == args.len); + return result; + } + + result = type_new(pctx->perm, TYPE_LAMBDA, pointer_size, pointer_align); + result->ast = ast; + result->func.ret = ret; + result->func.args = args.tight_copy(pctx->perm); + result->func.hash_without_ret = hash_without_ret; // @function_overloading scrap this if we changed course + map_insert(&pctx->type_map, hash, result); + + return result; +} + + +function Ast_Type * +type_enum(Ast_Decl *ast, Ast_Type *type){ + if(!type){ + type = type_s64; + } + + Ast_Type *result = type_new(pctx->perm, TYPE_ENUM, type->size, type->align); + result->base = type; + result->ast = ast; + return result; +} + +function Ast_Type * +type_incomplete(Ast *ast){ + Ast_Type *result = type_new(pctx->perm, TYPE_INCOMPLETE, 0, 0); + result->ast = ast; + return result; +} + +function void type_complete(Ast_Type *type); +function void +type_struct_complete(Ast_Type *type, Ast_Decl *node){ + assert(node->kind == AST_STRUCT); + // @todo: compute size, alignement, offset !!! + // @note: resolve all the struct members first + Scratch scratch; + Array members = {scratch}; + type->kind = TYPE_COMPLETING; + size_t members_size = 0; + For(node->scope->decls){ + resolve_decl(it); + assert(it->type->kind != TYPE_INCOMPLETE); + assert(is_pow2(it->type->align)); + + Ast_Resolved_Member m = {}; + m.offset = type->size; + members_size += it->type->size; + type->align = max(type->align, it->type->align); + type->size = it->type->size + align_up(type->size, it->type->align); + + m.name = it->name; + m.value = it->value; + members.add(m); + } + type->size = align_up(type->size, type->align); + type->padding = type->size - members_size; + type->agg.members = members.tight_copy(pctx->perm); + type->kind = TYPE_STRUCT; +} + +function void +type_complete(Ast_Type *type){ + if(!type) { + return; + } + if(type->kind == TYPE_COMPLETING){ + compiler_error(type->ast->pos, "Cyclic type dependency"); + } + else if(type->kind != TYPE_INCOMPLETE){ + return; + } + + type_struct_complete(type, (Ast_Decl *)type->ast); + pctx->ordered_decls.add((Ast_Decl *)type->ast); +} + +function void +init_type(){ + type_pointer_to_char = type_pointer(type_char); + type_pointer_to_void = type_pointer(type_void); +} function void typename_base(String_Builder *sb, Ast_Type *type){ diff --git a/core_typechecking.h b/core_typechecking.h index 17147af..6e14f69 100644 --- a/core_typechecking.h +++ b/core_typechecking.h @@ -23,297 +23,6 @@ enum{ function Operand resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context = 0); function void resolve_decl(Ast_Decl *ast); function Ast_Decl *resolve_name(Ast_Scope *parent_scope, Token *pos, Intern_String name, Search_Flag search_flags = 0); - -function Resolve_Flag -inherit_flag(Resolve_Flag flag, B32 ast_can_be_null){ - unset_flag(flag, AST_CAN_BE_NULL); - set_flag(flag, ast_can_be_null); - return flag; -} - -//----------------------------------------------------------------------------- -// Operands -//----------------------------------------------------------------------------- -function Operand -operand(Ast_Decl *decl){ - Operand result = {}; - result.type = decl->type; - result.is_const = decl->kind != AST_VAR ? true : false; - result.is_lvalue= decl->kind == AST_CONST ? false : true; // Cant assign to const values - result.value = decl->value; - result.resolved_decl = decl; - if(decl->kind == AST_LAMBDA){ - result.is_const = false; - } - return result; -} - -function Operand -operand_type(Ast_Type *type){ - Operand result = {}; - result.type = type_type; - result.is_const = true; - result.is_lvalue = false; - result.type_val = type; - return result; -} - -function Operand -operand_int(BigInt big_int){ - Operand result = {}; - result.type = untyped_int; - result.big_int_val = bigint_copy(pctx->perm, &big_int); - result.is_const = true; - result.is_lvalue = false; - return result; -} - -function Operand -operand_str(Intern_String intern_val){ - Operand result = {}; - result.type = type_string; - result.intern_val = intern_val; - result.is_const = true; - result.is_lvalue = false; - return result; -} - -function Operand -operand_lambda(Ast_Type *type){ - Operand result = {}; - result.type = type; - result.is_const = true; - result.is_lvalue = false; - return result; -} - -function Operand -operand_const_rvalue(Value value){ - Operand result = {}; - result.is_const = true; - result.value = value; - return result; -} - -function Operand -operand_lvalue(Ast_Type *type){ - Operand result = {}; - result.type = type; - result.is_const = false; - result.is_lvalue = true; - return result; -} - -function Operand -operand_rvalue(Ast_Type *type){ - Operand result = {}; - result.type = type; - result.is_const = false; - result.is_lvalue = false; - return result; -} - -//----------------------------------------------------------------------------- -// Hash consed types -//----------------------------------------------------------------------------- -function Ast_Type * -type_new(Allocator *allocator, Ast_Type_Kind kind, SizeU size, SizeU align){ - Ast_Type *result = exp_alloc_type(allocator, Ast_Type, AF_ZeroMemory); - result->kind = kind; - result->size = size; - result->align = align; - result->type_id = pctx->type_ids++; - pctx->all_types.add(result); - return result; -} - -function Ast_Type * -type_copy(Allocator *a, Ast_Type *type){ - // @warning: This changes type id !!!! - Ast_Type *result = exp_alloc_type(a, Ast_Type); - memory_copy(result, type, sizeof(Ast_Type)); - result->type_id = pctx->type_ids++; - pctx->all_types.add(result); - return result; -} - -function Ast_Type * -type_pointer(Ast_Type *base){ - Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, (void *)base); - if(!result){ - result = type_new(pctx->perm, TYPE_POINTER, pointer_size, pointer_align); - result->base = base; - result->is_unsigned = true; - map_insert(&pctx->type_map, base, result); - } - assert(result->kind == TYPE_POINTER); - return result; -} - -function Ast_Type * -type_slice(Ast_Type *base, Ast *ast){ - U64 hash_base = hash_ptr(base); - U64 hash = hash_mix(hash_base, hash_u64(ARRAY_SIZE_SLICE)); - Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash); - if(result){ - assert(result->kind == TYPE_SLICE); - assert(result->arr.base == base); - return result; - } - - struct Slice{void *p; S64 len;}; - result = type_new(pctx->perm, TYPE_SLICE, sizeof(Slice), alignof(Slice)); - result->arr.base = base; - result->arr.slice_hash = hash; - result->ast = ast; - map_insert(&pctx->type_map, hash, result); - return result; -} - -function Ast_Type * -type_try_tupling(Array types, Ast *ast){ - if(types.len == 0) return type_void; - if(types.len == 1) return types[0]; - - U64 hash = 13; - For(types) hash = hash_mix(hash, hash_ptr(it)); - Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash); - if(result){ - assert(result->kind == TYPE_TUPLE); - assert(result->agg.members.len == types.len); - assert(result->agg.members.len > 1); - return result; - } - - // @todo alignment, offsets - result = type_new(pctx->perm, TYPE_TUPLE, 0, pointer_align); - result->agg.members = array_make(pctx->perm, types.len); - For(types){ - Ast_Resolved_Member m = {}; - m.type = it; - m.offset = 0; // @todo - result->size += it->size; - result->agg.members.add(m); - } - map_insert(&pctx->type_map, hash, result); - assert(result->agg.members.len > 1); - - return result; -} - -function Ast_Type * -type_array(Ast_Type *base, S64 size){ - U64 hash_base = hash_ptr(base); - U64 hash = hash_mix(hash_base, hash_u64(size)); - Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash); - if(result){ - assert(result->kind == TYPE_ARRAY); - assert(result->arr.size == size); - assert(result->arr.base == base); - return result; - } - - result = type_new(pctx->perm, TYPE_ARRAY, size*base->size, pointer_align); - result->arr.base = base; - result->arr.size = size; - result->arr.slice_hash = hash_mix(hash_base, hash_u64(ARRAY_SIZE_SLICE)); - map_insert(&pctx->type_map, hash, result); - return result; -} - -function Ast_Type * -type_lambda(Ast *ast, Array return_vals, Array args){ - Ast_Type *ret = type_try_tupling(return_vals, ast); - U64 hash_without_ret = 13; // @function_overloading scrap this if we changed course - For(args) hash_without_ret = hash_mix(hash_without_ret, hash_ptr(it)); - U64 hash = hash_mix(hash_ptr(ret), hash_without_ret); - Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash); - - if(result){ - assert(result->kind == TYPE_LAMBDA); - assert(result->func.args.len == args.len); - return result; - } - - result = type_new(pctx->perm, TYPE_LAMBDA, pointer_size, pointer_align); - result->ast = ast; - result->func.ret = ret; - result->func.args = args.tight_copy(pctx->perm); - result->func.hash_without_ret = hash_without_ret; // @function_overloading scrap this if we changed course - map_insert(&pctx->type_map, hash, result); - - return result; -} - - -function Ast_Type * -type_enum(Ast_Decl *ast, Ast_Type *type){ - if(!type){ - type = type_s64; - } - - Ast_Type *result = type_new(pctx->perm, TYPE_ENUM, type->size, type->align); - result->base = type; - result->ast = ast; - return result; -} - -function Ast_Type * -type_incomplete(Ast *ast){ - Ast_Type *result = type_new(pctx->perm, TYPE_INCOMPLETE, 0, 0); - result->ast = ast; - return result; -} - -function void type_complete(Ast_Type *type); -function void -type_struct_complete(Ast_Type *type, Ast_Decl *node){ - assert(node->kind == AST_STRUCT); - // @todo: compute size, alignement, offset !!! - // @note: resolve all the struct members first - Scratch scratch; - Array members = {scratch}; - type->kind = TYPE_COMPLETING; - size_t members_size = 0; - For(node->scope->decls){ - resolve_decl(it); - assert(it->type->kind != TYPE_INCOMPLETE); - assert(is_pow2(it->type->align)); - - Ast_Resolved_Member m = {}; - m.offset = type->size; - members_size += it->type->size; - type->align = max(type->align, it->type->align); - type->size = it->type->size + align_up(type->size, it->type->align); - - m.name = it->name; - m.value = it->value; - members.add(m); - } - type->size = align_up(type->size, type->align); - type->padding = type->size - members_size; - type->agg.members = members.tight_copy(pctx->perm); - type->kind = TYPE_STRUCT; -} - -function void -type_complete(Ast_Type *type){ - if(!type) { - return; - } - if(type->kind == TYPE_COMPLETING){ - compiler_error(type->ast->pos, "Cyclic type dependency"); - } - else if(type->kind != TYPE_INCOMPLETE){ - return; - } - - type_struct_complete(type, (Ast_Decl *)type->ast); - pctx->ordered_decls.add((Ast_Decl *)type->ast); -} - -function void -init_type(){ - type_pointer_to_char = type_pointer(type_char); - type_pointer_to_void = type_pointer(type_void); -} \ No newline at end of file +function String gen_string_simple_decl(Allocator *a, Ast_Type *ast, String name = {}, Ast_Scope *scope = 0, bool scope_names = true); +#define CASE(kind,type) case AST_##kind: { Ast_##type *node = (Ast_##type *)ast; +#define BREAK() } break