mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Fix old_demos; Fix when bug; Fix enum .names
This commit is contained in:
@@ -43,7 +43,7 @@ del *.ilk > NUL 2> NUL
|
|||||||
|
|
||||||
cl %compiler_settings% "src\main.cpp" ^
|
cl %compiler_settings% "src\main.cpp" ^
|
||||||
/link %linker_settings% -OUT:%exe_name% ^
|
/link %linker_settings% -OUT:%exe_name% ^
|
||||||
&& odin run examples/demo.odin -opt=0
|
&& odin run examples/old_demos/demo006.odin -opt=0
|
||||||
rem && odin docs core/fmt.odin
|
rem && odin docs core/fmt.odin
|
||||||
|
|
||||||
del *.obj > NUL 2> NUL
|
del *.obj > NUL 2> NUL
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import "fmt.odin";
|
import "core:fmt.odin";
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
recursive_factorial :: proc(i: u64) -> u64 {
|
recursive_factorial :: proc(i: u64) -> u64 {
|
||||||
|
|||||||
+12
-12
@@ -1,9 +1,9 @@
|
|||||||
import win32 "sys/windows.odin" when ODIN_OS == "windows";
|
import win32 "core:sys/windows.odin" when ODIN_OS == "windows";
|
||||||
import wgl "sys/wgl.odin" when ODIN_OS == "windows";
|
import wgl "core:sys/wgl.odin" when ODIN_OS == "windows";
|
||||||
import "fmt.odin";
|
import "core:fmt.odin";
|
||||||
import "math.odin";
|
import "core:math.odin";
|
||||||
import "os.odin";
|
import "core:os.odin";
|
||||||
import gl "opengl.odin";
|
import gl "core:opengl.odin";
|
||||||
|
|
||||||
TWO_HEARTS :: '💕';
|
TWO_HEARTS :: '💕';
|
||||||
|
|
||||||
@@ -32,12 +32,12 @@ to_c_string :: proc(s: string) -> []u8 {
|
|||||||
|
|
||||||
|
|
||||||
Window :: struct {
|
Window :: struct {
|
||||||
width, height: int;
|
width, height: int,
|
||||||
wc: win32.Wnd_Class_Ex_A;
|
wc: win32.Wnd_Class_Ex_A,
|
||||||
dc: win32.Hdc;
|
dc: win32.Hdc,
|
||||||
hwnd: win32.Hwnd;
|
hwnd: win32.Hwnd,
|
||||||
opengl_context, rc: wgl.Hglrc;
|
opengl_context, rc: wgl.Hglrc,
|
||||||
c_title: []u8;
|
c_title: []u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
make_window :: proc(title: string, msg, height: int, window_proc: win32.Wnd_Proc) -> (Window, bool) {
|
make_window :: proc(title: string, msg, height: int, window_proc: win32.Wnd_Proc) -> (Window, bool) {
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import "fmt.odin";
|
import "core:fmt.odin";
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
fmt.println("Hellope, world!");
|
fmt.println("Hellope, world!");
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#import "fmt.odin";
|
import "core:fmt.odin";
|
||||||
#import "os.odin";
|
import "core:os.odin";
|
||||||
#import "mem.odin";
|
import "core:mem.odin";
|
||||||
// #import "http_test.odin" as ht;
|
// import "http_test.odin" as ht;
|
||||||
// #import "game.odin" as game;
|
// import "game.odin" as game;
|
||||||
// #import "punity.odin" as pn;
|
// import "punity.odin" as pn;
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
struct_padding();
|
struct_padding();
|
||||||
@@ -160,21 +160,21 @@ type_introspection :: proc() {
|
|||||||
info: ^Type_Info;
|
info: ^Type_Info;
|
||||||
x: int;
|
x: int;
|
||||||
|
|
||||||
info = type_info(int); // by type
|
info = type_info_of(int); // by type
|
||||||
info = type_info_of_val(x); // by value
|
info = type_info_of(x); // by value
|
||||||
// See: runtime.odin
|
// See: runtime.odin
|
||||||
|
|
||||||
match i in info {
|
match i in info.variant {
|
||||||
case Type_Info.Integer:
|
case Type_Info_Integer:
|
||||||
fmt.println("integer!");
|
fmt.println("integer!");
|
||||||
case Type_Info.Float:
|
case Type_Info_Float:
|
||||||
fmt.println("float!");
|
fmt.println("float!");
|
||||||
default:
|
case:
|
||||||
fmt.println("potato!");
|
fmt.println("potato!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unsafe cast
|
// Unsafe cast
|
||||||
integer_info := cast(^Type_Info.Integer)cast(rawptr)info;
|
integer_info := cast(^Type_Info_Integer)cast(rawptr)info;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -185,9 +185,9 @@ type_introspection :: proc() {
|
|||||||
v2: Vector3;
|
v2: Vector3;
|
||||||
v3: Vector3;
|
v3: Vector3;
|
||||||
|
|
||||||
t1 := type_info_of_val(v1);
|
t1 := type_info_of(v1);
|
||||||
t2 := type_info_of_val(v2);
|
t2 := type_info_of(v2);
|
||||||
t3 := type_info_of_val(v3);
|
t3 := type_info_of(v3);
|
||||||
|
|
||||||
fmt.println();
|
fmt.println();
|
||||||
fmt.print("Type of v1 is:\n\t", t1);
|
fmt.print("Type of v1 is:\n\t", t1);
|
||||||
@@ -262,12 +262,12 @@ crazy_introspection :: proc() {
|
|||||||
TOMATO,
|
TOMATO,
|
||||||
}
|
}
|
||||||
|
|
||||||
fruit_ti := type_info(Fruit);
|
fruit_ti := type_info_of(Fruit);
|
||||||
name := (union_cast(^Type_Info.Named)fruit_ti).name; // Unsafe casts
|
name := fruit_ti.variant.(Type_Info_Named).name;
|
||||||
info, _ := union_cast(^Type_Info.Enum)type_info_base(fruit_ti); // Unsafe casts
|
info, _ := type_info_base(fruit_ti).variant.(Type_Info_Enum);
|
||||||
|
|
||||||
fmt.printf("%s :: enum %T {\n", name, info.base);
|
fmt.printf("%s :: enum %T {\n", name, info.base);
|
||||||
for i := 0; i < len(info.values); i++ {
|
for _, i in info.values {
|
||||||
fmt.printf("\t%s\t= %v,\n", info.names[i], info.values[i]);
|
fmt.printf("\t%s\t= %v,\n", info.names[i], info.values[i]);
|
||||||
}
|
}
|
||||||
fmt.printf("}\n");
|
fmt.printf("}\n");
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
// Demo 002
|
// Demo 002
|
||||||
#load "fmt.odin";
|
export "core:fmt.odin";
|
||||||
#load "math.odin";
|
export "core:math.odin";
|
||||||
// #load "game.odin"
|
export "core:mem.odin";
|
||||||
|
// export "game.odin"
|
||||||
|
|
||||||
#thread_local tls_int: int;
|
#thread_local tls_int: int;
|
||||||
|
|
||||||
@@ -94,11 +95,9 @@ enumerations :: proc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
variadic_procedures :: proc() {
|
variadic_procedures :: proc() {
|
||||||
print_ints :: proc(args: ..int) {
|
print_ints :: proc(args: ...int) {
|
||||||
for arg, i in args {
|
for arg, i in args {
|
||||||
if i > 0 {
|
if i > 0 do print(", ");
|
||||||
print(", ");
|
|
||||||
}
|
|
||||||
print(arg);
|
print(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,13 +106,11 @@ variadic_procedures :: proc() {
|
|||||||
print_ints(1); nl();
|
print_ints(1); nl();
|
||||||
print_ints(1, 2, 3); nl();
|
print_ints(1, 2, 3); nl();
|
||||||
|
|
||||||
print_prefix_f32s :: proc(prefix: string, args: ..f32) {
|
print_prefix_f32s :: proc(prefix: string, args: ...f32) {
|
||||||
print(prefix);
|
print(prefix);
|
||||||
print(": ");
|
print(": ");
|
||||||
for arg, i in args {
|
for arg, i in args {
|
||||||
if i > 0 {
|
if i > 0 do print(", ");
|
||||||
print(", ");
|
|
||||||
}
|
|
||||||
print(arg);
|
print(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,13 +144,7 @@ new_builtins :: proc() {
|
|||||||
|
|
||||||
// Q: Should this be `free` rather than `free` and should I overload it for slices too?
|
// Q: Should this be `free` rather than `free` and should I overload it for slices too?
|
||||||
|
|
||||||
{
|
push_allocator default_allocator() {
|
||||||
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);
|
a := new(int);
|
||||||
defer free(a);
|
defer free(a);
|
||||||
|
|
||||||
@@ -164,7 +155,7 @@ new_builtins :: proc() {
|
|||||||
|
|
||||||
{
|
{
|
||||||
a: int = 123;
|
a: int = 123;
|
||||||
b: type_of_val(a) = 321;
|
b: type_of(a) = 321;
|
||||||
|
|
||||||
// NOTE(bill): This matches the current naming scheme
|
// NOTE(bill): This matches the current naming scheme
|
||||||
// size_of
|
// size_of
|
||||||
@@ -205,7 +196,7 @@ new_builtins :: proc() {
|
|||||||
|
|
||||||
a: [16]int;
|
a: [16]int;
|
||||||
a[1] = 1;
|
a[1] = 1;
|
||||||
b := ^a;
|
b := &a;
|
||||||
// Auto pointer deref
|
// Auto pointer deref
|
||||||
// consistent with record members
|
// consistent with record members
|
||||||
assert(b[1] == 1);
|
assert(b[1] == 1);
|
||||||
@@ -255,7 +246,7 @@ match_statement :: proc() {
|
|||||||
print("5!\n");
|
print("5!\n");
|
||||||
fallthrough; // explicit fallthrough
|
fallthrough; // explicit fallthrough
|
||||||
|
|
||||||
default:
|
case:
|
||||||
print("default!\n");
|
print("default!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,7 +258,7 @@ match_statement :: proc() {
|
|||||||
// break by default
|
// break by default
|
||||||
case TAU:
|
case TAU:
|
||||||
print("τ!\n");
|
print("τ!\n");
|
||||||
default:
|
case:
|
||||||
print("default!\n");
|
print("default!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,7 +270,7 @@ match_statement :: proc() {
|
|||||||
// break by default
|
// break by default
|
||||||
case "Goodbye":
|
case "Goodbye":
|
||||||
print("farewell\n");
|
print("farewell\n");
|
||||||
default:
|
case:
|
||||||
print("???\n");
|
print("???\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,7 +293,7 @@ match_statement :: proc() {
|
|||||||
print("dozens\n");
|
print("dozens\n");
|
||||||
case a >= 100 && a < 1000:
|
case a >= 100 && a < 1000:
|
||||||
print("hundreds\n");
|
print("hundreds\n");
|
||||||
default:
|
case:
|
||||||
print("a fuck ton\n");
|
print("a fuck ton\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,11 +323,9 @@ match_statement :: proc() {
|
|||||||
|
|
||||||
Vector3 :: struct {x, y, z: f32}
|
Vector3 :: struct {x, y, z: f32}
|
||||||
|
|
||||||
print_floats :: proc(args: ..f32) {
|
print_floats :: proc(args: ...f32) {
|
||||||
for arg, i in args {
|
for arg, i in args {
|
||||||
if i > 0 {
|
if i > 0 do print(", ");
|
||||||
print(", ");
|
|
||||||
}
|
|
||||||
print(arg);
|
print(arg);
|
||||||
}
|
}
|
||||||
println();
|
println();
|
||||||
@@ -355,7 +344,7 @@ namespacing :: proc() {
|
|||||||
Thing :: #type struct {
|
Thing :: #type struct {
|
||||||
y: int,
|
y: int,
|
||||||
test: bool,
|
test: bool,
|
||||||
}
|
};
|
||||||
|
|
||||||
b: Thing; // Uses this scope's Thing
|
b: Thing; // Uses this scope's Thing
|
||||||
b.test = true;
|
b.test = true;
|
||||||
@@ -473,10 +462,10 @@ namespacing :: proc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
e := Entity{position = Vector3{1, 2, 3}};
|
e := Entity{position = Vector3{1, 2, 3}};
|
||||||
print_pos_1(^e);
|
print_pos_1(&e);
|
||||||
print_pos_2(^e);
|
print_pos_2(&e);
|
||||||
print_pos_3(^e);
|
print_pos_3(&e);
|
||||||
print_pos_4(^e);
|
print_pos_4(&e);
|
||||||
|
|
||||||
// This is similar to C++'s `this` pointer that is implicit and only available in methods
|
// This is similar to C++'s `this` pointer that is implicit and only available in methods
|
||||||
}
|
}
|
||||||
@@ -574,20 +563,20 @@ subtyping :: proc() {
|
|||||||
entity_count := 0;
|
entity_count := 0;
|
||||||
|
|
||||||
next_entity :: proc(entities: []Entity, entity_count: ^int) -> ^Entity {
|
next_entity :: proc(entities: []Entity, entity_count: ^int) -> ^Entity {
|
||||||
e := ^entities[entity_count^];
|
e := &entities[entity_count^];
|
||||||
entity_count^++;
|
entity_count^ += 1;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
f: Frog;
|
f: Frog;
|
||||||
f.entity = next_entity(entities[..], ^entity_count);
|
f.entity = next_entity(entities[..], &entity_count);
|
||||||
f.position = Vector3{3, 4, 6};
|
f.position = Vector3{3, 4, 6};
|
||||||
|
|
||||||
using f.position;
|
using f.position;
|
||||||
print_floats(x, y, z);
|
print_floats(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
/*{
|
||||||
// Down casting
|
// Down casting
|
||||||
|
|
||||||
Entity :: struct {
|
Entity :: struct {
|
||||||
@@ -609,7 +598,7 @@ subtyping :: proc() {
|
|||||||
|
|
||||||
// NOTE(bill): `down_cast` is unsafe and there are not check are compile time or run time
|
// 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
|
// Q: Should I completely remove `down_cast` as I added it in about 30 minutes
|
||||||
}
|
}*/
|
||||||
|
|
||||||
{
|
{
|
||||||
// Multiple "inheritance"/subclassing
|
// Multiple "inheritance"/subclassing
|
||||||
@@ -630,7 +619,7 @@ subtyping :: proc() {
|
|||||||
|
|
||||||
tagged_unions :: proc() {
|
tagged_unions :: proc() {
|
||||||
{
|
{
|
||||||
EntityKind :: enum {
|
Entity_Kind :: enum {
|
||||||
INVALID,
|
INVALID,
|
||||||
FROG,
|
FROG,
|
||||||
GIRAFFE,
|
GIRAFFE,
|
||||||
@@ -638,8 +627,8 @@ tagged_unions :: proc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Entity :: struct {
|
Entity :: struct {
|
||||||
kind: EntityKind
|
kind: Entity_Kind
|
||||||
using data: raw_union {
|
using data: struct #raw_union {
|
||||||
frog: struct {
|
frog: struct {
|
||||||
jump_height: f32,
|
jump_height: f32,
|
||||||
colour: u32,
|
colour: u32,
|
||||||
@@ -657,33 +646,31 @@ tagged_unions :: proc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
e: Entity;
|
e: Entity;
|
||||||
e.kind = EntityKind.FROG;
|
e.kind = Entity_Kind.FROG;
|
||||||
e.frog.jump_height = 12;
|
e.frog.jump_height = 12;
|
||||||
|
|
||||||
f: type_of_val(e.frog);
|
f: type_of(e.frog);
|
||||||
|
|
||||||
// But this is very unsafe and extremely cumbersome to write
|
// But this is very unsafe and extremely cumbersome to write
|
||||||
// In C++, I use macros to alleviate this but it's not a solution
|
// In C++, I use macros to alleviate this but it's not a solution
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Entity :: union {
|
Frog :: struct {
|
||||||
Frog{
|
jump_height: f32,
|
||||||
jump_height: f32,
|
colour: u32,
|
||||||
colour: u32,
|
|
||||||
},
|
|
||||||
Giraffe{
|
|
||||||
neck_length: f32,
|
|
||||||
spot_count: int,
|
|
||||||
},
|
|
||||||
Helicopter{
|
|
||||||
blade_count: int,
|
|
||||||
weight: f32,
|
|
||||||
pilot_name: string,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
Giraffe :: struct {
|
||||||
|
neck_length: f32,
|
||||||
|
spot_count: int,
|
||||||
|
}
|
||||||
|
Helicopter :: struct {
|
||||||
|
blade_count: int,
|
||||||
|
weight: f32,
|
||||||
|
pilot_name: string,
|
||||||
|
}
|
||||||
|
Entity :: union {Frog, Giraffe, Helicopter};
|
||||||
|
|
||||||
using Entity;
|
|
||||||
f1: Frog = Frog{12, 0xff9900};
|
f1: Frog = Frog{12, 0xff9900};
|
||||||
f2: Entity = Frog{12, 0xff9900}; // Implicit cast
|
f2: Entity = Frog{12, 0xff9900}; // Implicit cast
|
||||||
f3 := cast(Entity)Frog{12, 0xff9900}; // Explicit cast
|
f3 := cast(Entity)Frog{12, 0xff9900}; // Explicit cast
|
||||||
@@ -703,7 +690,7 @@ tagged_unions :: proc() {
|
|||||||
// Requires a pointer to the union
|
// Requires a pointer to the union
|
||||||
// `x` will be a pointer to type of the case
|
// `x` will be a pointer to type of the case
|
||||||
|
|
||||||
match x in ^f {
|
match x in &f {
|
||||||
case Frog:
|
case Frog:
|
||||||
print("Frog!\n");
|
print("Frog!\n");
|
||||||
print(x.jump_height); nl();
|
print(x.jump_height); nl();
|
||||||
@@ -713,7 +700,7 @@ tagged_unions :: proc() {
|
|||||||
print("Giraffe!\n");
|
print("Giraffe!\n");
|
||||||
case Helicopter:
|
case Helicopter:
|
||||||
print("ROFLCOPTER!\n");
|
print("ROFLCOPTER!\n");
|
||||||
default:
|
case:
|
||||||
print("invalid entity\n");
|
print("invalid entity\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -755,11 +742,11 @@ tagged_unions :: proc() {
|
|||||||
AstNode :: struct {};
|
AstNode :: struct {};
|
||||||
ExactValue :: struct {};
|
ExactValue :: struct {};
|
||||||
|
|
||||||
EntityKind :: enum {
|
Entity_Kind :: enum {
|
||||||
Invalid,
|
Invalid,
|
||||||
Constant,
|
Constant,
|
||||||
Variable,
|
Variable,
|
||||||
UsingVariable,
|
Using_Variable,
|
||||||
TypeName,
|
TypeName,
|
||||||
Procedure,
|
Procedure,
|
||||||
Builtin,
|
Builtin,
|
||||||
@@ -769,14 +756,14 @@ tagged_unions :: proc() {
|
|||||||
Guid :: i64;
|
Guid :: i64;
|
||||||
Entity :: struct {
|
Entity :: struct {
|
||||||
|
|
||||||
kind: EntityKind,
|
kind: Entity_Kind,
|
||||||
guid: Guid,
|
guid: Guid,
|
||||||
|
|
||||||
scope: ^Scope,
|
scope: ^Scope,
|
||||||
token: Token,
|
token: Token,
|
||||||
type_: ^Type,
|
type_: ^Type,
|
||||||
|
|
||||||
using data: raw_union {
|
using data: struct #raw_union {
|
||||||
Constant: struct {
|
Constant: struct {
|
||||||
value: ExactValue,
|
value: ExactValue,
|
||||||
},
|
},
|
||||||
@@ -786,7 +773,7 @@ tagged_unions :: proc() {
|
|||||||
is_field: bool, // Is struct field
|
is_field: bool, // Is struct field
|
||||||
anonymous: bool, // Variable is an anonymous
|
anonymous: bool, // Variable is an anonymous
|
||||||
},
|
},
|
||||||
UsingVariable: struct {
|
Using_Variable: struct {
|
||||||
},
|
},
|
||||||
TypeName: struct {
|
TypeName: struct {
|
||||||
},
|
},
|
||||||
@@ -813,44 +800,44 @@ tagged_unions :: proc() {
|
|||||||
|
|
||||||
Guid :: i64;
|
Guid :: i64;
|
||||||
Entity_Base :: struct {
|
Entity_Base :: struct {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity :: 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,
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity :: struct {
|
||||||
guid: Guid,
|
guid: Guid,
|
||||||
|
|
||||||
scope: ^Scope,
|
scope: ^Scope,
|
||||||
token: Token,
|
token: Token,
|
||||||
type_: ^Type,
|
type_: ^Type,
|
||||||
|
|
||||||
Constant{
|
variant: union {Constant, Variable, Using_Variable, TypeName, Procedure, Builtin},
|
||||||
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{
|
||||||
|
variant = Variable{
|
||||||
e: Entity;
|
used = true,
|
||||||
|
anonymous = false,
|
||||||
e = Variable{
|
},
|
||||||
used = true,
|
|
||||||
anonymous = false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -863,13 +850,13 @@ tagged_unions :: proc() {
|
|||||||
{
|
{
|
||||||
// `Raw` unions still have uses, especially for mathematic types
|
// `Raw` unions still have uses, especially for mathematic types
|
||||||
|
|
||||||
Vector2 :: raw_union {
|
Vector2 :: struct #raw_union {
|
||||||
using xy_: struct { x, y: f32 },
|
using xy_: struct { x, y: f32 },
|
||||||
e: [2]f32,
|
e: [2]f32,
|
||||||
v: [vector 2]f32,
|
v: [vector 2]f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 :: raw_union {
|
Vector3 :: struct #raw_union {
|
||||||
using xyz_: struct { x, y, z: f32 },
|
using xyz_: struct { x, y, z: f32 },
|
||||||
xy: Vector2,
|
xy: Vector2,
|
||||||
e: [3]f32,
|
e: [3]f32,
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
#import "fmt.odin";
|
import "core:fmt.odin";
|
||||||
#import "utf8.odin";
|
import "core:utf8.odin";
|
||||||
#import "hash.odin";
|
import "core:hash.odin";
|
||||||
#import "mem.odin";
|
import "core:mem.odin";
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
{ // New Standard Library stuff
|
{ // New Standard Library stuff
|
||||||
s := "Hello";
|
s := "Hello";
|
||||||
fmt.println(s,
|
fmt.println(s,
|
||||||
utf8.valid_string(s),
|
utf8.valid_string(s),
|
||||||
hash.murmur64(cast([]byte)s));
|
hash.murmur64(cast([]u8)s));
|
||||||
|
|
||||||
// utf8.odin
|
// utf8.odin
|
||||||
// hash.odin
|
// hash.odin
|
||||||
@@ -20,10 +20,10 @@ main :: proc() {
|
|||||||
|
|
||||||
{
|
{
|
||||||
arena: mem.Arena;
|
arena: mem.Arena;
|
||||||
mem.init_arena_from_context(^arena, mem.megabytes(16)); // Uses default allocator
|
mem.init_arena_from_context(&arena, mem.megabytes(16)); // Uses default allocator
|
||||||
defer mem.free_arena(^arena);
|
defer mem.destroy_arena(&arena);
|
||||||
|
|
||||||
push_allocator mem.arena_allocator(^arena) {
|
push_allocator mem.arena_allocator(&arena) {
|
||||||
x := new(int);
|
x := new(int);
|
||||||
x^ = 1337;
|
x^ = 1337;
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ main :: proc() {
|
|||||||
// You can also "push" a context
|
// You can also "push" a context
|
||||||
|
|
||||||
c := context; // Create copy of the allocator
|
c := context; // Create copy of the allocator
|
||||||
c.allocator = mem.arena_allocator(^arena);
|
c.allocator = mem.arena_allocator(&arena);
|
||||||
|
|
||||||
push_context c {
|
push_context c {
|
||||||
x := new(int);
|
x := new(int);
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#import "fmt.odin";
|
import "core:fmt.odin";
|
||||||
#import "utf8.odin";
|
import "core:utf8.odin";
|
||||||
// #import "atomic.odin";
|
// import "core:atomic.odin";
|
||||||
// #import "hash.odin";
|
// import "core:hash.odin";
|
||||||
// #import "math.odin";
|
// import "core:math.odin";
|
||||||
// #import "mem.odin";
|
// import "core:mem.odin";
|
||||||
// #import "opengl.odin";
|
// import "core:opengl.odin";
|
||||||
// #import "os.odin";
|
// import "core:os.odin";
|
||||||
// #import "sync.odin";
|
// import "core:sync.odin";
|
||||||
// #import win32 "sys/windows.odin";
|
// import win32 "core:sys/windows.odin";
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
// syntax();
|
// syntax();
|
||||||
@@ -43,7 +43,7 @@ syntax :: proc() {
|
|||||||
Thing2 :: 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 interals are now just a `ptr+len+cap`
|
||||||
slice: []int; compile_assert(size_of_val(slice) == 3*size_of(int));
|
slice: []int; compile_assert(size_of(slice) == 3*size_of(int));
|
||||||
|
|
||||||
// Helper type - Help the reader understand what it is quicker
|
// Helper type - Help the reader understand what it is quicker
|
||||||
My_Int :: #type int;
|
My_Int :: #type int;
|
||||||
@@ -90,22 +90,17 @@ Prefix_Type :: struct {x: int, y: f32, z: rawptr};
|
|||||||
|
|
||||||
prefixes :: proc() {
|
prefixes :: proc() {
|
||||||
using var: Prefix_Type;
|
using var: Prefix_Type;
|
||||||
immutable const := Prefix_Type{1, 2, nil};
|
|
||||||
var.x = 123;
|
var.x = 123;
|
||||||
x = 123;
|
x = 123;
|
||||||
// const.x = 123; // const is immutable
|
|
||||||
|
|
||||||
|
|
||||||
|
foo :: proc(using pt: Prefix_Type) {
|
||||||
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`
|
// Same as C99's `restrict`
|
||||||
bar :: proc(no_alias a, b: ^int) {
|
bar :: proc(#no_alias a, b: ^int) {
|
||||||
// Assumes a never equals b so it can perform optimizations with that fact
|
// Assumes a never equals b so it can perform optimizations with that fact
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,14 +133,18 @@ when_statements :: proc() {
|
|||||||
foreign_procedures();
|
foreign_procedures();
|
||||||
}
|
}
|
||||||
|
|
||||||
#foreign_system_library win32_user "user32.lib" when ODIN_OS == "windows";
|
when ODIN_OS == "windows" {
|
||||||
|
foreign_system_library win32_user "user32.lib";
|
||||||
|
}
|
||||||
// NOTE: This is done on purpose for two reasons:
|
// NOTE: This is done on purpose for two reasons:
|
||||||
// * Makes it clear where the platform specific stuff is
|
// * Makes it clear where the platform specific stuff is
|
||||||
// * Removes the need to solve the travelling salesman problem when importing files :P
|
// * Removes the need to solve the travelling salesman problem when importing files :P
|
||||||
|
|
||||||
foreign_procedures :: proc() {
|
foreign_procedures :: proc() {
|
||||||
ShowWindow :: proc(hwnd: rawptr, cmd_show: i32) -> i32 #foreign win32_user;
|
foreign win32_user {
|
||||||
show_window :: proc(hwnd: rawptr, cmd_show: i32) -> i32 #foreign win32_user "ShowWindow";
|
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: 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
|
// NOTE: There is not link checking yet to see if that procedure does come from that library
|
||||||
|
|
||||||
@@ -203,14 +202,14 @@ loops :: proc() {
|
|||||||
fmt.println(val, idx);
|
fmt.println(val, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
primes := [..]int{2, 3, 5, 7, 11, 13, 17, 19};
|
primes := [...]int{2, 3, 5, 7, 11, 13, 17, 19};
|
||||||
|
|
||||||
for p in primes {
|
for p in primes {
|
||||||
fmt.println(p);
|
fmt.println(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pointers to arrays, slices, or strings are allowed
|
// Pointers to arrays, slices, or strings are allowed
|
||||||
for _ in ^primes {
|
for _ in &primes {
|
||||||
// ignore the value and just iterate across it
|
// ignore the value and just iterate across it
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +218,7 @@ loops :: proc() {
|
|||||||
name := "你好,世界";
|
name := "你好,世界";
|
||||||
fmt.println(name);
|
fmt.println(name);
|
||||||
for r in name {
|
for r in name {
|
||||||
compile_assert(type_of_val(r) == rune);
|
compile_assert(type_of(r) == rune);
|
||||||
fmt.printf("%r\n", r);
|
fmt.printf("%r\n", r);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,8 +269,8 @@ procedure_overloading :: proc() {
|
|||||||
a: i32 = 123;
|
a: i32 = 123;
|
||||||
b: f32;
|
b: f32;
|
||||||
c: rawptr;
|
c: rawptr;
|
||||||
fmt.println(foo(^a));
|
fmt.println(foo(&a));
|
||||||
foo(^b);
|
foo(&b);
|
||||||
foo(c);
|
foo(c);
|
||||||
// foo(nil); // nil could go to numerous types thus the ambiguity
|
// foo(nil); // nil could go to numerous types thus the ambiguity
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
#import "atomic.odin";
|
// import "core:atomic.odin";
|
||||||
#import "hash.odin";
|
import "core:hash.odin";
|
||||||
#import "mem.odin";
|
import "core:mem.odin";
|
||||||
#import "opengl.odin";
|
import "core:opengl.odin";
|
||||||
#import "strconv.odin";
|
import "core:strconv.odin";
|
||||||
#import "sync.odin";
|
import "core:sync.odin";
|
||||||
#import win32 "sys/windows.odin";
|
import win32 "core:sys/windows.odin";
|
||||||
|
|
||||||
#import "fmt.odin";
|
import "core:fmt.odin";
|
||||||
#import "os.odin";
|
import "core:os.odin";
|
||||||
#import "math.odin";
|
import "core:math.odin";
|
||||||
|
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
@@ -55,7 +55,7 @@ when true {
|
|||||||
for i in 0..16 {
|
for i in 0..16 {
|
||||||
}
|
}
|
||||||
// Is similar to
|
// Is similar to
|
||||||
for _i := 0; _i < 16; _i++ { immutable i := _i;
|
for i := 0; i < 16; i += 1 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,16 +77,15 @@ when true {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
t := type_info(int);
|
t := type_info_of(int);
|
||||||
using Type_Info;
|
match i in t.variant {
|
||||||
match i in t {
|
case Type_Info_Integer, Type_Info_Float:
|
||||||
case Integer, Float:
|
|
||||||
fmt.println("It's a number");
|
fmt.println("It's a number");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
x: any = 123;
|
x: any = 123;
|
||||||
foo match i in x {
|
foo: match i in x {
|
||||||
case int, f32:
|
case int, f32:
|
||||||
fmt.println("It's an int or f32");
|
fmt.println("It's an int or f32");
|
||||||
break foo;
|
break foo;
|
||||||
@@ -112,21 +111,20 @@ when true {
|
|||||||
|
|
||||||
{
|
{
|
||||||
// Slices now store a capacity
|
// Slices now store a capacity
|
||||||
buf: [256]byte;
|
buf: [256]u8;
|
||||||
s: []byte;
|
s: []u8;
|
||||||
s = buf[..0]; // == buf[0..0];
|
s = buf[..0]; // == buf[0..0];
|
||||||
fmt.println("count =", s.count);
|
fmt.println("count =", len(s));
|
||||||
fmt.println("capacity =", s.capacity);
|
fmt.println("capacity =", cap(s));
|
||||||
append(s, 1, 2, 3);
|
append(&s, 1, 2, 3);
|
||||||
fmt.println(s);
|
fmt.println(s);
|
||||||
|
|
||||||
s = buf[1..2..3];
|
s = buf[1..2..3];
|
||||||
fmt.println("count =", s.count);
|
fmt.println("count =", len(s));
|
||||||
fmt.println("capacity =", s.capacity);
|
fmt.println("capacity =", cap(s));
|
||||||
fmt.println(s);
|
fmt.println(s);
|
||||||
|
|
||||||
clear(s); // Sets count to zero
|
clear(&s); // Sets count to zero
|
||||||
s.count = 0; // Equivalent
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -136,11 +134,11 @@ when true {
|
|||||||
flags: u32,
|
flags: u32,
|
||||||
}
|
}
|
||||||
foo_array: [256]Foo;
|
foo_array: [256]Foo;
|
||||||
foo_as_bytes: []byte = slice_to_bytes(foo_array[..]);
|
foo_as_bytes: []u8 = mem.slice_to_bytes(foo_array[..]);
|
||||||
// Useful for things like
|
// Useful for things like
|
||||||
// os.write(handle, foo_as_bytes);
|
// os.write(handle, foo_as_bytes);
|
||||||
|
|
||||||
foo_slice := slice_ptr(cast(^Foo)foo_as_bytes.data, foo_as_bytes.count/size_of(Foo), foo_as_bytes.capacity/size_of(Foo));
|
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?
|
// 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?
|
// And if so what would the syntax be?
|
||||||
// slice_transmute([]Foo, foo_as_bytes);
|
// slice_transmute([]Foo, foo_as_bytes);
|
||||||
@@ -161,33 +159,26 @@ when true {
|
|||||||
fmt.println(i);
|
fmt.println(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
compile_assert(size_of([vector 7]bool) == size_of([7]bool));
|
compile_assert(size_of([vector 7]bool) >= size_of([7]bool));
|
||||||
compile_assert(size_of([vector 7]i32) == size_of([7]i32));
|
compile_assert(size_of([vector 7]i32) >= size_of([7]i32));
|
||||||
// align_of([vector 7]i32) != align_of([7]i32) // this may be the case
|
// align_of([vector 7]i32) != align_of([7]i32) // this may be the case
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// fmt.* changes
|
// fmt.* changes
|
||||||
// bprint* returns `int` (bytes written)
|
// bprint* returns `string`
|
||||||
// sprint* returns `string` (bytes written as a string)
|
|
||||||
|
|
||||||
data: [256]byte;
|
data: [256]u8;
|
||||||
str := fmt.sprintf(data[..0], "Hellope %d %s %c", 123, "others", '!');
|
str := fmt.bprintf(data[..], "Hellope %d %s %c", 123, "others", '!');
|
||||||
fmt.println(str);
|
fmt.println(str);
|
||||||
|
|
||||||
buf := data[..0];
|
|
||||||
count := fmt.bprintf(^buf, "Hellope %d %s %c", 321, "y'all", '!');
|
|
||||||
fmt.println(cast(string)buf[..count]);
|
|
||||||
|
|
||||||
// NOTE(bill): We may change this but because this is a library feature, I am not that bothered yet
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
x: [dynamic]f64;
|
x: [dynamic]f64;
|
||||||
reserve(x, 16);
|
reserve(&x, 16);
|
||||||
defer free(x); // `free` is overloaded for numerous types
|
defer free(x); // `free` is overloaded for numerous types
|
||||||
// Number literals can have underscores in them for readability
|
// Number literals can have underscores in them for readability
|
||||||
append(x, 2_000_000.500_000, 123, 5, 7); // variadic append
|
append(&x, 2_000_000.500_000, 123, 5, 7); // variadic append
|
||||||
|
|
||||||
for p, i in x {
|
for p, i in x {
|
||||||
if i > 0 { fmt.print(", "); }
|
if i > 0 { fmt.print(", "); }
|
||||||
@@ -201,13 +192,13 @@ when true {
|
|||||||
x := [dynamic]f64{2_000_000.500_000, 3, 5, 7};
|
x := [dynamic]f64{2_000_000.500_000, 3, 5, 7};
|
||||||
defer free(x);
|
defer free(x);
|
||||||
fmt.println(x); // fmt.print* supports printing of dynamic types
|
fmt.println(x); // fmt.print* supports printing of dynamic types
|
||||||
clear(x);
|
clear(&x);
|
||||||
fmt.println(x);
|
fmt.println(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
m: map[f32]int;
|
m: map[f32]int;
|
||||||
reserve(m, 16);
|
reserve(&m, 16);
|
||||||
defer free(m);
|
defer free(m);
|
||||||
|
|
||||||
m[1.0] = 1278;
|
m[1.0] = 1278;
|
||||||
@@ -241,12 +232,12 @@ when true {
|
|||||||
assert(ok && c == 7654);
|
assert(ok && c == 7654);
|
||||||
fmt.println(m);
|
fmt.println(m);
|
||||||
|
|
||||||
delete(m, "c"); // deletes entry with key "c"
|
delete(&m, "c"); // deletes entry with key "c"
|
||||||
_, found := m["c"];
|
_, found := m["c"];
|
||||||
assert(!found);
|
assert(!found);
|
||||||
|
|
||||||
fmt.println(m);
|
fmt.println(m);
|
||||||
clear(m);
|
clear(&m);
|
||||||
fmt.println(m);
|
fmt.println(m);
|
||||||
|
|
||||||
// NOTE: Fixed size maps are planned but we have not yet implemented
|
// NOTE: Fixed size maps are planned but we have not yet implemented
|
||||||
@@ -257,7 +248,21 @@ when true {
|
|||||||
Vector3 :: struct{x, y, z: f32};
|
Vector3 :: struct{x, y, z: f32};
|
||||||
Quaternion :: struct{x, y, z, w: f32};
|
Quaternion :: struct{x, y, z, w: f32};
|
||||||
|
|
||||||
Entity :: union {
|
// 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
|
// Common Fields
|
||||||
id: u64,
|
id: u64,
|
||||||
name: string,
|
name: string,
|
||||||
@@ -265,25 +270,13 @@ when true {
|
|||||||
orientation: Quaternion,
|
orientation: Quaternion,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
|
|
||||||
// Variants
|
variant: union { Frog, Door, Map },
|
||||||
Frog{
|
|
||||||
ribbit_volume: f32,
|
|
||||||
jump_height: f32,
|
|
||||||
},
|
|
||||||
Door{
|
|
||||||
openness: f32,
|
|
||||||
},
|
|
||||||
Map{
|
|
||||||
width, height: f32,
|
|
||||||
place_positions: []Vector3,
|
|
||||||
place_names: []string,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entity: Entity;
|
entity: Entity;
|
||||||
|
entity.id = 1337;
|
||||||
// implicit conversion from variant to base type
|
// implicit conversion from variant to base type
|
||||||
entity = Entity.Frog{
|
entity.variant = Frog{
|
||||||
id = 1337,
|
|
||||||
ribbit_volume = 0.5,
|
ribbit_volume = 0.5,
|
||||||
jump_height = 2.1,
|
jump_height = 2.1,
|
||||||
/*other data */
|
/*other data */
|
||||||
@@ -292,26 +285,25 @@ when true {
|
|||||||
entity.name = "Frank";
|
entity.name = "Frank";
|
||||||
entity.position = Vector3{1, 4, 9};
|
entity.position = Vector3{1, 4, 9};
|
||||||
|
|
||||||
using Entity;
|
match e in entity.variant {
|
||||||
match e in entity {
|
|
||||||
case Frog:
|
case Frog:
|
||||||
fmt.println("Ribbit");
|
fmt.println("Ribbit");
|
||||||
case Door:
|
case Door:
|
||||||
fmt.println("Creak");
|
fmt.println("Creak");
|
||||||
case Map:
|
case Map:
|
||||||
fmt.println("Rustle");
|
fmt.println("Rustle");
|
||||||
default:
|
case:
|
||||||
fmt.println("Just a normal entity");
|
fmt.println("Just a normal entity");
|
||||||
}
|
}
|
||||||
|
|
||||||
if frog, ok := union_cast(Frog)entity; ok {
|
if frog, ok := entity.variant.(Frog); ok {
|
||||||
fmt.printf("The frog jumps %f feet high at %v\n", frog.jump_height, frog.position);
|
fmt.printf("The frog jumps %f feet high at %v\n", frog.jump_height, entity.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Panics if not the correct type
|
// Panics if not the correct type
|
||||||
frog: Frog;
|
frog: Frog;
|
||||||
frog = union_cast(Frog)entity;
|
frog = entity.variant.(Frog);
|
||||||
frog, _ = union_cast(Frog)entity; // ignore error and force cast
|
frog, _ = entity.variant.(Frog); // ignore error and force cast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-40
@@ -1,7 +1,7 @@
|
|||||||
import win32 "sys/windows.odin";
|
import win32 "core:sys/windows.odin";
|
||||||
import "fmt.odin";
|
import "core:fmt.odin";
|
||||||
import "os.odin";
|
import "core:os.odin";
|
||||||
import "mem.odin";
|
import "core:mem.odin";
|
||||||
|
|
||||||
|
|
||||||
CANVAS_WIDTH :: 128;
|
CANVAS_WIDTH :: 128;
|
||||||
@@ -25,13 +25,13 @@ DRAW_LIST_RESERVE :: 128;
|
|||||||
MAX_KEYS :: 256;
|
MAX_KEYS :: 256;
|
||||||
|
|
||||||
Core :: struct {
|
Core :: struct {
|
||||||
stack: ^Bank;
|
stack: ^Bank,
|
||||||
storage: ^Bank;
|
storage: ^Bank,
|
||||||
|
|
||||||
running: bool;
|
running: bool,
|
||||||
key_modifiers: u32;
|
key_modifiers: u32,
|
||||||
key_states: [MAX_KEYS]u8;
|
key_states: [MAX_KEYS]u8,
|
||||||
key_deltas: [MAX_KEYS]u8;
|
key_deltas: [MAX_KEYS]u8,
|
||||||
|
|
||||||
perf_frame,
|
perf_frame,
|
||||||
perf_frame_inner,
|
perf_frame_inner,
|
||||||
@@ -39,66 +39,66 @@ Core :: struct {
|
|||||||
perf_audio,
|
perf_audio,
|
||||||
perf_blit,
|
perf_blit,
|
||||||
perf_blit_cvt,
|
perf_blit_cvt,
|
||||||
perf_blit_gdi: Perf_Span;
|
perf_blit_gdi: Perf_Span,
|
||||||
|
|
||||||
frame: i64;
|
frame: i64,
|
||||||
|
|
||||||
canvas: Canvas;
|
canvas: Canvas,
|
||||||
draw_list: ^Draw_List;
|
draw_list: ^Draw_List,
|
||||||
}
|
}
|
||||||
|
|
||||||
Perf_Span :: struct {
|
Perf_Span :: struct {
|
||||||
stamp: f64;
|
stamp: f64,
|
||||||
delta: f32;
|
delta: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
Bank :: struct {
|
Bank :: struct {
|
||||||
memory: []u8;
|
memory: []u8,
|
||||||
cursor: int;
|
cursor: int,
|
||||||
}
|
}
|
||||||
|
|
||||||
Bank_State :: struct {
|
Bank_State :: struct {
|
||||||
state: Bank;
|
state: Bank,
|
||||||
bank: ^Bank;
|
bank: ^Bank,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Color :: struct #raw_union {
|
Color :: struct #raw_union {
|
||||||
using channels: struct{a, b, g, r: u8};
|
using channels: struct{a, b, g, r: u8},
|
||||||
rgba: u32;
|
rgba: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
Palette :: struct {
|
Palette :: struct {
|
||||||
colors: [256]Color;
|
colors: [256]Color,
|
||||||
colors_count: u8;
|
colors_count: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rect :: struct #raw_union {
|
Rect :: struct #raw_union {
|
||||||
using minmax: struct {min_x, min_y, max_x, max_y: int};
|
using minmax: struct {min_x, min_y, max_x, max_y: int},
|
||||||
using pos: struct {left, top, right, bottom: int};
|
using pos: struct {left, top, right, bottom: int},
|
||||||
e: [4]int;
|
e: [4]int,
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitmap :: struct {
|
Bitmap :: struct {
|
||||||
pixels: []u8;
|
pixels: []u8,
|
||||||
width: int;
|
width: int,
|
||||||
height: int;
|
height: int,
|
||||||
}
|
}
|
||||||
|
|
||||||
Font :: struct {
|
Font :: struct {
|
||||||
using bitmap: Bitmap;
|
using bitmap: Bitmap,
|
||||||
char_width: int;
|
char_width: int,
|
||||||
char_height: int;
|
char_height: int,
|
||||||
}
|
}
|
||||||
|
|
||||||
Canvas :: struct {
|
Canvas :: struct {
|
||||||
using bitmap: ^Bitmap;
|
using bitmap: ^Bitmap,
|
||||||
palette: Palette;
|
palette: Palette,
|
||||||
translate_x: int;
|
translate_x: int,
|
||||||
translate_y: int;
|
translate_y: int,
|
||||||
clip: Rect;
|
clip: Rect,
|
||||||
font: ^Font;
|
font: ^Font,
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawFlag :: enum {
|
DrawFlag :: enum {
|
||||||
@@ -110,7 +110,7 @@ DrawFlag :: enum {
|
|||||||
|
|
||||||
Draw_Item :: struct {}
|
Draw_Item :: struct {}
|
||||||
Draw_List :: struct {
|
Draw_List :: struct {
|
||||||
items: []Draw_Item;
|
items: []Draw_Item,
|
||||||
}
|
}
|
||||||
|
|
||||||
Key :: enum {
|
Key :: enum {
|
||||||
|
|||||||
@@ -4823,6 +4823,9 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
|||||||
if (entity != nullptr && (entity->flags&EntityFlag_TypeField)) {
|
if (entity != nullptr && (entity->flags&EntityFlag_TypeField)) {
|
||||||
add_type_info_type(c, operand->type);
|
add_type_info_type(c, operand->type);
|
||||||
}
|
}
|
||||||
|
if (is_type_enum(operand->type)) {
|
||||||
|
add_type_info_type(c, operand->type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (entity == nullptr && selector->kind == AstNode_BasicLit) {
|
if (entity == nullptr && selector->kind == AstNode_BasicLit) {
|
||||||
if (is_type_struct(operand->type) || is_type_tuple(operand->type)) {
|
if (is_type_struct(operand->type) || is_type_tuple(operand->type)) {
|
||||||
|
|||||||
@@ -393,7 +393,6 @@ struct TypeAndToken {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void check_when_stmt(Checker *c, AstNodeWhenStmt *ws, u32 flags) {
|
void check_when_stmt(Checker *c, AstNodeWhenStmt *ws, u32 flags) {
|
||||||
flags &= ~Stmt_CheckScopeDecls;
|
|
||||||
Operand operand = {Addressing_Invalid};
|
Operand operand = {Addressing_Invalid};
|
||||||
check_expr(c, &operand, ws->cond);
|
check_expr(c, &operand, ws->cond);
|
||||||
if (operand.mode != Addressing_Constant || !is_type_boolean(operand.type)) {
|
if (operand.mode != Addressing_Constant || !is_type_boolean(operand.type)) {
|
||||||
|
|||||||
+31
-12
@@ -853,10 +853,19 @@ String ir_get_global_name(irModule *m, irValue *v) {
|
|||||||
String *found = map_get(&m->entity_names, hash_entity(e));
|
String *found = map_get(&m->entity_names, hash_entity(e));
|
||||||
if (found != nullptr) {
|
if (found != nullptr) {
|
||||||
name = *found;
|
name = *found;
|
||||||
|
} else {
|
||||||
|
GB_ASSERT(name.len > 0);
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ir_add_entity_name(irModule *m, Entity *e, String name) {
|
||||||
|
GB_ASSERT(name.len > 0);
|
||||||
|
map_set(&m->entity_names, hash_entity(e), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
irValue *ir_instr_local(irProcedure *p, Entity *e, bool zero_initialized) {
|
irValue *ir_instr_local(irProcedure *p, Entity *e, bool zero_initialized) {
|
||||||
@@ -1153,14 +1162,21 @@ irValue *ir_generate_array(irModule *m, Type *elem_type, i64 count, String prefi
|
|||||||
gbAllocator a = m->allocator;
|
gbAllocator a = m->allocator;
|
||||||
Token token = {Token_Ident};
|
Token token = {Token_Ident};
|
||||||
isize name_len = prefix.len + 10;
|
isize name_len = prefix.len + 10;
|
||||||
token.string.text = gb_alloc_array(a, u8, name_len);
|
|
||||||
token.string.len = gb_snprintf(cast(char *)token.string.text, name_len,
|
char *text = gb_alloc_array(a, char, name_len);
|
||||||
"%.*s-%llx", LIT(prefix), cast(unsigned long long)id)-1;
|
gb_snprintf(text, name_len,
|
||||||
Entity *e = make_entity_variable(a, nullptr, token, make_type_array(a, elem_type, count), false);
|
"%.*s-%llx", LIT(prefix), cast(unsigned long long)id);
|
||||||
|
|
||||||
|
String s = make_string_c(text);
|
||||||
|
|
||||||
|
Entity *e = make_entity_variable(a, nullptr,
|
||||||
|
make_token_ident(s),
|
||||||
|
make_type_array(a, elem_type, count),
|
||||||
|
false);
|
||||||
irValue *value = ir_value_global(a, e, nullptr);
|
irValue *value = ir_value_global(a, e, nullptr);
|
||||||
value->Global.is_private = true;
|
value->Global.is_private = true;
|
||||||
ir_module_add_value(m, e, value);
|
ir_module_add_value(m, e, value);
|
||||||
map_set(&m->members, hash_string(token.string), value);
|
map_set(&m->members, hash_string(s), value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3436,6 +3452,7 @@ irValue *ir_type_info(irProcedure *proc, Type *type) {
|
|||||||
type = default_type(type);
|
type = default_type(type);
|
||||||
|
|
||||||
i32 entry_index = cast(i32)type_info_index(info, type);
|
i32 entry_index = cast(i32)type_info_index(info, type);
|
||||||
|
GB_ASSERT(entry_index >= 0);
|
||||||
|
|
||||||
// gb_printf_err("%d %s\n", entry_index, type_to_string(type));
|
// gb_printf_err("%d %s\n", entry_index, type_to_string(type));
|
||||||
|
|
||||||
@@ -3639,7 +3656,8 @@ void ir_mangle_add_sub_type_name(irModule *m, Entity *field, String parent) {
|
|||||||
"%.*s.%.*s", LIT(parent), LIT(cn));
|
"%.*s.%.*s", LIT(parent), LIT(cn));
|
||||||
|
|
||||||
String child = {text, new_name_len-1};
|
String child = {text, new_name_len-1};
|
||||||
map_set(&m->entity_names, hash_entity(field), child);
|
GB_ASSERT(child.len > 0);
|
||||||
|
ir_add_entity_name(m, field, child);
|
||||||
ir_gen_global_type_name(m, field, child);
|
ir_gen_global_type_name(m, field, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5148,15 +5166,16 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
|||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
if (name == "names") {
|
if (name == "names") {
|
||||||
irValue *ti_ptr = ir_type_info(proc, type);
|
irValue *ti_ptr = ir_type_info(proc, type);
|
||||||
|
irValue *variant = ir_emit_struct_ep(proc, ti_ptr, 2);
|
||||||
|
|
||||||
irValue *names_ptr = nullptr;
|
irValue *names_ptr = nullptr;
|
||||||
|
|
||||||
if (is_type_enum(type)) {
|
if (is_type_enum(type)) {
|
||||||
irValue *enum_info = ir_emit_conv(proc, ti_ptr, t_type_info_enum_ptr);
|
irValue *enum_info = ir_emit_conv(proc, variant, t_type_info_enum_ptr);
|
||||||
names_ptr = ir_emit_struct_ep(proc, enum_info, 3);
|
names_ptr = ir_emit_struct_ep(proc, enum_info, 1);
|
||||||
} else if (type->kind == Type_Struct) {
|
} else if (type->kind == Type_Struct) {
|
||||||
irValue *struct_info = ir_emit_conv(proc, ti_ptr, t_type_info_struct_ptr);
|
irValue *struct_info = ir_emit_conv(proc, variant, t_type_info_struct_ptr);
|
||||||
names_ptr = ir_emit_struct_ep(proc, struct_info, 3);
|
names_ptr = ir_emit_struct_ep(proc, struct_info, 1);
|
||||||
}
|
}
|
||||||
return ir_addr(names_ptr);
|
return ir_addr(names_ptr);
|
||||||
} else {
|
} else {
|
||||||
@@ -7641,7 +7660,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
if (!e->scope->is_global) {
|
if (!e->scope->is_global) {
|
||||||
name = ir_mangle_name(s, e->token.pos.file, e);
|
name = ir_mangle_name(s, e->token.pos.file, e);
|
||||||
}
|
}
|
||||||
map_set(&m->entity_names, hash_entity(e), name);
|
ir_add_entity_name(m, e, name);
|
||||||
|
|
||||||
irValue *g = ir_value_global(a, e, nullptr);
|
irValue *g = ir_value_global(a, e, nullptr);
|
||||||
g->Global.name = name;
|
g->Global.name = name;
|
||||||
@@ -7716,7 +7735,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
} else if (check_is_entity_overloaded(e)) {
|
} else if (check_is_entity_overloaded(e)) {
|
||||||
name = ir_mangle_name(s, e->token.pos.file, e);
|
name = ir_mangle_name(s, e->token.pos.file, e);
|
||||||
}
|
}
|
||||||
map_set(&m->entity_names, hash_entity(e), name);
|
ir_add_entity_name(m, e, name);
|
||||||
|
|
||||||
switch (e->kind) {
|
switch (e->kind) {
|
||||||
case Entity_TypeName:
|
case Entity_TypeName:
|
||||||
|
|||||||
Reference in New Issue
Block a user