demo001.odin 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. import "core:fmt.odin";
  2. import "core:os.odin";
  3. import "core:mem.odin";
  4. // import "http_test.odin" as ht;
  5. // import "game.odin" as game;
  6. // import "punity.odin" as pn;
  7. main :: proc() {
  8. struct_padding();
  9. bounds_checking();
  10. type_introspection();
  11. any_type();
  12. crazy_introspection();
  13. namespaces_and_files();
  14. miscellany();
  15. /*
  16. ht.run();
  17. game.run();
  18. {
  19. init :: proc(c: ^pn.Core) {}
  20. step :: proc(c: ^pn.Core) {}
  21. pn.run(init, step);
  22. }
  23. */
  24. }
  25. struct_padding :: proc() {
  26. {
  27. A :: struct {
  28. a: u8,
  29. b: u32,
  30. c: u16,
  31. }
  32. B :: struct {
  33. a: [7]u8,
  34. b: [3]u16,
  35. c: u8,
  36. d: u16,
  37. }
  38. fmt.println("size_of(A):", size_of(A));
  39. fmt.println("size_of(B):", size_of(B));
  40. // n.b. http://cbloomrants.blogspot.co.uk/2012/07/07-23-12-structs-are-not-what-you-want.html
  41. }
  42. {
  43. A :: struct #ordered {
  44. a: u8,
  45. b: u32,
  46. c: u16,
  47. }
  48. B :: struct #ordered {
  49. a: [7]u8,
  50. b: [3]u16,
  51. c: u8,
  52. d: u16,
  53. }
  54. fmt.println("size_of(A):", size_of(A));
  55. fmt.println("size_of(B):", size_of(B));
  56. // C-style structure layout
  57. }
  58. {
  59. A :: struct #packed {
  60. a: u8,
  61. b: u32,
  62. c: u16,
  63. }
  64. B :: struct #packed {
  65. a: [7]u8,
  66. b: [3]u16,
  67. c: u8,
  68. d: u16,
  69. }
  70. fmt.println("size_of(A):", size_of(A));
  71. fmt.println("size_of(B):", size_of(B));
  72. // Useful for explicit layout
  73. }
  74. // Member sorting by priority
  75. // Alignment desc.
  76. // Size desc.
  77. // source order asc.
  78. /*
  79. A :: struct {
  80. a: u8
  81. b: u32
  82. c: u16
  83. }
  84. B :: struct {
  85. a: [7]u8
  86. b: [3]u16
  87. c: u8
  88. d: u16
  89. }
  90. Equivalent too
  91. A :: struct #ordered {
  92. b: u32
  93. c: u16
  94. a: u8
  95. }
  96. B :: struct #ordered {
  97. b: [3]u16
  98. d: u16
  99. a: [7]u8
  100. c: u8
  101. }
  102. */
  103. }
  104. bounds_checking :: proc() {
  105. x: [4]int;
  106. // x[-1] = 0; // Compile Time
  107. // x[4] = 0; // Compile Time
  108. {
  109. a, b := -1, 4;
  110. // x[a] = 0; // Runtime Time
  111. // x[b] = 0; // Runtime Time
  112. }
  113. // Works for arrays, strings, slices, and related procedures & operations
  114. {
  115. base: [10]int;
  116. s := base[2..6];
  117. a, b := -1, 6;
  118. #no_bounds_check {
  119. s[a] = 0;
  120. // #bounds_check s[b] = 0;
  121. }
  122. #no_bounds_check
  123. if s[a] == 0 {
  124. // Do whatever
  125. }
  126. // Bounds checking can be toggled explicit
  127. // on a per statement basis.
  128. // _any statement_
  129. }
  130. }
  131. type_introspection :: proc() {
  132. {
  133. info: ^Type_Info;
  134. x: int;
  135. info = type_info_of(int); // by type
  136. info = type_info_of(x); // by value
  137. // See: runtime.odin
  138. match i in info.variant {
  139. case Type_Info_Integer:
  140. fmt.println("integer!");
  141. case Type_Info_Float:
  142. fmt.println("float!");
  143. case:
  144. fmt.println("potato!");
  145. }
  146. // Unsafe cast
  147. integer_info := cast(^Type_Info_Integer)cast(rawptr)info;
  148. }
  149. {
  150. Vector2 :: struct { x, y: f32 }
  151. Vector3 :: struct { x, y, z: f32 }
  152. v1: Vector2;
  153. v2: Vector3;
  154. v3: Vector3;
  155. t1 := type_info_of(v1);
  156. t2 := type_info_of(v2);
  157. t3 := type_info_of(v3);
  158. fmt.println();
  159. fmt.print("Type of v1 is:\n\t", t1);
  160. fmt.println();
  161. fmt.print("Type of v2 is:\n\t", t2);
  162. fmt.println("\n");
  163. fmt.println("t1 == t2:", t1 == t2);
  164. fmt.println("t2 == t3:", t2 == t3);
  165. }
  166. }
  167. any_type :: proc() {
  168. a: any;
  169. x: int = 123;
  170. y: f64 = 6.28;
  171. z: string = "Yo-Yo Ma";
  172. // All types can be implicit cast to `any`
  173. a = x;
  174. a = y;
  175. a = z;
  176. a = a; // This the "identity" type, it doesn't get converted
  177. a = 123; // Literals are copied onto the stack first
  178. // any has two members
  179. // data - rawptr to the data
  180. // type_info - pointer to the type info
  181. fmt.println(x, y, z);
  182. // See: fmt.odin
  183. // For variadic any procedures in action
  184. }
  185. crazy_introspection :: proc() {
  186. {
  187. Fruit :: enum {
  188. APPLE,
  189. BANANA,
  190. GRAPE,
  191. MELON,
  192. PEACH,
  193. TOMATO,
  194. }
  195. s: string;
  196. // s = enum_to_string(Fruit.PEACH);
  197. fmt.println(s);
  198. f := Fruit.GRAPE;
  199. // s = enum_to_string(f);
  200. fmt.println(s);
  201. fmt.println(f);
  202. // See: runtime.odin
  203. }
  204. {
  205. // NOTE(bill): This is not safe code and I would not recommend this at all
  206. // I'd recommend you use `match type` to get the subtype rather than
  207. // casting pointers
  208. Fruit :: enum {
  209. APPLE,
  210. BANANA,
  211. GRAPE,
  212. MELON,
  213. PEACH,
  214. TOMATO,
  215. }
  216. fruit_ti := type_info_of(Fruit);
  217. name := fruit_ti.variant.(Type_Info_Named).name;
  218. info, _ := type_info_base(fruit_ti).variant.(Type_Info_Enum);
  219. fmt.printf("%s :: enum %T {\n", name, info.base);
  220. for _, i in info.values {
  221. fmt.printf("\t%s\t= %v,\n", info.names[i], info.values[i]);
  222. }
  223. fmt.printf("}\n");
  224. // NOTE(bill): look at that type-safe printf!
  225. }
  226. {
  227. Vector3 :: struct {x, y, z: f32}
  228. a := Vector3{x = 1, y = 4, z = 9};
  229. fmt.println(a);
  230. b := Vector3{x = 9, y = 3, z = 1};
  231. fmt.println(b);
  232. // NOTE(bill): See fmt.odin
  233. }
  234. // n.b. This pretty much "solves" serialization (to strings)
  235. }
  236. // #import "test.odin"
  237. namespaces_and_files :: proc() {
  238. // test.thing()
  239. // test.format.println()
  240. // test.println()
  241. /*
  242. // Non-exporting import
  243. #import "file.odin"
  244. #import "file.odin" as file
  245. #import "file.odin" as .
  246. #import "file.odin" as _
  247. // Exporting import
  248. #include "file.odin"
  249. */
  250. // Talk about scope rules and diagram
  251. }
  252. miscellany :: proc() {
  253. /*
  254. win32 `__imp__` prefix
  255. #dll_import
  256. #dll_export
  257. Change exported name/symbol for linking
  258. #link_name
  259. Custom calling conventions
  260. #stdcall
  261. #fastcall
  262. Runtime stuff
  263. #shared_global_scope
  264. */
  265. // assert(false)
  266. // #assert(false)
  267. // panic("Panic message goes here")
  268. }