The Mu shell has no string literals, only streams. No random access,
only sequential access. But I've been playing fast and loose with its
read pointer until now. Hopefully things are cleaned up now.
Refreshing the fake screen is still a heavyweight operation. Double-buffering
makes it less obvious but doesn't actually reduce the amount of work. We
need to ensure that we do enough work between refreshes to make them economic.
Font rendering now happens off the real screen, which provides the effect
of double-buffering.
Apps can now also use convert-graphemes-to-pixels for more traditional
double-buffering.
Rename cells containing screens to screen vars because of the ambiguity
that each grapheme in fake screens is represented by a type screen-cell.
While we're at it, we also analogously rename keyboard vars.
I wrote a comment about how some code was not covered by tests, and then
promptly forgot what it was for. This is why we need tests.
Now the hack is gone.
It turns out (bowboard screen 128) on a real screen massively slowed down
and ran out of memory since commit e2ab1b30b1 on May 19. The culprit was
these changes, which created memory allocations for a new trace on every
recursive call.
I originally had some vague desire to isolate these calls from the user-visible
trace. That's expensive enough that I'll wait until it becomes a concern
before trying to isolate again.
Now that we never have a null trace, tracing errors is always safe. And
now that we're running with low trace max-depth we're more likely to run
into problems with missing errors in the trace.
We now use traces everywhere for error-checking. Null traces introduce
the possibility of changing a functions error response, and therefore its
semantics.
Another commit, another bugfix.
Some snippets from my currently exploding todo list:
- always investigate lookup errors immediately. Beyond the root cause, they should never happen at the moment, while we aren't reclaiming memory.
we should always return a more precise error message. Usually involving null pointer checks.
- on abort, print out stack trace
- emit mapping of labels to addresses during survey
- store a mapping of symbols somewhere in the code image
- stop allocating 1KB per token; expand space for tokens as needed
Current plan:
- some way to define macros. For now:
(def f (litmac litfn () (a b) `(+ ,a , b)))
- macroexpand will expand calls by passing them through the cdr
(f 3 4)
macroexpand: ((litfn () (a b) `(+ ,a ,b)) 3 4)
=> (+ 3 4)
eval: (+ 3 4) => 7