aboutsummaryrefslogtreecommitdiff
path: root/code
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-04-02 22:03:52 +0100
committerGinger Bill <bill@gingerbill.org>2017-04-02 22:03:52 +0100
commit382a5ca6a27ea0f6dde4c0783d55f5dca8ac2575 (patch)
treefc7b7592651b166bdbbf7334649b062d584231e9 /code
parent96e8bb5b6f3c8d2cf2b0fae8c7a9c710c4e9dbb0 (diff)
Update and regression test old demos
Diffstat (limited to 'code')
-rw-r--r--code/game.odin85
-rw-r--r--code/old_demos/demo001.odin16
-rw-r--r--code/old_demos/demo002.odin732
-rw-r--r--code/old_demos/demo004.odin34
-rw-r--r--code/old_demos/demo005.odin28
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);
}
}