; An inventory report: items from the stock package, reorder rules held as ; function values, and the report's text built in an arena that is reset ; between runs. import stock "stock" struct Rule label: str applies: CFn(stock/Item) -> bool let report-width: i32 = 28 once runs: i32 const reorder-below = 5 ; Run the body n times, counting passes in the name given. macro repeat(i, n, & body) quote for ~i in range(~n) ~@body ; Say what went wrong when a check does not hold. macro expect(test, message) quote if not ~test println("expected:", ~message) fn gcd(a: i32, b: i32) -> i32 let x = a let y = b while y != 0 let r = x % y x = y y = r x fn line(it: stock/Item) -> () let price = stock/money(stock/value(it)) defer free(price) let dots = report-width - i32(length(it.name)) - i32(length(price)) print(it.name) for i in range(max(dots, 1)) print(".") println(str(slice(price))) fn is-low(it: stock/Item) -> bool = it.count < reorder-below fn count-if(items: [stock/Item], is-keep: Fn(stock/Item) -> bool) -> i32 let n = 0 for i in range(length(items)) if is-keep(items[i]) ++(n) n fn main() -> i32 let items = [stock/item("bolts", 12, 400), stock/item("nuts", 5, 3), stock/item("gears", 1250, 7), stock/item("belts", 899, 0)] let rules = [Rule{.label "reorder", .applies is-low}, Rule{.label "valuable", .applies fn(it) => stock/value(it) > 5000}] let frame = arena-new(4096) repeat(pass, 2): runs += 1 with-allocator(frame): println("report", runs) for i in range(length(items)) line(items[i]) for r in range(length(rules)) let names = vec-new(str) for i in range(length(items)) if rules[r].applies(items[i]) push(names, items[i].name) println(rules[r].label, slice(names)) free-all(frame) arena-destroy(frame) let total = 0 for i in range(0, length(items), 2) total += items[i].count println("even rows hold", total, "and share a factor of", gcd(items[0].count, items[2].count + 1)) println("sign bits", stock/sign-bit(-2.5), stock/sign-bit(2.5), "masked", bit-and(-total, 0xFF)) let big = 1000 println("worth over", big, count-if(slice(items), fn(it) => stock/value(it) > big)) expect(total == 407, "407 on even rows") expect(runs == 2, "two runs") 0