Files and arguments
Mira keeps her score sheet in a text file, one result to a line, with an empty line wherever she felt like leaving one. The repository has it as examples/scores/scores.txt.
mira 12
tomas 7
mira 5
tomas 9
ines 14The finished program is next to it, as examples/scores/scores.qdx. This chapter walks through its parts.
The file and its lines
fn main() -> int {
if arg_count() != 2 { panic("usage: scores <file>") } else {
let all = results_in(lines(read_file(arg(1))));
print_totals(all, players_in(all, bytes_nil()))
}
}arg_count is the number of command-line arguments, counting the program’s own name, and arg(1) is the first one after it. read_file returns a whole file as bytes, and lines splits bytes into a list at each line end.
That list has the type bytes_list, a union from the standard library with the cases bytes_nil() and bytes_cons(head, tail).
One line
A line holds a result or is blank, so reading one produces a union.
union entry { scored(made: result), blank() }
fn entry_in(line: bytes) -> entry {
let name_end = index_of_byte(line, space(), 0);
if len(line) == 0 { blank() }
else if name_end == len(line) { panic(concat("no points on this line: ", line)) }
else {
scored(made: result(player: slice(line, 0, name_end),
points: text_to_int(slice(line, name_end + 1, len(line)))))
}
}
fn space() -> int { 32 }index_of_byte finds the first space, and returns the length of the line when there is none. slice cuts out the bytes from one position up to another, and text_to_int reads decimal digits. A byte is a number, so the space character is written as 32, behind a function that gives it a name.
All the lines
fn results_in(remaining: bytes_list) -> results {
match remaining {
bytes_nil() => no_results(),
bytes_cons(head, tail) => match entry_in(head) {
blank() => results_in(tail),
scored(made) => result_then(first: made, rest: results_in(tail))
}
}
}One match walks the list of lines, and a second decides what each line contributes. Blank lines are skipped by going on with the rest.
Run it
bootstrap/qdx run std/*.qdx examples/scores/scores.qdx -- examples/scores/scores.txtines 14
mira 17
tomas 16Everything after -- is handed to the program as its arguments. The rest of the program collects the players’ names, sorts them, and prints a total for each using total_for from chapter 6.
A sheet with a mistake in it stops the program with a message.
no points on this line: miraThe program is finished. The last chapter looks under the standard library it has been leaning on.