diff --git a/build.bat b/build.bat index 33a71c2a4..bddb6ebf1 100644 --- a/build.bat +++ b/build.bat @@ -46,7 +46,7 @@ cl %compiler_settings% "src\main.c" ^ /link %linker_settings% -OUT:%exe_name% ^ && odin run code/demo.odin rem && odin build_dll code/example.odin ^ - rem odin run code/punity.odin + rem odin run code/demo.odin rem pushd src\asm rem nasm hellope.asm -fwin64 -o hellope.obj ^ diff --git a/code/demo.odin b/code/demo.odin index 5c05259b6..a24126d9d 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -1,283 +1,9 @@ #import "fmt.odin"; -#import "utf8.odin"; -// #import "atomic.odin"; -// #import "hash.odin"; -// #import "math.odin"; -// #import "mem.odin"; -// #import "opengl.odin"; -// #import "os.odin"; -// #import "sync.odin"; -// #import win32 "sys/windows.odin"; main :: proc() { - syntax(); + fmt.println(foo("FOO")); } -syntax :: proc() { - // Cyclic type checking - // Uncomment to see the error - // A :: struct {b: B}; - // B :: struct {a: A}; +foo :: proc(test: string, test1: string, args: ...any) { } - x: int; - y := cast(f32)x; - z := transmute(u32)y; - // down_cast, union_cast as similar too - - - - // Basic directives - fmt.printf("Basic directives = %s(%d): %s\n", #file, #line, #procedure); - // NOTE: new and improved `printf` - // TODO: It does need accurate float printing - - - - // record fields use the same syntax a procedure signatures - Thing1 :: struct { - x: f32, - y: int, - z: ^[]int, - }; - Thing2 :: struct {x: f32, y: int, z: ^[]int}; - - // Slice interals are now just a `ptr+count` - slice: []int; compile_assert(size_of_val(slice) == 2*size_of(int)); - - // Helper type - Help the reader understand what it is quicker - My_Int :: type int; - My_Proc :: type proc(int) -> f32; - - - // All declarations with : are either variable or constant - // To make these declarations syntactically consistent - v_variable := 123; - c_constant :: 123; - c_type1 :: int; - c_type2 :: []int; - c_proc :: proc() { /* code here */ }; - - - x += 1; - x -= 1; - // ++ and -- have been removed - // x++; - // x--; - // Question: Should they be added again? - // They were removed as they are redundant and statements, not expressions - // like in C/C++ - - - // You can now build files as a `.dll` - // `odin build_dll demo.odin` - - - // New vector syntax - v: [vector 3]f32; - v[0] = 123; - v.x = 123; // valid for all vectors with count 1 to 4 - - - // Next part - prefixes(); -} - - -Prefix_Type :: struct {x: int, y: f32, z: rawptr}; - -thread_local my_tls: Prefix_Type; - -prefixes :: proc() { - using var: Prefix_Type; - immutable const := Prefix_Type{1, 2, nil}; - var.x = 123; - x = 123; - // const.x = 123; // const is immutable - - - - foo :: proc(using immutable pt: Prefix_Type, immutable int_ptr: ^int) { - // int_ptr = nil; // Not valid - int_ptr^ = 123; // Is valid - } - - - - // Same as C99's `restrict` - bar :: proc(no_alias a, b: ^int) { - // Assumes a never equals b so it can perform optimizations with that fact - } - - - when_statements(); -} - - - - - -when_statements :: proc() { - X :: 123 + 12; - Y :: X/5; - COND :: Y > 0; - - when COND { - fmt.println("Y > 0"); - } else { - fmt.println("Y <= 0"); - } - - - when false { - this_code_does_not_exist(123, 321); - but_its_syntax_is_valid(); - x :: ^^^^int; - } - - foreign_procedures(); -} - -#foreign_system_library win32_user "user32.lib" when ODIN_OS == "windows"; -// NOTE: This is done on purpose for two reasons: -// * Makes it clear where the platform specific stuff is -// * Removes the need to solve the travelling salesman problem when importing files :P - -foreign_procedures :: proc() { - ShowWindow :: proc(hwnd: rawptr, cmd_show: i32) -> i32 #foreign win32_user; - show_window :: proc(hwnd: rawptr, cmd_show: i32) -> i32 #foreign win32_user "ShowWindow"; - // NOTE: If that library doesn't get used, it doesn't get linked with - // NOTE: There is not link checking yet to see if that procedure does come from that library - - // See sys/windows.odin for more examples - - special_expressions(); -} - -special_expressions :: proc() { - // Block expression - x := { - a: f32 = 123; - b := a-123; - c := b/a; - give c; - }; // semicolon is required as it's an expression - - y := if x < 50 { - give x; - } else { - // TODO: Type cohesion is not yet finished - give 123; - }; // semicolon is required as it's an expression - - - // This is allows for inline blocks of code and will be a useful feature to have when - // macros will be implemented into the language - - loops(); -} - -loops :: proc() { - // The C-style for loop - for i := 0; i < 123; i += 1 { - break; - } - for i := 0; i < 123; { - break; - } - for false { - break; - } - for { - break; - } - - - for i in 0..<123 { // 123 exclusive - } - - for i in 0...122 { // 122 inclusive - } - - for val, idx in 12..<16 { - fmt.println(val, idx); - } - - primes := [...]int{2, 3, 5, 7, 11, 13, 17, 19}; - - for p in primes { - fmt.println(p); - } - - // Pointers to arrays, slices, or strings are allowed - for _ in ^primes { - // ignore the value and just iterate across it - } - - - - name := "你好,世界"; - fmt.println(name); - for r in name { - compile_assert(type_of_val(r) == rune); - fmt.printf("%r\n", r); - } - - when false { - for i, size := 0; i < name.count; i += size { - r: rune; - r, size = utf8.decode_rune(name[i:]); - fmt.printf("%r\n", r); - } - } - - procedure_overloading(); -} - - -procedure_overloading :: proc() { - THINGF :: 14451.1; - THINGI :: 14451; - - foo :: proc() { - fmt.printf("Zero args\n"); - } - foo :: proc(i: int) { - fmt.printf("int arg, i=%d\n", i); - } - foo :: proc(f: f64) { - i := cast(int)f; - fmt.printf("f64 arg, f=%d\n", i); - } - - foo(); - foo(THINGF); - // foo(THINGI); // 14451 is just a number so it could go to either procedures - foo(cast(int)THINGI); - - - - - foo :: proc(x: ^i32) -> (int, int) { - fmt.println("^int"); - return 123, cast(int)(x^); - } - foo :: proc(x: rawptr) { - fmt.println("rawptr"); - } - - - a: i32 = 123; - b: f32; - c: rawptr; - fmt.println(foo(^a)); - foo(^b); - foo(c); - // foo(nil); // nil could go to numerous types thus the ambiguity - - f: proc(); - f = foo; // The correct `foo` to chosen - f(); - - - // See math.odin and atomic.odin for more examples -} +foo :: proc(test: string) { } diff --git a/core/os.odin b/core/os.odin index 22e2d533c..2a44b8a88 100644 --- a/core/os.odin +++ b/core/os.odin @@ -1,2 +1,2 @@ -#include "os_windows.odin" when ODIN_OS == "windows" +#include "os_windows.odin" when ODIN_OS == "windows"; diff --git a/src/build.c b/src/build.c index 6db7dcd6b..b1dc08bc4 100644 --- a/src/build.c +++ b/src/build.c @@ -148,7 +148,7 @@ String get_filepath_extension(String path) { void init_build_context(BuildContext *bc) { bc->ODIN_VENDOR = str_lit("odin"); - bc->ODIN_VERSION = str_lit("0.0.5e"); + bc->ODIN_VERSION = str_lit("0.0.6b"); bc->ODIN_ROOT = odin_root_dir(); #if defined(GB_SYSTEM_WINDOWS) diff --git a/src/check_expr.c b/src/check_expr.c index e8318a071..defcf7c63 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -138,13 +138,17 @@ i64 check_distance_between_types(Checker *c, Operand *operand, Type *type) { return -1; } if (is_type_untyped(src)) { + if (is_type_any(dst)) { + // NOTE(bill): Anything can cast to `Any` + add_type_info_type(c, s); + return 10; + } if (dst->kind == Type_Basic) { if (operand->mode == Addressing_Constant) { if (check_representable_as_constant(c, operand->value, dst, NULL)) { return 1; - } else { - return -1; } + return -1; } if (src->kind == Type_Basic && src->Basic.kind == Basic_UntypedBool) { if (is_type_boolean(dst)) { @@ -3549,7 +3553,7 @@ Type *check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNod for_array(i, ce->args) { Operand o = {0}; check_multi_expr(c, &o, ce->args.e[i]); - if (o.type->kind != Type_Tuple) { + if (o.type == NULL || o.type->kind != Type_Tuple) { array_add(&operands, o); } else { TypeTuple *tuple = &o.type->Tuple;