Browse Source

Remove old deprecated demos

They're so outdated they'll likely lead to confusion now.
Jeroen van Rijn 2 years ago
parent
commit
3c493194c9

+ 0 - 337
misc/old_demos/demo001.odin

@@ -1,337 +0,0 @@
-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")
-}
-
-
-
-

+ 0 - 879
misc/old_demos/demo002.odin

@@ -1,879 +0,0 @@
-// Demo 002
-export "core:fmt.odin";
-export "core:math.odin";
-export "core:mem.odin";
-// export "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 do 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 do 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?
-
-		push_allocator default_allocator() {
-			a := new(int);
-			defer free(a);
-
-			// Do whatever
-
-		}
-	}
-
-	{
-		a: int = 123;
-		b: type_of(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;
-		#assert(COND);
-		// #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
-
-		case:
-			print("default!\n");
-		}
-
-
-
-		match x := 1.5; x {
-		case 1.5:
-			print("1.5!\n");
-			// break by default
-		case TAU:
-			print("τ!\n");
-		case:
-			print("default!\n");
-		}
-
-
-
-		match x := "Hello"; x {
-		case "Hello":
-			print("greeting\n");
-			// break by default
-		case "Goodbye":
-			print("farewell\n");
-		case:
-			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");
-		case:
-			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 do 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^ += 1;
-			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() {
-	{
-		Entity_Kind :: enum {
-			INVALID,
-			FROG,
-			GIRAFFE,
-			HELICOPTER,
-		}
-
-		Entity :: struct {
-			kind: Entity_Kind
-			using data: struct #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 = Entity_Kind.FROG;
-		e.frog.jump_height = 12;
-
-		f: type_of(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
-	}
-
-	{
-		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,
-		}
-		Entity :: union {Frog, Giraffe, Helicopter};
-
-		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");
-		case:
-			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 {};
-
-		Entity_Kind :: enum {
-			Invalid,
-			Constant,
-			Variable,
-			Using_Variable,
-			TypeName,
-			Procedure,
-			Builtin,
-			Count,
-		}
-
-		Guid :: i64;
-		Entity :: struct {
-
-			kind: Entity_Kind,
-			guid: Guid,
-
-			scope: ^Scope,
-			token: Token,
-			type_: ^Type,
-
-			using data: struct #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
-				},
-				Using_Variable: 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 {
-		}
-
-
-		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
-		}
-		Using_Variable :: struct {
-		}
-		TypeName :: struct {
-		}
-		Procedure :: struct {
-			used: bool,
-		}
-		Builtin :: struct {
-			id: int,
-		}
-
-		Entity :: struct {
-			guid: Guid,
-
-			scope: ^Scope,
-			token: Token,
-			type_: ^Type,
-
-			variant: union {Constant, Variable, Using_Variable, TypeName, Procedure, Builtin},
-		}
-
-		e := Entity{
-			variant = 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 :: struct #raw_union {
-			using xy_: struct { x, y: f32 },
-			e: [2]f32,
-			v: [vector 2]f32,
-		}
-
-		Vector3 :: struct #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(); }

+ 0 - 66
misc/old_demos/demo004.odin

@@ -1,66 +0,0 @@
-import "core:fmt.odin";
-import "core:utf8.odin";
-import "core:hash.odin";
-import "core:mem.odin";
-
-main :: proc() {
-	{ // New Standard Library stuff
-		s := "Hello";
-		fmt.println(s,
-		            utf8.valid_string(s),
-		            hash.murmur64(cast([]u8)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.destroy_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
-}

+ 0 - 283
misc/old_demos/demo005.odin

@@ -1,283 +0,0 @@
-import "core:fmt.odin";
-import "core:utf8.odin";
-// import "core:atomic.odin";
-// import "core:hash.odin";
-// import "core:math.odin";
-// import "core:mem.odin";
-// import "core:opengl.odin";
-// import "core:os.odin";
-// import "core:sync.odin";
-// import win32 "core: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; #assert(size_of(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;
-	var.x = 123;
-	x = 123;
-
-
-	foo :: proc(using pt: Prefix_Type) {
-	}
-
-
-
-	// 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();
-}
-
-when ODIN_OS == "windows" {
-	foreign_system_library win32_user "user32.lib";
-}
-// 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() {
-	foreign win32_user {
-		ShowWindow  :: proc(hwnd: rawptr, cmd_show: i32) -> i32 ---;
-		show_window :: proc(hwnd: rawptr, cmd_show: i32) -> i32 #link_name "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 {
-		#assert(type_of(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
-}

+ 0 - 310
misc/old_demos/demo006.odin

@@ -1,310 +0,0 @@
-// import "core:atomic.odin";
-import "core:hash.odin";
-import "core:mem.odin";
-import "core:opengl.odin";
-import "core:strconv.odin";
-import "core:sync.odin";
-import win32 "core:sys/windows.odin";
-
-import "core:fmt.odin";
-import "core:os.odin";
-import "core:math.odin";
-
-
-main :: proc() {
-when true {
-/*
-	Added:
-		* Unexported entities and fields using an underscore prefix
-			- See `sync.odin` and explain
-
-	Removed:
-	 * Maybe/option types
-	 * Remove `type` keyword and other "reserved" keywords
-	 * ..< and .. removed and replace with .. (half-closed range)
-
-	Changed:
-	 * `#assert` and `assert` return the value of the condition for semantic reasons
-	 * thread_local -> #thread_local
-	 * #include -> #load
-	 * Files only get checked if they are actually used
-	 * match x in y {} // For type match statements
-	 * Version numbering now starts from 0.1.0 and uses the convention:
-	 	- major.minor.patch
-	 * Core library additions to Windows specific stuff
- */
-
-	{
-		Fruit :: enum {
-			APPLE,
-			BANANA,
-			COCONUT,
-		}
-		fmt.println(Fruit.names);
-	}
-
-	{
-		A :: struct           {x, y: f32};
-		B :: struct #align 16 {x, y: f32};
-		fmt.println("align_of(A) =", align_of(A));
-		fmt.println("align_of(B) =", align_of(B));
-	}
-
-	{
-		// Removal of ..< and ..
-		for i in 0..16 {
-		}
-		// Is similar to
-		for i := 0; i < 16; i += 1 {
-		}
-	}
-
-	{
-		thing: for i in 0..10 {
-			for j in i+1..10 {
-				if j == 2 {
-					fmt.println(i, j);
-					continue thing;
-				}
-				if j == 3 {
-					break thing;
-				}
-			}
-		}
-
-		// Works with, `for`, `for in`, `match`, `match in`
-		// NOTE(bill): This solves most of the problems I need `goto` for
-	}
-
-	{
-		t := type_info_of(int);
-		match i in t.variant {
-		case Type_Info_Integer, Type_Info_Float:
-			fmt.println("It's a number");
-		}
-
-
-		x: any = 123;
-		foo: match i in x {
-		case int, f32:
-			fmt.println("It's an int or f32");
-			break foo;
-		}
-	}
-
-	{
-		cond := true;
-		x: int;
-		if cond {
-			x = 3;
-		} else {
-			x = 4;
-		}
-
-
-		// Ternary operator
-		y := cond ? 3 : 4;
-
-		FOO :: true ? 123 : 432; // Constant ternary expression
-		fmt.println("Ternary values:", y, FOO);
-	}
-
-	{
-		// Slices now store a capacity
-		buf: [256]u8;
-		s: []u8;
-		s = buf[..0]; // == buf[0..0];
-		fmt.println("count =", len(s));
-		fmt.println("capacity =", cap(s));
-		append(&s, 1, 2, 3);
-		fmt.println(s);
-
-		s = buf[1..2..3];
-		fmt.println("count =", len(s));
-		fmt.println("capacity =", cap(s));
-		fmt.println(s);
-
-		clear(&s); // Sets count to zero
-	}
-
-	{
-		Foo :: struct {
-			x, y, z: f32,
-			ok:      bool,
-			flags:   u32,
-		}
-		foo_array: [256]Foo;
-		foo_as_bytes: []u8 = mem.slice_to_bytes(foo_array[..]);
-		// Useful for things like
-		// os.write(handle, foo_as_bytes);
-
-		foo_slice := mem.slice_ptr(cast(^Foo)&foo_as_bytes[0], len(foo_as_bytes)/size_of(Foo), cap(foo_as_bytes)/size_of(Foo));
-		// Question: Should there be a bytes_to_slice procedure or is it clearer to do this even if it is error prone?
-		// And if so what would the syntax be?
-		// slice_transmute([]Foo, foo_as_bytes);
-	}
-
-	{
-		Vec3 :: [vector 3]f32;
-
-		x := Vec3{1, 2, 3};
-		y := Vec3{4, 5, 6};
-		fmt.println(x < y);
-		fmt.println(x + y);
-		fmt.println(x - y);
-		fmt.println(x * y);
-		fmt.println(x / y);
-
-		for i in x {
-			fmt.println(i);
-		}
-
-		#assert(size_of([vector 7]bool) >= size_of([7]bool));
-		#assert(size_of([vector 7]i32) >= size_of([7]i32));
-		// align_of([vector 7]i32) != align_of([7]i32) // this may be the case
-	}
-
-	{
-		// fmt.* changes
-		// bprint* returns `string`
-
-		data: [256]u8;
-		str := fmt.bprintf(data[..], "Hellope %d %s %c", 123, "others", '!');
-		fmt.println(str);
-	}
-
-	{
-		x: [dynamic]f64;
-		reserve(&x, 16);
-		defer free(x); // `free` is overloaded for numerous types
-		// Number literals can have underscores in them for readability
-		append(&x, 2_000_000.500_000, 123, 5, 7); // variadic append
-
-		for p, i in x {
-			if i > 0 { fmt.print(", "); }
-			fmt.print(p);
-		}
-		fmt.println();
-	}
-
-	{
-		// Dynamic array "literals"
-		x := [dynamic]f64{2_000_000.500_000, 3, 5, 7};
-		defer free(x);
-		fmt.println(x); // fmt.print* supports printing of dynamic types
-		clear(&x);
-		fmt.println(x);
-	}
-
-	{
-		m: map[f32]int;
-		reserve(&m, 16);
-		defer free(m);
-
-		m[1.0] = 1278;
-		m[2.0] = 7643;
-		m[3.0] = 564;
-		_, ok := m[3.0];
-		c := m[3.0];
-		assert(ok && c == 564);
-
-		fmt.print("map[");
-		i := 0;
-		for val, key in m {
-			if i > 0 {
-				fmt.print(", ");
-			}
-			fmt.printf("%v=%v", key, val);
-			i += 1;
-		}
-		fmt.println("]");
-	}
-	{
-		m := map[string]u32{
-			"a" = 56,
-			"b" = 13453,
-			"c" = 7654,
-		};
-		defer free(m);
-
-		c := m["c"];
-		_, ok := m["c"];
-		assert(ok && c == 7654);
-		fmt.println(m);
-
-		delete(&m, "c"); // deletes entry with key "c"
-		_, found := m["c"];
-		assert(!found);
-
-		fmt.println(m);
-		clear(&m);
-		fmt.println(m);
-
-		// NOTE: Fixed size maps are planned but we have not yet implemented
-		// them as we have had no need for them as of yet
-	}
-
-	{
-		Vector3 :: struct{x, y, z: f32};
-		Quaternion :: struct{x, y, z, w: f32};
-
-		// Variants
-		Frog :: struct {
-			ribbit_volume: f32,
-			jump_height:   f32,
-		}
-		Door :: struct {
-			openness: f32,
-		}
-		Map :: struct {
-			width, height:   f32,
-			place_positions: []Vector3,
-			place_names:     []string,
-		}
-
-		Entity :: struct {
-			// Common Fields
-			id:             u64,
-			name:           string,
-			using position: Vector3,
-			orientation:    Quaternion,
-			flags:          u32,
-
-			variant: union { Frog, Door, Map },
-		}
-
-		entity: Entity;
-		entity.id = 1337;
-		// implicit conversion from variant to base type
-		entity.variant = Frog{
-			ribbit_volume = 0.5,
-			jump_height = 2.1,
-			/*other data */
-		};
-
-		entity.name = "Frank";
-		entity.position = Vector3{1, 4, 9};
-
-		match e in entity.variant {
-		case Frog:
-			fmt.println("Ribbit");
-		case Door:
-			fmt.println("Creak");
-		case Map:
-			fmt.println("Rustle");
-		case:
-			fmt.println("Just a normal entity");
-		}
-
-		if frog, ok := entity.variant.(Frog); ok {
-			fmt.printf("The frog jumps %f feet high at %v\n", frog.jump_height, entity.position);
-		}
-
-		// Panics if not the correct type
-		frog: Frog;
-		frog = entity.variant.(Frog);
-		frog, _ = entity.variant.(Frog); // ignore error and force cast
-	}
-}
-}
-

+ 0 - 570
misc/old_demos/demo007.odin

@@ -1,570 +0,0 @@
-import "core:fmt.odin"
-import "core:strconv.odin"
-import "core:mem.odin"
-import "core:bits.odin"
-import "core:hash.odin"
-import "core:math.odin"
-import "core:os.odin"
-import "core:raw.odin"
-import "core:sort.odin"
-import "core:strings.odin"
-import "core:types.odin"
-import "core:utf16.odin"
-import "core:utf8.odin"
-
-when ODIN_OS == "windows" {
-	import "core:atomics.odin"
-	import "core:opengl.odin"
-	import "core:thread.odin"
-	import win32 "core:sys/windows.odin"
-}
-
-general_stuff :: proc() {
-	{ // `do` for inline statmes rather than block
-		foo :: proc() do fmt.println("Foo!");
-		if   false do foo();
-		for  false do foo();
-		when false do foo();
-
-		if false do foo();
-		else     do foo();
-	}
-
-	{ // Removal of `++` and `--` (again)
-		x: int;
-		x += 1;
-		x -= 1;
-	}
-	{ // Casting syntaxes
-		i := i32(137);
-		ptr := &i;
-
-		fp1 := (^f32)(ptr);
-		// ^f32(ptr) == ^(f32(ptr))
-		fp2 := cast(^f32)ptr;
-
-		f1 := (^f32)(ptr)^;
-		f2 := (cast(^f32)ptr)^;
-
-		// Questions: Should there be two ways to do it?
-	}
-
-	/*
-	 * Remove *_val_of built-in procedures
-	 * size_of, align_of, offset_of
-	 * type_of, type_info_of
-	 */
-
-	{ // `expand_to_tuple` built-in procedure
-		Foo :: struct {
-			x: int,
-			b: bool,
-		}
-		f := Foo{137, true};
-		x, b := expand_to_tuple(f);
-		fmt.println(f);
-		fmt.println(x, b);
-		fmt.println(expand_to_tuple(f));
-	}
-
-	{
-		// ..  half-closed range
-		// .. open range
-
-		for in 0..2  {} // 0, 1
-		for in 0..2 {} // 0, 1, 2
-	}
-}
-
-default_struct_values :: proc() {
-	{
-		Vector3 :: struct {
-			x: f32,
-			y: f32,
-			z: f32,
-		}
-		v: Vector3;
-		fmt.println(v);
-	}
-	{
-		// Default values must be constants
-		Vector3 :: struct {
-			x: f32 = 1,
-			y: f32 = 4,
-			z: f32 = 9,
-		}
-		v: Vector3;
-		fmt.println(v);
-
-		v = Vector3{};
-		fmt.println(v);
-
-		// Uses the same semantics as a default values in a procedure
-		v = Vector3{137};
-		fmt.println(v);
-
-		v = Vector3{z = 137};
-		fmt.println(v);
-	}
-
-	{
-		Vector3 :: struct {
-			x := 1.0,
-			y := 4.0,
-			z := 9.0,
-		}
-		stack_default: Vector3;
-		stack_literal := Vector3{};
-		heap_one      := new(Vector3);         defer free(heap_one);
-		heap_two      := new_clone(Vector3{}); defer free(heap_two);
-
-		fmt.println("stack_default - ", stack_default);
-		fmt.println("stack_literal - ", stack_literal);
-		fmt.println("heap_one      - ", heap_one^);
-		fmt.println("heap_two      - ", heap_two^);
-
-
-		N :: 4;
-		stack_array: [N]Vector3;
-		heap_array := new([N]Vector3);    defer free(heap_array);
-		heap_slice := make([]Vector3, N); defer free(heap_slice);
-		fmt.println("stack_array[1] - ", stack_array[1]);
-		fmt.println("heap_array[1]  - ", heap_array[1]);
-		fmt.println("heap_slice[1]  - ", heap_slice[1]);
-	}
-}
-
-
-
-
-union_type :: proc() {
-	{
-		val: union{int, bool};
-		val = 137;
-		if i, ok := val.(int); ok {
-			fmt.println(i);
-		}
-		val = true;
-		fmt.println(val);
-
-		val = nil;
-
-		switch v in val {
-		case int:  fmt.println("int",  v);
-		case bool: fmt.println("bool", v);
-		case:      fmt.println("nil");
-		}
-	}
-	{
-		// There is a duality between `any` and `union`
-		// An `any` has a pointer to the data and allows for any type (open)
-		// A `union` has as binary blob to store the data and allows only certain types (closed)
-		// The following code is with `any` but has the same syntax
-		val: any;
-		val = 137;
-		if i, ok := val.(int); ok {
-			fmt.println(i);
-		}
-		val = true;
-		fmt.println(val);
-
-		val = nil;
-
-		switch v in val {
-		case int:  fmt.println("int",  v);
-		case bool: fmt.println("bool", v);
-		case:      fmt.println("nil");
-		}
-	}
-
-	Vector3 :: struct {x, y, z: f32};
-	Quaternion :: struct {x, y, z: f32, w: f32 = 1};
-
-	// More realistic examples
-	{
-		// NOTE(bill): For the above basic examples, you may not have any
-		// particular use for it. However, my main use for them is not for these
-		// simple cases. My main use is for hierarchical types. Many prefer
-		// subtyping, embedding the base data into the derived types. Below is
-		// an example of this for a basic game Entity.
-
-		Entity :: struct {
-			id:          u64,
-			name:        string,
-			position:    Vector3,
-			orientation: Quaternion,
-
-			derived: any,
-		}
-
-		Frog :: struct {
-			using entity: Entity,
-			jump_height:  f32,
-		}
-
-		Monster :: struct {
-			using entity: Entity,
-			is_robot:     bool,
-			is_zombie:    bool,
-		}
-
-		// See `parametric_polymorphism` procedure for details
-		new_entity :: proc(T: type) -> ^Entity {
-			t := new(T);
-			t.derived = t^;
-			return t;
-		}
-
-		entity := new_entity(Monster);
-
-		switch e in entity.derived {
-		case Frog:
-			fmt.println("Ribbit");
-		case Monster:
-			if e.is_robot  do fmt.println("Robotic");
-			if e.is_zombie do fmt.println("Grrrr!");
-		}
-	}
-
-	{
-		// NOTE(bill): A union can be used to achieve something similar. Instead
-		// of embedding the base data into the derived types, the derived data
-		// in embedded into the base type. Below is the same example of the
-		// basic game Entity but using an union.
-
-		Entity :: struct {
-			id:          u64,
-			name:        string,
-			position:    Vector3,
-			orientation: Quaternion,
-
-			derived: union {Frog, Monster},
-		}
-
-		Frog :: struct {
-			using entity: ^Entity,
-			jump_height:  f32,
-		}
-
-		Monster :: struct {
-			using entity: ^Entity,
-			is_robot:     bool,
-			is_zombie:    bool,
-		}
-
-		// See `parametric_polymorphism` procedure for details
-		new_entity :: proc(T: type) -> ^Entity {
-			t := new(Entity);
-			t.derived = T{entity = t};
-			return t;
-		}
-
-		entity := new_entity(Monster);
-
-		switch e in entity.derived {
-		case Frog:
-			fmt.println("Ribbit");
-		case Monster:
-			if e.is_robot  do fmt.println("Robotic");
-			if e.is_zombie do fmt.println("Grrrr!");
-		}
-
-		// NOTE(bill): As you can see, the usage code has not changed, only its
-		// memory layout. Both approaches have their own advantages but they can
-		// be used together to achieve different results. The subtyping approach
-		// can allow for a greater control of the memory layout and memory
-		// allocation, e.g. storing the derivatives together. However, this is
-		// also its disadvantage. You must either preallocate arrays for each
-		// derivative separation (which can be easily missed) or preallocate a
-		// bunch of "raw" memory; determining the maximum size of the derived
-		// types would require the aid of metaprogramming. Unions solve this
-		// particular problem as the data is stored with the base data.
-		// Therefore, it is possible to preallocate, e.g. [100]Entity.
-
-		// It should be noted that the union approach can have the same memory
-		// layout as the any and with the same type restrictions by using a
-		// pointer type for the derivatives.
-
-		/*
-			Entity :: struct {
-				..
-				derived: union{^Frog, ^Monster};
-			}
-
-			Frog :: struct {
-				using entity: Entity;
-				..
-			}
-			Monster :: struct {
-				using entity: Entity;
-				..
-
-			}
-			new_entity :: proc(T: type) -> ^Entity {
-				t := new(T);
-				t.derived = t;
-				return t;
-			}
-		*/
-	}
-}
-
-parametric_polymorphism :: proc() {
-	print_value :: proc(value: $T) {
-		fmt.printf("print_value: %T %v\n", value, value);
-	}
-
-	v1: int    = 1;
-	v2: f32    = 2.1;
-	v3: f64    = 3.14;
-	v4: string = "message";
-
-	print_value(v1);
-	print_value(v2);
-	print_value(v3);
-	print_value(v4);
-
-	fmt.println();
-
-	add :: proc(p, q: $T) -> T {
-		x: T = p + q;
-		return x;
-	}
-
-	a := add(3, 4);
-	fmt.printf("a: %T = %v\n", a, a);
-
-	b := add(3.2, 4.3);
-	fmt.printf("b: %T = %v\n", b, b);
-
-	// This is how `new` is implemented
-	alloc_type :: proc(T: type) -> ^T {
-		t := cast(^T)alloc(size_of(T), align_of(T));
-		t^ = T{}; // Use default initialization value
-		return t;
-	}
-
-	copy_slice :: proc(dst, src: []$T) -> int {
-		n := min(len(dst), len(src));
-		if n > 0 {
-			mem.copy(&dst[0], &src[0], n*size_of(T));
-		}
-		return n;
-	}
-
-	double_params :: proc(a: $A, b: $B) -> A {
-		return a + A(b);
-	}
-
-	fmt.println(double_params(12, 1.345));
-
-
-
-	{ // Polymorphic Types and Type Specialization
-		Table_Slot :: struct(Key, Value: type) {
-			occupied: bool,
-			hash:     u32,
-			key:      Key,
-			value:    Value,
-		}
-		TABLE_SIZE_MIN :: 32;
-		Table :: struct(Key, Value: type) {
-			count:     int,
-			allocator: Allocator,
-			slots:     []Table_Slot(Key, Value),
-		}
-
-		// Only allow types that are specializations of a (polymorphic) slice
-		make_slice :: proc(T: type/[]$E, len: int) -> T {
-			return make(T, len);
-		}
-
-
-		// Only allow types that are specializations of `Table`
-		allocate :: proc(table: ^$T/Table, capacity: int) {
-			c := context;
-			if table.allocator.procedure != nil do c.allocator = table.allocator;
-
-			push_context c {
-				table.slots = make_slice(type_of(table.slots), max(capacity, TABLE_SIZE_MIN));
-			}
-		}
-
-		expand :: proc(table: ^$T/Table) {
-			c := context;
-			if table.allocator.procedure != nil do c.allocator = table.allocator;
-
-			push_context c {
-				old_slots := table.slots;
-
-				cap := max(2*cap(table.slots), TABLE_SIZE_MIN);
-				allocate(table, cap);
-
-				for s in old_slots do if s.occupied {
-					put(table, s.key, s.value);
-				}
-
-				free(old_slots);
-			}
-		}
-
-		// Polymorphic determination of a polymorphic struct
-		// put :: proc(table: ^$T/Table, key: T.Key, value: T.Value) {
-		put :: proc(table: ^Table($Key, $Value), key: Key, value: Value) {
-			hash := get_hash(key); // Ad-hoc method which would fail in a different scope
-			index := find_index(table, key, hash);
-			if index < 0 {
-				if f64(table.count) >= 0.75*f64(cap(table.slots)) {
-					expand(table);
-				}
-				assert(table.count <= cap(table.slots));
-
-				hash := get_hash(key);
-				index = int(hash % u32(cap(table.slots)));
-
-				for table.slots[index].occupied {
-					if index += 1; index >= cap(table.slots) {
-						index = 0;
-					}
-				}
-
-				table.count += 1;
-			}
-
-			slot := &table.slots[index];
-			slot.occupied = true;
-			slot.hash     = hash;
-			slot.key      = key;
-			slot.value    = value;
-		}
-
-
-		// find :: proc(table: ^$T/Table, key: T.Key) -> (T.Value, bool) {
-		find :: proc(table: ^Table($Key, $Value), key: Key) -> (Value, bool) {
-			hash := get_hash(key);
-			index := find_index(table, key, hash);
-			if index < 0 {
-				return Value{}, false;
-			}
-			return table.slots[index].value, true;
-		}
-
-		find_index :: proc(table: ^Table($Key, $Value), key: Key, hash: u32) -> int {
-			if cap(table.slots) <= 0 do return -1;
-
-			index := int(hash % u32(cap(table.slots)));
-			for table.slots[index].occupied {
-				if table.slots[index].hash == hash {
-					if table.slots[index].key == key {
-						return index;
-					}
-				}
-
-				if index += 1; index >= cap(table.slots) {
-					index = 0;
-				}
-			}
-
-			return -1;
-		}
-
-		get_hash :: proc(s: string) -> u32 { // fnv32a
-			h: u32 = 0x811c9dc5;
-			for i in 0..len(s) {
-				h = (h ~ u32(s[i])) * 0x01000193;
-			}
-			return h;
-		}
-
-
-		table: Table(string, int);
-
-		for i in 0..36 do put(&table, "Hellope", i);
-		for i in 0..42 do put(&table, "World!",  i);
-
-		found, _ := find(&table, "Hellope");
-		fmt.printf("`found` is %v\n", found);
-
-		found, _ = find(&table, "World!");
-		fmt.printf("`found` is %v\n", found);
-
-		// I would not personally design a hash table like this in production
-		// but this is a nice basic example
-		// A better approach would either use a `u64` or equivalent for the key
-		// and let the user specify the hashing function or make the user store
-		// the hashing procedure with the table
-	}
-}
-
-
-
-
-prefix_table := [?]string{
-	"White",
-	"Red",
-	"Green",
-	"Blue",
-	"Octarine",
-	"Black",
-};
-
-threading_example :: proc() {
-	when ODIN_OS == "windows" {
-		unordered_remove :: proc(array: ^[]$T, index: int, loc := #caller_location) {
-			__bounds_check_error_loc(loc, index, len(array));
-			array[index] = array[len(array)-1];
-			pop(array);
-		}
-		ordered_remove :: proc(array: ^[]$T, index: int, loc := #caller_location) {
-			__bounds_check_error_loc(loc, index, len(array));
-			copy(array[index..], array[index+1..]);
-			pop(array);
-		}
-
-		worker_proc :: proc(t: ^thread.Thread) -> int {
-			for iteration in 1..5 {
-				fmt.printf("Thread %d is on iteration %d\n", t.user_index, iteration);
-				fmt.printf("`%s`: iteration %d\n", prefix_table[t.user_index], iteration);
-				// win32.sleep(1);
-			}
-			return 0;
-		}
-
-		threads := make([]^thread.Thread, 0, len(prefix_table));
-		defer free(threads);
-
-		for i in 0..len(prefix_table) {
-			if t := thread.create(worker_proc); t != nil {
-				t.init_context = context;
-				t.use_init_context = true;
-				t.user_index = len(threads);
-				append(&threads, t);
-				thread.start(t);
-			}
-		}
-
-		for len(threads) > 0 {
-			for i := 0; i < len(threads); /**/ {
-				if t := threads[i]; thread.is_done(t) {
-					fmt.printf("Thread %d is done\n", t.user_index);
-					thread.destroy(t);
-
-					ordered_remove(&threads, i);
-				} else {
-					i += 1;
-				}
-			}
-		}
-	}
-}
-
-main :: proc() {
-	when false {
-		fmt.println("\n# general_stuff");              general_stuff();
-		fmt.println("\n# default_struct_values");      default_struct_values();
-		fmt.println("\n# union_type");                 union_type();
-		fmt.println("\n# parametric_polymorphism");    parametric_polymorphism();
-		fmt.println("\n# threading_example");          threading_example();
-	}
-}
-

+ 0 - 778
misc/old_demos/demo008.odin

@@ -1,778 +0,0 @@
-import "core:fmt.odin"
-import "core:strconv.odin"
-import "core:mem.odin"
-import "core:bits.odin"
-import "core:hash.odin"
-import "core:math.odin"
-import "core:math/rand.odin"
-import "core:os.odin"
-import "core:raw.odin"
-import "core:sort.odin"
-import "core:strings.odin"
-import "core:types.odin"
-import "core:utf16.odin"
-import "core:utf8.odin"
-
-// File scope `when` statements
-when ODIN_OS == "windows" {
-	import "core:atomics.odin"
-	import "core:thread.odin"
-	import win32 "core:sys/windows.odin"
-}
-
-@(link_name="general_stuff")
-general_stuff :: proc() {
-	fmt.println("# general_stuff");
-	{ // `do` for inline statements rather than block
-		foo :: proc() do fmt.println("Foo!");
-		if   false do foo();
-		for  false do foo();
-		when false do foo();
-
-		if false do foo();
-		else     do foo();
-	}
-
-	{ // Removal of `++` and `--` (again)
-		x: int;
-		x += 1;
-		x -= 1;
-	}
-	{ // Casting syntaxes
-		i := i32(137);
-		ptr := &i;
-
-		_ = (^f32)(ptr);
-		// ^f32(ptr) == ^(f32(ptr))
-		_ = cast(^f32)ptr;
-
-		_ = (^f32)(ptr)^;
-		_ = (cast(^f32)ptr)^;
-
-		// Questions: Should there be two ways to do it?
-	}
-
-	/*
-	 * Remove *_val_of built-in procedures
-	 * size_of, align_of, offset_of
-	 * type_of, type_info_of
-	 */
-
-	{ // `expand_to_tuple` built-in procedure
-		Foo :: struct {
-			x: int,
-			b: bool,
-		}
-		f := Foo{137, true};
-		x, b := expand_to_tuple(f);
-		fmt.println(f);
-		fmt.println(x, b);
-		fmt.println(expand_to_tuple(f));
-	}
-
-	{
-		// ..  half-closed range
-		// .. open range
-
-		for in 0..2  {} // 0, 1
-		for in 0..2 {} // 0, 1, 2
-	}
-
-	{ // Multiple sized booleans
-
-		x0: bool; // default
-		x1: b8  = true;
-		x2: b16 = false;
-		x3: b32 = true;
-		x4: b64 = false;
-
-		fmt.printf("x1: %T = %v;\n", x1, x1);
-		fmt.printf("x2: %T = %v;\n", x2, x2);
-		fmt.printf("x3: %T = %v;\n", x3, x3);
-		fmt.printf("x4: %T = %v;\n", x4, x4);
-
-		// Having specific sized booleans is very useful when dealing with foreign code
-		// and to enforce specific alignment for a boolean, especially within a struct
-	}
-
-	{ // `distinct` types
-		// Originally, all type declarations would create a distinct type unless #type_alias was present.
-		// Now the behaviour has been reversed. All type declarations create a type alias unless `distinct` is present.
-		// If the type expression is `struct`, `union`, `enum`, or `proc`, the types will always been distinct.
-
-		Int32 :: i32;
-		#assert(Int32 == i32);
-
-		My_Int32 :: distinct i32;
-		#assert(My_Int32 != i32);
-
-		My_Struct :: struct{x: int};
-		#assert(My_Struct != struct{x: int});
-	}
-}
-
-default_struct_values :: proc() {
-	fmt.println("# default_struct_values");
-	{
-		Vector3 :: struct {
-			x: f32,
-			y: f32,
-			z: f32,
-		}
-		v: Vector3;
-		fmt.println(v);
-	}
-	{
-		// Default values must be constants
-		Vector3 :: struct {
-			x: f32 = 1,
-			y: f32 = 4,
-			z: f32 = 9,
-		}
-		v: Vector3;
-		fmt.println(v);
-
-		v = Vector3{};
-		fmt.println(v);
-
-		// Uses the same semantics as a default values in a procedure
-		v = Vector3{137};
-		fmt.println(v);
-
-		v = Vector3{z = 137};
-		fmt.println(v);
-	}
-
-	{
-		Vector3 :: struct {
-			x := 1.0,
-			y := 4.0,
-			z := 9.0,
-		}
-		stack_default: Vector3;
-		stack_literal := Vector3{};
-		heap_one      := new(Vector3);         defer free(heap_one);
-		heap_two      := new_clone(Vector3{}); defer free(heap_two);
-
-		fmt.println("stack_default  - ", stack_default);
-		fmt.println("stack_literal  - ", stack_literal);
-		fmt.println("heap_one       - ", heap_one^);
-		fmt.println("heap_two       - ", heap_two^);
-
-
-		N :: 4;
-		stack_array: [N]Vector3;
-		heap_array := new([N]Vector3);    defer free(heap_array);
-		heap_slice := make([]Vector3, N); defer free(heap_slice);
-		fmt.println("stack_array[1] - ", stack_array[1]);
-		fmt.println("heap_array[1]  - ", heap_array[1]);
-		fmt.println("heap_slice[1]  - ", heap_slice[1]);
-	}
-}
-
-
-
-
-union_type :: proc() {
-	fmt.println("\n# union_type");
-	{
-		val: union{int, bool};
-		val = 137;
-		if i, ok := val.(int); ok {
-			fmt.println(i);
-		}
-		val = true;
-		fmt.println(val);
-
-		val = nil;
-
-		switch v in val {
-		case int:  fmt.println("int",  v);
-		case bool: fmt.println("bool", v);
-		case:      fmt.println("nil");
-		}
-	}
-	{
-		// There is a duality between `any` and `union`
-		// An `any` has a pointer to the data and allows for any type (open)
-		// A `union` has as binary blob to store the data and allows only certain types (closed)
-		// The following code is with `any` but has the same syntax
-		val: any;
-		val = 137;
-		if i, ok := val.(int); ok {
-			fmt.println(i);
-		}
-		val = true;
-		fmt.println(val);
-
-		val = nil;
-
-		switch v in val {
-		case int:  fmt.println("int",  v);
-		case bool: fmt.println("bool", v);
-		case:      fmt.println("nil");
-		}
-	}
-
-	Vector3 :: struct {x, y, z: f32};
-	Quaternion :: struct {x, y, z: f32, w: f32 = 1};
-
-	// More realistic examples
-	{
-		// NOTE(bill): For the above basic examples, you may not have any
-		// particular use for it. However, my main use for them is not for these
-		// simple cases. My main use is for hierarchical types. Many prefer
-		// subtyping, embedding the base data into the derived types. Below is
-		// an example of this for a basic game Entity.
-
-		Entity :: struct {
-			id:          u64,
-			name:        string,
-			position:    Vector3,
-			orientation: Quaternion,
-
-			derived: any,
-		}
-
-		Frog :: struct {
-			using entity: Entity,
-			jump_height:  f32,
-		}
-
-		Monster :: struct {
-			using entity: Entity,
-			is_robot:     bool,
-			is_zombie:    bool,
-		}
-
-		// See `parametric_polymorphism` procedure for details
-		new_entity :: proc(T: type) -> ^Entity {
-			t := new(T);
-			t.derived = t^;
-			return t;
-		}
-
-		entity := new_entity(Monster);
-
-		switch e in entity.derived {
-		case Frog:
-			fmt.println("Ribbit");
-		case Monster:
-			if e.is_robot  do fmt.println("Robotic");
-			if e.is_zombie do fmt.println("Grrrr!");
-		}
-	}
-
-	{
-		// NOTE(bill): A union can be used to achieve something similar. Instead
-		// of embedding the base data into the derived types, the derived data
-		// in embedded into the base type. Below is the same example of the
-		// basic game Entity but using an union.
-
-		Entity :: struct {
-			id:          u64,
-			name:        string,
-			position:    Vector3,
-			orientation: Quaternion,
-
-			derived: union {Frog, Monster},
-		}
-
-		Frog :: struct {
-			using entity: ^Entity,
-			jump_height:  f32,
-		}
-
-		Monster :: struct {
-			using entity: ^Entity,
-			is_robot:     bool,
-			is_zombie:    bool,
-		}
-
-		// See `parametric_polymorphism` procedure for details
-		new_entity :: proc(T: type) -> ^Entity {
-			t := new(Entity);
-			t.derived = T{entity = t};
-			return t;
-		}
-
-		entity := new_entity(Monster);
-
-		switch e in entity.derived {
-		case Frog:
-			fmt.println("Ribbit");
-		case Monster:
-			if e.is_robot  do fmt.println("Robotic");
-			if e.is_zombie do fmt.println("Grrrr!");
-		}
-
-		// NOTE(bill): As you can see, the usage code has not changed, only its
-		// memory layout. Both approaches have their own advantages but they can
-		// be used together to achieve different results. The subtyping approach
-		// can allow for a greater control of the memory layout and memory
-		// allocation, e.g. storing the derivatives together. However, this is
-		// also its disadvantage. You must either preallocate arrays for each
-		// derivative separation (which can be easily missed) or preallocate a
-		// bunch of "raw" memory; determining the maximum size of the derived
-		// types would require the aid of metaprogramming. Unions solve this
-		// particular problem as the data is stored with the base data.
-		// Therefore, it is possible to preallocate, e.g. [100]Entity.
-
-		// It should be noted that the union approach can have the same memory
-		// layout as the any and with the same type restrictions by using a
-		// pointer type for the derivatives.
-
-		/*
-			Entity :: struct {
-				..
-				derived: union{^Frog, ^Monster},
-			}
-
-			Frog :: struct {
-				using entity: Entity,
-				..
-			}
-			Monster :: struct {
-				using entity: Entity,
-				..
-
-			}
-			new_entity :: proc(T: type) -> ^Entity {
-				t := new(T);
-				t.derived = t;
-				return t;
-			}
-		*/
-	}
-}
-
-parametric_polymorphism :: proc() {
-	fmt.println("# parametric_polymorphism");
-
-	print_value :: proc(value: $T) {
-		fmt.printf("print_value: %T %v\n", value, value);
-	}
-
-	v1: int    = 1;
-	v2: f32    = 2.1;
-	v3: f64    = 3.14;
-	v4: string = "message";
-
-	print_value(v1);
-	print_value(v2);
-	print_value(v3);
-	print_value(v4);
-
-	fmt.println();
-
-	add :: proc(p, q: $T) -> T {
-		x: T = p + q;
-		return x;
-	}
-
-	a := add(3, 4);
-	fmt.printf("a: %T = %v\n", a, a);
-
-	b := add(3.2, 4.3);
-	fmt.printf("b: %T = %v\n", b, b);
-
-	// This is how `new` is implemented
-	alloc_type :: proc(T: type) -> ^T {
-		t := cast(^T)alloc(size_of(T), align_of(T));
-		t^ = T{}; // Use default initialization value
-		return t;
-	}
-
-	copy_slice :: proc(dst, src: []$T) -> int {
-		return mem.copy(&dst[0], &src[0], n*size_of(T));
-	}
-
-	double_params :: proc(a: $A, b: $B) -> A {
-		return a + A(b);
-	}
-
-	fmt.println(double_params(12, 1.345));
-
-
-
-	{ // Polymorphic Types and Type Specialization
-		Table_Slot :: struct(Key, Value: type) {
-			occupied: bool,
-			hash:     u32,
-			key:      Key,
-			value:    Value,
-		}
-		TABLE_SIZE_MIN :: 32;
-		Table :: struct(Key, Value: type) {
-			count:     int,
-			allocator: Allocator,
-			slots:     []Table_Slot(Key, Value),
-		}
-
-		// Only allow types that are specializations of a (polymorphic) slice
-		make_slice :: proc(T: type/[]$E, len: int) -> T {
-			return make(T, len);
-		}
-
-
-		// Only allow types that are specializations of `Table`
-		allocate :: proc(table: ^$T/Table, capacity: int) {
-			c := context;
-			if table.allocator.procedure != nil do c.allocator = table.allocator;
-
-			context <- c {
-				table.slots = make_slice(type_of(table.slots), max(capacity, TABLE_SIZE_MIN));
-			}
-		}
-
-		expand :: proc(table: ^$T/Table) {
-			c := context;
-			if table.allocator.procedure != nil do c.allocator = table.allocator;
-
-			context <- c {
-				old_slots := table.slots;
-
-				cap := max(2*len(table.slots), TABLE_SIZE_MIN);
-				allocate(table, cap);
-
-				for s in old_slots do if s.occupied {
-					put(table, s.key, s.value);
-				}
-
-				free(old_slots);
-			}
-		}
-
-		// Polymorphic determination of a polymorphic struct
-		// put :: proc(table: ^$T/Table, key: T.Key, value: T.Value) {
-		put :: proc(table: ^Table($Key, $Value), key: Key, value: Value) {
-			hash := get_hash(key); // Ad-hoc method which would fail in a different scope
-			index := find_index(table, key, hash);
-			if index < 0 {
-				if f64(table.count) >= 0.75*f64(len(table.slots)) {
-					expand(table);
-				}
-				assert(table.count <= len(table.slots));
-
-				hash := get_hash(key);
-				index = int(hash % u32(len(table.slots)));
-
-				for table.slots[index].occupied {
-					if index += 1; index >= len(table.slots) {
-						index = 0;
-					}
-				}
-
-				table.count += 1;
-			}
-
-			slot := &table.slots[index];
-			slot.occupied = true;
-			slot.hash     = hash;
-			slot.key      = key;
-			slot.value    = value;
-		}
-
-
-		// find :: proc(table: ^$T/Table, key: T.Key) -> (T.Value, bool) {
-		find :: proc(table: ^Table($Key, $Value), key: Key) -> (Value, bool) {
-			hash := get_hash(key);
-			index := find_index(table, key, hash);
-			if index < 0 {
-				return Value{}, false;
-			}
-			return table.slots[index].value, true;
-		}
-
-		find_index :: proc(table: ^Table($Key, $Value), key: Key, hash: u32) -> int {
-			if len(table.slots) <= 0 do return -1;
-
-			index := int(hash % u32(len(table.slots)));
-			for table.slots[index].occupied {
-				if table.slots[index].hash == hash {
-					if table.slots[index].key == key {
-						return index;
-					}
-				}
-
-				if index += 1; index >= len(table.slots) {
-					index = 0;
-				}
-			}
-
-			return -1;
-		}
-
-		get_hash :: proc(s: string) -> u32 { // fnv32a
-			h: u32 = 0x811c9dc5;
-			for i in 0..len(s) {
-				h = (h ~ u32(s[i])) * 0x01000193;
-			}
-			return h;
-		}
-
-
-		table: Table(string, int);
-
-		for i in 0..36 do put(&table, "Hellope", i);
-		for i in 0..42 do put(&table, "World!",  i);
-
-		found, _ := find(&table, "Hellope");
-		fmt.printf("`found` is %v\n", found);
-
-		found, _ = find(&table, "World!");
-		fmt.printf("`found` is %v\n", found);
-
-		// I would not personally design a hash table like this in production
-		// but this is a nice basic example
-		// A better approach would either use a `u64` or equivalent for the key
-		// and let the user specify the hashing function or make the user store
-		// the hashing procedure with the table
-	}
-}
-
-
-
-
-prefix_table := [?]string{
-	"White",
-	"Red",
-	"Green",
-	"Blue",
-	"Octarine",
-	"Black",
-};
-
-threading_example :: proc() {
-	when ODIN_OS == "windows" {
-		fmt.println("# threading_example");
-
-		unordered_remove :: proc(array: ^[dynamic]$T, index: int, loc := #caller_location) {
-			__bounds_check_error_loc(loc, index, len(array));
-			array[index] = array[len(array)-1];
-			pop(array);
-		}
-		ordered_remove :: proc(array: ^[dynamic]$T, index: int, loc := #caller_location) {
-			__bounds_check_error_loc(loc, index, len(array));
-			copy(array[index..], array[index+1..]);
-			pop(array);
-		}
-
-		worker_proc :: proc(t: ^thread.Thread) -> int {
-			for iteration in 1..5 {
-				fmt.printf("Thread %d is on iteration %d\n", t.user_index, iteration);
-				fmt.printf("`%s`: iteration %d\n", prefix_table[t.user_index], iteration);
-				// win32.sleep(1);
-			}
-			return 0;
-		}
-
-		threads := make([dynamic]^thread.Thread, 0, len(prefix_table));
-		defer free(threads);
-
-		for in prefix_table {
-			if t := thread.create(worker_proc); t != nil {
-				t.init_context = context;
-				t.use_init_context = true;
-				t.user_index = len(threads);
-				append(&threads, t);
-				thread.start(t);
-			}
-		}
-
-		for len(threads) > 0 {
-			for i := 0; i < len(threads); /**/ {
-				if t := threads[i]; thread.is_done(t) {
-					fmt.printf("Thread %d is done\n", t.user_index);
-					thread.destroy(t);
-
-					ordered_remove(&threads, i);
-				} else {
-					i += 1;
-				}
-			}
-		}
-	}
-}
-
-array_programming :: proc() {
-	fmt.println("# array_programming");
-	{
-		a := [3]f32{1, 2, 3};
-		b := [3]f32{5, 6, 7};
-		c := a * b;
-		d := a + b;
-		e := 1 +  (c - d) / 2;
-		fmt.printf("%.1f\n", e); // [0.5, 3.0, 6.5]
-	}
-
-	{
-		a := [3]f32{1, 2, 3};
-		b := swizzle(a, 2, 1, 0);
-		assert(b == [3]f32{3, 2, 1});
-
-		c := swizzle(a, 0, 0);
-		assert(c == [2]f32{1, 1});
-		assert(c == 1);
-	}
-
-	{
-		Vector3 :: distinct [3]f32;
-		a := Vector3{1, 2, 3};
-		b := Vector3{5, 6, 7};
-		c := (a * b)/2 + 1;
-		d := c.x + c.y + c.z;
-		fmt.printf("%.1f\n", d); // 22.0
-
-		cross :: proc(a, b: Vector3) -> Vector3 {
-			i := swizzle(a, 1, 2, 0) * swizzle(b, 2, 0, 1);
-			j := swizzle(a, 2, 0, 1) * swizzle(b, 1, 2, 0);
-			return i - j;
-		}
-
-		blah :: proc(a: Vector3) -> f32 {
-			return a.x + a.y + a.z;
-		}
-
-		x := cross(a, b);
-		fmt.println(x);
-		fmt.println(blah(x));
-	}
-}
-
-
-using println in import "core:fmt.odin"
-
-using_in :: proc() {
-	fmt.println("# using in");
-	using print in fmt;
-
-	println("Hellope1");
-	print("Hellope2\n");
-
-	Foo :: struct {
-		x, y: int,
-		b: bool,
-	}
-	f: Foo;
-	f.x, f.y = 123, 321;
-	println(f);
-	using x, y in f;
-	x, y = 456, 654;
-	println(f);
-}
-
-named_proc_return_parameters :: proc() {
-	fmt.println("# named proc return parameters");
-
-	foo0 :: proc() -> int {
-		return 123;
-	}
-	foo1 :: proc() -> (a: int) {
-		a = 123;
-		return;
-	}
-	foo2 :: proc() -> (a, b: int) {
-		// Named return values act like variables within the scope
-		a = 321;
-		b = 567;
-		return b, a;
-	}
-	fmt.println("foo0 =", foo0()); // 123
-	fmt.println("foo1 =", foo1()); // 123
-	fmt.println("foo2 =", foo2()); // 567 321
-}
-
-
-enum_export :: proc() {
-	fmt.println("# enum #export");
-
-	Foo :: enum #export {A, B, C};
-
-	f0 := A;
-	f1 := B;
-	f2 := C;
-	fmt.println(f0, f1, f2);
-}
-
-explicit_procedure_overloading :: proc() {
-	fmt.println("# explicit procedure overloading");
-
-	add_ints :: proc(a, b: int) -> int {
-		x := a + b;
-		fmt.println("add_ints", x);
-		return x;
-	}
-	add_floats :: proc(a, b: f32) -> f32 {
-		x := a + b;
-		fmt.println("add_floats", x);
-		return x;
-	}
-	add_numbers :: proc(a: int, b: f32, c: u8) -> int {
-		x := int(a) + int(b) + int(c);
-		fmt.println("add_numbers", x);
-		return x;
-	}
-
-	add :: proc[add_ints, add_floats, add_numbers];
-
-	add(int(1), int(2));
-	add(f32(1), f32(2));
-	add(int(1), f32(2), u8(3));
-
-	add(1, 2);     // untyped ints coerce to int tighter than f32
-	add(1.0, 2.0); // untyped floats coerce to f32 tighter than int
-	add(1, 2, 3);  // three parameters
-
-	// Ambiguous answers
-	// add(1.0, 2);
-	// add(1, 2.0);
-}
-
-complete_switch :: proc() {
-	fmt.println("# complete_switch");
-	{ // enum
-		Foo :: enum #export {
-			A,
-			B,
-			C,
-			D,
-		}
-
-		b := Foo.B;
-		f := Foo.A;
-		#complete switch f {
-		case A: fmt.println("A");
-		case B: fmt.println("B");
-		case C: fmt.println("C");
-		case D: fmt.println("D");
-		case:   fmt.println("?");
-		}
-	}
-	{ // union
-		Foo :: union {int, bool};
-		f: Foo = 123;
-		#complete switch in f {
-		case int:  fmt.println("int");
-		case bool: fmt.println("bool");
-		case:
-		}
-	}
-}
-
-
-main :: proc() {
-	when true {
-		general_stuff();
-		default_struct_values();
-		union_type();
-		parametric_polymorphism();
-		threading_example();
-		array_programming();
-		using_in();
-		named_proc_return_parameters();
-		enum_export();
-		explicit_procedure_overloading();
-		complete_switch();
-	}
-}

+ 0 - 412
misc/old_demos/old_runtime.odin

@@ -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
-	#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()
-}

+ 0 - 430
misc/old_stuff/demo_backup.odin

@@ -1,430 +0,0 @@
-import (
-	"fmt.odin";
-	"atomics.odin";
-	"bits.odin";
-	"decimal.odin";
-	"hash.odin";
-	"math.odin";
-	"mem.odin";
-	"opengl.odin";
-	"os.odin";
-	"raw.odin";
-	"strconv.odin";
-	"strings.odin";
-	"sync.odin";
-	"sort.odin";
-	"types.odin";
-	"utf8.odin";
-	"utf16.odin";
-/*
-*/
-)
-
-
-general_stuff :: proc() {
-	// Complex numbers
-	a := 3 + 4i;
-	b: complex64 = 3 + 4i;
-	c: complex128 = 3 + 4i;
-	d := complex(2, 3);
-
-	e := a / conj(a);
-	fmt.println("(3+4i)/(3-4i) =", e);
-	fmt.println(real(e), "+", imag(e), "i");
-
-
-	// C-style variadic procedures
-	foreign __llvm_core {
-		// The variadic part allows for extra type checking too which C does not provide
-		c_printf :: proc(fmt: ^u8, #c_vararg args: ..any) -> i32 #link_name "printf" ---;
-	}
-	str := "%d\n\x00";
-	// c_printf(&str[0], i32(789456123));
-
-
-	Foo :: struct {
-		x: int;
-		y: f32;
-		z: string;
-	}
-	foo := Foo{123, 0.513, "A string"};
-	x, y, z := expand_to_tuple(foo);
-	fmt.println(x, y, z);
-	#assert(type_of(x) == int);
-	#assert(type_of(y) == f32);
-	#assert(type_of(z) == string);
-
-
-	// By default, all variables are zeroed
-	// This can be overridden with the "uninitialized value"
-	// This is similar to `nil` but applied to everything
-	undef_int: int = ---;
-
-
-	// Context system is now implemented using Implicit Parameter Passing (IPP)
-	// The previous implementation was Thread Local Storage (TLS)
-	// IPP has the advantage that it works on systems without TLS and that you can
-	// link the context to the stack frame and thus look at previous contexts
-	//
-	// It does mean that a pointer is implicitly passed procedures with the default
-	// Odin calling convention (#cc_odin)
-	// This can be overridden with something like #cc_contextless or #cc_c if performance
-	// is worried about
-
-}
-
-foreign_blocks :: proc() {
-	// See sys/windows.odin
-}
-
-default_arguments :: proc() {
-	hello :: proc(a: int = 9, b: int = 9) do fmt.printf("a is %d; b is %d\n", a, b);
-	fmt.println("\nTesting default arguments:");
-	hello(1, 2);
-	hello(1);
-	hello();
-}
-
-named_arguments :: proc() {
-	Colour :: enum {
-		Red,
-		Orange,
-		Yellow,
-		Green,
-		Blue,
-		Octarine,
-	};
-	using Colour;
-
-	make_character :: proc(name, catch_phrase: string, favourite_colour, least_favourite_colour: Colour) {
-		fmt.println();
-		fmt.printf("My name is %v and I like %v.  %v\n", name, favourite_colour, catch_phrase);
-	}
-
-	make_character("Frank", "¡Ay, caramba!", Blue, Green);
-
-
-	// As the procedures have more and more parameters, it is very easy
-	// to get many of the arguments in the wrong order especialy if the
-	// types are the same
-	make_character("¡Ay, caramba!", "Frank", Green, Blue);
-
-	// Named arguments help to disambiguate this problem
-	make_character(catch_phrase = "¡Ay, caramba!", name = "Frank",
-	               least_favourite_colour = Green, favourite_colour = Blue);
-
-
-	// The named arguments can be specifed in any order.
-	make_character(favourite_colour = Octarine, catch_phrase = "U wot m8!",
-	               least_favourite_colour = Green, name = "Dennis");
-
-
-	// NOTE: You cannot mix named arguments with normal values
-	/*
-	make_character("Dennis",
-	               favourite_colour = Octarine, catch_phrase = "U wot m8!",
-	               least_favourite_colour = Green);
-	*/
-
-
-	// Named arguments can also aid with default arguments
-	numerous_things :: proc(s: string, a := 1, b := 2, c := 3.14,
-	                        d := "The Best String!", e := false, f := 10.3/3.1, g := false) {
-		g_str := g ? "true" : "false";
-		fmt.printf("How many?! %s: %v\n", s, g_str);
-	}
-
-	numerous_things("First");
-	numerous_things(s = "Second", g = true);
-
-
-	// Default values can be placed anywhere, not just at the end like in other languages
-	weird :: proc(pre: string, mid: int = 0, post: string) {
-		fmt.println(pre, mid, post);
-	}
-
-	weird("How many things", 42, "huh?");
-	weird(pre = "Prefix", post = "Pat");
-
-}
-
-
-default_return_values :: proc() {
-	foo :: proc(x: int) -> (first: string = "Hellope", second := "world!") {
-		match x {
-		case 0: return;
-		case 1: return "Goodbye";
-		case 2: return "Goodbye", "cruel world..";
-		case 3: return second = "cruel world..", first = "Goodbye";
-		}
-
-		return second = "my old friend.";
-	}
-
-	fmt.printf("%s %s\n", foo(0));
-	fmt.printf("%s %s\n", foo(1));
-	fmt.printf("%s %s\n", foo(2));
-	fmt.printf("%s %s\n", foo(3));
-	fmt.printf("%s %s\n", foo(4));
-	fmt.println();
-
-
-	// A more "real" example
-	Error :: enum {
-		None,
-		WhyTheNumberThree,
-		TenIsTooBig,
-	};
-
-	Entity :: struct {
-		name: string;
-		id:   u32;
-	}
-
-	some_thing :: proc(input: int) -> (result: ^Entity = nil, err := Error.None) {
-		match {
-		case input == 3:  return err = Error.WhyTheNumberThree;
-		case input >= 10: return err = Error.TenIsTooBig;
-		}
-
-		e := new(Entity);
-		e.id = u32(input);
-
-		return result = e;
-	}
-}
-
-call_location :: proc() {
-	amazing :: proc(n: int, using loc := #caller_location) {
-		fmt.printf("%s(%d:%d) just asked to do something amazing.\n",
-				   fully_pathed_filename, line, column);
-		fmt.printf("Normal -> %d\n", n);
-		fmt.printf("Amazing -> %d\n", n+1);
-		fmt.println();
-	}
-
-	loc := #location(main);
-	fmt.println("`main` is located at", loc);
-
-	fmt.println("This line is located at", #location());
-	fmt.println();
-
-	amazing(3);
-	amazing(4, #location(call_location));
-
-	// See _preload.odin for the implementations of `assert` and `panic`
-
-}
-
-
-explicit_parametric_polymorphic_procedures :: proc() {
-	// This is how `new` is actually implemented, see _preload.odin
-	alloc_type :: proc(T: type) -> ^T do return cast(^T)alloc(size_of(T), align_of(T));
-
-	int_ptr := alloc_type(int);
-	defer free(int_ptr);
-	int_ptr^ = 137;
-	fmt.println(int_ptr, int_ptr^);
-
-	// Named arguments work too!
-	another_ptr := alloc_type(T = f32);
-	defer free(another_ptr);
-
-
-	add :: proc(T: type, args: ..T) -> T {
-		res: T;
-		for arg in args do res += arg;
-		return res;
-	}
-
-	fmt.println("add =", add(int, 1, 2, 3, 4, 5, 6));
-
-	swap :: proc(T: type, a, b: ^T) {
-		tmp := a^;
-		a^ = b^;
-		b^ = tmp;
-	}
-
-	a, b: int = 3, 4;
-	fmt.println("Pre-swap:", a, b);
-	swap(int, &a, &b);
-	fmt.println("Post-swap:", a, b);
-	a, b = b, a; // Or use this syntax for this silly example case
-
-
-	Vector2 :: struct {x, y: f32;};
-	{
-		// A more complicated example using subtyping
-		// Something like this could be used in a game
-
-		Entity :: struct {
-			using position: Vector2;
-			flags:          u64;
-			id:             u64;
-			derived:        any;
-		}
-
-		Rock :: struct {
-			using entity: Entity;
-			heavy: bool;
-		}
-		Door :: struct {
-			using entity: Entity;
-			open:         bool;
-		}
-		Monster :: struct {
-			using entity: Entity;
-			is_robot:     bool;
-			is_zombie:    bool;
-		}
-
-		new_entity :: proc(T: type, x, y: f32) -> ^T {
-			result := new(T);
-			result.derived = result^;
-			result.x = x;
-			result.y = y;
-
-			return result;
-		}
-
-		entities: [dynamic]^Entity;
-
-		rock := new_entity(Rock, 3, 5);
-
-		// Named arguments work too!
-		door := new_entity(T = Door, x = 3, y = 6);
-
-		// And named arguments can be any order
-		monster := new_entity(
-			y = 1,
-			x = 2,
-			T = Monster,
-		);
-
-		append(&entities, rock, door, monster);
-
-		fmt.println("Subtyping");
-		for entity in entities {
-			match e in entity.derived {
-			case Rock:    fmt.println("Rock",    e.x, e.y);
-			case Door:    fmt.println("Door",    e.x, e.y);
-			case Monster: fmt.println("Monster", e.x, e.y);
-			}
-		}
-	}
-	{
-		Entity :: struct {
-			using position: Vector2;
-			flags:          u64;
-			id:             u64;
-			variant: union { Rock, Door, Monster };
-		}
-
-		Rock :: struct {
-			using entity: ^Entity;
-			heavy: bool;
-		}
-		Door :: struct {
-			using entity: ^Entity;
-			open:         bool;
-		}
-		Monster :: struct {
-			using entity: ^Entity;
-			is_robot:     bool;
-			is_zombie:    bool;
-		}
-
-		new_entity :: proc(T: type, x, y: f32) -> ^T {
-			result := new(Entity);
-			result.variant = T{entity = result};
-			result.x = x;
-			result.y = y;
-
-			return cast(^T)&result.variant;
-		}
-
-		entities: [dynamic]^Entity;
-
-		rock := new_entity(Rock, 3, 5);
-
-		// Named arguments work too!
-		door := new_entity(T = Door, x = 3, y = 6);
-
-		// And named arguments can be any order
-		monster := new_entity(
-			y = 1,
-			x = 2,
-			T = Monster,
-		);
-
-		append(&entities, rock, door, monster);
-
-		fmt.println("Union");
-		for entity in entities {
-			match e in entity.variant {
-			case Rock:    fmt.println("Rock",    e.x, e.y);
-			case Door:    fmt.println("Door",    e.x, e.y);
-			case Monster: fmt.println("Monster", e.x, e.y);
-			}
-		}
-	}
-}
-
-
-implicit_polymorphic_assignment :: proc() {
-	yep :: proc(p: proc(x: int)) {
-		p(123);
-	}
-
-	frank :: proc(x: $T)    do fmt.println("frank ->", x);
-	tim   :: proc(x, y: $T) do fmt.println("tim ->", x, y);
-	yep(frank);
-	// yep(tim);
-}
-
-
-
-
-main :: proc() {
-/*
-	foo :: proc(x: i64,  y: f32) do fmt.println("#1", x, y);
-	foo :: proc(x: type, y: f32) do fmt.println("#2", type_info(x), y);
-	foo :: proc(x: type)         do fmt.println("#3", type_info(x));
-
-	f :: foo;
-
-	f(y = 3785.1546, x = 123);
-	f(x = int, y = 897.513);
-	f(x = f32);
-
-	general_stuff();
-	foreign_blocks();
-	default_arguments();
-	named_arguments();
-	default_return_values();
-	call_location();
-	explicit_parametric_polymorphic_procedures();
-	implicit_polymorphic_assignment();
-
-
-	// Command line argument(s)!
-	// -opt=0,1,2,3
-*/
-/*
-	program := "+ + * - /";
-	accumulator := 0;
-
-	for token in program {
-		match token {
-		case '+': accumulator += 1;
-		case '-': accumulator -= 1;
-		case '*': accumulator *= 2;
-		case '/': accumulator /= 2;
-		case: // Ignore everything else
-		}
-	}
-
-	fmt.printf("The program \"%s\" calculates the value %d\n",
-			   program, accumulator);
-*/
-}