aboutsummaryrefslogtreecommitdiff
path: root/code/old_demos
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-08-27 17:03:27 +0100
committerGinger Bill <bill@gingerbill.org>2017-08-27 17:03:27 +0100
commitb9e347ef5072ac3d1f8dcc1ba2d678109f9ff016 (patch)
tree5890f5aba3eaced5c85d6ca7b95d69df163397b5 /code/old_demos
parent6707c8750e951ed6533ab3d4240314cf0bba7147 (diff)
Replace `import_load` with `using import .`
Diffstat (limited to 'code/old_demos')
-rw-r--r--code/old_demos/demo001.odin337
-rw-r--r--code/old_demos/demo002.odin892
-rw-r--r--code/old_demos/demo004.odin66
-rw-r--r--code/old_demos/demo005.odin284
-rw-r--r--code/old_demos/old_runtime.odin412
5 files changed, 0 insertions, 1991 deletions
diff --git a/code/old_demos/demo001.odin b/code/old_demos/demo001.odin
deleted file mode 100644
index 5f30af8fe..000000000
--- a/code/old_demos/demo001.odin
+++ /dev/null
@@ -1,337 +0,0 @@
-#import "fmt.odin";
-#import "os.odin";
-#import "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(int); // by type
- info = type_info_of_val(x); // by value
- // See: runtime.odin
-
- match i in info {
- case Type_Info.Integer:
- fmt.println("integer!");
- case Type_Info.Float:
- fmt.println("float!");
- default:
- 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_val(v1);
- t2 := type_info_of_val(v2);
- t3 := type_info_of_val(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(Fruit);
- 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("%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");
-
- // 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)
- // compile_assert(false)
- // panic("Panic message goes here")
-}
-
-
-
-
diff --git a/code/old_demos/demo002.odin b/code/old_demos/demo002.odin
deleted file mode 100644
index 78cdb194a..000000000
--- a/code/old_demos/demo002.odin
+++ /dev/null
@@ -1,892 +0,0 @@
-// Demo 002
-#load "fmt.odin";
-#load "math.odin";
-// #load "game.odin"
-
-#thread_local tls_int: int;
-
-main :: proc() {
- // Forenotes
-
- // Semicolons are now optional
- // Rule for when a semicolon is expected after a statement
- // - If the next token is not on the same line
- // - if the next token is a closing brace }
- // - Otherwise, a semicolon is needed
- //
- // Expections:
- // for, if, match
- // if x := thing(); x < 123 {}
- // for i := 0; i < 123; i++ {}
-
- // Q: Should I use the new rule or go back to the old one without optional semicolons?
-
-
- // #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 :: proc() {
- Thing :: struct {
- id: int,
- x: f32,
- name: string,
- };
- {
- t1: Thing;
- t1.id = 1;
-
- t3 := Thing{};
- t4 := Thing{1, 2, "Fred"};
- // t5 := Thing{1, 2};
-
- t6 := Thing{
- name = "Tom",
- x = 23,
- };
- }
-}
-
-enumerations :: proc() {
- {
- Fruit :: enum {
- APPLE, // 0
- BANANA, // 1
- PEAR, // 2
- };
-
- f := Fruit.APPLE;
- // g12: int = Fruit.BANANA
- g: int = cast(int)Fruit.BANANA;
- // However, you can use enums are index values as _any_ integer allowed
- }
- {
- Fruit1 :: enum int {
- APPLE,
- BANANA,
- PEAR,
- }
-
- Fruit2 :: enum u8 {
- APPLE,
- BANANA,
- PEAR,
- }
-
- Fruit3 :: enum u8 {
- APPLE = 1,
- BANANA, // 2
- PEAR = 5,
- TOMATO, // 6
- }
- }
-
- // Q: remove the need for `type` if it's a record (struct/enum/raw_union/union)?
-}
-
-variadic_procedures :: proc() {
- print_ints :: proc(args: ..int) {
- for arg, i in args {
- if i > 0 {
- print(", ");
- }
- print(arg);
- }
- }
-
- print_ints(); // nl()
- print_ints(1); nl();
- print_ints(1, 2, 3); nl();
-
- print_prefix_f32s :: proc(prefix: string, args: ..f32) {
- print(prefix);
- print(": ");
- for arg, i in args {
- if i > 0 {
- print(", ");
- }
- print(arg);
- }
- }
-
- 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
-
- // This is first step for a `print` procedure but I do not have an `any` type
- // yet as this requires a few other things first - i.e. introspection
-
- // NOTE(bill): I haven't yet added the feature of expanding a slice or array into
- // a variadic a parameter but it's pretty trivial to add
-}
-
-new_builtins :: proc() {
- {
- a := new(int);
- b := make([]int, 12);
- c := make([]int, 12, 16);
-
- 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 `free` and should I overload it for slices too?
-
- {
- prev_context := context;
- defer __context = prev_context;
- // Q: Should I add a `push_context` feature to the language?
-
- __context.allocator = default_allocator();
-
- a := new(int);
- defer free(a);
-
- // Do whatever
-
- }
- }
-
- {
- a: int = 123;
- b: type_of_val(a) = 321;
-
- // NOTE(bill): This matches the current naming scheme
- // size_of
- // align_of
- // offset_of
- //
- // size_of_val
- // align_of_val
- // offset_of_val
- // type_of_val
- }
-
- {
- // Compile time assert
- COND :: true;
- compile_assert(COND);
- // compile_assert(!COND)
-
- // Runtime assert
- x := true;
- assert(x);
- // assert(!x);
- }
-
- {
- 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
- // pointer indexing
- // pointer slicing
-
- // Reason
-
- a: [16]int;
- a[1] = 1;
- b := ^a;
- // Auto pointer deref
- // consistent with record members
- assert(b[1] == 1);
-
- // Q: Should I add them back in at the cost of inconsitency?
- }
-
- {
- 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(C); nl();
- print(D); nl();
- print(E); nl();
- }
-}
-
-
-match_statement :: proc() {
- // NOTE(bill): `match` statements are similar to `switch` statements
- // in other languages but there are few differences
-
- {
- match x := 5; x {
- case 1: // cases must be constant expression
- print("1!\n");
- // break by default
-
- case 2:
- s := "2!\n"; // Each case has its own scope
- print(s);
- break; // explicit break
-
- case 3, 4: // multiple cases
- print("3 or 4!\n");
-
- case 5:
- print("5!\n");
- fallthrough; // explicit fallthrough
-
- default:
- print("default!\n");
- }
-
-
-
- match x := 1.5; x {
- case 1.5:
- print("1.5!\n");
- // break by default
- case TAU:
- print("τ!\n");
- default:
- print("default!\n");
- }
-
-
-
- match x := "Hello"; x {
- case "Hello":
- print("greeting\n");
- // break by default
- case "Goodbye":
- print("farewell\n");
- default:
- print("???\n");
- }
-
-
-
-
-
-
- a := 53;
- match {
- case a == 1:
- print("one\n");
- case a == 2:
- print("a couple\n");
- case a < 7, a == 7:
- print("a few\n");
- case a < 12: // intentional bug
- print("several\n");
- case a >= 12 && a < 100:
- print("dozens\n");
- case a >= 100 && a < 1000:
- print("hundreds\n");
- default:
- print("a fuck ton\n");
- }
-
- // Identical to this
-
- b := 53;
- if b == 1 {
- print("one\n");
- } else if b == 2 {
- print("a couple\n");
- } else if b < 7 || b == 7 {
- print("a few\n");
- } else if b < 12 { // intentional bug
- print("several\n");
- } else if b >= 12 && b < 100 {
- print("dozens\n");
- } else if b >= 100 && b < 1000 {
- print("hundreds\n");
- } else {
- print("a fuck ton\n");
- }
-
- // However, match statements allow for `break` and `fallthrough` unlike
- // an if statement
- }
-}
-
-Vector3 :: struct {x, y, z: f32}
-
-print_floats :: proc(args: ..f32) {
- for arg, i in args {
- if i > 0 {
- print(", ");
- }
- print(arg);
- }
- println();
-}
-
-namespacing :: proc() {
- {
- Thing :: #type struct {
- x: f32,
- name: string,
- };
-
- a: Thing;
- a.x = 3;
- {
- Thing :: #type struct {
- y: int,
- test: bool,
- }
-
- b: Thing; // Uses this scope's Thing
- b.test = true;
- }
- }
-/*
- {
- Entity :: struct {
- Guid :: int
- Nested :: struct {
- MyInt :: int
- i: int
- }
-
- CONSTANT :: 123
-
-
- guid: Guid
- name: string
- pos: Vector3
- vel: Vector3
- nested: Nested
- }
-
- guid: Entity.Guid = Entity.CONSTANT
- i: Entity.Nested.MyInt
-
-
-
- {
- using Entity
- guid: Guid = CONSTANT
- using Nested
- i: MyInt
- }
-
-
- {
- using Entity.Nested
- guid: Entity.Guid = Entity.CONSTANT
- i: MyInt
- }
-
-
- {
- e: Entity
- using e
- guid = 27832
- name = "Bob"
-
- print(e.guid as int); nl()
- print(e.name); nl()
- }
-
- {
- using e: Entity
- guid = 78456
- name = "Thing"
-
- print(e.guid as int); nl()
- print(e.name); nl()
- }
- }
-
- {
- Entity :: struct {
- Guid :: int
- Nested :: struct {
- MyInt :: int
- i: int
- }
-
- CONSTANT :: 123
-
-
- guid: Guid
- name: string
- using pos: Vector3
- vel: Vector3
- using nested: ^Nested
- }
-
- e := Entity{nested = new(Entity.Nested)}
- e.x = 123
- e.i = Entity.CONSTANT
- }
-
-*/
-
- {
- Entity :: struct {
- position: Vector3
- }
-
- print_pos_1 :: proc(entity: ^Entity) {
- print("print_pos_1: ");
- print_floats(entity.position.x, entity.position.y, entity.position.z);
- }
-
- print_pos_2 :: proc(entity: ^Entity) {
- using entity;
- print("print_pos_2: ");
- print_floats(position.x, position.y, position.z);
- }
-
- print_pos_3 :: proc(using entity: ^Entity) {
- print("print_pos_3: ");
- print_floats(position.x, position.y, position.z);
- }
-
- print_pos_4 :: proc(using entity: ^Entity) {
- 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);
-
- // This is similar to C++'s `this` pointer that is implicit and only available in methods
- }
-}
-
-subtyping :: proc() {
- {
- // C way for subtyping/subclassing
-
- Entity :: struct {
- position: Vector3,
- }
-
- Frog :: struct {
- entity: Entity,
- jump_height: f32,
- }
-
- f: Frog;
- f.entity.position = Vector3{1, 2, 3};
-
- using f.entity;
- position = Vector3{1, 2, 3};
-
- }
-
- {
- // C++ way for subtyping/subclassing
-
- Entity :: struct {
- position: Vector3
- }
-
- Frog :: struct {
- using entity: Entity,
- jump_height: f32,
- }
-
- f: Frog;
- f.position = Vector3{1, 2, 3};
-
-
- print_pos :: proc(using entity: Entity) {
- print("print_pos: ");
- print_floats(position.x, position.y, position.z);
- }
-
- print_pos(f.entity);
- // print_pos(f);
-
- // Subtype Polymorphism
- }
-
- {
- // More than C++ way for subtyping/subclassing
-
- Entity :: struct {
- position: Vector3,
- }
-
- 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};
-
-
- print_pos :: proc(using entity: ^Entity) {
- print("print_pos: ");
- print_floats(position.x, position.y, position.z);
- }
-
- print_pos(f.entity);
- // print_pos(^f);
- // print_pos(f);
- }
-
- {
- // More efficient subtyping
-
- Entity :: struct {
- position: Vector3,
- }
-
- Frog :: struct {
- jump_height: f32,
- using entity: ^Entity,
- }
-
- 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;
- }
-
- f: Frog;
- f.entity = next_entity(entities[..], ^entity_count);
- f.position = Vector3{3, 4, 6};
-
- using f.position;
- print_floats(x, y, z);
- }
-
- {
- // Down casting
-
- Entity :: struct {
- position: Vector3,
- }
-
- Frog :: struct {
- jump_height: f32,
- using entity: Entity,
- }
-
- f: Frog;
- f.jump_height = 564;
- e := ^f.entity;
-
- 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
- }
-
- {
- // Multiple "inheritance"/subclassing
-
- Entity :: struct {
- position: Vector3,
- }
- Climber :: struct {
- speed: f32,
- }
-
- Frog :: struct {
- using entity: Entity,
- using climber: Climber,
- }
- }
-}
-
-tagged_unions :: proc() {
- {
- EntityKind :: enum {
- INVALID,
- FROG,
- GIRAFFE,
- HELICOPTER,
- }
-
- Entity :: struct {
- kind: EntityKind
- using data: raw_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,
- },
- }
- }
-
- e: Entity;
- e.kind = EntityKind.FROG;
- e.frog.jump_height = 12;
-
- f: type_of_val(e.frog);
-
- // But this is very unsafe and extremely cumbersome to write
- // In C++, I use macros to alleviate this but it's not a solution
- }
-
- {
- 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"};
-
-
-
-
- // Requires a pointer to the union
- // `x` will be a pointer to type of the case
-
- match x in ^f {
- case Frog:
- print("Frog!\n");
- print(x.jump_height); nl();
- // x.jump_height = 3;
- print(x.jump_height); nl();
- case Giraffe:
- print("Giraffe!\n");
- case Helicopter:
- print("ROFLCOPTER!\n");
- default:
- print("invalid entity\n");
- }
-
-
- // Q: Allow for a non pointer version with takes a copy instead?
- // Or it takes the pointer the data and not a copy
-
-
- // 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,
- }
- */
- // This is to allow for pointer casting if needed
-
-
- // Advantage over subtyping version
- MAX_ENTITES :: 64;
- entities: [MAX_ENTITES]Entity;
-
- entities[0] = Frog{};
- entities[1] = Helicopter{};
- // etc.
- }
-
-
- {
- // Transliteration of code from this actual compiler
- // Some stuff is missing
- Type :: struct {};
- Scope :: struct {};
- Token :: struct {};
- AstNode :: struct {};
- ExactValue :: struct {};
-
- EntityKind :: enum {
- Invalid,
- Constant,
- Variable,
- UsingVariable,
- TypeName,
- Procedure,
- Builtin,
- Count,
- }
-
- Guid :: i64;
- Entity :: struct {
-
- kind: EntityKind,
- guid: Guid,
-
- scope: ^Scope,
- token: Token,
- type_: ^Type,
-
- using data: raw_union {
- Constant: struct {
- 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
- },
- UsingVariable: struct {
- },
- TypeName: struct {
- },
- Procedure: struct {
- used: bool,
- },
- Builtin: struct {
- id: int,
- },
- },
- }
-
- // Plus all the constructing procedures that go along with them!!!!
- // It's a nightmare
- }
-
- {
- Type :: struct {};
- Scope :: struct {};
- Token :: struct {};
- AstNode :: struct {};
- ExactValue :: struct {};
-
-
- Guid :: i64;
- Entity_Base :: struct {
-
- }
-
- Entity :: union {
- guid: Guid,
-
- 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;
-
- e: Entity;
-
- e = Variable{
- used = true,
- anonymous = false,
- };
-
-
-
- // Q: Allow a "base" type to be added to a union?
- // Or even `using` on union to get the same properties?
- }
-
-
- {
- // `Raw` unions still have uses, especially for mathematic types
-
- Vector2 :: raw_union {
- using xy_: struct { x, y: f32 },
- e: [2]f32,
- v: [vector 2]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;
-
- v3: Vector3;
- v3.x = 1;
- v3.e[0] = 1;
- v3.v[0] = 1;
- v3.xy.x = 1;
- }
-}
-
-nl :: proc() { println(); }
diff --git a/code/old_demos/demo004.odin b/code/old_demos/demo004.odin
deleted file mode 100644
index 86588d60d..000000000
--- a/code/old_demos/demo004.odin
+++ /dev/null
@@ -1,66 +0,0 @@
-#import "fmt.odin";
-#import "utf8.odin";
-#import "hash.odin";
-#import "mem.odin";
-
-main :: proc() {
- { // New Standard Library stuff
- s := "Hello";
- fmt.println(s,
- utf8.valid_string(s),
- hash.murmur64(cast([]byte)s));
-
- // utf8.odin
- // hash.odin
- // - crc, fnv, fnva, murmur
- // mem.odin
- // - Custom allocators
- // - Helpers
- }
-
- {
- 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;
-
- fmt.println(x^);
- }
-
- /*
- push_allocator x {
- ...
- }
-
- is equivalent to:
-
- {
- prev_allocator := __context.allocator
- __context.allocator = x
- defer __context.allocator = prev_allocator
-
- ...
- }
- */
-
- // You can also "push" a context
-
- c := context; // Create copy of the allocator
- c.allocator = mem.arena_allocator(^arena);
-
- push_context c {
- x := new(int);
- x^ = 365;
-
- fmt.println(x^);
- }
- }
-
- // Backend improvements
- // - Minimal dependency building (only build what is needed)
- // - Numerous bugs fixed
- // - Mild parsing recovery after bad syntax error
-}
diff --git a/code/old_demos/demo005.odin b/code/old_demos/demo005.odin
deleted file mode 100644
index f9d1a4a4c..000000000
--- a/code/old_demos/demo005.odin
+++ /dev/null
@@ -1,284 +0,0 @@
-#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();
- procedure_overloading();
-}
-
-syntax :: proc() {
- // Cyclic type checking
- // Uncomment to see the error
- // A :: struct {b: B};
- // B :: struct {a: A};
-
- x: int;
- y := cast(f32)x;
- z := transmute(u32)y;
- // down_cast, union_cast are 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+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;
-
-
- // 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
- u, 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; // Not 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..123-1 { // 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
-}
diff --git a/code/old_demos/old_runtime.odin b/code/old_demos/old_runtime.odin
deleted file mode 100644
index 655058e0a..000000000
--- a/code/old_demos/old_runtime.odin
+++ /dev/null
@@ -1,412 +0,0 @@
-#include "win32.odin"
-
-assume :: proc(cond: bool) #foreign "llvm.assume"
-
-__debug_trap :: proc() #foreign "llvm.debugtrap"
-__trap :: proc() #foreign "llvm.trap"
-read_cycle_counter :: proc() -> u64 #foreign "llvm.readcyclecounter"
-
-bit_reverse16 :: proc(b: u16) -> u16 #foreign "llvm.bitreverse.i16"
-bit_reverse32 :: proc(b: u32) -> u32 #foreign "llvm.bitreverse.i32"
-bit_reverse64 :: proc(b: u64) -> u64 #foreign "llvm.bitreverse.i64"
-
-byte_swap16 :: proc(b: u16) -> u16 #foreign "llvm.bswap.i16"
-byte_swap32 :: proc(b: u32) -> u32 #foreign "llvm.bswap.i32"
-byte_swap64 :: proc(b: u64) -> u64 #foreign "llvm.bswap.i64"
-
-fmuladd_f32 :: proc(a, b, c: f32) -> f32 #foreign "llvm.fmuladd.f32"
-fmuladd_f64 :: proc(a, b, c: f64) -> f64 #foreign "llvm.fmuladd.f64"
-
-// TODO(bill): make custom heap procedures
-heap_alloc :: proc(len: int) -> rawptr #foreign "malloc"
-heap_dealloc :: proc(ptr: rawptr) #foreign "free"
-
-memory_zero :: proc(data: rawptr, len: int) {
- d := slice_ptr(data as ^byte, len)
- for i := 0; i < len; i++ {
- d[i] = 0
- }
-}
-
-memory_compare :: proc(dst, src: rawptr, len: int) -> int {
- s1, s2: ^byte = dst, src
- for i := 0; i < len; i++ {
- a := ptr_offset(s1, i)^
- b := ptr_offset(s2, i)^
- if a != b {
- return (a - b) as int
- }
- }
- return 0
-}
-
-memory_copy :: proc(dst, src: rawptr, n: int) #inline {
- if dst == src {
- return
- }
-
- v128b :: type {4}u32
- compile_assert(align_of(v128b) == 16)
-
- d, s: ^byte = dst, src
-
- for ; s as uint % 16 != 0 && n != 0; n-- {
- d^ = s^
- d, s = ptr_offset(d, 1), ptr_offset(s, 1)
- }
-
- if d as uint % 16 == 0 {
- for ; n >= 16; d, s, n = ptr_offset(d, 16), ptr_offset(s, 16), n-16 {
- (d as ^v128b)^ = (s as ^v128b)^
- }
-
- if n&8 != 0 {
- (d as ^u64)^ = (s as ^u64)^
- d, s = ptr_offset(d, 8), ptr_offset(s, 8)
- }
- if n&4 != 0 {
- (d as ^u32)^ = (s as ^u32)^;
- d, s = ptr_offset(d, 4), ptr_offset(s, 4)
- }
- if n&2 != 0 {
- (d as ^u16)^ = (s as ^u16)^
- d, s = ptr_offset(d, 2), ptr_offset(s, 2)
- }
- if n&1 != 0 {
- d^ = s^
- d, s = ptr_offset(d, 1), ptr_offset(s, 1)
- }
- return;
- }
-
- // IMPORTANT NOTE(bill): Little endian only
- LS :: proc(a, b: u32) -> u32 #inline { return a << b }
- RS :: proc(a, b: u32) -> u32 #inline { return a >> b }
- /* NOTE(bill): Big endian version
- LS :: proc(a, b: u32) -> u32 #inline { return a >> b; }
- RS :: proc(a, b: u32) -> u32 #inline { return a << b; }
- */
-
- w, x: u32
-
- if d as uint % 4 == 1 {
- w = (s as ^u32)^
- d^ = s^; d = ptr_offset(d, 1); s = ptr_offset(s, 1)
- d^ = s^; d = ptr_offset(d, 1); s = ptr_offset(s, 1)
- d^ = s^; d = ptr_offset(d, 1); s = ptr_offset(s, 1)
- n -= 3
-
- for n > 16 {
- d32 := d as ^u32
- s32 := ptr_offset(s, 1) as ^u32
- x = s32^; d32^ = LS(w, 24) | RS(x, 8)
- d32, s32 = ptr_offset(d32, 1), ptr_offset(s32, 1)
- w = s32^; d32^ = LS(x, 24) | RS(w, 8)
- d32, s32 = ptr_offset(d32, 1), ptr_offset(s32, 1)
- x = s32^; d32^ = LS(w, 24) | RS(x, 8)
- d32, s32 = ptr_offset(d32, 1), ptr_offset(s32, 1)
- w = s32^; d32^ = LS(x, 24) | RS(w, 8)
- d32, s32 = ptr_offset(d32, 1), ptr_offset(s32, 1)
-
- d, s, n = ptr_offset(d, 16), ptr_offset(s, 16), n-16
- }
-
- } else if d as uint % 4 == 2 {
- w = (s as ^u32)^
- d^ = s^; d = ptr_offset(d, 1); s = ptr_offset(s, 1)
- d^ = s^; d = ptr_offset(d, 1); s = ptr_offset(s, 1)
- n -= 2
-
- for n > 17 {
- d32 := d as ^u32
- s32 := ptr_offset(s, 2) as ^u32
- x = s32^; d32^ = LS(w, 16) | RS(x, 16)
- d32, s32 = ptr_offset(d32, 1), ptr_offset(s32, 1)
- w = s32^; d32^ = LS(x, 16) | RS(w, 16)
- d32, s32 = ptr_offset(d32, 1), ptr_offset(s32, 1)
- x = s32^; d32^ = LS(w, 16) | RS(x, 16)
- d32, s32 = ptr_offset(d32, 1), ptr_offset(s32, 1)
- w = s32^; d32^ = LS(x, 16) | RS(w, 16)
- d32, s32 = ptr_offset(d32, 1), ptr_offset(s32, 1)
-
- d, s, n = ptr_offset(d, 16), ptr_offset(s, 16), n-16
- }
-
- } else if d as uint % 4 == 3 {
- w = (s as ^u32)^
- d^ = s^
- n -= 1
-
- for n > 18 {
- d32 := d as ^u32
- s32 := ptr_offset(s, 3) as ^u32
- x = s32^; d32^ = LS(w, 8) | RS(x, 24)
- d32, s32 = ptr_offset(d32, 1), ptr_offset(s32, 1)
- w = s32^; d32^ = LS(x, 8) | RS(w, 24)
- d32, s32 = ptr_offset(d32, 1), ptr_offset(s32, 1)
- x = s32^; d32^ = LS(w, 8) | RS(x, 24)
- d32, s32 = ptr_offset(d32, 1), ptr_offset(s32, 1)
- w = s32^; d32^ = LS(x, 8) | RS(w, 24)
- d32, s32 = ptr_offset(d32, 1), ptr_offset(s32, 1)
-
- d, s, n = ptr_offset(d, 16), ptr_offset(s, 16), n-16
- }
- }
-
- if n&16 != 0 {
- (d as ^v128b)^ = (s as ^v128b)^
- d, s = ptr_offset(d, 16), ptr_offset(s, 16)
- }
- if n&8 != 0 {
- (d as ^u64)^ = (s as ^u64)^
- d, s = ptr_offset(d, 8), ptr_offset(s, 8)
- }
- if n&4 != 0 {
- (d as ^u32)^ = (s as ^u32)^;
- d, s = ptr_offset(d, 4), ptr_offset(s, 4)
- }
- if n&2 != 0 {
- (d as ^u16)^ = (s as ^u16)^
- d, s = ptr_offset(d, 2), ptr_offset(s, 2)
- }
- if n&1 != 0 {
- d^ = s^
- }
-}
-
-memory_move :: proc(dst, src: rawptr, n: int) #inline {
- d, s: ^byte = dst, src
- if d == s {
- return
- }
- if d >= ptr_offset(s, n) || ptr_offset(d, n) <= s {
- memory_copy(d, s, n)
- return
- }
-
- // TODO(bill): Vectorize the shit out of this
- if d < s {
- if s as int % size_of(int) == d as int % size_of(int) {
- for d as int % size_of(int) != 0 {
- if n == 0 {
- return
- }
- n--
- d^ = s^
- d, s = ptr_offset(d, 1), ptr_offset(s, 1)
- }
- di, si := d as ^int, s as ^int
- for n >= size_of(int) {
- di^ = si^
- di, si = ptr_offset(di, 1), ptr_offset(si, 1)
- n -= size_of(int)
- }
- }
- for ; n > 0; n-- {
- d^ = s^
- d, s = ptr_offset(d, 1), ptr_offset(s, 1)
- }
- } else {
- if s as int % size_of(int) == d as int % size_of(int) {
- for ptr_offset(d, n) as int % size_of(int) != 0 {
- if n == 0 {
- return
- }
- n--
- d^ = s^
- d, s = ptr_offset(d, 1), ptr_offset(s, 1)
- }
- for n >= size_of(int) {
- n -= size_of(int)
- di := ptr_offset(d, n) as ^int
- si := ptr_offset(s, n) as ^int
- di^ = si^
- }
- for ; n > 0; n-- {
- d^ = s^
- d, s = ptr_offset(d, 1), ptr_offset(s, 1)
- }
- }
- for n > 0 {
- n--
- dn := ptr_offset(d, n)
- sn := ptr_offset(s, n)
- dn^ = sn^
- }
- }
-}
-
-__string_eq :: proc(a, b: string) -> bool {
- if len(a) != len(b) {
- return false
- }
- if ^a[0] == ^b[0] {
- return true
- }
- return memory_compare(^a[0], ^b[0], len(a)) == 0
-}
-
-__string_cmp :: proc(a, b : string) -> int {
- min_len := len(a)
- if len(b) < min_len {
- min_len = len(b)
- }
- for i := 0; i < min_len; i++ {
- x := a[i]
- y := b[i]
- if x < y {
- return -1
- } else if x > y {
- return +1
- }
- }
-
- if len(a) < len(b) {
- return -1
- } else if len(a) > len(b) {
- return +1
- }
- return 0
-}
-
-__string_ne :: proc(a, b : string) -> bool #inline { return !__string_eq(a, b) }
-__string_lt :: proc(a, b : string) -> bool #inline { return __string_cmp(a, b) < 0 }
-__string_gt :: proc(a, b : string) -> bool #inline { return __string_cmp(a, b) > 0 }
-__string_le :: proc(a, b : string) -> bool #inline { return __string_cmp(a, b) <= 0 }
-__string_ge :: proc(a, b : string) -> bool #inline { return __string_cmp(a, b) >= 0 }
-
-
-
-
-Allocation_Mode :: type enum {
- ALLOC,
- DEALLOC,
- DEALLOC_ALL,
- RESIZE,
-}
-
-
-
-Allocator_Proc :: type proc(allocator_data: rawptr, mode: Allocation_Mode,
- size, alignment: int,
- old_memory: rawptr, old_size: int, flags: u64) -> rawptr
-
-Allocator :: type struct {
- procedure: Allocator_Proc;
- data: rawptr
-}
-
-
-Context :: type struct {
- thread_ptr: rawptr
-
- user_data: rawptr
- user_index: int
-
- allocator: Allocator
-}
-
-#thread_local context: Context
-
-DEFAULT_ALIGNMENT :: 2*size_of(int)
-
-
-__check_context :: proc() {
- if context.allocator.procedure == null {
- context.allocator = __default_allocator()
- }
- if context.thread_ptr == null {
- // TODO(bill):
- // context.thread_ptr = current_thread_pointer()
- }
-}
-
-
-alloc :: proc(size: int) -> rawptr #inline { return alloc_align(size, DEFAULT_ALIGNMENT) }
-
-alloc_align :: proc(size, alignment: int) -> rawptr #inline {
- __check_context()
- a := context.allocator
- return a.procedure(a.data, Allocation_Mode.ALLOC, size, alignment, null, 0, 0)
-}
-
-dealloc :: proc(ptr: rawptr) #inline {
- __check_context()
- a := context.allocator
- _ = a.procedure(a.data, Allocation_Mode.DEALLOC, 0, 0, ptr, 0, 0)
-}
-dealloc_all :: proc(ptr: rawptr) #inline {
- __check_context()
- a := context.allocator
- _ = a.procedure(a.data, Allocation_Mode.DEALLOC_ALL, 0, 0, ptr, 0, 0)
-}
-
-
-resize :: proc(ptr: rawptr, old_size, new_size: int) -> rawptr #inline { return resize_align(ptr, old_size, new_size, DEFAULT_ALIGNMENT) }
-resize_align :: proc(ptr: rawptr, old_size, new_size, alignment: int) -> rawptr #inline {
- __check_context()
- a := context.allocator
- return a.procedure(a.data, Allocation_Mode.RESIZE, new_size, alignment, ptr, old_size, 0)
-}
-
-
-
-default_resize_align :: proc(old_memory: rawptr, old_size, new_size, alignment: int) -> rawptr {
- if old_memory == null {
- return alloc_align(new_size, alignment)
- }
-
- if new_size == 0 {
- dealloc(old_memory)
- return null
- }
-
- if new_size == old_size {
- return old_memory
- }
-
- new_memory := alloc_align(new_size, alignment)
- if new_memory == null {
- return null
- }
-
- memory_copy(new_memory, old_memory, min(old_size, new_size));
- dealloc(old_memory)
- return new_memory
-}
-
-
-__default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocation_Mode,
- size, alignment: int,
- old_memory: rawptr, old_size: int, flags: u64) -> rawptr {
- using Allocation_Mode
- match mode {
- case ALLOC:
- return heap_alloc(size)
- case RESIZE:
- return default_resize_align(old_memory, old_size, size, alignment)
- case DEALLOC:
- heap_dealloc(old_memory)
- case DEALLOC_ALL:
- // NOTE(bill): Does nothing
- }
-
- return null
-}
-
-__default_allocator :: proc() -> Allocator {
- return Allocator{
- __default_allocator_proc,
- null,
- }
-}
-
-
-
-
-__assert :: proc(msg: string) {
- file_write(file_get_standard(File_Standard.ERROR), msg as []byte)
- // TODO(bill): Which is better?
- // __trap()
- __debug_trap()
-}