demo005.odin 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. #import "fmt.odin";
  2. #import "utf8.odin";
  3. // #import "atomic.odin";
  4. // #import "hash.odin";
  5. // #import "math.odin";
  6. // #import "mem.odin";
  7. // #import "opengl.odin";
  8. // #import "os.odin";
  9. // #import "sync.odin";
  10. // #import win32 "sys/windows.odin";
  11. main :: proc() {
  12. // syntax();
  13. procedure_overloading();
  14. }
  15. syntax :: proc() {
  16. // Cyclic type checking
  17. // Uncomment to see the error
  18. // A :: struct {b: B};
  19. // B :: struct {a: A};
  20. x: int;
  21. y := cast(f32)x;
  22. z := transmute(u32)y;
  23. // down_cast, union_cast are similar too
  24. // Basic directives
  25. fmt.printf("Basic directives = %s(%d): %s\n", #file, #line, #procedure);
  26. // NOTE: new and improved `printf`
  27. // TODO: It does need accurate float printing
  28. // record fields use the same syntax a procedure signatures
  29. Thing1 :: struct {
  30. x: f32,
  31. y: int,
  32. z: ^[]int,
  33. };
  34. Thing2 :: struct {x: f32, y: int, z: ^[]int};
  35. // Slice interals are now just a `ptr+count`
  36. slice: []int; compile_assert(size_of_val(slice) == 2*size_of(int));
  37. // Helper type - Help the reader understand what it is quicker
  38. My_Int :: type int;
  39. My_Proc :: type proc(int) -> f32;
  40. // All declarations with : are either variable or constant
  41. // To make these declarations syntactically consistent
  42. v_variable := 123;
  43. c_constant :: 123;
  44. c_type1 :: int;
  45. c_type2 :: []int;
  46. c_proc :: proc() { /* code here */ };
  47. x += 1;
  48. x -= 1;
  49. // ++ and -- have been removed
  50. // x++;
  51. // x--;
  52. // Question: Should they be added again?
  53. // They were removed as they are redundant and statements, not expressions
  54. // like in C/C++
  55. // You can now build files as a `.dll`
  56. // `odin build_dll demo.odin`
  57. // New vector syntax
  58. u, v: [vector 3]f32;
  59. v[0] = 123;
  60. v.x = 123; // valid for all vectors with count 1 to 4
  61. // Next part
  62. prefixes();
  63. }
  64. Prefix_Type :: struct {x: int, y: f32, z: rawptr};
  65. thread_local my_tls: Prefix_Type;
  66. prefixes :: proc() {
  67. using var: Prefix_Type;
  68. immutable const := Prefix_Type{1, 2, nil};
  69. var.x = 123;
  70. x = 123;
  71. // const.x = 123; // const is immutable
  72. foo :: proc(using immutable pt: Prefix_Type, immutable int_ptr: ^int) {
  73. // int_ptr = nil; // Not valid
  74. int_ptr^ = 123; // Is valid
  75. }
  76. // Same as C99's `restrict`
  77. bar :: proc(no_alias a, b: ^int) {
  78. // Assumes a never equals b so it can perform optimizations with that fact
  79. }
  80. when_statements();
  81. }
  82. when_statements :: proc() {
  83. X :: 123 + 12;
  84. Y :: X/5;
  85. COND :: Y > 0;
  86. when COND {
  87. fmt.println("Y > 0");
  88. } else {
  89. fmt.println("Y <= 0");
  90. }
  91. when false {
  92. this_code_does_not_exist(123, 321);
  93. but_its_syntax_is_valid();
  94. x :: ^^^^int;
  95. }
  96. foreign_procedures();
  97. }
  98. #foreign_system_library win32_user "user32.lib" when ODIN_OS == "windows";
  99. // NOTE: This is done on purpose for two reasons:
  100. // * Makes it clear where the platform specific stuff is
  101. // * Removes the need to solve the travelling salesman problem when importing files :P
  102. foreign_procedures :: proc() {
  103. ShowWindow :: proc(hwnd: rawptr, cmd_show: i32) -> i32 #foreign win32_user;
  104. show_window :: proc(hwnd: rawptr, cmd_show: i32) -> i32 #foreign win32_user "ShowWindow";
  105. // NOTE: If that library doesn't get used, it doesn't get linked with
  106. // NOTE: There is not link checking yet to see if that procedure does come from that library
  107. // See sys/windows.odin for more examples
  108. special_expressions();
  109. }
  110. special_expressions :: proc() {
  111. // Block expression
  112. x := {
  113. a: f32 = 123;
  114. b := a-123;
  115. c := b/a;
  116. give c;
  117. }; // semicolon is required as it's an expression
  118. y := if x < 50 {
  119. give x;
  120. } else {
  121. // TODO: Type cohesion is not yet finished
  122. give 123;
  123. }; // semicolon is required as it's an expression
  124. // This is allows for inline blocks of code and will be a useful feature to have when
  125. // macros will be implemented into the language
  126. loops();
  127. }
  128. loops :: proc() {
  129. // The C-style for loop
  130. for i := 0; i < 123; i += 1 {
  131. break;
  132. }
  133. for i := 0; i < 123; {
  134. break;
  135. }
  136. for false {
  137. break;
  138. }
  139. for {
  140. break;
  141. }
  142. for i in 0..<123 { // 123 exclusive
  143. }
  144. for i in 0...122 { // 122 inclusive
  145. }
  146. for val, idx in 12..<16 {
  147. fmt.println(val, idx);
  148. }
  149. primes := [...]int{2, 3, 5, 7, 11, 13, 17, 19};
  150. for p in primes {
  151. fmt.println(p);
  152. }
  153. // Pointers to arrays, slices, or strings are allowed
  154. for _ in ^primes {
  155. // ignore the value and just iterate across it
  156. }
  157. name := "你好,世界";
  158. fmt.println(name);
  159. for r in name {
  160. compile_assert(type_of_val(r) == rune);
  161. fmt.printf("%r\n", r);
  162. }
  163. when false {
  164. for i, size := 0; i < name.count; i += size {
  165. r: rune;
  166. r, size = utf8.decode_rune(name[i:]);
  167. fmt.printf("%r\n", r);
  168. }
  169. }
  170. procedure_overloading();
  171. }
  172. procedure_overloading :: proc() {
  173. THINGF :: 14451.1;
  174. THINGI :: 14451;
  175. foo :: proc() {
  176. fmt.printf("Zero args\n");
  177. }
  178. foo :: proc(i: int) {
  179. fmt.printf("int arg, i=%d\n", i);
  180. }
  181. foo :: proc(f: f64) {
  182. i := cast(int)f;
  183. fmt.printf("f64 arg, f=%d\n", i);
  184. }
  185. foo();
  186. foo(THINGF);
  187. // foo(THINGI); // 14451 is just a number so it could go to either procedures
  188. foo(cast(int)THINGI);
  189. foo :: proc(x: ^i32) -> (int, int) {
  190. fmt.println("^int");
  191. return 123, cast(int)(x^);
  192. }
  193. foo :: proc(x: rawptr) {
  194. fmt.println("rawptr");
  195. }
  196. a: i32 = 123;
  197. b: f32;
  198. c: rawptr;
  199. fmt.println(foo(^a));
  200. foo(^b);
  201. foo(c);
  202. // foo(nil); // nil could go to numerous types thus the ambiguity
  203. f: proc();
  204. f = foo; // The correct `foo` to chosen
  205. f();
  206. // See math.odin and atomic.odin for more examples
  207. }