123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- import "core:fmt.odin";
- import "core:os.odin";
- import "core:mem.odin";
- // import "http_test.odin" as ht;
- // import "game.odin" as game;
- // import "punity.odin" as pn;
- main :: proc() {
- struct_padding();
- bounds_checking();
- type_introspection();
- any_type();
- crazy_introspection();
- namespaces_and_files();
- miscellany();
- /*
- ht.run();
- game.run();
- {
- init :: proc(c: ^pn.Core) {}
- step :: proc(c: ^pn.Core) {}
- pn.run(init, step);
- }
- */
- }
- struct_padding :: proc() {
- {
- A :: struct {
- a: u8,
- b: u32,
- c: u16,
- }
- B :: struct {
- a: [7]u8,
- b: [3]u16,
- c: u8,
- d: u16,
- }
- fmt.println("size_of(A):", size_of(A));
- fmt.println("size_of(B):", size_of(B));
- // n.b. http://cbloomrants.blogspot.co.uk/2012/07/07-23-12-structs-are-not-what-you-want.html
- }
- {
- A :: struct #ordered {
- a: u8,
- b: u32,
- c: u16,
- }
- B :: struct #ordered {
- a: [7]u8,
- b: [3]u16,
- c: u8,
- d: u16,
- }
- fmt.println("size_of(A):", size_of(A));
- fmt.println("size_of(B):", size_of(B));
- // C-style structure layout
- }
- {
- A :: struct #packed {
- a: u8,
- b: u32,
- c: u16,
- }
- B :: struct #packed {
- a: [7]u8,
- b: [3]u16,
- c: u8,
- d: u16,
- }
- fmt.println("size_of(A):", size_of(A));
- fmt.println("size_of(B):", size_of(B));
- // Useful for explicit layout
- }
- // Member sorting by priority
- // Alignment desc.
- // Size desc.
- // source order asc.
- /*
- A :: struct {
- a: u8
- b: u32
- c: u16
- }
- B :: struct {
- a: [7]u8
- b: [3]u16
- c: u8
- d: u16
- }
- Equivalent too
- A :: struct #ordered {
- b: u32
- c: u16
- a: u8
- }
- B :: struct #ordered {
- b: [3]u16
- d: u16
- a: [7]u8
- c: u8
- }
- */
- }
- bounds_checking :: proc() {
- x: [4]int;
- // x[-1] = 0; // Compile Time
- // x[4] = 0; // Compile Time
- {
- a, b := -1, 4;
- // x[a] = 0; // Runtime Time
- // x[b] = 0; // Runtime Time
- }
- // Works for arrays, strings, slices, and related procedures & operations
- {
- base: [10]int;
- s := base[2..6];
- a, b := -1, 6;
- #no_bounds_check {
- s[a] = 0;
- // #bounds_check s[b] = 0;
- }
- #no_bounds_check
- if s[a] == 0 {
- // Do whatever
- }
- // Bounds checking can be toggled explicit
- // on a per statement basis.
- // _any statement_
- }
- }
- type_introspection :: proc() {
- {
- info: ^Type_Info;
- x: int;
- info = type_info_of(int); // by type
- info = type_info_of(x); // by value
- // See: runtime.odin
- match i in info.variant {
- case Type_Info_Integer:
- fmt.println("integer!");
- case Type_Info_Float:
- fmt.println("float!");
- case:
- fmt.println("potato!");
- }
- // Unsafe cast
- integer_info := cast(^Type_Info_Integer)cast(rawptr)info;
- }
- {
- Vector2 :: struct { x, y: f32 }
- Vector3 :: struct { x, y, z: f32 }
- v1: Vector2;
- v2: Vector3;
- v3: Vector3;
- t1 := type_info_of(v1);
- t2 := type_info_of(v2);
- t3 := type_info_of(v3);
- fmt.println();
- fmt.print("Type of v1 is:\n\t", t1);
- fmt.println();
- fmt.print("Type of v2 is:\n\t", t2);
- fmt.println("\n");
- fmt.println("t1 == t2:", t1 == t2);
- fmt.println("t2 == t3:", t2 == t3);
- }
- }
- any_type :: proc() {
- a: any;
- x: int = 123;
- y: f64 = 6.28;
- z: string = "Yo-Yo Ma";
- // All types can be implicit cast to `any`
- a = x;
- a = y;
- a = z;
- a = a; // This the "identity" type, it doesn't get converted
- a = 123; // Literals are copied onto the stack first
- // any has two members
- // data - rawptr to the data
- // type_info - pointer to the type info
- fmt.println(x, y, z);
- // See: fmt.odin
- // For variadic any procedures in action
- }
- crazy_introspection :: proc() {
- {
- Fruit :: enum {
- APPLE,
- BANANA,
- GRAPE,
- MELON,
- PEACH,
- TOMATO,
- }
- s: string;
- // s = enum_to_string(Fruit.PEACH);
- fmt.println(s);
- f := Fruit.GRAPE;
- // s = enum_to_string(f);
- fmt.println(s);
- fmt.println(f);
- // See: runtime.odin
- }
- {
- // NOTE(bill): This is not safe code and I would not recommend this at all
- // I'd recommend you use `match type` to get the subtype rather than
- // casting pointers
- Fruit :: enum {
- APPLE,
- BANANA,
- GRAPE,
- MELON,
- PEACH,
- TOMATO,
- }
- fruit_ti := type_info_of(Fruit);
- name := fruit_ti.variant.(Type_Info_Named).name;
- info, _ := type_info_base(fruit_ti).variant.(Type_Info_Enum);
- fmt.printf("%s :: enum %T {\n", name, info.base);
- for _, i in info.values {
- fmt.printf("\t%s\t= %v,\n", info.names[i], info.values[i]);
- }
- fmt.printf("}\n");
- // NOTE(bill): look at that type-safe printf!
- }
- {
- Vector3 :: struct {x, y, z: f32}
- a := Vector3{x = 1, y = 4, z = 9};
- fmt.println(a);
- b := Vector3{x = 9, y = 3, z = 1};
- fmt.println(b);
- // NOTE(bill): See fmt.odin
- }
- // n.b. This pretty much "solves" serialization (to strings)
- }
- // #import "test.odin"
- namespaces_and_files :: proc() {
- // test.thing()
- // test.format.println()
- // test.println()
- /*
- // Non-exporting import
- #import "file.odin"
- #import "file.odin" as file
- #import "file.odin" as .
- #import "file.odin" as _
- // Exporting import
- #include "file.odin"
- */
- // Talk about scope rules and diagram
- }
- miscellany :: proc() {
- /*
- win32 `__imp__` prefix
- #dll_import
- #dll_export
- Change exported name/symbol for linking
- #link_name
- Custom calling conventions
- #stdcall
- #fastcall
- Runtime stuff
- #shared_global_scope
- */
- // assert(false)
- // #assert(false)
- // panic("Panic message goes here")
- }
|