e6b42204ef
See shell/README.md for (extremely klunky) instructions.
226 lines
9.6 KiB
Markdown
226 lines
9.6 KiB
Markdown
## Reference documentation on available primitives
|
|
|
|
### Data Structures
|
|
|
|
For memory safety, the following data structures are opaque and only modified
|
|
using functions described further down. I still find it useful to understand
|
|
how they work under the hood.
|
|
|
|
- Handles: addresses to objects allocated on the heap. They're augmented with
|
|
book-keeping to guarantee memory-safety, and so cannot be stored in registers.
|
|
See [mu.md](mu.md) for details, but in brief:
|
|
- You need `addr` values to access data they point to.
|
|
- You can't store `addr` values in other types. They're temporary.
|
|
- You can store `handle` values in other types.
|
|
- To convert `handle` to `addr`, use `lookup`.
|
|
- Reclaiming memory (currently unimplemented) invalidates all `addr`
|
|
values.
|
|
|
|
- Arrays: size-prefixed regions of memory containing multiple elements of a
|
|
single type. Contents are preceded by 4 bytes (32 bits) containing the
|
|
`size` of the array in bytes.
|
|
|
|
- Slices: a pair of 32-bit addresses denoting a [half-open](https://en.wikipedia.org/wiki/Interval_(mathematics))
|
|
\[`start`, `end`) interval to live memory with a consistent lifetime.
|
|
|
|
Invariant: `start` <= `end`
|
|
|
|
- Streams: strings prefixed by 32-bit `write` and `read` indexes that the next
|
|
write or read goes to, respectively.
|
|
|
|
- offset 0: write index
|
|
- offset 4: read index
|
|
- offset 8: size of array (in bytes)
|
|
- offset 12: start of array data
|
|
|
|
Invariant: 0 <= `read` <= `write` <= `size`
|
|
|
|
Writes to a stream abort if it's full. Reads to a stream abort if it's
|
|
empty.
|
|
|
|
- Graphemes: 32-bit fragments of utf-8 that encode a single Unicode code-point.
|
|
- Code-points: 32-bit integers representing a Unicode character.
|
|
|
|
### Functions
|
|
|
|
The most useful functions from 400.mu and later .mu files. Look for definitions
|
|
(using `ctags`) to see type signatures.
|
|
|
|
- `abort`: print a message in red on the bottom left of the screen and halt
|
|
|
|
#### assertions for tests
|
|
|
|
- `check`: fails current test if given boolean is false (`= 0`).
|
|
- `check-not`: fails current test if given boolean isn't false (`!= 0`).
|
|
- `check-ints-equal`: fails current test if given ints aren't equal.
|
|
- `check-strings-equal`: fails current test if given strings have different bytes.
|
|
- `check-stream-equal`: fails current test if stream's data doesn't match
|
|
string in its entirety. Ignores the stream's read index.
|
|
- `check-array-equal`: fails if an array's elements don't match what's written
|
|
in a whitespace-separated string.
|
|
- `check-next-stream-line-equal`: fails current test if next line of stream
|
|
until newline doesn't match string.
|
|
|
|
#### predicates
|
|
|
|
- `handle-equal?`: checks if two handles point at the identical address. Does
|
|
not compare payloads at their respective addresses.
|
|
|
|
- `array-equal?`: checks if two arrays (of ints only for now) have identical
|
|
elements.
|
|
|
|
- `string-equal?`: compares two strings.
|
|
- `stream-data-equal?`: compares a stream with a string.
|
|
- `next-stream-line-equal?`: compares with string the next line in a stream, from
|
|
`read` index to newline.
|
|
|
|
- `slice-empty?`: checks if the `start` and `end` of a slice are equal.
|
|
- `slice-equal?`: compares a slice with a string.
|
|
- `slice-starts-with?`: compares the start of a slice with a string.
|
|
|
|
- `stream-full?`: checks if a write to a stream would abort.
|
|
- `stream-empty?`: checks if a read from a stream would abort.
|
|
|
|
#### arrays
|
|
|
|
- `populate`: allocates space for `n` objects of the appropriate type.
|
|
- `copy-array`: allocates enough space and writes out a copy of an array of
|
|
some type.
|
|
- `slice-to-string`: allocates space for an array of bytes and copies the
|
|
slice into it.
|
|
|
|
#### streams
|
|
|
|
- `populate-stream`: allocates space in a stream for `n` objects of the
|
|
appropriate type.
|
|
- `write-to-stream`: writes arbitrary objects to a stream of the appropriate
|
|
type.
|
|
- `read-from-stream`: reads arbitrary objects from a stream of the appropriate
|
|
type.
|
|
- `stream-to-array`: allocates just enough space and writes out a stream's
|
|
data between its read index (inclusive) and write index (exclusive).
|
|
|
|
- `clear-stream`: resets everything in the stream to `0` (except its `size`).
|
|
- `rewind-stream`: resets the read index of the stream to `0` without modifying
|
|
its contents.
|
|
|
|
- `write`: writes a string into a stream of bytes. Doesn't support streams of
|
|
other types.
|
|
- `write-stream`: concatenates one stream into another.
|
|
- `write-slice`: writes a slice into a stream of bytes.
|
|
- `append-byte`: writes a single byte into a stream of bytes.
|
|
- `append-byte-hex`: writes textual representation of lowest byte in hex to
|
|
a stream of bytes. Does not write a '0x' prefix.
|
|
- `read-byte`: reads a single byte from a stream of bytes.
|
|
- `read-grapheme`: reads a single unicode grapheme (up to 4 bytes containing a
|
|
single code-point encoded in utf-8) from a stream of bytes.
|
|
|
|
#### reading/writing hex representations of integers
|
|
|
|
- `write-int32-hex`
|
|
- `hex-int?`: checks if a slice contains an int in hex. Supports '0x' prefix.
|
|
- `parse-hex-int`: reads int in hex from string
|
|
- `parse-hex-int-from-slice`: reads int in hex from slice
|
|
- `parse-array-of-ints`: reads in multiple ints in hex, separated by whitespace.
|
|
- `hex-digit?`: checks if byte is in [0, 9] or [a, f] (lowercase only)
|
|
|
|
- `write-int32-decimal`
|
|
- `parse-decimal-int`
|
|
- `parse-decimal-int-from-slice`
|
|
- `parse-decimal-int-from-stream`
|
|
- `parse-array-of-decimal-ints`
|
|
- `decimal-digit?`: checks if byte is in [0, 9]
|
|
|
|
#### printing to screen
|
|
|
|
All screen primitives require a screen object, which can be either the real
|
|
screen on the computer or a fake screen for tests.
|
|
|
|
The real screen on the Mu computer can currently display only ASCII characters,
|
|
though it's easy to import more of the font. There is only one font. All
|
|
graphemes are 8 pixels wide and 16 pixels tall. These constraints only apply
|
|
to the real screen.
|
|
|
|
- `draw-grapheme`: draws a single grapheme at a given coordinate, with given
|
|
foreground and background colors.
|
|
- `render-grapheme`: like `draw-grapheme` and can also handle newlines
|
|
assuming text is printed left-to-right, top-to-bottom.
|
|
- `draw-code-point`
|
|
- `clear-screen`
|
|
|
|
- `draw-text-rightward`: draws a single line of text, stopping when it reaches
|
|
either the provided bound or the right screen margin.
|
|
- `draw-stream-rightward`
|
|
- `draw-text-rightward-over-full-screen`: does not provide a bound.
|
|
- `draw-text-wrapping-right-then-down`: draws multiple lines of text on screen
|
|
with simplistic word-wrap (no hyphenation) within (x, y) bounds.
|
|
- `draw-stream-wrapping-right-then-down`
|
|
- `draw-text-wrapping-right-then-down-over-full-screen`
|
|
- `draw-int32-hex-wrapping-right-then-down`
|
|
- `draw-int32-hex-wrapping-right-then-down-over-full-screen`
|
|
- `draw-int32-decimal-wrapping-right-then-down`
|
|
- `draw-int32-decimal-wrapping-right-then-down-over-full-screen`
|
|
|
|
Similar primitives for writing text top-to-bottom, left-to-right.
|
|
|
|
- `draw-text-downward`
|
|
- `draw-stream-downward`
|
|
- `draw-text-wrapping-down-then-right`
|
|
- `draw-stream-wrapping-down-then-right`
|
|
- `draw-text-wrapping-down-then-right-over-full-screen`
|
|
- `draw-int32-hex-wrapping-down-then-right`
|
|
- `draw-int32-hex-wrapping-down-then-right-over-full-screen`
|
|
- `draw-int32-decimal-wrapping-down-then-right`
|
|
- `draw-int32-decimal-wrapping-down-then-right-over-full-screen`
|
|
|
|
Screens remember the current cursor position.
|
|
|
|
- `cursor-position`
|
|
- `set-cursor-position`
|
|
- `draw-grapheme-at-cursor`
|
|
- `draw-code-point-at-cursor`
|
|
- `draw-cursor`: highlights the current position of the cursor. Programs must
|
|
pass in the grapheme to draw at the cursor position, and are responsible for
|
|
clearing the highlight when the cursor moves.
|
|
- `move-cursor-left`, `move-cursor-right`, `move-cursor-up`, `move-cursor-down`.
|
|
These primitives always silently fail if the desired movement would go out
|
|
of screen bounds.
|
|
- `move-cursor-to-left-margin-of-next-line`
|
|
- `move-cursor-rightward-and-downward`: move cursor one grapheme to the right
|
|
|
|
- `draw-text-rightward-from-cursor`
|
|
- `draw-text-wrapping-right-then-down-from-cursor`
|
|
- `draw-text-wrapping-right-then-down-from-cursor-over-full-screen`
|
|
- `draw-int32-hex-wrapping-right-then-down-from-cursor`
|
|
- `draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen`
|
|
- `draw-int32-decimal-wrapping-right-then-down-from-cursor`
|
|
- `draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen`
|
|
|
|
- `draw-text-wrapping-down-then-right-from-cursor`
|
|
- `draw-text-wrapping-down-then-right-from-cursor-over-full-screen`
|
|
|
|
Assertions for tests:
|
|
|
|
- `check-screen-row`: compare a screen from the left margin of a given row
|
|
index with a string. The row index counts downward from 0 at the top of the
|
|
screen. String can be smaller or larger than a single row, and defines the
|
|
region of interest. Strings longer than a row wrap around to the left margin
|
|
of the next screen row. Currently assumes text is printed left-to-right on
|
|
the screen.
|
|
- `check-screen-row-from`: compare a fragment of a screen (left to write, top
|
|
to bottom) starting from a given (x, y) coordinate with an expected string.
|
|
Currently assumes text is printed left-to-right and top-to-bottom on the
|
|
screen.
|
|
- `check-screen-row-in-color`: like `check-screen-row` but:
|
|
- also compares foreground color
|
|
- ignores screen locations where the expected string contains spaces
|
|
- `check-screen-row-in-color-from`
|
|
- `check-screen-row-in-background-color`
|
|
- `check-screen-row-in-background-color-from`
|
|
- `check-background-color-in-screen-row`: unlike previous functions, this
|
|
doesn't check screen contents, only background color. Ignores background
|
|
color where expected string contains spaces, and compares background color
|
|
where expected string does not contain spaces. Never compares the character
|
|
at any screen location.
|
|
- `check-background-color-in-screen-row-from`
|