main :: () {
print("Type info for int:\n");
print(" Size: %\n", size_of(int));
print(" Alignment: %\n", align_of(int));
print("\nType info for Player:\n");
print(" Size: %\n", size_of(Player));
print(" Alignment: %\n", align_of(Player));
player := Player.{"Test", 100, 50, .{0, 0}};
print_struct_info(player);
print("\nType checks:\n");
print(" int is type: %\n", type_is_integer(int));
print(" float is type: %\n", type_is_float(float32));
print(" Player is struct: %\n", type_is_struct(Player));
numbers: [..]int;
defer array_reset(*numbers);
for 1..5 array_add(*numbers, it);
print("\nGeneric max: %\n", generic_max(numbers));
floats: [..]float64;
defer array_reset(*floats);
for 1..5 array_add(*floats, it * 1.5);
print("Generic max float: %\n", generic_max(floats));
print("\nCompile-time factorial of 5: %\n", FACTORIAL_5);
print("Compile-time fibonacci of 10: %\n", FIBONACCI_10);
arr: [ARRAY_SIZE]int;
print("Array of size %: %\n", ARRAY_SIZE, arr);
int_container := Container(int).{value = 42};
print_container(int_container);
str_container := Container(string).{value = "Hello"};
print_container(str_container);
baked_add := bake add_with_offset(10);
print("Baked add(5): %\n", baked_add(5));
print("\nFor expansion:\n");
print_names(*player);
print("\nAuto struct print:\n");
auto_print(player);
any_value: Any = player;
handle_any(any_value);
print("\nJSON-like output:\n");
serialize_like_json(player);
}
Player :: struct {
name: string;
health: int;
mana: int;
position: Vector2;
}
Vector2 :: struct {
x: float;
y: float;
}
print_struct_info :: (s: $T) {
ti := type_info(T);
if ti.type != .STRUCT {
print("Not a struct\n");
return;
}
info := cast(*Type_Info_Struct) ti;
print("Struct '%' has % members:\n", info.name, info.members.count);
for info.members {
print(" %: % (offset %)\n", it.name, it.type, it.offset_in_bytes);
}
}
generic_max :: (arr: []$T) -> T {
if arr.count == 0 return T.{};
max_val := arr[0];
for arr {
if it > max_val max_val = it;
}
return max_val;
}
Container :: struct ($T: Type) {
value: T;
}
print_container :: (c: Container($T)) {
print("Container<%>: %\n", T, c.value);
}
factorial :: ($n: int) -> int #expand {
#if n == 0 {
return 1;
} else {
return n * factorial(n - 1);
}
}
fibonacci :: ($n: int) -> int #expand {
#if n <= 1 {
return n;
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
FACTORIAL_5 :: #run factorial(5);
FIBONACCI_10 :: #run fibonacci(10);
ARRAY_SIZE :: #run 10 + 5;
add_with_offset :: (offset: int, x: int) -> int {
return x + offset;
}
bake :: (proc: (int, int) -> int, offset: int) -> (int) -> int {
return (x: int) -> int {
return proc(offset, x);
};
}
print_names :: (s: *$T) #expand {
#insert #run -> string {
ti := type_info(T);
if ti.type != .STRUCT return "";
info := cast(*Type_Info_Struct) ti;
builder: String_Builder;
for info.members {
print_to_builder(*builder, "print(\"%: %\\n\", s.%);\n",
it.name, it.name);
}
return builder_to_string(*builder);
};
}
auto_print :: (s: $T) {
ti := type_info(T);
if ti.type != .STRUCT {
print("%\n", s);
return;
}
info := cast(*Type_Info_Struct) ti;
print("% {\n", info.name);
for info.members {
print(" % = ", it.name);
print("<?>\n");
}
print("}\n");
}
handle_any :: (value: Any) {
print("Any type: %\n", value.type);
if value.type == type_info(int) {
ptr := cast(*int) value.value_pointer;
print(" As int: %\n", ptr.*);
} else if value.type == type_info(string) {
ptr := cast(*string) value.value_pointer;
print(" As string: %\n", ptr.*);
}
}
serialize_like_json :: (s: $T) {
ti := type_info(T);
if ti.type != .STRUCT {
print("\"%\"", s);
return;
}
info := cast(*Type_Info_Struct) ti;
print("{\n");
for info.members {
print(" \"%\": ", it.name);
print("<?>");
if it_index < info.members.count - 1 print(",");
print("\n");
}
print("}\n");
}
type_is_integer :: ($T: Type) -> bool #expand {
ti := type_info(T);
return ti.type == .INTEGER;
}
type_is_float :: ($T: Type) -> bool #expand {
ti := type_info(T);
return ti.type == .FLOAT;
}
type_is_struct :: ($T: Type) -> bool #expand {
ti := type_info(T);
return ti.type == .STRUCT;
}
#import "Basic";