core/failure
Shared: available on every enabled target.
Words for a person: a short English phrase for each failure atom the core library raises.
failure.words(problem) gives the phrase for any of the 32 atoms in failure.reason, every atom a core module fails with, so a call's else (problem) passes its failure straight on, whatever subset it declares. A phrase is lower case with no final stop and reads after a subject and a colon, settings: not found; it is static text, borrows nothing and never changes with a locale. A set that also holds an atom of the program's own does not widen to failure.reason, and a match arm of _ does not narrow it, so such a program names each library atom it passes on. platform/posix's errno detail stays with its provider. Nothing is linked into a program that never calls words; one that does carries every phrase, about 6 KB of code and text on Cortex-M0 (D388).
Items
Executable example
This complete program is maintained in the repository runtime tests. View source.
-- A program that reports its failures to a person, as `path: reason` -- lines on standard error, with the library's own words for each reason: -- a file that is not there, a count that is not a number and one too -- large for its type. It ends with status 1, as a tool that failed does. import core/failure import core/io import core/text import hosted/system -- `subject: reason` and a line ending, on standard error. report: (host: system.host, subject: []u8, reason: failure.reason) -> none = stream: io.file = io.err(host) io.write(host, stream, subject) else none io.write(host, stream, ": ") else none io.write(host, stream, failure.words(reason)) else none io.write(host, stream, "\n") else none end report -- Read the file at `path`, reporting why it cannot be opened. opened: (host: system.host, path: []u8) -> (yes: bool) = yes = false file := io.open_read(host, text.host_over(path)) else (problem) report(host, path, problem) return end io.close(host, file) else none yes = true end opened -- Read `count` as a byte count, reporting why it is not one. counted: (host: system.host, count: []u8) -> (yes: bool) = yes = false _ = text.parse_u8(count) else (problem) report(host, count, problem) return end yes = true end counted public main: () -> (code: i32) = host := system.new() code = 0 missing: bool = not opened(host, "landin-absent-notes.txt") not_number: bool = not counted(host, "twelve") too_large: bool = not counted(host, "300") if missing and not_number and too_large then code = 1 end if end main
reason type
public reason: type = mem.out_of_bounds | mem.empty | mem.full | mem.not_emptyEvery atom a core module fails with: the set words takes. A call's failure, problem in its else (problem), widens to it whatever subset of these atoms the call declares. A set that also holds an atom of the program's own does not: a match arm names each library atom and passes that atom on, since a _ arm leaves the set as it was.
words function
public words: (problem: reason) -> (phrase: []u8)A short English phrase for a library failure, in lower case with no final stop, so that it reads after a subject and a colon as settings: not found does. The phrase is static text: it borrows nothing and is never freed. Every atom of reason has its own phrase, and the phrases are fixed: a program may compare them, and no locale changes them.