This commit is contained in:
Kartik K. Agaram 2021-03-09 00:24:03 -08:00
parent cec5ef31b3
commit a77643c66a
2 changed files with 27 additions and 45 deletions

View File

@ -31,14 +31,7 @@ compatibility with the past. ([More details.](http://akkartik.name/akkartik-conv
Tests are a key mechanism here for creating a computer that others can make
their own. I want to encourage a style of active and interactive reading with
Mu. If something doesn't make sense, try changing it and see what tests break.
Any breaking change should break some well-named test somewhere. This requirement
implies that any manual test should be easy to turn into a reproducible
automated test. Mu is a testbed for providing this guarantee. It exposes
testable interfaces for hardware using dependency injection so that tests can
run on -- and make assertions against -- fake hardware. It also is an experiment
in [automated white-box testing](http://akkartik.name/post/tracing-tests)
which promises robust tests for performance, concurrency, fault-tolerance,
etc.
Any breaking change should cause a failure in some well-named test somewhere.
Currently Mu requires a 32-bit x86 processor.
@ -61,6 +54,14 @@ In priority order:
- Memory leaks over memory corruption.
- Teach the computer bottom-up.
Thorough test coverage in particular deserves some elaboration. It implies
that any manual test should be easy to turn into a reproducible automated
test. Mu has some unconventional methods for providing this guarantee. It
exposes testable interfaces for hardware using dependency injection so that
tests can run on -- and make assertions against -- fake hardware. It also
performs [automated white-box testing](http://akkartik.name/post/tracing-tests)
which enables robust tests for performance, concurrency, fault-tolerance, etc.
## Non-goals
- Speed. Staying close to machine code should naturally keep Mu fast enough.
@ -102,13 +103,15 @@ Mu programs can be written for two very different environments:
(under emulation; I haven't tested on native hardware yet). There's just a
screen and a keyboard, and that's it. No mouse, no hardware acceleration, no
virtual memory, no process separation, no multi-tasking, no persistent
storage, no network.
storage, no network. All tests run on boot. `main` only runs if all tests
pass.
* The top-level is built using tools created under the `linux/` sub-directory.
This sub-directory contains an entirely separate set of standard libraries
intended for building programs that run with just a Linux kernel, reading
from stdin and writing to stdout. The Mu compiler is such a program, at
`linux/mu.subx`.
`linux/mu.subx`. Individual programs typically run tests if given some
commandline argument like `test`.
While I currently focus on programs without an OS, the `linux/` sub-directory
is fairly ergonomic. There's a couple of dozen example programs to try out

View File

@ -49,14 +49,7 @@
### 'system calls'
As I said at the top, a primary design goal of SubX (and Mu more broadly) is
to explore ways to turn arbitrary manual tests into reproducible automated
tests. SubX aims for this goal by baking testable interfaces deep into the
stack, at the OS syscall level. The idea is that every syscall that interacts
with hardware (and so the environment) should be *dependency injected* so that
it's possible to insert fake hardware in tests.
But those are big goals. Here are the syscalls I have so far:
Low-level testable primitives for unsafe SubX code.
- `write`: takes two arguments, a file `f` and an address to array `s`.
@ -89,12 +82,6 @@ But those are big goals. Here are the syscalls I have so far:
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).
- `new-segment`
Allocates a whole new segment of memory for the program, discontiguous with
both existing code and data (heap) segments. Just a more opinionated form of
[`mmap`](http://man7.org/linux/man-pages/man2/mmap.2.html).
- `allocate`: takes two arguments, an address to allocation-descriptor `ad`
and an integer `n`
@ -108,22 +95,6 @@ But those are big goals. Here are the syscalls I have so far:
management, where a sub-system gets a chunk of memory and further parcels it
out to individual allocations. Particularly helpful for (surprise) tests.
- `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.
- ... _(to be continued)_
I will continue to import syscalls over time from [the old Mu VM in the parent
directory](https://github.com/akkartik/mu), which has experimented with
interfaces for the screen, keyboard, mouse, disk and network.
### Functions
The most useful functions from 400.mu and later .mu files. Look for definitions
@ -180,8 +151,8 @@ doesn't yet parse floating-point literals:
#### arrays and strings
- `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.
- `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.
@ -189,8 +160,6 @@ doesn't yet parse floating-point literals:
- `substring`: string, start, length -> string
- `split-string`: string, delimiter -> array of strings
- `copy-array-object`
#### predicates
- `kernel-string-equal?`: compares a kernel string with a string
@ -363,6 +332,16 @@ from a slice:
- `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`)
#### file system
#### 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.