sysl

Standard Library

What ships with the compiler, module by module — the core every program has, and the layers a target may not.

The reference is the language: what the compiler reads, what a type is, what a declaration binds. This section is the other half of what a program has — the modules that ship with the compiler, and what each of them offers.

They are kept apart on purpose. Nothing in this section is a language feature: every type here is an ordinary struct or enum, every function is ordinary sysl, and a program could have written any of it. Option is a generic enum, unwrap is a member that calls exit, print is a library function reached by a desugaring. The line matters because it is the language’s own rule about itself — there are no functions built into the compiler that a program could not have written, and the one exception is the seam out to C.

So a page in the reference tells you what the compiler will accept. A page here tells you what somebody already wrote for you, and where it will not be there.

The library is a tree, and the tree is the point

sysl is one module with submodules under it, and each is a directory. A program reaches the core without asking; everything below it is imported by name.

moduleholdsrequires
syslthe core — Option, Result, Display, the operator traits, print, assert
sysl.textthe whole text surface — validation, the character cursors, Ascii and Search, splitting and joining, StrBuilder, the parsers, CString
sysl.regexPOSIX Extended Regular Expressions — regex, Regex, Match
sysl.bufBuf[T], the growable sequence, and ByteSink
sysl.ioReader, stdin(), lines() and console_lines(), and the in-memory bytes_reader() / bytes_writer()
sysl.fsfiles and paths — read_text, write_bytes, exists, rename, and IoErroros
sysl.mathmax, min, pi, the float functions, the integer traits Signed and Bits, and the integer arithmetic above them — pow, gcd, lcm, divmod, is_power_of_two, next_power_of_two
sysl.math.complexComplex[F: Float] — the operators at two argument lists each, the transcendental set, and the branch cuts
sysl.timeInstant and Duration — with 5.ms and 5.hours on any integer — the civil calendar — LocalDate, LocalTime, LocalDateTime, Offset — the fixed-offset conversions, and the ISO 8601 renderers and parsers
sysl.posix.timethe two clocks the host keeps — now for a wall reading, monotonic for measuringposix
sysl.syncAtomic[T], SpinLock, and the five memory orderings
sysl.posix.threadsspawn, Thread.join, yield_now, and Mutex[T]posix
sysl.termthe escape sequences a terminal understands — colour, emphasis, and the screen
sysl.posix.ttywhether to write them at all — is_tty, color_wanted, color, color_err — and taking the terminal over: raw, cooked, flush, tty_writerposix
sysl.term.edita line editor for a terminal with no line discipline — echo, editing, history, over a Reader and a Writer
sysl.sliceswhat a program does to a []T — searching, comparing, reverse, two sorts that neither allocate, binary_search, and as_ptr for a C binding
sysl.encodinghexadecimal and base64 both ways, fixed-width integers to and from bytes at either byte order, and DecodeError
sysl.randPCG32, seeded by the caller and reproducible — below without modulo bias, range, unit, shuffle
sysl.posix.randseed_from_os, kept apart so the generator stays freestandingposix
sysl.argscommand-line options — Scan, Cli, and args_of for a raw argv
sysl.harnessa test framework that runs on the targetrun, check, check_eq, check_slice_eq, skip, and a tally
sysl.systhe platform seam — what a freestanding target replaces

The split is by capability, not by taste, and the namespace is the column written into the path. sysl.fs is requires os, because a filesystem is something the environment either has or does not — and files exist on operating systems that are not POSIX, which is why it is the one gated module that does not sit under sysl.posix. Everything under sysl.posix is requires posix and nothing else: threads because pthreads is what they are, tty because isatty and termios are, rand because entropy comes from the kernel, time because clock_gettime is a call into it. So a module a target cannot support is not one that fails to link — it is one a capability clause will not let that program import in the first place, and now one you can spot by its name.

It is also why sysl.posix.tty, sysl.posix.rand and sysl.posix.time are modules of their own rather than functions in sysl.term, sysl.rand and sysl.time. A requirement is module-wide, so one function asking for posix beside the escape sequences would have taken all forty constants away from the allocator-free programs that most want to colour a line; one asking for it beside the generator would have taken PCG32 away from every target that has no operating system to seed it from; and one asking for it beside Instant would have taken the whole civil calendar away from a program that only wanted to add two durations. Three instances of one shape, and the shape is worth naming: where a module is portable except for how it gets started, the getting started goes in a submodule.

That is why the atomics live apart from the threads: sysl.sync requires nothing, so a kernel can have a spinlock without acquiring a scheduler along with it.

alloc is not in that column, and the omission is the point. No module requires it, because allocation is refused at the call rather than at the import — so a program under no alloc still imports sysl.text and still gets from_utf8, the cursors, and Search, and is refused only where it reaches for join or a StrBuilder. A capability that gated whole modules would have cost the allocator-free subset most of the library it can actually use.

Where some of this already is

Three pieces of the library are documented in the reference instead, because the language has machinery that only makes sense beside them:

  • Option, Result and the Fallible latch are on errors and contracts, because ? is a language form and it is what those types are for.
  • assert and panic are on attributes and compile time, beside the @test protocol they exist to serve.
  • The operator traits — which trait a + or a < reaches — are on expressions, because dispatch is a rule about the operator rather than about the trait.

This section links to them rather than repeating them.

Pages

  • The core module — `sysl` itself — the names every program has without asking: rendering, hashing, subscripting, iteration, callables, and the two ways a program stops.
  • The text module — `sysl.text` — validating bytes into text, walking it by character, searching and trimming without an allocator, building and splitting with one, and reading values back out.
  • Regular expressions — `sysl.regex` — POSIX Extended Regular Expressions, matched by a Pike VM whose cost is the input length times the pattern length and never anything worse.
  • The buf module — `sysl.buf` — `Buf[T]`, the growable sequence written in ordinary sysl, and `ByteSink`, the one `Writer` the library supplies.
  • The io module — `sysl.io` — `Reader`, the one trait input travels through; `FdReader` and `stdin()`; and `lines()`, the cursor that borrows what it reads from.
  • The fs module — `sysl.fs` — files and paths, in three tiers; `IoError` and why it is an enum; and `requires os`, the capability that decides whether the module exists at all.
  • The slices module — `sysl.slices` — the operations over a built-in slice: searching, comparing, reversing, two sorts that neither of them allocates, a binary search that answers where a missing value belongs, and the pointer a C binding hands across.
  • The encoding module — `sysl.encoding` — hexadecimal and base64 in both directions, fixed-width integers to and from bytes at either byte order, and a `DecodeError` that says what a caller can act on.
  • The math module — `sysl.math` — the `Float` trait over both widths, `Signed` and `Bits` over the open integer family, the constants, `min`/`max`/`clamp` over anything ordered, the float comparisons, and the integer arithmetic above the operators.
  • The complex module — `sysl.math.complex` — `Complex[F: Float]`, generic over both float widths: the operators at two argument lists each, the transcendental set, and the branch cuts written down.
  • The rand module — `sysl.rand` — PCG32, seeded by the caller and reproducible; a bounded integer with no modulo bias, a shuffle that is Fisher-Yates, and OS seeding kept in a module of its own so a freestanding target need never import it.
  • The time module — `sysl.time` — `Instant` and `Duration` kept apart, the proleptic Gregorian calendar, `LocalDate`/`LocalTime`/`LocalDateTime`, the ISO 8601 renderers and the parsers that read them back.
  • sysl.sync — Atomics, the five memory orderings, and a spinlock — the concurrency a target has before it has a scheduler.
  • sysl.posix.threads — Starting a thread, waiting for one, and the mutex above the spinlock — the half of concurrency that needs a scheduler.
  • sysl.term — The escape sequences a terminal understands — colour, emphasis, and the screen — as constants a program with no allocator can still name.
  • sysl.args — How argc and argv become a []string, and the two layers that read options out of them.
  • The harness module — `sysl.harness` — a test framework that runs on the target: named tests, a located failure with both values rendered, three verdicts and a tally, with no allocator, no operating system and no debug host underneath.
  • sysl.sys — The platform seam — every declaration in the standard library that is not sysl, in one file you cannot call.

Search

Esc
to navigate to open Esc to close