move comment to a clearer location
[mu.git] / vocabulary.md
blobe0beb0909fefd77fd9fa8732002bbcc0a04dbc9a
1 ## Reference documentation on available primitives
3 ### Data Structures
5 For memory safety, the following data structures are opaque and only modified
6 using functions described further down. I still find it useful to understand
7 how they work under the hood.
9 - Handles: addresses to objects allocated on the heap. They're augmented with
10   book-keeping to guarantee memory-safety, and so cannot be stored in registers.
11   See [mu.md](mu.md) for details, but in brief:
12     - You need `addr` values to access data they point to.
13     - You can't store `addr` values in other types. They're temporary.
14     - You can store `handle` values in other types.
15     - To convert `handle` to `addr`, use `lookup`.
16     - Reclaiming memory (currently unimplemented) invalidates all `addr`
17       values.
19 - Arrays: size-prefixed regions of memory containing multiple elements of a
20   single type. Contents are preceded by 4 bytes (32 bits) containing the
21   `size` of the array in bytes.
23 - Slices: a pair of 32-bit addresses denoting a [half-open](https://en.wikipedia.org/wiki/Interval_(mathematics))
24   \[`start`, `end`) interval to live memory with a consistent lifetime.
26   Invariant: `start` <= `end`
28 - Streams: strings prefixed by 32-bit `write` and `read` indexes that the next
29   write or read goes to, respectively.
31   - offset 0: write index
32   - offset 4: read index
33   - offset 8: size of array (in bytes)
34   - offset 12: start of array data
36   Invariant: 0 <= `read` <= `write` <= `size`
38   By default, writes to a stream abort if it's full. Reads to a stream abort
39   if it's empty.
41 - Graphemes: a sequence of up to 4 utf-8 bytes that encode a single Unicode
42   code-point.
43 - Code-points: integer representing a Unicode character. Must be representable
44   in 32 bits as utf-8; largest supported value is 0x10000.
46 Mu will let you convert between `byte`, `code-point-utf8` and `code-point`
47 using `copy`, and trust that you know what you're doing. Be aware that doing
48 so is only correct for English/Latin characters, digits and symbols (ASCII).
50 ### Functions
52 The most useful functions from 400.mu and later .mu files. Look in
53 signatures.mu for their full type signatures.
55 - `abort`: print a message in red on the bottom left of the screen and halt
57 #### assertions for tests
59 - `check`: fails current test if given boolean is false (`= 0`).
60 - `check-not`: fails current test if given boolean isn't false (`!= 0`).
61 - `check-ints-equal`: fails current test if given ints aren't equal.
62 - `check-strings-equal`: fails current test if given strings have different bytes.
63 - `check-stream-equal`: fails current test if stream's data doesn't match
64   string in its entirety. Ignores the stream's read index.
65 - `check-array-equal`: fails if an array's elements don't match what's written
66   in a whitespace-separated string.
67 - `check-next-stream-line-equal`: fails current test if next line of stream
68   until newline doesn't match string.
70 #### predicates
72 - `handle-equal?`: checks if two handles point at the identical address. Does
73   not compare payloads at their respective addresses.
75 - `array-equal?`: checks if two arrays (of ints only for now) have identical
76   elements.
78 - `string-equal?`: compares two strings.
79 - `stream-data-equal?`: compares a stream with a string.
80 - `next-stream-line-equal?`: compares with string the next line in a stream, from
81   `read` index to newline.
83 - `slice-empty?`: checks if the `start` and `end` of a slice are equal.
84 - `slice-equal?`: compares a slice with a string.
85 - `slice-starts-with?`: compares the start of a slice with a string.
87 - `stream-full?`: checks if a write to a stream would abort.
88 - `stream-empty?`: checks if a read from a stream would abort.
90 #### arrays
92 - `populate`: allocates space for `n` objects of the appropriate type.
93 - `copy-array`: allocates enough space and writes out a copy of an array of
94   some type.
95 - `slice-to-string`: allocates space for an array of bytes and copies the
96   slice into it.
98 #### streams
100 - `populate-stream`: allocates space in a stream for `n` objects of the
101   appropriate type.
102 - `write-to-stream`: writes arbitrary objects to a stream of the appropriate
103   type.
104 - `read-from-stream`: reads arbitrary objects from a stream of the appropriate
105   type.
106 - `stream-to-array`: allocates just enough space and writes out a stream's
107   data between its read index (inclusive) and write index (exclusive).
109 - `clear-stream`: resets everything in the stream to `0` (except its `size`).
110 - `rewind-stream`: resets the read index of the stream to `0` without modifying
111   its contents.
113 - `write`: writes a string into a stream of bytes. Doesn't support streams of
114   other types.
115 - `try-write`: writes a string into a stream of bytes if possible. Doesn't
116   support streams of other types.
117 - `write-stream`: concatenates one stream into another.
118 - `write-slice`: writes a slice into a stream of bytes.
119 - `append-byte`: writes a single byte into a stream of bytes.
120 - `append-byte-hex`: writes textual representation of lowest byte in hex to
121   a stream of bytes. Does not write a '0x' prefix.
122 - `read-byte`: reads a single byte from a stream of bytes.
123 - `read-code-point-utf8`: reads a single unicode code-point-utf8 (up to 4
124   bytes) from a stream of bytes.
126 #### reading/writing hex representations of integers
128 - `write-int32-hex`
129 - `hex-int?`: checks if a slice contains an int in hex. Supports '0x' prefix.
130 - `parse-hex-int`: reads int in hex from string
131 - `parse-hex-int-from-slice`: reads int in hex from slice
132 - `parse-array-of-ints`: reads in multiple ints in hex, separated by whitespace.
133 - `hex-digit?`: checks if byte is in [0, 9] or [a, f] (lowercase only)
135 - `write-int32-decimal`
136 - `parse-decimal-int`
137 - `parse-decimal-int-from-slice`
138 - `parse-decimal-int-from-stream`
139 - `parse-array-of-decimal-ints`
140 - `decimal-digit?`: checks if a code-point-utf8 is in [0, 9]
142 #### printing to screen
144 `pixel-on-real-screen` draws a single pixel in one of 256 colors.
146 All text-mode screen primitives require a screen object, which can be either
147 the real screen on the computer or a fake screen for tests.
149 The real screen on the Mu computer can currently display a subset of Unicode.
150 There is only one font, and it's mostly fixed-width, with individual glyphs
151 for code-points being either 8 or 16 pixels wide.
153 - `draw-code-point`: draws a single code-point at a given coordinate, with
154   given foreground and background colors. Returns the number of 8-pixel wide
155   grid locations used (either 1 or 2).
156 - `render-code-point`: like `draw-code-point`, but handles newlines and
157   updates cursor position. Assumes text is printed left-to-right,
158   top-to-bottom.
159 - `clear-screen`
161 - `draw-text-rightward`: draws a single line of text, stopping when it reaches
162   either the provided bound or the right screen margin.
163 - `draw-stream-rightward`
164 - `draw-text-rightward-over-full-screen`: does not provide a bound.
165 - `draw-text-wrapping-right-then-down`: draws multiple lines of text on screen
166   with simplistic word-wrap (no hyphenation) within (x, y) bounds.
167 - `draw-stream-wrapping-right-then-down`
168 - `draw-text-wrapping-right-then-down-over-full-screen`
169 - `draw-int32-hex-wrapping-right-then-down`
170 - `draw-int32-hex-wrapping-right-then-down-over-full-screen`
171 - `draw-int32-decimal-wrapping-right-then-down`
172 - `draw-int32-decimal-wrapping-right-then-down-over-full-screen`
174 Similar primitives for writing text top-to-bottom, left-to-right.
176 - `draw-text-downward`
177 - `draw-stream-downward`
178 - `draw-text-wrapping-down-then-right`
179 - `draw-stream-wrapping-down-then-right`
180 - `draw-text-wrapping-down-then-right-over-full-screen`
181 - `draw-int32-hex-wrapping-down-then-right`
182 - `draw-int32-hex-wrapping-down-then-right-over-full-screen`
183 - `draw-int32-decimal-wrapping-down-then-right`
184 - `draw-int32-decimal-wrapping-down-then-right-over-full-screen`
186 Screens remember the current cursor position. The following primitives
187 automatically read and update the cursor position in various ways.
189 - `cursor-position`
190 - `set-cursor-position`
191 - `draw-code-point-at-cursor-over-full-screen`: `render-code-point` at
192   cursor position.
193 - `draw-cursor`: highlights the current position of the cursor. Programs must
194   pass in the code-point to draw at the cursor position, and are responsible
195   for clearing the highlight when the cursor moves.
196 - `move-cursor-left`, `move-cursor-right`, `move-cursor-up`, `move-cursor-down`.
197   These primitives always silently fail if the desired movement would go out
198   of screen bounds.
199 - `move-cursor-to-left-margin-of-next-line`
200 - `move-cursor-rightward-and-downward`: move cursor one code-point-utf8 to the
201   right.
203 - `draw-text-rightward-from-cursor`: truncate at some right margin.
204 - `draw-text-rightward-from-cursor-over-full-screen`: truncate at right edge
205   of screen.
206 - `draw-text-wrapping-right-then-down-from-cursor`: wrap at some right margin.
207 - `draw-text-wrapping-right-then-down-from-cursor-over-full-screen`: wrap at
208   right edge of screen.
209 - `draw-int32-hex-wrapping-right-then-down-from-cursor`
210 - `draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen`
211 - `draw-int32-decimal-wrapping-right-then-down-from-cursor`
212 - `draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen`
214 - `draw-text-wrapping-down-then-right-from-cursor`: wrap at some bottom
215   margin.
216 - `draw-text-wrapping-down-then-right-from-cursor-over-full-screen`: wrap at
217   bottom edge of screen.
219 Assertions for tests:
221 - `check-screen-row`: compare a screen from the left margin of a given row
222   index with a string. The row index counts downward from 0 at the top of the
223   screen. String can be smaller or larger than a single row, and defines the
224   region of interest. Strings longer than a row wrap around to the left margin
225   of the next screen row. Currently assumes text is printed left-to-right on
226   the screen.
227 - `check-screen-row-from`: compare a fragment of a screen (left to write, top
228   to bottom) starting from a given (x, y) coordinate with an expected string.
229   Currently assumes text is printed left-to-right and top-to-bottom on the
230   screen.
231 - `check-screen-row-in-color`: like `check-screen-row` but:
232   - also compares foreground color
233   - ignores screen locations where the expected string contains spaces
234 - `check-screen-row-in-color-from`
235 - `check-screen-row-in-background-color`
236 - `check-screen-row-in-background-color-from`
237 - `check-background-color-in-screen-row`: unlike previous functions, this
238   doesn't check screen contents, only background color. Ignores background
239   color where expected string contains spaces, and compares background color
240   where expected string does not contain spaces. Never compares the character
241   at any screen location.
242 - `check-background-color-in-screen-row-from`
244 #### pixel graphics
246 - `pixel`: draw a single point at (x, y) with a given color between 0 and 255.
247 - `draw-line`: between two points (x1, y1) and (x2, y2)
248 - `draw-horizontal-line`
249 - `draw-vertical-line`
250 - `draw-circle`
251 - `draw-disc`: takes an inner and outer radius
252 - `draw-monotonic-bezier`: draw curved lines with a single control point.
253   Doesn't support curves with "U-turns".
255 #### events
257 `read-key` reads a single key from the keyboard and returns it if it exists.
258 Returns 0 if no key has been pressed. Currently only supports single-byte
259 (ASCII) keys, which are identical to their code-point and code-point-utf8
260 representations.
262 `read-line-from-keyboard` reads keys from keyboard, echoes them to screen
263 (with given fg/bg colors) and accumulates them in a stream until it encounters
264 a newline.
266 `read-mouse-event` returns a recent change in x and y coordinate.
268 `timer-counter` returns a monotonically increasing counter with some
269 fixed frequency. You can periodically poll it to check for intervals passing,
270 but can't make assumptions about how much time has passed.
272 Mu doesn't currently support interrupt-based events.
274 We also don't yet have a fake keyboard.
276 #### persistent storage
278 `read-ata-disk` synchronously reads a whole number of _sectors_ from a _disk_
279 of persistent storage. The disk must follow the ATA specification with a
280 28-bit sector address. Each sector is 512 bytes. Therefore, Mu currently
281 supports ATA hard disks of up to 128GB capacity.
283 Similarly, `write-ata-disk` synchronously writes a whole number of sectors to
284 disk.
286 Mu doesn't currently support asynchronous transfers to or from a disk.