diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-04-02 22:03:52 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-04-02 22:03:52 +0100 |
| commit | 382a5ca6a27ea0f6dde4c0783d55f5dca8ac2575 (patch) | |
| tree | fc7b7592651b166bdbbf7334649b062d584231e9 /code | |
| parent | 96e8bb5b6f3c8d2cf2b0fae8c7a9c710c4e9dbb0 (diff) | |
Update and regression test old demos
Diffstat (limited to 'code')
| -rw-r--r-- | code/game.odin | 85 | ||||
| -rw-r--r-- | code/old_demos/demo001.odin | 16 | ||||
| -rw-r--r-- | code/old_demos/demo002.odin | 732 | ||||
| -rw-r--r-- | code/old_demos/demo004.odin | 34 | ||||
| -rw-r--r-- | code/old_demos/demo005.odin | 28 |
5 files changed, 448 insertions, 447 deletions
diff --git a/code/game.odin b/code/game.odin index b49b78b59..fc32eaf58 100644 --- a/code/game.odin +++ b/code/game.odin @@ -1,4 +1,5 @@ -#import "win32.odin" when ODIN_OS == "windows"; +#import win32 "sys/windows.odin" when ODIN_OS == "windows"; +#import wgl "sys/wgl.odin" when ODIN_OS == "windows"; #import "fmt.odin"; #import "math.odin"; #import "os.odin"; @@ -12,11 +13,11 @@ time_now :: proc() -> f64 { counter: i64; win32.QueryPerformanceCounter(^counter); - result := counter as f64 / win32_perf_count_freq as f64; + result := cast(f64)counter / cast(f64)win32_perf_count_freq; return result; } win32_print_last_error :: proc() { - err_code := win32.GetLastError() as int; + err_code := cast(int)win32.GetLastError(); if err_code != 0 { fmt.println("GetLastError: %", err_code); } @@ -24,42 +25,42 @@ win32_print_last_error :: proc() { // Yuk! to_c_string :: proc(s: string) -> []u8 { - c_str := new_slice(u8, s.count+1); - copy(c_str, s as []byte); - c_str[s.count] = 0; + c_str := make([]u8, len(s)+1); + copy(c_str, cast([]byte)s); + c_str[len(s)] = 0; return c_str; } Window :: struct { - width, height: int; - wc: win32.WNDCLASSEXA; - dc: win32.HDC; - hwnd: win32.HWND; - opengl_context, rc: win32.HGLRC; - c_title: []u8; + width, height: int, + wc: win32.WndClassExA, + dc: win32.Hdc, + hwnd: win32.Hwnd, + opengl_context, rc: wgl.Hglrc, + c_title: []u8, } -make_window :: proc(title: string, msg, height: int, window_proc: win32.WNDPROC) -> (Window, bool) { +make_window :: proc(title: string, msg, height: int, window_proc: win32.Wnd_Proc) -> (Window, bool) { using win32; w: Window; w.width, w.height = msg, height; class_name := "Win32-Odin-Window\x00"; - c_class_name := class_name.data; - if title[title.count-1] != 0 { + c_class_name := ^class_name[0]; + if title[len(title)-1] != 0 { w.c_title = to_c_string(title); } else { - w.c_title = title as []u8; + w.c_title = cast([]u8)title; } instance := GetModuleHandleA(nil); - w.wc = WNDCLASSEXA{ - size = size_of(WNDCLASSEXA) as u32, + w.wc = WndClassExA{ + size = size_of(WndClassExA), style = CS_VREDRAW | CS_HREDRAW, - instance = instance as HINSTANCE, + instance = cast(Hinstance)instance, class_name = c_class_name, wnd_proc = window_proc, }; @@ -70,10 +71,10 @@ make_window :: proc(title: string, msg, height: int, window_proc: win32.WNDPROC) } w.hwnd = CreateWindowExA(0, - c_class_name, w.c_title.data, + c_class_name, ^w.c_title[0], WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, - w.width as i32, w.height as i32, + cast(i32)w.width, cast(i32)w.height, nil, nil, instance, nil); if w.hwnd == nil { @@ -85,7 +86,7 @@ make_window :: proc(title: string, msg, height: int, window_proc: win32.WNDPROC) { pfd := PIXELFORMATDESCRIPTOR{ - size = size_of(PIXELFORMATDESCRIPTOR) as u32, + size = size_of(PIXELFORMATDESCRIPTOR), version = 1, flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, pixel_type = PFD_TYPE_RGBA, @@ -97,19 +98,20 @@ make_window :: proc(title: string, msg, height: int, window_proc: win32.WNDPROC) }; SetPixelFormat(w.dc, ChoosePixelFormat(w.dc, ^pfd), nil); - w.opengl_context = wglCreateContext(w.dc); - wglMakeCurrent(w.dc, w.opengl_context); + w.opengl_context = wgl.CreateContext(w.dc); + wgl.MakeCurrent(w.dc, w.opengl_context); attribs := [8]i32{ - WGL_CONTEXT_MAJOR_VERSION_ARB, 2, - WGL_CONTEXT_MINOR_VERSION_ARB, 1, - WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + wgl.CONTEXT_MAJOR_VERSION_ARB, 2, + wgl.CONTEXT_MINOR_VERSION_ARB, 1, + wgl.CONTEXT_PROFILE_MASK_ARB, wgl.CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0, // NOTE(bill): tells the proc that this is the end of attribs }; - wglCreateContextAttribsARB := wglGetProcAddress(("wglCreateContextAttribsARB\x00" as string).data) as wglCreateContextAttribsARBType; - w.rc = wglCreateContextAttribsARB(w.dc, 0, ^attribs[0]); - wglMakeCurrent(w.dc, w.rc); + wgl_str := "wglCreateContextAttribsARB\x00"; + wglCreateContextAttribsARB := cast(wgl.Create_Context_Attribs_ARB_Type)wgl.GetProcAddress(^wgl_str[0]); + w.rc = wglCreateContextAttribsARB(w.dc, nil, ^attribs[0]); + wgl.MakeCurrent(w.dc, w.rc); SwapBuffers(w.dc); } @@ -117,7 +119,7 @@ make_window :: proc(title: string, msg, height: int, window_proc: win32.WNDPROC) } destroy_window :: proc(w: ^Window) { - free(w.c_title.data); + free(w.c_title); } display_window :: proc(w: ^Window) { @@ -129,7 +131,7 @@ run :: proc() { using win32; using math; - win32_proc :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #no_inline { + win32_proc :: proc(hwnd: win32.Hwnd, msg: u32, wparam: win32.Wparam, lparam: win32.Lparam) -> win32.Lresult #no_inline { if msg == WM_DESTROY || msg == WM_CLOSE || msg == WM_QUIT { os.exit(0); return 0; @@ -137,7 +139,7 @@ run :: proc() { return DefWindowProcA(hwnd, msg, wparam, lparam); } - window, window_success := make_window("Odin Language Demo", 854, 480, win32_proc); + window, window_success := make_window("Odin Language Demo", 854, 480, cast(Wnd_Proc)win32_proc); if !window_success { return; } @@ -153,10 +155,10 @@ run :: proc() { for running { curr_time := time_now(); - dt := (curr_time - prev_time) as f32; + dt := cast(f32)(curr_time - prev_time); prev_time = curr_time; - msg: MSG; + msg: Msg; for PeekMessageA(^msg, nil, 0, 0, PM_REMOVE) > 0 { if msg.message == WM_QUIT { running = false; @@ -178,7 +180,7 @@ run :: proc() { if is_key_down(Key_Code.UP) { v[1] += 1; } if is_key_down(Key_Code.DOWN) { v[1] -= 1; } - v = vec2_norm0(v); + v = norm(v); pos += v * Vec2{SPEED * dt}; } @@ -188,8 +190,8 @@ run :: proc() { gl.Clear(gl.COLOR_BUFFER_BIT); gl.LoadIdentity(); - gl.Ortho(0, window.width as f64, - 0, window.height as f64, 0, 1); + gl.Ortho(0, cast(f64)window.width, + 0, cast(f64)window.height, 0, 1); draw_rect :: proc(x, y, w, h: f32) { gl.Begin(gl.TRIANGLES); @@ -207,9 +209,14 @@ run :: proc() { draw_rect(pos.x, pos.y, 50, 50); display_window(^window); - ms_to_sleep := (16 - 1000*dt) as i32; + ms_to_sleep := cast(i32)(16 - 1000*dt); if ms_to_sleep > 0 { win32.Sleep(ms_to_sleep); } } } + + +main :: proc() { + run(); +} diff --git a/code/old_demos/demo001.odin b/code/old_demos/demo001.odin index c3fc0f663..5f30af8fe 100644 --- a/code/old_demos/demo001.odin +++ b/code/old_demos/demo001.odin @@ -136,7 +136,7 @@ bounds_checking :: proc() { { base: [10]int; - s := base[2:6]; + s := base[2..6]; a, b := -1, 6; #no_bounds_check { @@ -164,7 +164,7 @@ type_introspection :: proc() { info = type_info_of_val(x); // by value // See: runtime.odin - match type i in info { + match i in info { case Type_Info.Integer: fmt.println("integer!"); case Type_Info.Float: @@ -174,7 +174,7 @@ type_introspection :: proc() { } // Unsafe cast - integer_info := cast(^Type_Info.Integer)info; + integer_info := cast(^Type_Info.Integer)cast(rawptr)info; } { @@ -263,12 +263,12 @@ crazy_introspection :: proc() { } fruit_ti := type_info(Fruit); - name := (cast(^Type_Info.Named)fruit_ti).name; // Unsafe casts - info := cast(^Type_Info.Enum)type_info_base(fruit_ti); // Unsafe casts + name := (union_cast(^Type_Info.Named)fruit_ti).name; // Unsafe casts + info, _ := union_cast(^Type_Info.Enum)type_info_base(fruit_ti); // Unsafe casts - fmt.printf("% :: enum % {\n", name, info.base); - for i := 0; i < info.values.count; i += 1 { - fmt.printf("\t%\t= %,\n", info.names[i], info.values[i]); + fmt.printf("%s :: enum %T {\n", name, info.base); + for i := 0; i < len(info.values); i++ { + fmt.printf("\t%s\t= %v,\n", info.names[i], info.values[i]); } fmt.printf("}\n"); diff --git a/code/old_demos/demo002.odin b/code/old_demos/demo002.odin index 57b1b5c73..78cdb194a 100644 --- a/code/old_demos/demo002.odin +++ b/code/old_demos/demo002.odin @@ -1,9 +1,9 @@ // Demo 002 -#include "basic.odin" -#include "math.odin" -// #include "game.odin" +#load "fmt.odin"; +#load "math.odin"; +// #load "game.odin" -#thread_local tls_int: int +#thread_local tls_int: int; main :: proc() { // Forenotes @@ -25,64 +25,64 @@ main :: proc() { // #thread_local - see runtime.odin and above at `tls_int` // #foreign_system_library - see win32.odin - // struct_compound_literals() - // enumerations() - // variadic_procedures() - // new_builtins() - // match_statement() - // namespacing() - // subtyping() - // tagged_unions() + // struct_compound_literals(); + // enumerations(); + // variadic_procedures(); + // new_builtins(); + // match_statement(); + // namespacing(); + // subtyping(); + // tagged_unions(); } struct_compound_literals :: proc() { - Thing :: type struct { - id: int - x: f32 - name: string - } + Thing :: struct { + id: int, + x: f32, + name: string, + }; { - t1: Thing - t1.id = 1 + t1: Thing; + t1.id = 1; - t3 := Thing{} - t4 := Thing{1, 2, "Fred"} - // t5 := Thing{1, 2} + t3 := Thing{}; + t4 := Thing{1, 2, "Fred"}; + // t5 := Thing{1, 2}; t6 := Thing{ name = "Tom", x = 23, - } + }; } } enumerations :: proc() { { - Fruit :: type enum { + Fruit :: enum { APPLE, // 0 BANANA, // 1 PEAR, // 2 - } + }; - f := Fruit.APPLE + f := Fruit.APPLE; // g12: int = Fruit.BANANA - g: int = Fruit.BANANA as int + g: int = cast(int)Fruit.BANANA; // However, you can use enums are index values as _any_ integer allowed } { - Fruit1 :: type enum int { + Fruit1 :: enum int { APPLE, BANANA, PEAR, } - Fruit2 :: type enum u8 { + Fruit2 :: enum u8 { APPLE, BANANA, PEAR, } - Fruit3 :: type enum u8 { + Fruit3 :: enum u8 { APPLE = 1, BANANA, // 2 PEAR = 5, @@ -95,32 +95,32 @@ enumerations :: proc() { variadic_procedures :: proc() { print_ints :: proc(args: ..int) { - for i := 0; i < len(args); i++ { + for arg, i in args { if i > 0 { - print_string(", ") + print(", "); } - print_int(args[i]) + print(arg); } } print_ints(); // nl() - print_ints(1); nl() - print_ints(1, 2, 3); nl() + print_ints(1); nl(); + print_ints(1, 2, 3); nl(); print_prefix_f32s :: proc(prefix: string, args: ..f32) { - print_string(prefix) - print_string(": ") - for i := 0; i < len(args); i++ { + print(prefix); + print(": "); + for arg, i in args { if i > 0 { - print_string(", ") + print(", "); } - print_f32(args[i]) + print(arg); } } - print_prefix_f32s("a"); nl() - print_prefix_f32s("b", 1); nl() -7 print_prefix_f32s("c", 1, 2, 3); nl() + print_prefix_f32s("a"); nl(); + print_prefix_f32s("b", 1); nl(); + print_prefix_f32s("c", 1, 2, 3); nl(); // Internally, the variadic procedures get allocated to an array on the stack, // and this array is passed a slice @@ -134,28 +134,28 @@ variadic_procedures :: proc() { new_builtins :: proc() { { - a := new(int) - b := new_slice(int, 12) - c := new_slice(int, 12, 16) + a := new(int); + b := make([]int, 12); + c := make([]int, 12, 16); - defer delete(a) - defer delete(b) - defer delete(c) + defer free(a); + defer free(b); + defer free(c); // NOTE(bill): These use the current context's allocator not the default allocator // see runtime.odin - // Q: Should this be `free` rather than `delete` and should I overload it for slices too? + // Q: Should this be `free` rather than `free` and should I overload it for slices too? { - prev_context := context - defer context = prev_context + prev_context := context; + defer __context = prev_context; // Q: Should I add a `push_context` feature to the language? - context.allocator = __default_allocator() + __context.allocator = default_allocator(); - a := new(int) - defer delete(a) + a := new(int); + defer free(a); // Do whatever @@ -163,8 +163,8 @@ new_builtins :: proc() { } { - a: int = 123 - b: type_of_val(a) = 321 + a: int = 123; + b: type_of_val(a) = 321; // NOTE(bill): This matches the current naming scheme // size_of @@ -179,22 +179,22 @@ new_builtins :: proc() { { // Compile time assert - COND :: true - compile_assert(COND) + COND :: true; + compile_assert(COND); // compile_assert(!COND) // Runtime assert - x := true - assert(x) - // assert(!x) + x := true; + assert(x); + // assert(!x); } { - x: ^u32 = null; - y := ptr_offset(x, 100) - z := ptr_sub(y, x) - w := slice_ptr(x, 12) - t := slice_ptr(x, 12, 16) + x: ^u32 = nil; + y := x+100; + z := y-x; + w := slice_ptr(x, 12); + t := slice_ptr(x, 12, 16); // NOTE(bill): These are here because I've removed: // pointer arithmetic @@ -203,32 +203,32 @@ new_builtins :: proc() { // Reason - a: [16]int + a: [16]int; a[1] = 1; - b := ^a + b := ^a; // Auto pointer deref // consistent with record members - assert(b[1] == 1) + assert(b[1] == 1); // Q: Should I add them back in at the cost of inconsitency? } { - a, b := -1, 2 - print_int(min(a, b)); nl() - print_int(max(a, b)); nl() - print_int(abs(a)); nl() + a, b := -1, 2; + print(min(a, b)); nl(); + print(max(a, b)); nl(); + print(abs(a)); nl(); // These work at compile time too - A :: -1 - B :: 2 - C :: min(A, B) - D :: max(A, B) - E :: abs(A) - - print_int(C); nl() - print_int(D); nl() - print_int(E); nl() + A :: -1; + B :: 2; + C :: min(A, B); + D :: max(A, B); + E :: abs(A); + + print(C); nl(); + print(D); nl(); + print(E); nl(); } } @@ -240,47 +240,47 @@ match_statement :: proc() { { match x := 5; x { case 1: // cases must be constant expression - print_string("1!\n") + print("1!\n"); // break by default case 2: s := "2!\n"; // Each case has its own scope - print_string(s) - break // explicit break + print(s); + break; // explicit break case 3, 4: // multiple cases - print_string("3 or 4!\n") + print("3 or 4!\n"); case 5: - print_string("5!\n") - fallthrough // explicit fallthrough + print("5!\n"); + fallthrough; // explicit fallthrough default: - print_string("default!\n") + print("default!\n"); } match x := 1.5; x { case 1.5: - print_string("1.5!\n") + print("1.5!\n"); // break by default - case MATH_TAU: - print_string("τ!\n") + case TAU: + print("τ!\n"); default: - print_string("default!\n") + print("default!\n"); } match x := "Hello"; x { case "Hello": - print_string("greeting\n") + print("greeting\n"); // break by default case "Goodbye": - print_string("farewell\n") + print("farewell\n"); default: - print_string("???\n") + print("???\n"); } @@ -288,41 +288,41 @@ match_statement :: proc() { - a := 53 + a := 53; match { case a == 1: - print_string("one\n") + print("one\n"); case a == 2: - print_string("a couple\n") + print("a couple\n"); case a < 7, a == 7: - print_string("a few\n") + print("a few\n"); case a < 12: // intentional bug - print_string("several\n") + print("several\n"); case a >= 12 && a < 100: - print_string("dozens\n") + print("dozens\n"); case a >= 100 && a < 1000: - print_string("hundreds\n") + print("hundreds\n"); default: - print_string("a fuck ton\n") + print("a fuck ton\n"); } // Identical to this - b := 53 + b := 53; if b == 1 { - print_string("one\n") + print("one\n"); } else if b == 2 { - print_string("a couple\n") + print("a couple\n"); } else if b < 7 || b == 7 { - print_string("a few\n") + print("a few\n"); } else if b < 12 { // intentional bug - print_string("several\n") + print("several\n"); } else if b >= 12 && b < 100 { - print_string("dozens\n") + print("dozens\n"); } else if b >= 100 && b < 1000 { - print_string("hundreds\n") + print("hundreds\n"); } else { - print_string("a fuck ton\n") + print("a fuck ton\n"); } // However, match statements allow for `break` and `fallthrough` unlike @@ -330,45 +330,43 @@ match_statement :: proc() { } } -Vector3 :: type struct { - x, y, z: f32 -} +Vector3 :: struct {x, y, z: f32} print_floats :: proc(args: ..f32) { - for i := 0; i < len(args); i++ { + for arg, i in args { if i > 0 { - print_string(", ") + print(", "); } - print_f32(args[i]) + print(arg); } - print_nl() + println(); } namespacing :: proc() { { - Thing :: type struct { - x: f32 - name: string - } + Thing :: #type struct { + x: f32, + name: string, + }; - a: Thing - a.x = 3 + a: Thing; + a.x = 3; { - Thing :: type struct { - y: int - test: bool + Thing :: #type struct { + y: int, + test: bool, } - b: Thing // Uses this scope's Thing - b.test = true + b: Thing; // Uses this scope's Thing + b.test = true; } } - +/* { - Entity :: type struct { - Guid :: type int - Nested :: type struct { - MyInt :: type int + Entity :: struct { + Guid :: int + Nested :: struct { + MyInt :: int i: int } @@ -408,8 +406,8 @@ namespacing :: proc() { guid = 27832 name = "Bob" - print_int(e.guid as int); nl() - print_string(e.name); nl() + print(e.guid as int); nl() + print(e.name); nl() } { @@ -417,16 +415,16 @@ namespacing :: proc() { guid = 78456 name = "Thing" - print_int(e.guid as int); nl() - print_string(e.name); nl() + print(e.guid as int); nl() + print(e.name); nl() } } { - Entity :: type struct { - Guid :: type int - Nested :: type struct { - MyInt :: type int + Entity :: struct { + Guid :: int + Nested :: struct { + MyInt :: int i: int } @@ -445,40 +443,40 @@ namespacing :: proc() { e.i = Entity.CONSTANT } - +*/ { - Entity :: type struct { + Entity :: struct { position: Vector3 } print_pos_1 :: proc(entity: ^Entity) { - print_string("print_pos_1: ") - print_floats(entity.position.x, entity.position.y, entity.position.z) + print("print_pos_1: "); + print_floats(entity.position.x, entity.position.y, entity.position.z); } print_pos_2 :: proc(entity: ^Entity) { - using entity - print_string("print_pos_2: ") - print_floats(position.x, position.y, position.z) + using entity; + print("print_pos_2: "); + print_floats(position.x, position.y, position.z); } print_pos_3 :: proc(using entity: ^Entity) { - print_string("print_pos_3: ") - print_floats(position.x, position.y, position.z) + print("print_pos_3: "); + print_floats(position.x, position.y, position.z); } print_pos_4 :: proc(using entity: ^Entity) { - using position - print_string("print_pos_4: ") - print_floats(x, y, z) + using position; + print("print_pos_4: "); + print_floats(x, y, z); } - e := Entity{position = Vector3{1, 2, 3}} - print_pos_1(^e) - print_pos_2(^e) - print_pos_3(^e) - print_pos_4(^e) + e := Entity{position = Vector3{1, 2, 3}}; + print_pos_1(^e); + print_pos_2(^e); + print_pos_3(^e); + print_pos_4(^e); // This is similar to C++'s `this` pointer that is implicit and only available in methods } @@ -488,46 +486,46 @@ subtyping :: proc() { { // C way for subtyping/subclassing - Entity :: type struct { - position: Vector3 + Entity :: struct { + position: Vector3, } - Frog :: type struct { - entity: Entity - jump_height: f32 + Frog :: struct { + entity: Entity, + jump_height: f32, } - f: Frog - f.entity.position = Vector3{1, 2, 3} + f: Frog; + f.entity.position = Vector3{1, 2, 3}; - using f.entity - position = Vector3{1, 2, 3} + using f.entity; + position = Vector3{1, 2, 3}; } { // C++ way for subtyping/subclassing - Entity :: type struct { + Entity :: struct { position: Vector3 } - Frog :: type struct { - using entity: Entity - jump_height: f32 + Frog :: struct { + using entity: Entity, + jump_height: f32, } - f: Frog - f.position = Vector3{1, 2, 3} + f: Frog; + f.position = Vector3{1, 2, 3}; print_pos :: proc(using entity: Entity) { - print_string("print_pos: ") - print_floats(position.x, position.y, position.z) + print("print_pos: "); + print_floats(position.x, position.y, position.z); } - print_pos(f.entity) - print_pos(f) + print_pos(f.entity); + // print_pos(f); // Subtype Polymorphism } @@ -535,79 +533,79 @@ subtyping :: proc() { { // More than C++ way for subtyping/subclassing - Entity :: type struct { - position: Vector3 + Entity :: struct { + position: Vector3, } - Frog :: type struct { - jump_height: f32 - using entity: ^Entity // Doesn't have to be first member! + Frog :: struct { + jump_height: f32, + using entity: ^Entity, // Doesn't have to be first member! } - f: Frog - f.entity = new(Entity) - f.position = Vector3{1, 2, 3} + f: Frog; + f.entity = new(Entity); + f.position = Vector3{1, 2, 3}; print_pos :: proc(using entity: ^Entity) { - print_string("print_pos: ") - print_floats(position.x, position.y, position.z) + print("print_pos: "); + print_floats(position.x, position.y, position.z); } - print_pos(f.entity) - print_pos(^f) - print_pos(f) + print_pos(f.entity); + // print_pos(^f); + // print_pos(f); } { // More efficient subtyping - Entity :: type struct { - position: Vector3 + Entity :: struct { + position: Vector3, } - Frog :: type struct { - jump_height: f32 - using entity: ^Entity + Frog :: struct { + jump_height: f32, + using entity: ^Entity, } - MAX_ENTITES :: 64 - entities: [MAX_ENTITES]Entity - entity_count := 0 + MAX_ENTITES :: 64; + entities: [MAX_ENTITES]Entity; + entity_count := 0; next_entity :: proc(entities: []Entity, entity_count: ^int) -> ^Entity { - e := ^entities[entity_count^] - entity_count^++ - return e + e := ^entities[entity_count^]; + entity_count^++; + return e; } - f: Frog - f.entity = next_entity(entities[:], ^entity_count) - f.position = Vector3{3, 4, 6} + f: Frog; + f.entity = next_entity(entities[..], ^entity_count); + f.position = Vector3{3, 4, 6}; - using f.position - print_floats(x, y, z) + using f.position; + print_floats(x, y, z); } { // Down casting - Entity :: type struct { - position: Vector3 + Entity :: struct { + position: Vector3, } - Frog :: type struct { - jump_height: f32 - using entity: Entity + Frog :: struct { + jump_height: f32, + using entity: Entity, } - f: Frog - f.jump_height = 564 - e := ^f.entity + f: Frog; + f.jump_height = 564; + e := ^f.entity; - frog := e down_cast ^Frog - print_string("down_cast: ") - print_f32(frog.jump_height); nl() + frog := down_cast(^Frog)e; + print("down_cast: "); + print(frog.jump_height); nl(); // NOTE(bill): `down_cast` is unsafe and there are not check are compile time or run time // Q: Should I completely remove `down_cast` as I added it in about 30 minutes @@ -616,51 +614,51 @@ subtyping :: proc() { { // Multiple "inheritance"/subclassing - Entity :: type struct { - position: Vector3 + Entity :: struct { + position: Vector3, } - Climber :: type struct { - speed: f32 + Climber :: struct { + speed: f32, } - Frog :: type struct { - using entity: Entity - using climber: Climber + Frog :: struct { + using entity: Entity, + using climber: Climber, } } } tagged_unions :: proc() { { - EntityKind :: type enum { + EntityKind :: enum { INVALID, FROG, GIRAFFE, HELICOPTER, } - Entity :: type struct { + Entity :: struct { kind: EntityKind using data: raw_union { frog: struct { - jump_height: f32 - colour: u32 - } + jump_height: f32, + colour: u32, + }, giraffe: struct { - neck_length: f32 - spot_count: int - } + neck_length: f32, + spot_count: int, + }, helicopter: struct { - blade_count: int - weight: f32 - pilot_name: string - } + blade_count: int, + weight: f32, + pilot_name: string, + }, } } - e: Entity - e.kind = EntityKind.FROG - e.frog.jump_height = 12 + e: Entity; + e.kind = EntityKind.FROG; + e.frog.jump_height = 12; f: type_of_val(e.frog); @@ -669,35 +667,35 @@ tagged_unions :: proc() { } { - Entity :: type union { - Frog: struct { - jump_height: f32 - colour: u32 - } - Giraffe: struct { - neck_length: f32 - spot_count: int - } - Helicopter: struct { - blade_count: int - weight: f32 - pilot_name: string - } - } - - using Entity - f1: Frog = Frog{12, 0xff9900} - f2: Entity = Frog{12, 0xff9900} // Implicit cast - f3 := Frog{12, 0xff9900} as Entity // Explicit cast + Entity :: union { + Frog{ + jump_height: f32, + colour: u32, + }, + Giraffe{ + neck_length: f32, + spot_count: int, + }, + Helicopter{ + blade_count: int, + weight: f32, + pilot_name: string, + }, + } + + using Entity; + f1: Frog = Frog{12, 0xff9900}; + f2: Entity = Frog{12, 0xff9900}; // Implicit cast + f3 := cast(Entity)Frog{12, 0xff9900}; // Explicit cast // f3.Frog.jump_height = 12 // There are "members" of a union - e, f, g, h: Entity - f = Frog{12, 0xff9900} - g = Giraffe{2.1, 23} - h = Helicopter{4, 1000, "Frank"} + e, f, g, h: Entity; + f = Frog{12, 0xff9900}; + g = Giraffe{2.1, 23}; + h = Helicopter{4, 1000, "Frank"}; @@ -705,18 +703,18 @@ tagged_unions :: proc() { // Requires a pointer to the union // `x` will be a pointer to type of the case - match type x : ^f { + match x in ^f { case Frog: - print_string("Frog!\n") - print_f32(x.jump_height); nl() - x.jump_height = 3 - print_f32(x.jump_height); nl() + print("Frog!\n"); + print(x.jump_height); nl(); + // x.jump_height = 3; + print(x.jump_height); nl(); case Giraffe: - print_string("Giraffe!\n") + print("Giraffe!\n"); case Helicopter: - print_string("ROFLCOPTER!\n") + print("ROFLCOPTER!\n"); default: - print_string("invalid entity\n") + print("invalid entity\n"); } @@ -724,26 +722,26 @@ tagged_unions :: proc() { // Or it takes the pointer the data and not a copy - fp := ^f as ^Frog // Unsafe - print_f32(fp.jump_height); nl() + // fp := cast(^Frog)^f; // Unsafe + // print(fp.jump_height); nl(); // Internals of a tagged union /* struct { - data: [size_of_biggest_tag]u8 - tag_index: int + data: [size_of_biggest_tag]u8, + tag_index: int, } */ // This is to allow for pointer casting if needed // Advantage over subtyping version - MAX_ENTITES :: 64 - entities: [MAX_ENTITES]Entity + MAX_ENTITES :: 64; + entities: [MAX_ENTITES]Entity; - entities[0] = Frog{} - entities[1] = Helicopter{} + entities[0] = Frog{}; + entities[1] = Helicopter{}; // etc. } @@ -751,13 +749,13 @@ tagged_unions :: proc() { { // Transliteration of code from this actual compiler // Some stuff is missing - Type :: type struct {} - Scope :: type struct {} - Token :: type struct {} - AstNode :: type struct {} - ExactValue :: type struct {} + Type :: struct {}; + Scope :: struct {}; + Token :: struct {}; + AstNode :: struct {}; + ExactValue :: struct {}; - EntityKind :: type enum { + EntityKind :: enum { Invalid, Constant, Variable, @@ -768,37 +766,37 @@ tagged_unions :: proc() { Count, } - Entity :: type struct { - Guid :: type i64 + Guid :: i64; + Entity :: struct { - kind: EntityKind - guid: Guid + kind: EntityKind, + guid: Guid, - scope: ^Scope - token: Token - type_: ^Type + scope: ^Scope, + token: Token, + type_: ^Type, using data: raw_union { Constant: struct { - value: ExactValue - } + value: ExactValue, + }, Variable: struct { - visited: bool // Cycle detection - used: bool // Variable is used - is_field: bool // Is struct field - anonymous: bool // Variable is an anonymous - } + visited: bool, // Cycle detection + used: bool, // Variable is used + is_field: bool, // Is struct field + anonymous: bool, // Variable is an anonymous + }, UsingVariable: struct { - } + }, TypeName: struct { - } + }, Procedure: struct { - used: bool - } + used: bool, + }, Builtin: struct { - id: int - } - } + id: int, + }, + }, } // Plus all the constructing procedures that go along with them!!!! @@ -806,60 +804,54 @@ tagged_unions :: proc() { } { - Type :: type struct {} - Scope :: type struct {} - Token :: type struct {} - AstNode :: type struct {} - ExactValue :: type struct {} + Type :: struct {}; + Scope :: struct {}; + Token :: struct {}; + AstNode :: struct {}; + ExactValue :: struct {}; - Entity :: type union { - Base :: type struct { - Guid :: type i64 - guid: Guid + Guid :: i64; + Entity_Base :: struct { - scope: ^Scope - token: Token - type_: ^Type - } + } + Entity :: union { + guid: Guid, - Constant: struct { - using base: Base - value: ExactValue - } - Variable: struct { - using base: Base - visited: bool // Cycle detection - used: bool // Variable is used - is_field: bool // Is struct field - anonymous: bool // Variable is an anonymous - } - UsingVariable: struct { - using base: Base - } - TypeName: struct { - using base: Base - } - Procedure: struct { - using base: Base - used: bool - } - Builtin: struct { - using base: Base - id: int - } + scope: ^Scope, + token: Token, + type_: ^Type, + + Constant{ + value: ExactValue, + }, + Variable{ + visited: bool, // Cycle detection + used: bool, // Variable is used + is_field: bool, // Is struct field + anonymous: bool, // Variable is an anonymous + }, + UsingVariable{ + }, + TypeName{ + }, + Procedure{ + used: bool, + }, + Builtin{ + id: int, + }, } - using Entity + using Entity; - e: Entity + e: Entity; e = Variable{ - base = Base{}, used = true, anonymous = false, - } + }; @@ -871,30 +863,30 @@ tagged_unions :: proc() { { // `Raw` unions still have uses, especially for mathematic types - Vector2 :: type raw_union { - using xy_: struct { x, y: f32 } - e: [2]f32 - v: {2}f32 + Vector2 :: raw_union { + using xy_: struct { x, y: f32 }, + e: [2]f32, + v: [vector 2]f32, } - Vector3 :: type raw_union { - using xyz_: struct { x, y, z: f32 } - xy: Vector2 - e: [3]f32 - v: {3}f32 + Vector3 :: raw_union { + using xyz_: struct { x, y, z: f32 }, + xy: Vector2, + e: [3]f32, + v: [vector 3]f32, } - v2: Vector2 - v2.x = 1 - v2.e[0] = 1 - v2.v[0] = 1 + v2: Vector2; + v2.x = 1; + v2.e[0] = 1; + v2.v[0] = 1; - v3: Vector3 - v3.x = 1 - v3.e[0] = 1 - v3.v[0] = 1 - v3.xy.x = 1 + v3: Vector3; + v3.x = 1; + v3.e[0] = 1; + v3.v[0] = 1; + v3.xy.x = 1; } } -nl :: proc() { print_nl() } +nl :: proc() { println(); } diff --git a/code/old_demos/demo004.odin b/code/old_demos/demo004.odin index 80812cd18..86588d60d 100644 --- a/code/old_demos/demo004.odin +++ b/code/old_demos/demo004.odin @@ -1,14 +1,14 @@ -#import "fmt.odin" -#import "utf8.odin" -#import "hash.odin" -#import "mem.odin" +#import "fmt.odin"; +#import "utf8.odin"; +#import "hash.odin"; +#import "mem.odin"; main :: proc() { { // New Standard Library stuff - s := "Hello" + s := "Hello"; fmt.println(s, utf8.valid_string(s), - hash.murmur64(s.data, s.count)) + hash.murmur64(cast([]byte)s)); // utf8.odin // hash.odin @@ -19,15 +19,15 @@ main :: proc() { } { - arena: mem.Arena - mem.init_arena_from_context(^arena, mem.megabytes(16)) // Uses default allocator - defer mem.free_arena(^arena) + arena: mem.Arena; + mem.init_arena_from_context(^arena, mem.megabytes(16)); // Uses default allocator + defer mem.free_arena(^arena); push_allocator mem.arena_allocator(^arena) { - x := new(int) - x^ = 1337 + x := new(int); + x^ = 1337; - fmt.println(x^) + fmt.println(x^); } /* @@ -48,14 +48,14 @@ main :: proc() { // You can also "push" a context - c := current_context() // Create copy of the allocator - c.allocator = mem.arena_allocator(^arena) + c := context; // Create copy of the allocator + c.allocator = mem.arena_allocator(^arena); push_context c { - x := new(int) - x^ = 365 + x := new(int); + x^ = 365; - fmt.println(x^) + fmt.println(x^); } } diff --git a/code/old_demos/demo005.odin b/code/old_demos/demo005.odin index 4198cffb6..f9d1a4a4c 100644 --- a/code/old_demos/demo005.odin +++ b/code/old_demos/demo005.odin @@ -42,12 +42,12 @@ syntax :: proc() { }; 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)); + // Slice interals are now just a `ptr+len+cap` + slice: []int; compile_assert(size_of_val(slice) == 3*size_of(int)); // Helper type - Help the reader understand what it is quicker - My_Int :: type int; - My_Proc :: type proc(int) -> f32; + My_Int :: #type int; + My_Proc :: #type proc(int) -> f32; // All declarations with : are either variable or constant @@ -59,6 +59,7 @@ syntax :: proc() { c_proc :: proc() { /* code here */ }; +/* x += 1; x -= 1; // ++ and -- have been removed @@ -67,7 +68,7 @@ syntax :: proc() { // 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` @@ -85,7 +86,7 @@ syntax :: proc() { Prefix_Type :: struct {x: int, y: f32, z: rawptr}; -thread_local my_tls: Prefix_Type; +#thread_local my_tls: Prefix_Type; prefixes :: proc() { using var: Prefix_Type; @@ -98,7 +99,7 @@ prefixes :: proc() { foo :: proc(using immutable pt: Prefix_Type, immutable int_ptr: ^int) { // int_ptr = nil; // Not valid - int_ptr^ = 123; // Is valid + // int_ptr^ = 123; // Not valid } @@ -154,6 +155,7 @@ foreign_procedures :: proc() { } special_expressions :: proc() { +/* // Block expression x := { a: f32 = 123; @@ -168,7 +170,7 @@ special_expressions :: proc() { // 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 @@ -191,17 +193,17 @@ loops :: proc() { break; } - for i in 0..<123 { // 123 exclusive + for i in 0..123 { // 123 exclusive } - for i in 0...122 { // 122 inclusive + for i in 0..123-1 { // 122 inclusive } - for val, idx in 12..<16 { + for val, idx in 12..16 { fmt.println(val, idx); } - primes := [...]int{2, 3, 5, 7, 11, 13, 17, 19}; + primes := [..]int{2, 3, 5, 7, 11, 13, 17, 19}; for p in primes { fmt.println(p); @@ -224,7 +226,7 @@ loops :: proc() { when false { for i, size := 0; i < name.count; i += size { r: rune; - r, size = utf8.decode_rune(name[i:]); + r, size = utf8.decode_rune(name[i..]); fmt.printf("%r\n", r); } } |