# the set keyword sets a property of the current scope # (i.e. the entire build script, a target, etc.) set RUSTC_EXE = "rustc"; set ASM_EXE = "clang"; set CC_EXE = "clang"; set LINK_EXE = "ld.lld"; set BUILD_PREFIX = "build"; # regular function definitions work very much like they do in ECMAScript 5, # except that the rather verbose "function" keyword is shortened to "fn". fn hello(p1, p2) { print("hello, world"); return p1 + p1; } fn fn_with_callback(cb) { print(cb(2, 2)); } fn get_bit() { return 2; } # a target is a single component. # targets can depend on other targets. target kern { # if statements work just like you expect them to ... if (2 > 3) { print("2 > 3"); } else { print("2 <= 3"); } # ... so do while loops ... var y = 0; while (true) { print(y); y += 1; if (y == 10) { break; } } # ... and even for loops for (var x = 0; x < 10; x += 1) { print(x); } # functions are first-class citizens; they can be defined as inline # anonymous functions that you can treat like any other value var captured_val = "-.-"; fn_with_callback(fn(a, b) { captured_val = "OwO"; return a + b; }); print(captured_val); (fn(a, b) { return a + b; })(1, 2); # math works exactly as you would expect it to var owo = 1 + 2 * 3 * 4 - 5; # and, naturally, there are also all the bitwise goodies var bitmask = 1 << 2 | 1 << 8 ^ get_bit() & 1; # this is exactly equal to the above, but with added # parentheses to make the operator precedences clear bitmask = (1 << 2) | ((1 << 8) ^ (get_bit() & 1)); # the type keyword defines whether the target is supposed to be # compiled into an executable binary (exe) or a library (lib). type "exe"; # the depend keyword adds one or more dependencies to the target. depend [ "libk", "arch", ]; # the source keyword adds one or more source files to the target. # the file extension determines what language/compiler to use. source "kern/lib.rs"; } target libk { print("hello, world"); type "lib"; depend "arch"; source "libk/lib.rs"; } target arch { type "lib"; source [ "arch/lib.rs", "arch/**.nasm", ]; }