Compiler restructure, now can call compiler to compile files, fix error where strict type

was equal it's original type, working on examples
This commit is contained in:
Krzosa Karol
2022-06-27 13:13:32 +02:00
parent b4f38caabe
commit 2597e66135
9 changed files with 399 additions and 322 deletions

View File

@@ -0,0 +1,97 @@
#import "kernel32.kl"
main :: (): int
// Let's say we have a type
some_type := int
// this function call allows us to get extensive type information
// about this type. For example this information allows us to walk
// the type tree, pretty print all values in that type, along with their sizes.
// Other use cases allow us to do a type safe printf
type_info: *Type_Info = get_type_info(some_type)
// It can be null, requiring the type information would be a bit unwise
// this is a lot of data
if !type_info
return
_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)
type_info := get_type_info(t)
if !type_info
return
switch type_info.kind
Type_Info_Kind.S64, Type_Info_Kind.S32, Type_Info_Kind.S16, Type_Info_Kind.S8, Type_Info_Kind.INT
OutputDebugStringA("Integer")
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 :: (a: Any)
type_info := get_type_info(a.type)
if !type_info
return
print_type(a.type)
OutputDebugStringA(" - ")
// @todo check for types here
switch type_info.kind
Type_Info_Kind.S64, Type_Info_Kind.S32, Type_Info_Kind.S16, Type_Info_Kind.S8, Type_Info_Kind.INT
OutputDebugStringA("Integer")
Type_Info_Kind.U64, Type_Info_Kind.U32, Type_Info_Kind.U16, Type_Info_Kind.U8
OutputDebugStringA("Unsigned")
Type_Info_Kind.F64
data := a.data->*F64
print_float(*data)
Type_Info_Kind.POINTER
OutputDebugStringA("Pointer")
default;; OutputDebugStringA("Unknown")
little_untyped_test :: ()
if true == false;; pass
if true;; pass
cast_value1 := 32->S64
cast_value2 := true->Bool
value3 := !true
value4 := !325252
value5 := !42.42
some_constant :: 10
value6 := !some_constant
var_not_const := 0
value7 := some_constant + - -some_constant + +-32 + -var_not_const
value3 = value3 + value4 + value5 + cast_value2 + value6
cast_value1 += 1 + value7
// switch 4
// 4;; OutputDebugStringA("4")
// 3;; OutputDebugStringA("3")
// some_type: Type = Vec2
// char_info := get_type_info(char)
// val := 4232.23
// thing: Any = val
// print(val)
// print(some_type)
// // print_array({125.23, 32})
// assert(char_info.kind == Type_Info_Kind.CHAR)

View File

@@ -0,0 +1,43 @@
main :: (): int
// Types can be evaluated at compile time for equality
#assert(int == int)
#assert(int != char)
#assert(*char == *char)
// They can also be evaluated at runtime, they basically get
// replaced with type ids, which are just unique integers assigned
// to each type
assert(int == int)
assert(int != char)
assert(*char == *char)
// We can assign types to compile time variable constants
New_Type :: int
// This is a loose association
thing: int = 10
new_type_thing: New_Type = thing
// to force typechecker to treat
// both of these types as different we need to add a #strict directive
Strict_Type :: #strict int
// new_strict_type_thing: Strict_Type = thing // This produces a compile time type error
// But this works
strict_thing: Strict_Type = 10
#assert(New_Type != Strict_Type)
#assert(New_Type == int)
// We can also assign types to runtime variables, there is a special type for that
some_type: Type = int
some_type_implicit := char
// These can be checked for equality using ifs and switches
if some_type == char
pass
elif some_type_implicit == char
pass