diff --git a/ccodegen.cpp b/ccodegen.cpp index 95886e2..4b7e47c 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -680,10 +680,13 @@ parse_all_modules(){ function Ast_Module * add_module(Intern_String filename){ For(pctx->modules){ - if(it->name == filename) + if(it->name == filename){ + log_info("Returning registered module: %Q\n", filename); return it; + } } + log_info("Adding module: %Q\n", filename); Ast_Module *result = ast_module(filename); register_ast_file(result->name, result, true); pctx->modules.add(result); @@ -722,7 +725,7 @@ begin_compilation(){ global F64 generating_time_begin; global F64 generating_time_end; function String -end_compilation(){ +get_compilation_result(){ generating_time_begin = os_time(); #if 1 @@ -806,7 +809,11 @@ typedef struct String{ } String string_result = string_flatten(pctx->perm, &pctx->gen); - exp_destroy(pctx->heap); generating_time_end = os_time(); return string_result; } + +function void +compiler_cleanup(){ + exp_destroy(pctx->heap); +} diff --git a/main.cpp b/main.cpp index ec47dc4..7bbe029 100644 --- a/main.cpp +++ b/main.cpp @@ -41,12 +41,15 @@ want to export all the symbols, we can namespace them optionally. ------------------------------------------------------------------------------- @todo +[ ] - Better error messages when type difference +[ ] - Casting pointers to and from void should be implicit +[ ] - Kilobyte, Megabyte, Gigabyte +[ ] - Mixing loads and imports leads to code duplication, is that what we want??? [ ] - Fix field access, cant cast, cant index [ ] - Add parent_scope to Ast_Type [ ] - Switch [ ] - Some way to take slice of data [ ] - Optional function renaming in codegen -[ ] - Multiple return values [ ] - Using in structs to embed members, then casting offsets to that embedded member [ ] - Comma notation when declaring variables thing1, thing2: S32 @@ -71,6 +74,7 @@ want to export all the symbols, we can namespace them optionally. [ ] - Conditional compilation #if @donzo +[x] - Multiple return values [x] - Add c string [-] - Should compound resolution use an algorithm to reorder compounds to initialize all fields in order [x] - slices should be properly displayed in debugger @@ -157,36 +161,19 @@ int main(int argument_count, char **arguments){ test_intern_table(); -#if 0 - if(argument_count > 1){ - Scratch scratch; - String name = string_fmt(scratch, "%s.kl", arguments[1]); - String c_filename = string_fmt(scratch, "%s.c", arguments[1]); - - String run_program = string_fmt(scratch, "%s.exe", arguments[1]); - - Array files = {scratch}; - files.add(name); - String result = compile_files(files); - - assert(f); - - - F64 begin = os_time(); - system((const char *)compiler_call.str); - printf("\nCompile time: %f", os_time() - begin); - - system((const char *)run_program.str); - } -#else emit_line_directives = true; + String program_name = "main.kl"_s; + if(argument_count > 1){ + program_name = string_from_cstring(arguments[1]); + } + F64 total_time = os_time(); begin_compilation(); - Ast_Module *module = add_module(pctx->intern("main.kl"_s)); + Ast_Module *module = add_module(pctx->intern(program_name)); parse_all_modules(); assert(module); resolve_everything_in_module(module); - String result = end_compilation(); + String result = get_compilation_result(); assert(os_write_file("program.c"_s, result)); { Scratch scratch; @@ -200,6 +187,5 @@ int main(int argument_count, char **arguments){ printf("\nparsing = %f", parsing_time_end - parsing_time_begin); printf("\nresolving = %f", resolving_time_end - resolving_time_begin); printf("\ngeneratin = %f", generating_time_end - generating_time_begin); -#endif __debugbreak(); } diff --git a/parsing.cpp b/parsing.cpp index a221fd8..ad499f1 100644 --- a/parsing.cpp +++ b/parsing.cpp @@ -675,11 +675,13 @@ register_ast_file(Intern_String filename, Ast_Module *module, B32 global_implici Ast_File *file = 0; For(module->all_loaded_files){ if(it->filename == filename){ + log_info("%Q :: Returning registered file: %Q\n", module->name, filename); file = it; break; } } if(!file){ + log_info("%Q :: Registering file: %Q\n", module->name, filename); AST_NEW(File, FILE, 0, 0); file = result; file->filename = filename; diff --git a/programs/base.kl b/programs/base.kl index 458e039..1d606b9 100644 --- a/programs/base.kl +++ b/programs/base.kl @@ -1,12 +1,18 @@ -Os :: #import "os.kl" - +Os :: #import "os.kl" SizeU :: #strict U64 +arena_di: U64 + Arena :: struct + di: U64 // @debug_id memory: Os.Memory alignment: U64 len: U64 + ADDITIONAL_COMMIT_SIZE :: 1024*1024 + DEFAULT_RESERVE_SIZE :: 1024*1024*1024 + DEFAULT_ALIGNMENT :: 8 + clamp_top_sizeu :: (val: SizeU, max: SizeU): SizeU if val > max return max @@ -22,3 +28,22 @@ get_align_offset :: (size: SizeU, align: SizeU): SizeU align_up :: (size: SizeU, align: SizeU): SizeU result := size + get_align_offset(size, align) return result + +arena_init :: (a: *Arena) + a.memory = Os.reserve(a.DEFAULT_RESERVE_SIZE) + a.alignment = a.DEFAULT_ALIGNMENT + a.di = arena_di++ + +arena_push_size :: (a: *Arena, size: SizeU): *void + generous_size := size + a.alignment + if a.len + generous_size > a.memory.commit + if a.memory.reserve == 0 + arena_init(a) + result := Os.commit(&a.memory, generous_size + a.ADDITIONAL_COMMIT_SIZE) + assert(result == true) + a.len = align_up(a.len, a.alignment) + assert(a.memory.reserve > a.len + a.memory.commit) + result: *void = a.memory.data + a.len + a.len += size + return result + diff --git a/programs/main.kl b/programs/main.kl index 983a1a1..6802ce8 100644 --- a/programs/main.kl +++ b/programs/main.kl @@ -4,7 +4,6 @@ #load "os.kl" question_mark16 :: 0x003f -String16 :: struct;; str: *U16; len: S64 String32 :: struct;; str: *U32; len: S64 UTF32_Result :: struct out_str: U32 diff --git a/programs/os.kl b/programs/os.kl index 43c6e37..0e25b8b 100644 --- a/programs/os.kl +++ b/programs/os.kl @@ -39,6 +39,7 @@ release :: (m: *Memory) m.commit = 0 m.reserve = 0 +String16 :: struct;; str: *U16; len: S64 print :: (string: String16) handle := GetStdHandle(STD_OUTPUT_HANDLE) WriteConsoleW(handle, (string.str)->*void, string.len->DWORD, 0, 0) diff --git a/typechecking.cpp b/typechecking.cpp index 5b458bf..926c612 100644 --- a/typechecking.cpp +++ b/typechecking.cpp @@ -44,7 +44,7 @@ convert_untyped_to_typed(Token *pos, Value a, Ast_Type *new_type){ } function void -make_sure_types_are_compatible(Token *pos, Value *a, Value *b){ +make_sure_types_are_compatible_for_constant_evaluation(Token *pos, Value *a, Value *b){ if((is_pointer(a->type) && is_int(b->type)) || (is_pointer(b->type) && is_int(a->type))){ return; } @@ -53,7 +53,7 @@ make_sure_types_are_compatible(Token *pos, Value *a, Value *b){ } else if(is_typed(a->type) && is_typed(b->type)){ if(a->type != b->type){ - fail: compiler_error(pos, "Type mismatch in make_sure_types_are_compatible - left: %s right: %s", docname(a->type), docname(b->type)); + fail: compiler_error(pos, "Type mismatch in make_sure_types_are_compatible_for_constant_evaluation - left: %s right: %s", docname(a->type), docname(b->type)); } } @@ -78,7 +78,7 @@ compare_values(Token *pos, Token_Kind op, Value a, Value b, bool is_const){ if(!(is_numeric(a.type) && is_numeric(b.type))) compiler_error(pos, "Constant application of binary %s on values of type %s and %s is not allowed", name(op), docname(a.type), docname(b.type)); - make_sure_types_are_compatible(pos, &a, &b); + make_sure_types_are_compatible_for_constant_evaluation(pos, &a, &b); B32 result = 0; if(is_const){ @@ -132,7 +132,7 @@ eval_binary(Token *pos, Token_Kind op, Value a, Value b, bool is_const){ if(!(is_numeric(a.type) && is_numeric(b.type))) compiler_error(pos, "Constant application of binary %s on values of type %s and %s is not allowed", name(op), docname(a.type), docname(b.type)); - make_sure_types_are_compatible(pos, &a, &b); + make_sure_types_are_compatible_for_constant_evaluation(pos, &a, &b); Value result = {}; result.type = a.type; @@ -286,6 +286,12 @@ make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Type *typ assert(type); expr->type = type; } + else if(is_void_pointer(type) && is_pointer(expr->type)){ + expr->type = type; + } + else if(is_pointer(type) && is_void_pointer(expr->type)){ + expr->type = type; + } else if(is_untyped(expr->type)){ expr->value = convert_untyped_to_typed(pos, expr->value, type); } @@ -723,7 +729,7 @@ resolve_field_access(Ast_Expr *node, Ast_Scope *context){ } Ast_Type *type = decl->type; - if(type == type_type && is_enum(decl->type_val)) type = decl->type_val; + if(type == type_type && (is_enum(decl->type_val) || is_struct(decl->type_val))) type = decl->type_val; if(current) current->resolved_type = type; if(is_pointer(type)) type = type->base; diff --git a/typechecking.h b/typechecking.h index 673ddc7..fdd47bd 100644 --- a/typechecking.h +++ b/typechecking.h @@ -286,4 +286,5 @@ type_complete(Ast_Type *type){ 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 diff --git a/types.h b/types.h index 13003e3..41bb584 100644 --- a/types.h +++ b/types.h @@ -198,9 +198,10 @@ global Ast_Type type__int = {TYPE_INT, sizeof(int), __alignof(int)}; global Ast_Type *type_char = &type__char; global Ast_Type *type_int = &type__int; global Ast_Type *type_pointer_to_char; // Needs to be inited at runtime +global Ast_Type *type_void = &type__void; +global Ast_Type *type_pointer_to_void; // Needs to be inited at runtime global Ast_Type *type_type = &type__type; -global Ast_Type *type_void = &type__void; global Ast_Type *type_string = &type__string; global Ast_Type *type_bool = &type__bool; @@ -232,6 +233,8 @@ force_inline B32 is_slice(Ast_Type *a){return a->kind == TYPE_SLICE;} force_inline B32 is_tuple(Ast_Type *a){return a->kind == TYPE_TUPLE;} force_inline B32 is_enum(Ast_Type *a){return a->kind == TYPE_ENUM;} force_inline B32 is_pointer(Ast_Type *a){return a->kind == TYPE_POINTER;} +force_inline B32 is_void(Ast_Type *a){return a->kind == TYPE_VOID;} +force_inline B32 is_void_pointer(Ast_Type *a){return a == type_pointer_to_void;} force_inline B32 is_string(Ast_Type *a){return a->kind == TYPE_STRING || a->kind == TYPE_UNTYPED_STRING || a == type_pointer_to_char;} force_inline B32 is_untyped_int(Ast_Type *a){return a->kind == TYPE_UNTYPED_INT;} force_inline B32 is_typed_int(Ast_Type *a){return (a->kind >= TYPE_S64 && a->kind <= TYPE_U8);}