Landin library reference discuss source

compiler/tests/fixtures/runtime/library-text-columns/main.ldn

1--  A price list in columns: each count right-aligned under its heading,
2--  and each price, a float, with two decimals.
3import core/io
4import core/text
5import hosted/system
6
7item: type = struct
8    name: utf8
9    count: u64
10    price: f64
11end item
12
13--- Append `value` to `line` in decimal, right-aligned in a field `width`
14--- bytes wide.
15append_right: (inout line: text.builder, value: u64, width: usize)
16              -> none ! text.no_space =
17    start: usize = text.length(line)
18    try text.append_u64(line, value)
19    try text.align_right(line, start, width, u8(' '))
20end append_right
21
22--- Append `value` with two decimals, rounded half away from zero.  Floats
23--- are not formattable, so this scales the value to whole hundredths and
24--- writes the integer part, a point and the two digits after it.
25append_hundredths: (inout line: text.builder, value: f64)
26                   -> none ! text.no_space =
27    mut magnitude: f64 = value
28    if value < 0.0 then
29        magnitude = -value
30    end if
31    --  The conversion truncates toward zero, so adding a half rounds.
32    hundredths: u64 = u64(magnitude * 100.0 + 0.5)
33    if value < 0.0 and hundredths > 0 then
34        try text.append_byte(line, u8('-'))
35    end if
36    try text.append_u64(line, hundredths / 100)
37    try text.append_byte(line, u8('.'))
38    start: usize = text.length(line)
39    try text.append_u64(line, hundredths % 100)
40    try text.align_right(line, start, 2, u8('0'))
41end append_hundredths
42
43--- Write `one` into `line` as a row: its name, then its count and its
44--- price right-aligned under their headings.
45write_row: (inout line: text.builder, one: item) -> none ! text.no_space =
46    text.clear(line)
47    try text.append_text(line, one.name)
48    try text.align_left(line, 0, 8, u8(' '))
49    try append_right(line, one.count, 6)
50    start: usize = text.length(line)
51    try append_hundredths(line, one.price)
52    try text.align_right(line, start, 8, u8(' '))
53    try text.append_byte(line, u8('\n'))
54end write_row
55
56public main: () -> (code: i32) =
57    host := system.new()
58    mut storage: [256]u8 = zeroed
59    mut out := io.buffered_over(host, io.out(host), storage)
60    defer io.flush(out) else none
61    code = 1
62    items: [4]item = [(name: "bolts", count: 1200, price: 0.125),
63                      (name: "nuts", count: 950, price: 0.08),
64                      (name: "washers", count: 75, price: 0.0625),
65                      (name: "refund", count: 1, price: -2.5)]
66    io.put(out, "item     count   price\n") else none
67    mut buffer: [64]u8 = zeroed
68    mut line := text.over(buffer)
69    for one in items do
70        write_row(line, one) else (problem)
71            return
72        end
73        io.put(out, text.used(line)) else (problem)
74            return
75        end
76    end for
77    io.flush(out) else (problem)
78        return
79    end
80    code = 0
81end main