4.2 KiB
A prototype shell for the Mu computer
Currently runs a tiny dialect of Lisp. Steps to run it from the top-level:
- Build it:
./translate shell/*.mu # generates code.img
You can now already run it (under emulation):
qemu-system-i386 code.img
But let's add some more 'meat' to play with.
- Create a data disk with a library of functions.
dd if=/dev/zero of=data.img count=20160
cat shell/data.limg |dd of=data.img conv=notrunc
Run with data disk (and 2GB of RAM):
qemu-system-i386 -m 2G -hda code.img -hdb data.img
The Mu computer has a fixed-size screen, which the shell environment partitions into two major regions, with a context-sensitive menu of keyboard shortcuts along the bottom. (No mouse support at the moment.) On the left, two-thirds of the screen is for editing functions and viewing documentation on available primitives. On the right is a REPL where you can try out expressions and see their output. The REPL also has a little toy screen and keyboard for interactively playing with side effects of expressions.
Try typing in some expressions at the REPL and hitting ctrl-s
to see their
results. Hit ctrl-m
to focus on the ...
after a run, and browse how the
trace of how the results were computed. Here's a 2-minute demo.
- If your Qemu installation supports them, one of these commandline arguments may speed up emulation:
-enable-kvm
-accel ___
(run with-accel help
for a list of available options)
If you do this, I recommend also adjusting the responsiveness
mask in
shell/evaluate.mu, which controls how frequently the fake screen updates.
Smaller values will seem more responsive, larger values will leave more time
to run your programs. I like to see the screen update about once a second.
Some suggested values depending on how fast your Qemu is running:
-enable-kvm
on a T420s running Linux:0xffff/responsiveness=64k
-accel tcg
on a 2019 Mac:0xfff/responsiveness=4k
Putting it all together, here's the command I typically use on Linux:
qemu-system-i386 -m 2G -enable-kvm -hda code.img -hdb data.img
Indent-sensitivity
The Mu shell is a Lisp under the hood. However, you'll see a lot fewer parentheses than most Lisps because it can often automatically insert them based on indentation.
If you're already used to Lisp and always type in all parens, everything will
continue to work. In particular, paren-insertion is disabled inside explicitly
added parens. Once Mu sees a (
, it stops trying to be smart until it sees a
)
.
I recommend tastefully only removing parens from top-level (def
, mac
,
define
) and control-flow words (if
, while
, for
, etc.) Continue using
parens for most real function calls. When in doubt, insert parens.
The rule for when parens are inserted is:
Multi-word lines without leading parens are implicitly grouped with later indented lines
For example:
if (> n 0) => (if (> n 0)
34 34)
No indented lines after? Parens go around a single line:
f a => (f a)
f b (f b)
Lines with a single word are never wrapped in parens:
def (foo) => (def (foo)
42 42)
Lines with a leading paren never get more parens:
def (foo x) => (def (foo x)
(print x) x (print x) x)
Putting these rules together, parens are not required around the if
in:
if (= 1 (% x 2))
'odd
'even
Known issues
-
No mouse support.
-
Don't press keys too quickly (such as by holding down a key). The Mu computer will crash (and often Qemu will segfault).
-
Mu currently assumes access to 2GB of RAM. To increase that, modify the definition of
Heap
in 120allocate.subx, and then modify the-m 2G
argument in the Qemu commands above. Mu currently has no virtual memory. If your Heap is too large for RAM, allocating past the end of RAM will succeed. However, accessing addresses not backed by RAM will fail with this error:lookup: failed