about summary refs log tree commit diff stats
path: root/js/map-maker/imgs/extracted-1688-map/MapPartsWhite/towns_white/19.png
blob: 9b514d8a2620ad9a0e7ce74d9c916f312f167c8c (plain)
ofshex dumpascii
0000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 1c 00 00 00 1a 08 06 00 00 00 a4 54 3c .PNG........IHDR..............T<
0020 89 00 00 02 05 49 44 41 54 78 da ed d6 4f 48 d3 71 18 c7 f1 41 46 03 bd 14 fe 01 83 3c 04 1d 0a .....IDATx...OH.q...AF......<...
0040 46 1e 22 88 a1 a7 28 14 a5 20 82 2e 86 92 08 62 08 5d ea 50 b4 5b 87 11 1e 22 8a 24 0f 8a a0 78 F."...(........b.].P.[...".$...x
0060 d1 4b 91 14 4a 21 0c 14 85 c0 18 a8 ac 18 a4 60 64 a8 d0 6a b9 5f ef 07 3f a3 2f 63 83 9c 3f 6f .K..J!.........`d..j._..?./c..?o
0080 fb c2 8b e9 f7 37 7f 0f cf f3 fb 3e cf cf 40 a0 b4 f2 2c cf f3 6e a1 1d 17 11 42 13 3a 71 0f 77 .....7.....>..@...,..n....B.:q.w
00a0 fc 0e 56 eb ed ae 4d bc 45 3f 3e 23 8d 0c be 23 e8 67 c0 1a dd b8 17 67 d1 80 28 92 f8 81 41 bf ..V...M.E?>#...#.g.....g..(...A.
00c0 33 ac 72 02 5e c5 43 65 99 54 a6 77 fd 0e 58 ae 4c 6e a0 1e 2d b8 8f 4f 58 c5 73 bf 03 06 f1 ce 3.r.^.Ce.T.w..X.Ln..-..OX.s.....
00e0 ca e9 ec 9d c7 14 7e 21 e1 67 b0 43 e8 50 f9 1a 9c 7d 3b ad f3 f8 62 a5 f6 23 50 b5 8e bd 3d ab ......~!.g.C.P...};...b..#P...=.
0100 19 7c c5 10 ba 71 09 97 31 8b 38 9a f7 1b ec 82 9d 3c e7 d8 a7 75 f4 7f 62 19 2f 2d 08 62 58 41 .|...q..1.8......<...u..b./-.bXA
0120 db 7e 82 f5 21 e5 fd 5b 16 70 47 3f db e7 12 9e e2 1a e6 b0 85 61 54 14 1b 70 4c 27 ef 85 26 ca .~..!..[.pG?.........aT..pL'..&.
0140 49 84 71 5b fb 66 5c a5 8e a9 d4 eb 2a 7b a8 98 80 ef f1 1a 95 79 ae 59 90 84 b2 9c d6 33 5c 54 I.q[.f\.....*{.......y.Y.....3\T
0160 59 ad ec a3 a8 db 4b 30 cb e8 a3 f5 58 81 eb 8d f8 a0 9b 5b c0 05 65 66 d5 58 d3 fe e4 5e 02 3e Y.....K0....X......[..ef.X...^.>
0180 d6 a9 eb 2a 70 fd 8c 4a fe 0d cf 54 89 49 8d b9 57 6a 9d 37 ff db d8 37 f1 48 7d d5 57 e0 7b 11 ...*p..J...T.I..Wj.7...7.H}.W.{.
01a0 95 33 ae 31 37 a4 40 51 f5 e4 86 2a 94 9d 46 e1 7c 37 39 8c 07 1a 53 23 d8 56 a9 ae e3 94 06 f7 .3.17.@Q...*..F.|79...S#.V......
01c0 71 9c 53 b0 b4 3e 9f 68 fa d8 49 9d d0 e8 4b 2b fb 01 b5 8f 1d ae 13 81 9c 69 11 d3 78 ca 38 6d q.S..>.h..I...K+.........i..x.8m
01e0 90 71 da 21 f7 77 bb e9 6f 67 ef 8f da 28 fb dd 94 0e de a6 b2 3f 96 9b e1 51 e7 85 da 26 ad 9a .q.!.w..og...(.......?...Q...&..
0200 26 d9 57 d0 86 fa 33 ac fd 88 06 43 8f fe ce 9c d6 5b e5 88 ee 5b 56 4c 8b 54 28 c0 15 b7 b1 f5 &.W...3....C.....[...[VL.T(.....
0220 cc 6b 4a ff 07 95 d6 81 ad bf 6f 81 8a 77 a7 06 80 e2 00 00 00 00 49 45 4e 44 ae 42 60 82 .kJ.......o..w........IEND.B`.
a id='n152' href='#n152'>152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
## 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.

- Kernel strings: null-terminated regions of memory. Unsafe and to be avoided,
  but needed for interacting with the kernel.

- 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`

- File descriptors (fd): Low-level 32-bit integers that the kernel uses to
  track files opened by the program.

- File: 32-bit value containing either a fd or an address to a stream (fake
  file).

- Buffered files (buffered-file): Contain a file descriptor and a stream for
  buffering reads/writes. Each `buffered-file` must exclusively perform either
  reads or writes.

- Graphemes: 32-bit fragments of utf-8 that encode a single Unicode code-point.
- Code-points: 32-bit integers representing a Unicode character.

### 'system calls'

Low-level testable primitives for unsafe SubX code.

- `write`: takes two arguments, a file `f` and an address to array `s`.

  Comparing this interface with the Unix `write()` syscall shows two benefits:

  1. SubX can handle 'fake' file descriptors in tests.

  1. `write()` accepts buffer and its size in separate arguments, which
     requires callers to manage the two separately and so can be error-prone.
     SubX's wrapper keeps the two together to increase the chances that we
     never accidentally go out of array bounds.

- `read`: takes two arguments, a file `f` and an address to stream `s`. Reads
  as much data from `f` as can fit in (the free space of) `s`.

  Like with `write()`, this wrapper around the Unix `read()` syscall adds the
  ability to handle 'fake' file descriptors in tests, and reduces the chances
  of clobbering outside array bounds.

  One bit of weirdness here: in tests we do a redundant copy from one stream
  to another. See [the comments before the implementation](http://akkartik.github.io/mu/html/060read.subx.html)
  for a discussion of alternative interfaces.

- `stop`: takes two arguments:
  - `ed` is an address to an _exit descriptor_. Exit descriptors allow us to
    `exit()` the program in production, but return to the test harness within
    tests. That allows tests to make assertions about when `exit()` is called.
  - `value` is the status code to `exit()` with.

  For more details on exit descriptors and how to create one, see [the
  comments before the implementation](http://akkartik.github.io/mu/html/059stop.subx.html).

- `allocate`: takes two arguments, an address to allocation-descriptor `ad`
  and an integer `n`

  Allocates a contiguous range of memory that is guaranteed to be exclusively
  available to the caller. Returns the starting address to the range in `eax`.

  An allocation descriptor tracks allocated vs available addresses in some
  contiguous range of memory. The int specifies the number of bytes to allocate.

  Explicitly passing in an allocation descriptor allows for nested memory
  management, where a sub-system gets a chunk of memory and further parcels it
  out to individual allocations. Particularly helpful for (surprise) tests.

### Functions

The most useful functions from 400.mu and later .mu files. Look for definitions
(using `ctags`) to see type signatures.

_(Compound arguments are usually passed in by reference. Where the results are
compound objects that don't fit in a register, the caller usually passes in
allocated memory for it.)_

#### 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-array-equal`: only arrays of ints, passes in a literal array in a
  whitespace-separated string.
- `check-stream-equal`: fails current test if stream doesn't match string
- `check-next-stream-line-equal`: fails current test if next line of stream
  until newline doesn't match string

Every Mu computer has a global trace that programs can write to, and that
tests can make assertions on.

- `clear-trace-stream`
- `check-trace-contains`
- `check-trace-scans-to`: like `check-trace-contains` but with an implicit,
  stateful start index

#### error handling

- `error`: takes three arguments, an exit-descriptor, a file and a string (message)

  Prints out the message to the file and then exits using the provided
  exit-descriptor.

- `error-byte`: like `error` but takes an extra byte value that it prints out
  at the end of the message.

#### numbers

- `abs`
- `repeated-shift-left`, since x86 only supports bit-shifts by constant values
- `repeated-shift-right`
- `shift-left-bytes`: shift left by `n*8` bits
- `integer-divide`

Floating point constructors, since x86 doesn't support immediate floats and Mu
doesn't yet parse floating-point literals:

- `rational`: int, int -> float
- `fill-in-rational`: int, int, (addr float)
- `fill-in-sqrt`: int, (addr float)

#### arrays and strings

- `populate`: allocates space for `n` objects of the appropriate type.
- `copy-array-object`: 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.

- `array-equal?`
- `substring`: string, start, length -> string
- `split-string`: string, delimiter -> array of strings

#### predicates

- `kernel-string-equal?`: compares a kernel string with a string
- `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
- `slice-ends-with?`: compares the end of a slice with a string

#### writing to disk

- `write`: string -> file
  - Can also be used to cat a string into a stream.
- `write-stream`: stream -> file
  - Can also be used to cat one stream into another.
- `write-stream-data`: stream -> file
  - Like `write-stream` but ignores read index.
- `write-slice`: slice -> stream
- `append-byte`: int -> stream
- `append-byte-hex`: int -> stream
  - textual representation in hex, no '0x' prefix

- `write-int`: int -> stream
  - write number to stream
- `write-int32-hex`: int -> stream
  - textual representation in hex, including '0x' prefix
- `write-int32-hex-buffered`: int -> buffered-file
- `write-int32-decimal`
- `write-int32-decimal-buffered`
- `write-buffered`: string -> buffered-file
- `write-slice-buffered`: slice -> buffered-file
- `flush`: buffered-file
- `write-byte-buffered`: int -> buffered-file
- `write-byte-buffered`: int -> buffered-file
  - textual representation in hex, no '0x' prefix
- `print-int32-buffered`: int -> buffered-file
  - textual representation in hex, including '0x' prefix

- `write-grapheme`: grapheme -> stream
- `to-grapheme`: code-point -> grapheme

- `write-float-decimal-approximate`: float, precision: int -> stream

- `new-buffered-file`
- `populate-buffered-file-containing`: string -> buffered-file

Unless otherwise states, writes to a stream will abort the entire program if
there isn't enough room in the destination stream.

#### reading from disk

- `read`: file -> stream
  - Can also be used to cat one stream into another.
  - Will silently stop reading when destination runs out of space.
- `read-byte-buffered`: buffered-file -> byte
- `read-line-buffered`: buffered-file -> stream
  - Will abort the entire program if there isn't enough room.

- `read-grapheme`: stream -> grapheme
- `read-grapheme-buffered`: buffered-file -> grapheme

- `read-lines`: buffered-file -> array of strings

#### non-IO operations on streams

- `populate-stream`: allocates space in a stream for `n` objects of the
  appropriate type.
  - Will abort the entire program if `n*b` requires more than 32 bits.
- `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.

#### reading/writing hex representations of integers

- `is-hex-int?`: slice -> boolean
- `parse-hex-int`: string -> int
- `parse-hex-int-from-slice`: slice -> int
- `is-hex-digit?`: byte -> boolean

- `parse-array-of-ints`
- `parse-array-of-decimal-ints`

#### 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. Mu supports a subset of
Unix terminal properties supported by almost all modern terminal emulators.

- `enable-screen-type-mode` (default)
- `enable-screen-grid-mode`

- `clear-screen`
- `screen-size`

- `move-cursor`
- `hide-cursor`
- `show-cursor`

- `print-string`: string -> screen
- `print-stream`
- `print-grapheme`
- `print-code-point`
- `print-int32-hex`
- `print-int32-decimal`
- `print-int32-decimal-right-justified`
- `print-array-of-ints-in-decimal`

- `print-float-hex`
- `print-float-decimal-approximate`: up to some precision

Printing to screen is stateful, and preserves formatting unless explicitly
manipulated.

- `reset-formatting`
- `start-color`: adjusts foreground and background
- `start-bold`
- `start-underline`
- `start-reverse-video`
- `start-blinking`

Assertions for tests:

- `screen-grapheme-at`
- `screen-color-at`
- `screen-background-color-at`
- `screen-bold-at?`
- `screen-underline-at?`
- `screen-reverse-at?`
- `screen-blink-at?`

- `check-screen-row`
- `check-screen-row-from`
- `check-screen-row-in-color`
- `check-screen-row-in-color-from`
- `check-screen-row-in-background-color`
- `check-screen-row-in-background-color-from`
- `check-screen-row-in-bold`
- `check-screen-row-in-bold-from`
- `check-screen-row-in-underline`
- `check-screen-row-in-underline-from`
- `check-screen-row-in-reverse`
- `check-screen-row-in-reverse-from`
- `check-screen-row-in-blinking`
- `check-screen-row-in-blinking-from`

#### keyboard

- `enable-keyboard-type-mode`: process keystrokes on `enter` (default mode)
- `read-line-from-real-keyboard`

- `enable-keyboard-immediate-mode`: process keystrokes as they're typed
- `read-key-from-real-keyboard`

#### tokenization

from a stream:
- `next-token`: stream, delimiter byte -> slice
- `skip-chars-matching`: stream, delimiter byte
- `skip-chars-not-matching`: stream, delimiter byte

from a slice:
- `next-token-from-slice`: start, end, delimiter byte -> slice
  - Given a slice and a delimiter byte, returns a new slice inside the input
    that ends at the delimiter byte.

- `skip-chars-matching-in-slice`: curr, end, delimiter byte -> new-curr (in `eax`)
- `skip-chars-not-matching-in-slice`:  curr, end, delimiter byte -> new-curr (in `eax`)

#### miscellaneous sensors and actuators

- `open`: filename, write? -> buffered-file

- `time`: returns the time in seconds since the epoch.

- `ntime`: returns the number of nanoseconds since some arbitrary point.
  Saturates at 32 bits. Useful for fine-grained measurements over relatively
  short durations.

- `sleep`: sleep for some number of whole seconds and some fraction of a
  second expressed in nanoseconds. Not having decimal literals can be awkward
  here.