-
-
Notifications
You must be signed in to change notification settings - Fork 577
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3e79ec4
commit ec9c8fb
Showing
4 changed files
with
578 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,282 @@ | ||
#import "fmt.odin"; | ||
#import "utf8.odin"; | ||
// #import "atomic.odin"; | ||
// #import "hash.odin"; | ||
// #import "math.odin"; | ||
// #import "mem.odin"; | ||
// #import "opengl.odin"; | ||
// #import "os.odin"; | ||
// #import "sync.odin"; | ||
// #import win32 "sys/windows.odin"; | ||
|
||
main :: proc() { | ||
fmt.println(foo("FOO")); | ||
// syntax(); | ||
procedure_overloading(); | ||
} | ||
|
||
foo :: proc(test: string, test1: string, args: ...any) { } | ||
syntax :: proc() { | ||
// Cyclic type checking | ||
// Uncomment to see the error | ||
// A :: struct {b: B}; | ||
// B :: struct {a: A}; | ||
|
||
foo :: proc(test: string) { } | ||
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+count` | ||
slice: []int; compile_assert(size_of_val(slice) == 2*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; | ||
immutable const := Prefix_Type{1, 2, nil}; | ||
var.x = 123; | ||
x = 123; | ||
// const.x = 123; // const is immutable | ||
|
||
|
||
|
||
foo :: proc(using immutable pt: Prefix_Type, immutable int_ptr: ^int) { | ||
// int_ptr = nil; // Not valid | ||
int_ptr^ = 123; // Is valid | ||
} | ||
|
||
|
||
|
||
// 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(); | ||
} | ||
|
||
#foreign_system_library win32_user "user32.lib" when ODIN_OS == "windows"; | ||
// 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() { | ||
ShowWindow :: proc(hwnd: rawptr, cmd_show: i32) -> i32 #foreign win32_user; | ||
show_window :: proc(hwnd: rawptr, cmd_show: i32) -> i32 #foreign win32_user "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...122 { // 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 { | ||
compile_assert(type_of_val(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 | ||
} |
Oops, something went wrong.