demo001.odin 5.2 KB

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