11-globals.ha (4111B)
1 use rt::{compile, exited, EXIT_SUCCESS}; 2 3 // globals without type hint 4 def NOHINT = 1234z; 5 let nohint = 12z; 6 const nohintconst = 123z; 7 // with type defined afterwards 8 const nhval = nh { 9 field = 1, 10 }; 11 type nh = struct { 12 field: int, 13 }; 14 15 let x: int = 42, y: int = 69; 16 17 fn write() void = { 18 assert(x == 42 && y == 69); 19 x = 1337; 20 assert(x == 1337); 21 22 assert(nohint == 12); 23 assert(nohintconst == 123); 24 assert(NOHINT == 1234); 25 assert(nhval.field == 1); 26 }; 27 28 let ar: [3]int = [1, 2, 3]; 29 let sl: []int = [1, 2, 3]; 30 let st: str = "Hello!"; 31 32 type coords = struct { x: int, y: int }; 33 let su: coords = coords { y = 10, x = 20}; 34 let su_autofill: coords = coords { y = 10, x = 20, ... }; 35 let au: coords = coords { ... }; 36 37 type coords3 = struct { coords: coords, z: int }; 38 let a3: coords3 = coords3 { ... }; 39 40 type embedded = struct { a: uint, b: u8 }; 41 42 type with_embedded = struct { embedded, c: int }; 43 let em: with_embedded = with_embedded { a = 3, b = 4, c = 18 }; 44 let em_autofill: with_embedded = with_embedded { ... }; 45 46 type with_embedded2 = struct { c: int, embedded }; 47 let em2: with_embedded2 = with_embedded2 { a = 3, b = 4, c = 18 }; 48 let em2_autofill: with_embedded2 = with_embedded2 { ... }; 49 50 type aenum = enum u64 { 51 BIG_VALUE = 0x1234567887654321, 52 }; 53 const big_value: aenum = aenum::BIG_VALUE; 54 55 type renum = enum rune { 56 R1 = 'a', 57 R2 = 'g', 58 }; 59 let renum_val = renum::R1; 60 61 const float: f32 = 1234.5678; 62 const double: f64 = 1234.5678; 63 64 fn storage() void = { 65 assert(len(ar) == 3); 66 assert(ar[0] == 1 && ar[1] == 2 && ar[2] == 3); 67 assert(len(sl) == 3); 68 assert(sl[0] == 1 && sl[1] == 2 && sl[2] == 3); 69 assert(len(st) == 6); 70 assert(su.x == 20 && su.y == 10); 71 assert(su_autofill.x == 20 && su_autofill.y == 10); 72 assert(au.x == 0 && au.y == 0); 73 assert(a3.coords.x == 0 && a3.coords.y == 0 && a3.z == 0); 74 assert(em.a == 3 && em.b == 4 && em.c == 18); 75 assert(em_autofill.a == 0 && em_autofill.b == 0 && em_autofill.c == 0); 76 assert(em2.a == 3 && em2.b == 4 && em2.c == 18); 77 assert(em2_autofill.a == 0 && em2_autofill.b == 0 && em2_autofill.c == 0); 78 assert(big_value == 0x1234567887654321: aenum); 79 assert(float == 1234.5678); 80 assert(double == 1234.5678); 81 }; 82 83 fn invariants() void = { 84 assert(compile("fn test() int; let x: int = test();") as exited != EXIT_SUCCESS); 85 assert(compile("const a: u8 = 2; const b: u8 = a + 5;") as exited != EXIT_SUCCESS); 86 }; 87 88 fn counter() int = { 89 static let x = 0; 90 x += 1; 91 return x; 92 }; 93 94 fn static_binding() void = { 95 assert(counter() == 1); 96 assert(counter() == 2); 97 assert(counter() == 3); 98 }; 99 100 const val: u32 = 42; 101 const tup: (u8, str) = (2, "asdf"); 102 const ptr: *u32 = &val; 103 const ptr_tup: *(u8, str) = &tup; 104 // TODO const ptr_memb: *str = &tup.1; 105 106 fn pointers() void = { 107 assert(ptr == &val && *ptr == val); 108 }; 109 110 type foo = (int | uint); 111 112 let subtype: foo = 10u; 113 114 let arr_of_tagged_of_tuple: [3]((int, int)|void) = [(1, 2), (3, 4), (5, 6)]; 115 116 fn tagged() void = { 117 assert((arr_of_tagged_of_tuple[0] as (int, int)).0 == 1); 118 assert((arr_of_tagged_of_tuple[0] as (int, int)).1 == 2); 119 assert((arr_of_tagged_of_tuple[1] as (int, int)).0 == 3); 120 assert((arr_of_tagged_of_tuple[1] as (int, int)).1 == 4); 121 assert((arr_of_tagged_of_tuple[2] as (int, int)).0 == 5); 122 assert((arr_of_tagged_of_tuple[2] as (int, int)).1 == 6); 123 assert(subtype is uint); 124 // TODO: subset-compat 125 }; 126 127 // Real-world sample 128 129 type basic = enum { 130 FN, 131 FOR, 132 IF, 133 IN, 134 NOT, 135 SWITCH, 136 WHILE, 137 }; 138 139 const keywords: [_](str, basic) = [ 140 ("fn", basic::FN), 141 ("for", basic::FOR), 142 ("if", basic::IF), 143 ("in", basic::IN), 144 ("not", basic::NOT), 145 ("switch", basic::SWITCH), 146 ("while", basic::WHILE), 147 ]; 148 149 fn tuplearray() void = { 150 assert(keywords[0].0 == "fn"); 151 assert(keywords[1].0 == "for"); 152 assert(keywords[2].0 == "if"); 153 assert(keywords[3].0 == "in"); 154 assert(keywords[4].0 == "not"); 155 assert(keywords[5].0 == "switch"); 156 assert(keywords[6].0 == "while"); 157 }; 158 159 export fn main() void = { 160 // TODO: Expand this test: 161 // - Declare & validate globals of more types 162 // - Globals which are pointers to other globals 163 write(); 164 storage(); 165 invariants(); 166 static_binding(); 167 pointers(); 168 tagged(); 169 tuplearray(); 170 };