oxdesign.ox (5982B)
1 i32 ~x = 42; // make a integer 32bit that is a variable (can be updated) `~` initialised with 2. 2 i32 x = 42; // like a "let" statement or final variable, runtime constant. 3 i32 #x = 42; // compile time constant 4 5 // give me the raw pointer of x and assign it to y 6 i32* y = &x; 7 8 9 // default types 10 // i8, i16, i32, i64, 11 // u8, u16, u32, u64, 12 // f8, f16, f32, f64, 13 // str, chr, bool, 14 15 // arrays (fixed) and lists (dynamic) 16 arr<i32>[16] ages; // fixed slice of 16 17 vec<i32> bobs; // dynamic list 18 set<str> names; // sets 19 20 type Person { 21 i32 age, 22 str name, 23 } 24 25 fn say_hello () void { 26 print("hello"); // print is part of stdlib.local which is auto imported 27 warn("hello"); // this print to stderr instead 28 print_("hello\n"); // all of the above but with `_` won't insert a trailing \n 29 fatal("hello"); // fatal print, returning non-zero 30 } 31 32 // strings are really arrays of special u32, aka vec<chr> 33 typedef chr u32; // (but u32 is not a rune/chr, as the whole UTF-16 range does not cover u32) 34 35 // exported function returns one i32 36 fx add (i32 a, b) i32 => a + b; 37 38 // fx = function is exported 39 // fn = function is static 40 41 fx passed (Person p) {} // ownership passed and cannot be used after 42 fn borrow (Person& p) {} // borrowed and unmutable 43 fn mutate (Person~ p) {} // borrowed and mutable 44 fn unsafe (Person* p) unsafe {} // C style passing of pointer, must tag `unsafe` 45 46 // lambda style function definition 47 fx add = (i32 a, b) i32 => a + b; 48 49 // void return is implicit, so is void type arg 50 fx say_hello() { 51 print("hello"); 52 } 53 54 // multiple return values go into parens 55 fx flip(i32 a, b) (i32, i32) => b, a; 56 57 struct Person { 58 str name, 59 i16 age, 60 i32 number, 61 str street, 62 str suburb, 63 str postcode, 64 str country, 65 // string interpolation `$.` is identifying a type component 66 fx address () str => "$.number, $.street, $.suburb $.postcode\n$.country" 67 } 68 69 extend Person { 70 ... 71 } 72 73 // lambda style main function 74 fn main => print("hello world"); 75 76 fn main(i32 argc, arr<str> argv) int = { 77 if argc != 0 { 78 print("usage..."); 79 return 0; 80 } 81 print("hello world! $argc"); // string interpolation similar to Dart's 82 return 0; 83 } 84 85 fn rename({str name}) str {} // enforce the label to be passed: rename(name:"jack") 86 87 // if statement don't have required parens, they're optional 88 89 if a == b { 90 do_this(); 91 } else if a == c { 92 do_that(); 93 } else { 94 do_nothing(); 95 } 96 97 // inline if can be done as is 98 if cache_miss() { print("cached missed!"); } 99 100 // ternary if 101 i32 bla = cond ? 42 : 420; 102 103 // for statements 104 // classic for statement use commas separated init, cond and modifier 105 for (i32 i = 0, i < 42, i++) {} 106 107 for i32 i in 0..< 42 {} // shorthand for loop with for each 108 109 for chr c in word {} // for each .. in 110 111 for (chr c, i32 i) in word {} // for each in with index, parens optional 112 113 // while loops 114 while cond == true { 115 // body 116 } 117 118 // infinite loop until broken 119 loop {} 120 121 // switch 122 switch (action.key) { 123 KEY_ENTER { 124 open_door(); 125 } 126 KEY_UP { move_up(); } 127 default { 128 warn("unsupported!") 129 } 130 } 131 132 // match expr 133 chr c = match key { 134 61 => 'a'; 135 62 => 'b'; 136 default => '_'; 137 } 138 139 140 // dealing with nil values. They're not allowed unless unsafe in play. 141 Person? p = find("jack"); 142 143 if Person x = p { 144 print("found jack of ${x.age} age"); // safe usage 145 } 146 147 if p { 148 print("found jack of ${p!.age} age"); // force unwrap 149 } 150 151 Person* p = NULL; // is allowed. NULL is a constant 0xffffff of some kind. 152 153 // not allowed: Person&? Person~? 154 155 // null coalescing of maybes 156 print("jack may be of ${p?.age ?? \"some unknown\"}"); 157 158 i32 res = some_test() ?? 42; 159 160 // namespacing 161 162 ns main; // is default and not required, this unit will require a main function 163 ns tools; // loosely required to be in tools/ 164 165 // using namespaces, importing, namespaces are forced lowercase to not impact types 166 167 use math; // bring all of math functions in, to be prefixed by math.something 168 use math { random, sin, cos }; // limit the import to these symbols, directly accessible: sin() 169 use math as mth; // alias math to `mth` 170 171 172 // async operations using the Aloha assignment operator `~=` 173 174 i32? response = await some_long_action(); 175 176 // error handling 177 178 fn fetch_data({str url}) async str! { 179 // fetch the data of the website, parse the body content 180 // return the body content 181 await ... 182 return content; 183 } 184 185 struct Error { 186 u16 code, 187 str message, 188 Error? cause 189 } 190 191 str website_data = await try fetch_data(url: "fleacebook.com") or Error e => print("could not fetch data ${e.message}"); 192 193 194 fx flip(i32 a, b) (i32, i32)! { 195 196 } 197 198 199 // APPENDIX 200 201 // keywords 202 // return, break, continue, if, else, for, while, loop, goto, defer, heap, free, 203 // type, ext, union, arr, vec, set, typedef, fx, fn, maybe, mut, ref, ptr, voidptr, 204 // unsafe, inline 205 206 207 // types 208 // all of the 209 // stdlib.local auto imported 210 // equivalent of `use always { print, print_, warn, warn_, fatal }` 211 // print, print_, warn, warn_, fatal 212 213 // FFI interaction with C and C types 214 // core FFI aliases 215 typedef voidptr = void*; 216 typedef cstr = char*; 217 typedef ccstr = const char*; 218 219 use math; 220 use c <stdio.h>; 221 use c <stdlib.h>; 222 use c <stdint.h>; 223 use c "include/termbox2.h"; 224 225 extern c { 226 fn printf(ccstr, ...) int; 227 fn free(voidptr); 228 fn malloc(size_t) voidptr; 229 fn tb_print(i32, i32, u16, u16, cstr); // x, y, fg, bg, text 230 231 // NOTES 232 // don't use `const char*` etc. and warn against it at compile time 233 // use cstr or ccstr instead to avoid the baggage of weird 234 // pointer precedence and const position 235 // 236 } 237 238 fn main() { 239 voidptr ptr = malloc(65128); 240 // invalid: *ptr = 420 // voidptr should be undereferenceable 241 // no deref of voidptr without a cast 242 ptr<u8> bytes = cast(ptr<u8> p); 243 bytes[0] = 42; 244 free(ptr); 245 246 // presume init called etc. 247 tb_print(12, 12, TB_MAGENTA, TB_BLACK, c_const_str("some words of wisdom")); 248 }