clean up internals of lispm.c
it's Sunday cleanup time!
git: commit
I moved all the bits hackery to internal-obj.h, and optimized the code
size such that it fits back into 4K limit, taking 4082 bytes according
to make stat with my GCC version. This time I left more extended
explanation in the branch commits.
verbose branch logs
-
[6061537b] avoid unnecessary round trip through quote
Previously I turned the parsed empty list and numeric value into an instruction to quote them. The
eval()would then reduce the(CONS QUOTE val)to(CONS () val), and then returnval. Notably, this extra step of reducingQUOTEis not needed, and we can generate the(CONS () val)instruction at the semantic analysis phase. -
[a679f6d2] introduce internal-obj.h
I extract all the bit-tagging hackery from lispm.c to a separate internal header file. I also noted a typo in internal-macros.h filename.
Another significant change is the rework of free/bound distinction. I rephrase it in terms of integer comparisons:
- forall p q. BOUND_REC(p) > BOUND(q) && BOUND_REC(p) > FREE(q)
- forall p. BOUND_REC(p+1) > BOUND_REC(p) && BOUND(p+1) > BOUND(p) && FREE(p+1) > FREE(p)
- forall p. BOUND_REC(p) > BOUND(p) > FREE(p)
Then lex_frame_use overwrites the current association only if it is larger than the previous association.
Frame depth handling got trickier. I want to avoid the
lispm_shortnum_val()calls inevframe_set(). This means that I need to store a shortnum inM.frame_depthduring evaluation. For this reason I always keep a shortnum in this field, however:eval()treats this depth as a shortnum; whereassema()treats this depth as a regular unsigned value. That is because I expecteval()can causesema()through a recursivelispm_eval0()call caused by an extension, but I don’t expect any semantic analysis function to calleval(). I also addedframe_depth_guard()to verify in assertions mode that bothsema()andeval()restore the frame_depth upon exit.
A minor change is that I got rid of
lispm_is_valid_result()check. I let the user decide which results they consider valid. -
[20761412] make lispm_init() non-throwing
Since this function is not expected to be guarded by
lispm_rt_try(), it should not throw. This means thathtable_ensure()must return an error status.I took this opportunity also to simplify the interaction between lexer and
htable_ensure(). Now lexer always puts the currently read literal atM.tpposition and makes it NUL-terminated, whereashtable_hashandhtable_ensurerely on this convention.