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