Compiling multiple examples

This commit is contained in:
Krzosa Karol
2022-06-27 13:37:55 +02:00
parent 2597e66135
commit 7b343ca642
4 changed files with 74 additions and 65 deletions

View File

@@ -9,15 +9,15 @@ global F64 init_ctx_time_end;
function void function void
begin_compilation(){ begin_compilation(){
init_ctx_time_begin = os_time(); init_ctx_time_begin = os_time();
OS_Heap *heap = exp_alloc_type(&pernament_arena, OS_Heap); OS_Heap *heap = exp_alloc_type(&pernament_arena, OS_Heap, AF_ZeroMemory);
*heap = win32_os_heap_create(false, mib(4), 0); *heap = win32_os_heap_create(false, mib(4), 0);
Parse_Ctx *ctx = exp_alloc_type(&pernament_arena, Parse_Ctx); Parse_Ctx *ctx = exp_alloc_type(&pernament_arena, Parse_Ctx, AF_ZeroMemory);
parse_init(ctx, &pernament_arena, heap); parse_init(ctx, &pernament_arena, heap);
init_ctx_time_end = os_time(); init_ctx_time_end = os_time();
} }
function void function void
compiler_cleanup(){ destroy_compiler(){
exp_destroy(pctx->heap); exp_destroy(pctx->heap);
exp_free_all(pctx->perm); exp_free_all(pctx->perm);
} }
@@ -246,4 +246,5 @@ compile_file(String filename, U32 compile_flags = COMPILE_NULL){
printf("\nresolving = %f", resolving_time_end - resolving_time_begin); printf("\nresolving = %f", resolving_time_end - resolving_time_begin);
printf("\ngeneratin = %f", generating_time_end - generating_time_begin); printf("\ngeneratin = %f", generating_time_end - generating_time_begin);
} }
destroy_compiler();
} }

View File

@@ -1,9 +1,6 @@
#import "kernel32.kl"
main :: (): int main :: (): int
// Let's say we have a type // Let's say we have a type
some_type := int some_type := S64
// this function call allows us to get extensive type information // this function call allows us to get extensive type information
// about this type. For example this information allows us to walk // about this type. For example this information allows us to walk
@@ -14,71 +11,78 @@ main :: (): int
// It can be null, requiring the type information would be a bit unwise // It can be null, requiring the type information would be a bit unwise
// this is a lot of data // this is a lot of data
if !type_info if !type_info
return return 1
if type_info.type == S64
// We can use size_of and align_of operators
// to figure out the type alignment and it's size
assert(type_info.size == size_of(S64))
assert(type_info.align == align_of(S64))
else;; assert(false, "We expected S64 here! What a boomer!")
_gcvt :: #foreign (value: F64, digits: int, buffer: *char): *char
print_float :: (value: F64)
buff: [100]char
_gcvt(value, 10, &buff[0])
OutputDebugStringA(&buff[0])
print_type :: (t: Type) // _gcvt :: #foreign (value: F64, digits: int, buffer: *char): *char
type_info := get_type_info(t) // print_float :: (value: F64)
if !type_info // buff: [100]char
return // _gcvt(value, 10, &buff[0])
// OutputDebugStringA(&buff[0])
switch type_info.kind // print_type :: (t: Type)
Type_Info_Kind.S64, Type_Info_Kind.S32, Type_Info_Kind.S16, Type_Info_Kind.S8, Type_Info_Kind.INT // type_info := get_type_info(t)
OutputDebugStringA("Integer") // if !type_info
Type_Info_Kind.U64, Type_Info_Kind.U32, Type_Info_Kind.U16, Type_Info_Kind.U8 // return
OutputDebugStringA("Unsigned")
Type_Info_Kind.F64, Type_Info_Kind.F32
OutputDebugStringA("Float")
Type_Info_Kind.POINTER
OutputDebugStringA("*")
print_type(type_info.base_type)
default;; OutputDebugStringA("Unknown")
print :: (a: Any) // switch type_info.kind
type_info := get_type_info(a.type) // Type_Info_Kind.S64, Type_Info_Kind.S32, Type_Info_Kind.S16, Type_Info_Kind.S8, Type_Info_Kind.INT
if !type_info // OutputDebugStringA("Integer")
return // Type_Info_Kind.U64, Type_Info_Kind.U32, Type_Info_Kind.U16, Type_Info_Kind.U8
// OutputDebugStringA("Unsigned")
// Type_Info_Kind.F64, Type_Info_Kind.F32
// OutputDebugStringA("Float")
// Type_Info_Kind.POINTER
// OutputDebugStringA("*")
// print_type(type_info.base_type)
// default;; OutputDebugStringA("Unknown")
print_type(a.type) // print :: (a: Any)
OutputDebugStringA(" - ") // type_info := get_type_info(a.type)
// @todo check for types here // if !type_info
switch type_info.kind // return
Type_Info_Kind.S64, Type_Info_Kind.S32, Type_Info_Kind.S16, Type_Info_Kind.S8, Type_Info_Kind.INT
OutputDebugStringA("Integer") // print_type(a.type)
Type_Info_Kind.U64, Type_Info_Kind.U32, Type_Info_Kind.U16, Type_Info_Kind.U8 // OutputDebugStringA(" - ")
OutputDebugStringA("Unsigned") // // @todo check for types here
Type_Info_Kind.F64 // switch type_info.kind
data := a.data->*F64 // Type_Info_Kind.S64, Type_Info_Kind.S32, Type_Info_Kind.S16, Type_Info_Kind.S8, Type_Info_Kind.INT
print_float(*data) // OutputDebugStringA("Integer")
Type_Info_Kind.POINTER // Type_Info_Kind.U64, Type_Info_Kind.U32, Type_Info_Kind.U16, Type_Info_Kind.U8
OutputDebugStringA("Pointer") // OutputDebugStringA("Unsigned")
default;; OutputDebugStringA("Unknown") // Type_Info_Kind.F64
// data := a.data->*F64
// print_float(*data)
// Type_Info_Kind.POINTER
// OutputDebugStringA("Pointer")
// default;; OutputDebugStringA("Unknown")
little_untyped_test :: () // little_untyped_test :: ()
if true == false;; pass // if true == false;; pass
if true;; pass // if true;; pass
cast_value1 := 32->S64 // cast_value1 := 32->S64
cast_value2 := true->Bool // cast_value2 := true->Bool
value3 := !true // value3 := !true
value4 := !325252 // value4 := !325252
value5 := !42.42 // value5 := !42.42
some_constant :: 10 // some_constant :: 10
value6 := !some_constant // value6 := !some_constant
var_not_const := 0 // var_not_const := 0
value7 := some_constant + - -some_constant + +-32 + -var_not_const // value7 := some_constant + - -some_constant + +-32 + -var_not_const
value3 = value3 + value4 + value5 + cast_value2 + value6 // value3 = value3 + value4 + value5 + cast_value2 + value6
cast_value1 += 1 + value7 // cast_value1 += 1 + value7
// switch 4 // switch 4

View File

@@ -17,16 +17,19 @@ main :: (): int
// This is a loose association // This is a loose association
thing: int = 10 thing: int = 10
new_type_thing: New_Type = thing new_type_thing: New_Type = thing
#assert(New_Type == int)
// to force typechecker to treat // to force typechecker to treat
// both of these types as different we need to add a #strict directive // both of these types as different we need to add a #strict directive
Strict_Type :: #strict int Strict_Type :: #strict int
// new_strict_type_thing: Strict_Type = thing // This produces a compile time type error // new_strict_type_thing: Strict_Type = thing // This produces a compile time type error
// But this works // But this works
strict_thing: Strict_Type = 10 strict_thing: Strict_Type = 10
#assert(New_Type != Strict_Type) #assert(Strict_Type != int)
#assert(New_Type == int)
// If we want to use those types together we need to cast
assert(new_type_thing + strict_thing->int != 0)
// We can also assign types to runtime variables, there is a special type for that // We can also assign types to runtime variables, there is a special type for that
some_type: Type = int some_type: Type = int

View File

@@ -228,6 +228,7 @@ int main(int argument_count, char **arguments){
program_name = string_from_cstring(arguments[1]); program_name = string_from_cstring(arguments[1]);
} }
compile_file(program_name); compile_file("examples/runtime_type_information.kl"_s);
compile_file("examples/types_as_first_class_values.kl"_s);
__debugbreak(); __debugbreak();
} }