From http://erights.org via https://github.com/darius/squeam
- a simple memory allocator, assuming we rarely free: http://akkartik.github.io/mu/blob/5a68894ca/subx/066allocate.subx
- a sketch of safe pointers for a later compiler of a C-like language: http://akkartik.github.io/mu/blob/5a68894ca/subx/apps/handle.subx
- compiled a fairly small Linux kernel and ran SubX with it on Qemu. Still need to get it booting a real laptop and VPS. Also, /dev/fb0.
- light background for my terminals! And for the above code renderings.
Next up: compiling SubX in SubX. Phase 1 is done: translating text hex bytes into binary http://akkartik.github.io/mu/blob/5a68894ca/subx/apps/hex.subx.html. 1700 lines, but sub 200 lines/instructions excluding tests and comments.
Phase 2: packing operand bitfields into bytes.
Phase 3: translating labels. *That* will be interesting, without a hash table for strings.
It took some doing to make them look ok on my 256-color terminal, but also pass the WCAG contrast checker. (They barely do.) Tell me what you think.
What the different colors signify:
https://github.com/akkartik/mu/blob/c6f522007/subx/Readme.md
Well, I just ported that one line (and the page of helpers backing it) to my own assembly lang, and it only took me 2 months to do it 😂
In my defense: a) It's *thoroughly* unit-tested asm, and b) I had to rethink the design of a couple of OS syscalls to make them testable.
https://github.com/akkartik/mu/blob/3b6fcde4f/subx/Readme.md
SubX now supports code in multiple files. Segments with the same name get merged.
One subtlety: later code is *prepended* to earlier code. Gives us executable libraries with overrideable entrypoints.
$ git clone https://github.com/akkartik/mu
$ cd mu/subx
$ ./subx translate *.subx -o out
$ ./out # run tests
$ ./subx translate *.subx apps/factorial.subx -o out
$ ./out; echo $?
120 # factorial(5)
$ ./out test # run tests
https://github.com/akkartik/mu/blob/29ab43973a/subx/Readme.md
We also now have the ability to allocate new segments in virtual memory using mmap()
. The first new segment I plan on is a 'trace' segment that tests can write to and make assertions on. Automated white-box testing.
Next up, once I have some tracing primitives: a dependency-injected interface for sockets so that we can write automated tests for a fake network.
SubX now has a test harness, and support for string literals.
Current (increasingly silly) factorial program to compare with the parent toot: http://akkartik.name/images/20180923-subx-factorial.html
Two new features:
a) Autogenerated `run_tests` (line 26) which calls all functions starting with 'test_'.
b) String literals (line 31). They get transparently moved to the data segment and replaced with their address.
https://github.com/akkartik/mu/blob/37d53a709/subx/Readme.md
There's only one problem: I don't know how to build a compiler. Not really. And definitely not in machine code. So I'm going to be fumbling around for a bit. Lots more wrong turns in my future.
I've been trying to port the Crenshaw compiler to SubX. With tests. It's been slow going, because I have to think about how to make Crenshaw's primitives like Error()
and Abort()
testable.
I don't know if just learning to build a compiler will sustain my motivation, though. So some other ideas:
a) Some sort of idealized register allocator in Python or something. I've never built one, and my intuitions on how hard it is seem off.
b) Port Mu's fake screen/keyboard to SubX so that I can reimplement https://github.com/akkartik/mu/tree/master/edit#readme. It was just too sluggish since Mu was interpreted. Even my 12-year-old students quickly dropped it in favor of Vim.
I've also made labels a little safer, so you can't call to inside a function, or jump to within a different function: https://github.com/akkartik/mu/blob/7328af20a/subx/037label_types.cc
Next stop: socket syscalls!
https://github.com/akkartik/mu/blob/7328af20a/subx/Readme.md
As I build up the ladder of abstractions I want to pull up the ladder behind me:
a) Unsafe programs will always work.
b) But unsafe programs will always emit warnings.
As long as SubX programs are always distributed in source form, it will be easy to check for unsafe code. Coming soon: type- and bounds-checking.
https://github.com/akkartik/mu/tree/76aace4625/subx
Concretely, SubX lines can get long, and the comment at the end is often far away and hard to line up visually with the instruction it's referring to. The solution: dot leaders[2].
https://github.com/akkartik/mu/tree/55b4627de1/subx
[1] Originally in the context of Lisp: https://github.com/akkartik/wart/commit/c2e6d0c6d3
[2] https://www.w3.org/Style/Examples/007/leaders.en.html
http://akkartik.name/images/20180730-subx-factorial.html
Ok, I think I understand calling conventions now.
Also coming face to face with the pain of debugging machine code 😀
https://github.com/akkartik/mu/commit/62c6d1638a