demo.odin 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. //
  2. // Odin v0.3 Demo
  3. //
  4. #import "fmt.odin";
  5. main :: proc() {
  6. /*
  7. Minor features
  8. --------------
  9. * Lexical sugar
  10. - ≠, ≤, ≥
  11. * Label syntax change
  12. name: for {
  13. break name;
  14. }
  15. * `#no_alias` (replacing keyword `no_alias`)
  16. * `#ordered` reimplemented
  17. * "bits.odin"
  18. * `default:` is replaced with `case:`
  19. * XOR for booleans
  20. * Bug fixes
  21. * Removed Quaternion types quaternion128 & quaternion256
  22. * `rune` is a core type - allowing for extra type information at runtime
  23. * `byte` is removed - use `u8` instead (which it was an alias for)
  24. */
  25. // 128 bit integers
  26. {
  27. x: u128 = 1234567890123;
  28. y: u128 = 9876543210123;
  29. z := (x * y) + x + y;
  30. fmt.println(z);
  31. a: i128 = +1234567890123;
  32. b: i128 = -9876543210123;
  33. c := (a * b) + a + b;
  34. fmt.println(c);
  35. }
  36. // Divisor based modulo operator
  37. {
  38. x: i128 = -15;
  39. y: i128 = 2;
  40. fmt.println(x % y); // Dividend based
  41. fmt.println(x %% y); // Divisor based
  42. // a %% b == ((a % b) + b) % b;
  43. }
  44. // Casting syntax
  45. {
  46. // Casting operations have had their syntax change for simplicity and consistency
  47. // Original:
  48. // Regular cast: `cast(type) expr`
  49. // Bit cast: `transmute(type) expr`
  50. // Union cast: `union_cast(type) expr`
  51. // Regular Cast
  52. f: f32 = 123.321;
  53. i := i32(f); // type(expr)
  54. // Bit cast
  55. fbits := transmute(u32, f);
  56. // Type assertion - replaces `union_cast`
  57. Entity :: union {
  58. id: u64,
  59. position: [vector 2]f32,
  60. name: string,
  61. Tree{leaf_count: int},
  62. Frog{ribbit_volume: f32},
  63. }
  64. e: Entity;
  65. e = Entity.Frog{ribbit_volume = 0.5, name = "Trevor"};
  66. if frog, ok := e.(Entity.Frog); ok {
  67. fmt.printf("%s the frog ribbits at %f\n", frog.name, frog.ribbit_volume);
  68. }
  69. // Panics if the type assertion fails
  70. frog := e.(Entity.Frog);
  71. {
  72. // Type assertion can also be applied to `any`
  73. foo: any = 123;
  74. if i, ok := foo.(int); ok {
  75. fmt.println("Foo =", i);
  76. }
  77. }
  78. }
  79. // Syntax changes
  80. {
  81. // Originally `^` was used to represent pointer types, pointer dereferencing, and addressing of variables
  82. // The addressing of variable operation is not represented with `&`
  83. // This is to make sure the concept of a pointer type is separate from that of a addressing
  84. // it is also used for familiarity coming from other C-like languages
  85. x: int = 123;
  86. y: ^int = &x;
  87. z: int = y^;
  88. // This change also allows type casting to not require parentheses around the type for pointer evaluation
  89. // and consitency with other operations
  90. data := rawptr(&x);
  91. int_ptr := ^int(data);
  92. array: [10]int; // Type of the left
  93. x = array[0]; // Usage on the right
  94. ptr: ^int = &z; // Type of the left
  95. x = ptr^; // Usage on the right
  96. // Minor addition - member access through number
  97. TupleLike :: struct{int, f32, string}; // Fields all anonymous
  98. t: TupleLike;
  99. t.0 = 123;
  100. t.1 = 46.432;
  101. t.2 = "Foo";
  102. fmt.println(t);
  103. }
  104. // Bit fields
  105. {
  106. BoxProps :: bit_field {
  107. opaque: 1,
  108. fill_colour: 3,
  109. _: 4,
  110. show_border: 1,
  111. _: 3,
  112. border_style: 2,
  113. _: 2,
  114. width: 4,
  115. height: 4,
  116. };
  117. props: BoxProps;
  118. props.fill_colour = 4;
  119. props.show_border = 1;
  120. props.width = 12;
  121. props.height = 10;
  122. fmt.printf("Width: %d, Height: %d\n", props.width, props.height);
  123. Float32Data :: bit_field #align 4 {
  124. fraction: 23,
  125. exponent: 8,
  126. sign: 1,
  127. }
  128. f: f32 = -123.321;
  129. data := transmute(Float32Data, f);
  130. bits := transmute(u32, f);
  131. fmt.printf("%#05x %#02x %v\n", data.fraction, data.exponent, bool(data.sign));
  132. fmt.printf("%#08x\n", bits);
  133. }
  134. // Naming convention
  135. {
  136. // Odin has finally chose an official naming convention
  137. // In general, PascalCase for types and snake_case for values
  138. // Import Name: snake_case (but prefer single word)
  139. // Types: PascalCase
  140. // Union Variants: PascalCase
  141. // Enum Values: PascalCase
  142. // Procedures: snake_case
  143. // Local Variables: snake_case
  144. // Field Values: snake_case
  145. // Constant Variables: SCREAMING_SNAKE_CASE
  146. }
  147. // Goals for v0.4 and further
  148. // * Compile as C++ and use some of its constructs for sanity e.g. overloading
  149. // - Safe array with bounds checking
  150. // - Map type for self documentation
  151. // - u128 i128 acting like core types
  152. // * Context system implemented as Implicit Parameter Passing (IPP) rather than Thread Local Storage (TLS)
  153. // * Parameter Polymorphism
  154. // - Type parameter is procedures and types
  155. // * Decide upon a declaration syntax
  156. // - Current Style (name: type;) vs Prefix Style (var name: type;)
  157. // * Import system with a "solution" for packages/modules/libraries
  158. // * Better foreign interfacing with C (and maybe C++)
  159. // - Foreign variables
  160. // * Documentation Generation System for code
  161. // * General Documentation for Odin
  162. // * Attributes
  163. }