void pointer duck typing

This commit is contained in:
Krzosa Karol
2022-06-17 09:16:33 +02:00
parent 66d7c8ca52
commit ed017c79a5
9 changed files with 68 additions and 38 deletions

View File

@@ -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);
}

View File

@@ -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<String> 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();
}

View File

@@ -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;

View File

@@ -1,12 +1,18 @@
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

View File

@@ -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

View File

@@ -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)

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);}