demo005.odin 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. import "core:fmt.odin";
  2. import "core:utf8.odin";
  3. // import "core:atomic.odin";
  4. // import "core:hash.odin";
  5. // import "core:math.odin";
  6. // import "core:mem.odin";
  7. // import "core:opengl.odin";
  8. // import "core:os.odin";
  9. // import "core:sync.odin";
  10. // import win32 "core: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+len+cap`
  36. slice: []int; #assert(size_of(slice) == 3*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. /*
  48. x += 1;
  49. x -= 1;
  50. // ++ and -- have been removed
  51. // x++;
  52. // x--;
  53. // Question: Should they be added again?
  54. // They were removed as they are redundant and statements, not expressions
  55. // like in C/C++
  56. */
  57. // You can now build files as a `.dll`
  58. // `odin build_dll demo.odin`
  59. // New vector syntax
  60. u, v: [vector 3]f32;
  61. v[0] = 123;
  62. v.x = 123; // valid for all vectors with count 1 to 4
  63. // Next part
  64. prefixes();
  65. }
  66. Prefix_Type :: struct {x: int, y: f32, z: rawptr};
  67. #thread_local my_tls: Prefix_Type;
  68. prefixes :: proc() {
  69. using var: Prefix_Type;
  70. var.x = 123;
  71. x = 123;
  72. foo :: proc(using pt: Prefix_Type) {
  73. }
  74. // Same as C99's `restrict`
  75. bar :: proc(#no_alias a, b: ^int) {
  76. // Assumes a never equals b so it can perform optimizations with that fact
  77. }
  78. when_statements();
  79. }
  80. when_statements :: proc() {
  81. X :: 123 + 12;
  82. Y :: X/5;
  83. COND :: Y > 0;
  84. when COND {
  85. fmt.println("Y > 0");
  86. } else {
  87. fmt.println("Y <= 0");
  88. }
  89. when false {
  90. this_code_does_not_exist(123, 321);
  91. but_its_syntax_is_valid();
  92. x :: ^^^^int;
  93. }
  94. foreign_procedures();
  95. }
  96. when ODIN_OS == "windows" {
  97. foreign_system_library win32_user "user32.lib";
  98. }
  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. foreign win32_user {
  104. ShowWindow :: proc(hwnd: rawptr, cmd_show: i32) -> i32 ---;
  105. show_window :: proc(hwnd: rawptr, cmd_show: i32) -> i32 #link_name "ShowWindow" ---;
  106. }
  107. // NOTE: If that library doesn't get used, it doesn't get linked with
  108. // NOTE: There is not link checking yet to see if that procedure does come from that library
  109. // See sys/windows.odin for more examples
  110. special_expressions();
  111. }
  112. special_expressions :: proc() {
  113. /*
  114. // Block expression
  115. x := {
  116. a: f32 = 123;
  117. b := a-123;
  118. c := b/a;
  119. give c;
  120. }; // semicolon is required as it's an expression
  121. y := if x < 50 {
  122. give x;
  123. } else {
  124. // TODO: Type cohesion is not yet finished
  125. give 123;
  126. }; // semicolon is required as it's an expression
  127. */
  128. // This is allows for inline blocks of code and will be a useful feature to have when
  129. // macros will be implemented into the language
  130. loops();
  131. }
  132. loops :: proc() {
  133. // The C-style for loop
  134. for i := 0; i < 123; i += 1 {
  135. break;
  136. }
  137. for i := 0; i < 123; {
  138. break;
  139. }
  140. for false {
  141. break;
  142. }
  143. for {
  144. break;
  145. }
  146. for i in 0..123 { // 123 exclusive
  147. }
  148. for i in 0..123-1 { // 122 inclusive
  149. }
  150. for val, idx in 12..16 {
  151. fmt.println(val, idx);
  152. }
  153. primes := [?]int{2, 3, 5, 7, 11, 13, 17, 19};
  154. for p in primes {
  155. fmt.println(p);
  156. }
  157. // Pointers to arrays, slices, or strings are allowed
  158. for _ in &primes {
  159. // ignore the value and just iterate across it
  160. }
  161. name := "你好,世界";
  162. fmt.println(name);
  163. for r in name {
  164. #assert(type_of(r) == rune);
  165. fmt.printf("%r\n", r);
  166. }
  167. when false {
  168. for i, size := 0; i < name.count; i += size {
  169. r: rune;
  170. r, size = utf8.decode_rune(name[i..]);
  171. fmt.printf("%r\n", r);
  172. }
  173. }
  174. procedure_overloading();
  175. }
  176. procedure_overloading :: proc() {
  177. THINGF :: 14451.1;
  178. THINGI :: 14451;
  179. foo :: proc() {
  180. fmt.printf("Zero args\n");
  181. }
  182. foo :: proc(i: int) {
  183. fmt.printf("int arg, i=%d\n", i);
  184. }
  185. foo :: proc(f: f64) {
  186. i := cast(int)f;
  187. fmt.printf("f64 arg, f=%d\n", i);
  188. }
  189. foo();
  190. foo(THINGF);
  191. // foo(THINGI); // 14451 is just a number so it could go to either procedures
  192. foo(cast(int)THINGI);
  193. foo :: proc(x: ^i32) -> (int, int) {
  194. fmt.println("^int");
  195. return 123, cast(int)(x^);
  196. }
  197. foo :: proc(x: rawptr) {
  198. fmt.println("rawptr");
  199. }
  200. a: i32 = 123;
  201. b: f32;
  202. c: rawptr;
  203. fmt.println(foo(&a));
  204. foo(&b);
  205. foo(c);
  206. // foo(nil); // nil could go to numerous types thus the ambiguity
  207. f: proc();
  208. f = foo; // The correct `foo` to chosen
  209. f();
  210. // See math.odin and atomic.odin for more examples
  211. }