Landin library reference discuss source

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_empty

core/failure/failure.ldn:18

Every 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)

core/failure/failure.ldn:38

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.