Files
Odin/code/demo.odin
T
2016-09-22 23:18:29 +01:00

336 lines
5.2 KiB
Odin

#import "fmt.odin"
#import "os.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 type i : info {
case Type_Info.Integer:
fmt.println("integer!")
case Type_Info.Float:
fmt.println("float!")
default:
fmt.println("potato!")
}
// Unsafe cast
integer_info := info as ^Type_Info.Integer
}
{
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 := (fruit_ti as ^Type_Info.Named).name // Unsafe casts
info := type_info_base(fruit_ti) as ^Type_Info.Enum // Unsafe casts
fmt.printf("% :: enum % {\n", name, info.base);
for i := 0; i < info.values.count; i++ {
fmt.printf("\t%\t= %,\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
#load "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")
}