Projects : gscm : gscm_genesis

doc/CHANGES

Dir - Raw

1Testing & debugging after completion of rewrite:
2
31. Read/write ordering bug in pop() -- returned top of stack after having
4already removed it. Needed to store to a temporary.
5
62. "return SC_NULL" instead of "RETURN(SC_NULL)" in reader. Considered renaming
7the macro, but by any other name it would still refer to the same concept and
8still be subject to confusion. Seems like a fundamental pun between C and the
9embedded stack machine language. Wouldn't happen in Scheme since there return
10is just something that happens to the last expresssion in a sequence, not a
11command.
12
133. Toplevel error handler seems to be getting run without an actual error.
14Replacing toplevel with more basic evaluation tests for now.
15
161 -> ERROR: apply: not a procedure: -945832504593831248
17
18 The error is correct (1 is not a procedure) but the display is wrong.
19 (Incorrect untagging?)
20
21 Problem was in parse_integer / parse_decimal. Before, I used a C heap based
22 dynamic buffer mechanism, which tracked buffer pointer, allocation size and
23 filled size in a struct. In the rewrite I converted this to a string on the
24 Scheme heap, but since that doesn't distinguish fill from allocation, I
25 tracked fill in the lexeme_length global variable. (Ugly, but this one
26 internal use didn't seem to justify a whole new Scheme type.) But in
27 porting the integer parsers I used the Scheme string's length (allocation)
28 rather than the global. The chief hazard seems to be the two notions of
29 length, and passing around this un-truncated buffer in the reader internals
30 for efficiency. Reviewed other use of R_LEXEME for similar problems,
31 finding none. Changed the number parsers to take length as an argument to
32 at least reduce use of the global.
33
34#(1 2 3) -> ERROR: apply: not a procedure: #()
35
36 Again, a correct error but bad read or print of the vector.
37
38 In the reader, the length header of the vector was being set after
39 the "len" variable had already been used to count down to zero.
40 Rather than building the vector "by hand" I replaced this with the
41 recently added make_vector_uninit function.
42
43 But this also revealed that the local variable "len" was being unsafely
44 used across a recursive call. Rather than push/popping it every time I took
45 it out of the loop to be computed later by list_length(). Except here we
46 already know the list is really a list, so I wrote a new unsafe_list_length
47 function to omit the type and cycle checks of list_length.
48
49(letrec () 1) -> ERROR: eval: empty combination
50
51 LETREC was passing the body to EVAL_BODY through R_EXPR instead of R_BODY.
52 (Missed during manual register optimization.) Verified the other call to
53 EVAL_BODY. This fixed #3.
54
554. A register conflict in the error handler, where r_error_handler was assigned
56to R_PROC, then R_ERR_DETAIL was referenced, but the latter two had been
57optimized to share a register. Solved by reassigning R_ERR_DETAIL to a free
58register. I did go to some pains to verify the register assignments but perhaps
59gave short shrift to the error handler. It would be a good exercise to do a
60full audit for register conflicts, once the code is a bit more settled. The
61rules for this are detailed in a comment.
62
635. Two bugs relating to list_length, which is supposed to return -1 for safely
64detecting non-lists. First, builtin_list_length stored its result in a "value"
65instead of a "long", which being an unsigned type, prevented recognizing the
66negative. Second, for odd length improper lists (e.g. (1 2 3 . 4)), the is_pair
67check after the first of the two "fast = cdr(fast)" pointer advancements in the
68loop returned directly, bypassing the "fast != SC_NULL" improper list check
69after the loop. This irregularity resulted from being overly preoccupied with
70(premature) hand-optimization (doing a single length += 2 after the two
71advances in each loop instead of a length++ after each one), a tendency I've
72had to fight in other places as well. (Chiefly, using the friendly type
73constructor and accessor functions, which tag/untag values as needed, rather
74than duplicating their functionality to save a few instructions on redundant
75tag operations. In this, it helped that I convinced myself, by examining the
76generated assembly, that the compiler optimizations really are smart enough to
77factor out the tag operations, at least in some cases, and at least with static
78functions.)
79
806. In SET, checked for cdr(R_EXPR) == SC_NULL after having overwritten the
81intended R_EXPR with car(R_EXPR). Swapped the order. (Discovered by running the
82"bad" semantic test set, but woulda come up soon enough anyway as it completely
83broke "set!".)
84
85(Later... somewhere around Jan 2017)
86
877. yes '(' | gscm -> inf loop between gc/error handler for out of memory.
88sc_error1 does a string() allocation to set R_ERR_MSG, but the stack doesn't
89get dropped until after the longjmp. Fixed by dropping stack in the error
90handler. Also wrote a toplevel error handler callable from Scheme implementing
91the same behavior using a captured continuation.
92
938. The "apply" builtin did not copy its final argument (a list). The standard
94doesn't seem to specify whether it should or not, but "list" is required to
95return a newly allocated list, and my no-op implementation was assuming its
96argument list was already a fresh copy. Wrote a test case and fixed by making
97builtin_apply copy. Also broken in tinyscheme. Affects what is probably the
98simplest way to copy a list, (apply list some-list).
99
100Major refactoring: compiler, variable references...
101
102October 2017:
103
1049. Register effect bugs in assoc and member builtins (see tests-misc.scm).
105
10610. Miscompilation of "delay" (see tests-misc.scm).
107
10811. The compiler was not immune to redefinition of builtins. (REPL too?)
109Implemented immutable environments with a separate copy for the interaction
110environment. Immutable string/list/vector constants still need doing.
111
112Implemented piped subprocess extension
113
11412. Realized input_port()/output_port() could leak the file object and
115descriptor if they hit an out of memory error.
116
117November 2017: fuzz testing
118
11913. Infinite loop in the lexer for EOF in a comment.
120
121Implemented CLI options, memory stats, floor/ceiling/truncate/round/port?
122
123January 2018:
124
12514. Heap discipline broken in arithmetic builtins on flonums by way of "fold"
126helper.
127
128April 2018:
129
130Partial implementation of the long-missing number->string and string->number
131builtins, enabling removal of a bunch of printfs.
132
13315. Discovered by inspection that the open_file helper was unsafely storing a
134port in a local variable across a call to string_append_null. Made it pass the
135port by register instead and refactored a bit.
136
13716. Realized that the changes implemented for #12 can't actually solve the problem;
138file objects and descriptors still leak if a subsequent unrelated call gets the
139memory error. Backed them out in order to simplify port construction.
140
14117. builtin_open_subprocess was a mess all around. Changed the interface,
142improved comments, simplified the temporary argv construction (resolving a
143strict aliasing warning), and tightened syscall error handling. As above,
144realized that leaking resources due to allocation failures is not a problem
145that can be solved within the scope of this function (so e.g. it's fine to
146allocate the return value list after the child is spawned).
147
14818. REPL now accepts multi-valued returns, printing them one per line.
149
15019. Extensions are now available in an immutable (gales-scheme-environment),
151analogous to (scheme-report-environment 5), in addition to the interaction
152environment. This allows for hygienic packages making use of the extensions
153without dependency injection. Probably useless flush-input-port removed. Some
154toplevel error handler setup inconsistencies fixed, but the error plumbing
155needs more scrutiny.
156
15720. Implemented double-width multiply functions, signed and unsigned, in
158portable C and x86_64 assembly, plus range checking and float conversion
159helpers. Used these to fix long-standing overflows in * and expt builtins.
160Implemented extensions for wrapped, carried and bitwise arithmetic on fixnums.
161Factored tagging macros out of machine-specific #if-blocks and tightened their
162types by casting. Need to finish correctness proof for signed wide multiply.
163
164May 2018:
165
16621. Fixed self-initialization bug in macro expansion in fx-/wrap builtin (and
167added -Winit-self to gcc flags). Added fx-/carry-unsigned and fxmaj builtins.
168Made some internal functions static. Added startup assertion to enforce the
169assumption that unsigned long matches the value / pointer size. Minor tweaks to
170build in C99 pedantic mode; would like to move toward C89.
171
17222. Implemented if-exists extension for open-output-file. Switched to "let"
173forms in toplevel. Made static symbol variable setup/usage more consistent.
174
17523. Core:
176- Catch I/O errors in flush_port, read_char and peek_char, simplifying spec for
177 flush-output-port builtin.
178- Light comment editing. Remove specification comments for nonstandard
179 builtins, which now have their own extensions document.
180- Make eqv? and equal? do the simpler checks first, short-circuiting deep
181 inspection where possible.
182- Rename quit builtin to exit.
183- Add a GC thrash factor (knob not exposed yet) to hasten OOM detection when GC
184 reclaims less than heap_size/factor space.
185- Wipe registers on OOM detection (previously just the stack was dropped in
186 sc_error1, with reason unclear).
187- Rename fallback error handlers to fatal/fatal1 for clarity.
188
189Core/compiler/toplevel:
190- Implement "error" as a normal builtin, parallel to sc_error1, making
191 set-error-handler! work for Scheme-signalled errors too and removing the
192 compiler's special error procedure with its null-terminator wrangling.
193- Remove syn-env from the special compiler environment as it can be handled
194 purely from Scheme.
195- Merge the compiler environment (now just one binding) into the privileged
196 toplevel environment.
197
198Toplevel:
199- Extend call-with-output-file and with-output-to-file to pass through the
200 if-exists option.
201- Make with-input-from-file and with-output-to-file restore the current ports
202 on escape or reentry, not required by spec but clearly the right thing.
203 (Using a stub dynamic-wind, so won't actually work yet.)
204- Fix all four of those to work with multi-valued returns.
205- Make REPL error handler support multiple detail arguments (though the other
206 components don't yet).
207
20824. Added sync and data-sync options to flush-output-port extension.
209Refactoring of port argument wranglers.
210
21125. Big move of builtins to library. Startup time and performance of the
212builtins in question is degraded, but much hazardous and hard-to-verify
213microcode is eliminated.
214
215Removed compiler dependence on builtin forms:
216 and
217 or
218
219Removed compiler dependence on builtin procedures:
220 append
221 apply
222 assq
223 for-each
224 list
225 list-tail
226 map
227 memq
228 vector->list
229 zero?
230
231Compiler now depends on some extensions and uses eq? for fixnum comparison, in
232hopes of reducing performance impact on replaced builtins.
233
234Merged the syntax library into the toplevel, removing some startup complexity
235and allowing the toplevel to use library syntax.
236
237Fixed some edge cases of the "case" macro.
238
239The "load" builtin, by way of exec-from-port, now reads the whole file before
240evaluating the forms.
241
242Forms moved from core to syntax library:
243 and
244 or
245
246Builtins moved to library:
247 list
248 append
249 reverse
250 list-tail
251 list-ref
252 memq
253 memv
254 member
255 assq
256 assv
257 assoc
258 vector->list
259 apply
260 map
261 for-each
262
263New privileged builtins:
264 apply/unchecked
265 car/unchecked
266 cdr/unchecked
267 set-cdr/unchecked!
268 vector-ref/unchecked
269 fx+/unchecked
270
271Wrote some tests for the new library procedures. Accelerated negative tests by
272replacing bash/sed gunk with a custom error handler to run all in one process.
273Moved the currently failing immutability test to the negatives and expanded.
274
275June 2018:
276
27726. Make "string-append" run in linear rather than quadratic time, fixing a
278FIXME. Make toplevel "apply" and "append" list copying helpers work tail
279recursively, by mutation in one pass as in the original C, reducing memory
280overhead.
281
28227. Implemented dynamic-wind by adding a "spool" register and a new field in
283continuation objects to capture it, the necessary additions to the APPLY
284subroutine (now separated into APPLY_CONTINUATION), and a lowest common
285ancestor helper function.
286
287Substantially refactored error handling in both core and toplevel to:
288* work with dynamic winding while avoiding infinite loops;
289* avoid some unnecessary C to Scheme string conversions;
290* remove string_append helper, a poor interface (per change 26);
291* support multiple detail arguments to ERROR, per SRFI-23;
292* be generally clearer, I think.
293
294Similarly, the EXIT extension is now implemented using a continuation that
295returns the given code from the toplevel (and sc_toplevel now returns the code
296to main). This both makes it support unwinding and removes the need for a
297builtin exposing exit(). (At some point it might be nice to eliminate remaining
298uses of exit(), but so far it's still needed as an error handling fallback.)
299
300Builtins moved to library:
301 string
302 string->list
303 vector
304 set-error-handler!
305 exit
306
307New privileged builtins:
308 push-winding!
309 string-ref/unchecked
310 set-error-continuation!
311
312Extension added to library:
313 error
314
315builtin_error still exists, but only for reporting startup errors before it's
316replaced by the toplevel.
317
318Fixed a few cases where pointers were being followed into the heap without
319untagging. This had gone unnoticed because the three tag bits happen to
320overflow in the shift for array indexing on 64-bit.
321
322Some minor clarity and error context improvements to library procedures.
323
324Renamed list_length/unsafe_list_length, to avoid giving the impression that
325safety can be assumed for these internal helper functions.
326
327Some C89ist shuffling of declarations.
328
329Optimized builtin_cons: reuse pair from arg list as it's freshly allocated.
330
331sc_toplevel now returns the integer exit code,
332
333TODO: think thorough / test what happens on error or other escape in
334unwinding/rewinding, explicitly unspecified by R5RS.
335
33628. Minor optimization: compile quoted empty lists and quoted vectors to the
337values themselves, as they're not valid expressions and thus can be made
338self-evaluating simply by removing the check. Deprioritize "quote" in the
339builtin syntax dispatch (based on pure guesswork as to frequency). 1% speedup
340observed in some existing tests, 5% in a contrived one.
341
342Condense some redundant register aliases (R_OPERATOR->R_EXPR;
343R_BODY->R_OPERANDS), avoiding some pedantic self-assignment.
344
34529. Fixed a subtle semantics bug in FORCE, and wrote test: a promise's code may
346be entered more than once if it forces itself recursively; if results differ,
347the first must not be clobbered. Found by re-reading rationale in R5RS.
348
349In the same spirit of "mutability is not your friend", reverted the
350builtin_cons optimization from #27. While safe, arglist mutation is premature
351at this point; for example it may hinder debugging, which ought to be a
352strength of an interpreter. If I do decide to allow it, there's a bunch of
353other builtins that could do it too. But a better optimization might be to
354avoid building arglists in the first place for fixed-arity builtins.
355
35630. New builtins, with tests:
357 immutable?
358 cons/immutable
359 string-copy/immutable
360 vector-copy/immutable
361
362Slightly simplified some related code.
363
364In previous immutability work, rather than expose new primitives I had the
365reader construct strings and vectors as immutable. This was neither correct nor
366useful. Literal constants are now properly petrified by the compiler, and with
367that, all my tests are finally passing.
368
36931. Mega-IO-refactor, replacing stdio with Scheme-managed buffering, and
370implementing sockets extension.
371
372Port-based write functions now all use R_PORT rather than an argument and
373signal errors rather than returning status. This tidies up the printer quite a
374bit.
375
376Checking for open port on each read/write no longer needed - the kernel's FD
377validity check is enough.
378- Added bonus: (close-output-port (current-output-port)) at REPL was a segfault
379 as the check had been missed in the fallback error handler. Now "FATAL: Bad
380 file descriptor".
381 - Should probably prevent closing stdin/out though. (close-input-port
382 (current-input-port)) at REPL is an infinite loop.
383
384Replaced posix_spawn* with vfork, simplifying builtin_open_subprocess, possibly
385making it fast on more platforms, and removing another likely malloc user.
386
387New privileged builtins operating at the file descriptor level:
388 inet-stream-socket
389 inet-dgram-socket
390 unix-stream-socket
391 unix-dgram-socket
392 socket-ports
393 getsockname
394 getpeername
395 connect-inet
396 connect-unix
397 listen
398 accept
399 close
400
401New library procedures:
402 open-tcp-connection
403 open-tcp-listener
404 open-udp-socket
405 open-unix-connection
406 open-unix-listener
407 open-unix-datagram-socket
408 call-with-tcp-connection
409 call-with-unix-connection
410 sequential-tcp-server
411 sequential-unix-server
412
41332. Fix assertion violation (buffer overflow) introduced in #31, when writing
414to a closed port, catching the error, then writing again.
415
416Relatedly, any other write errors on the underlying FD will now close the port.
417(Rationale: if recovery were possible, the underlying system should already be
418doing it, so write errors are generally permanent; even if not, they can be
419asynchronous so no way to know how much was successfully written.)
420
421REPL error handler changed back to restarting using a captured continuation. (I
422think I had removed this deliberately in #27 in the spirit of simplifying, but
423the result was the REPL exiting with error status on a normal ^D termination if
424an error had ever been caught, because error handlers aren't really supposed to
425return.)
426
427Ugly (define-r5rs 'foo (lambda ...)) forms changed to internal definitions
428followed by bulk registration, in the same manner as the extensions in #31.
429
43033. New builtin: char-ready?, made possible by direct access to input buffers.
431Stream sockets are made nonblocking to work around poll/select defects, but
432undetected blocking is still possible, e.g. reading from disk or if standard
433input is an externally provided socket.
434
435Builtin moved to library and tests added: equal?
436
43734. Libc in-sourcing:
438- Removed stdio from main.c and indirect use via assert
439- Removed last direct uses of malloc by replacing GC root linked list with an
440 array and heap creation with mmap, also enabling the hugepages option
441- Removed last indirect use of malloc via atexit
442- Replaced stdlib.h/string.h with individual declarations
443
444Made write_err handle EINTR/EAGAIN/EWOULDBLOCK, sharing with flush_output_port.
445
446July 2018:
447
44835. Start of library-level bignum support, including addition, subtraction,
449Comba multiplication, and automatic fixnum promotion and demotion. Using
450non-opaque values until the proper privileged interface is settled.
451
452It looks like the reader and printer will have to be done in Scheme now.
453(They'd have to make non-tail calls back into Scheme to do base conversion, and
454such C-level recursion is verboten.) So much the better for sanity and future
455rewrites of the core though. A pared-down bootstrap reader will be preserved.
456
457Core:
458- More assertions
459- Flush ports on abort (with re-entry check, as flushing itself has assertions)
460- Bignum awareness in number predicates
461- Start replacing car(cdr(x)) pattern with cadr macro
462
463Builtins moved to library: + - *
464
465New builtin: fx</unsigned
466
467New privileged builtins:
468 fx-/unchecked
469 fx=/unchecked
470 fxneg/unchecked
471 fxnegative/unchecked?
472 bignum?
473 flonum?
474 flonum/unchecked
475 floneg/unchecked
476 flo+/unchecked
477 flo-/unchecked
478 flo*/unchecked
479
480Renamed builtin: fx-/carry-unsigned to fx-/borrow-unsigned. (Makes more sense
481to me as the overflow output is 1, not -1.)
482
483Syntax library:
484- SRFI-8 RECEIVE syntax to simplify call-with-values. (LET-VALUES is nicer but
485 ugly to implement.) Ideally this wouldn't be visible in the R5RS environment.
486- Fix quirk where COND with no successful tests returned #f rather than the ()
487 I'm generally using for "unspecified". This also worked around the compiler
488 bug that caused it to reject a literal #f as the final test.
489
49036. Serious bugfix: missed making the spool register a GC root in #27.
491
492Minor bugfixes:
493- Proper PEEK-CHAR semantics for devices with transient end-of-file e.g. tty.
494- Detect excess arguments in the helper macro for unary character functions.
495
496New builtin: read-token
497
498New privileged builtin: reverse-list->vector/unchecked
499
500Builtins moved to library: read string->number
501
502The full range of numeric syntax is now supported except for rational and
503complex: alternate radix (2/8/10/16), radix and exactness prefixes, exponents
504and sharped-out digits (though significant figures aren't actually tracked).
505Bignums come "for free", though base conversion is the naive quadratic
506algorithm.
507
508Simplified the (now) bootstrap number decoder by removing float syntax and
509promotions.
510
511Internal tweaks to the lexer and (now) bootstrap reader to support read-token.
512Also loosened the overly anal interpretation of allowed whitespace.
513
514Started downcasing labels (all-caps doesn't really serve a purpose and risks
515interference from libc extensions).
516
51737. Bignum division, conversion to flonum and output.
518
519Bugfix: bignum negation failed to demote in the case of *LEAST-FIXNUM*.
520
521Minor optimization: avoid some unnecessary untagging in fixnum ops.
522
523Builtins moved to library:
524 zero?
525 positive?
526 negative?
527 abs
528 quotient
529 remainder
530 modulo
531 exact->inexact
532 number->string
533 write
534 display
535 newline
536
537In addition to bignum support, quotient/remainder/modulo now properly maintain
538inexactness for flonum inputs, though can produce inf/nan.
539
540In the Scheme rewrite of the printer, I realized the special save/restore of
541current ports for error recovery is unnecessary now that dynamic-wind is taking
542care of it (they can't be set directly by user code).
543
544New library procedures: gcd lcm
545
546New builtins: fx= fx< fx<= fx<=/unsigned fxlength/unsigned
547
548Renamed builtin: fxshift-unsigned to fxshift/unsigned
549
550New privileged builtins:
551 fxdiv/unchecked
552 fxdiv/ext/unchecked
553 fixnum->dec/unchecked
554 fixnum->hex/unchecked
555 fixnum->oct/unchecked
556 fixnum->bin/unchecked
557 flonum->dec/unchecked
558 flonum/unsigned/unchecked
559 flodiv/unchecked
560 floquotient/unchecked
561 floremainder/unchecked
562 builtin?
563 builtin-name
564 promise?
565 continuation?
566
56738. Full bignum integration.
568
569Serious bugfix: (QUOTIENT *LEAST-FIXNUM* -1) => *LEAST-FIXNUM*
570(On the first pass for #37 it didn't occur to me that signed fixnum quotient
571had an edge case besides zero divisor. The equivalent problem existed in the
572prior C-only implementation, or possibly worse as C leaves negative division
573implementation-defined.)
574
575Builtins moved to library:
576 eqv?
577 = < > <= >=
578 odd? even?
579 max min
580 /
581 floor ceiling truncate round
582 exp log
583 sin cos tan
584 asin acos atan
585 sqrt
586 expt
587 inexact->exact
588
589Bignums now opaque and supported by all generic operators. Unlike the fixnum
590and flonum ops, which could also exist as unprivileged extensions, the bignum
591primitives are implicitly unchecked. In addition to bignum support, the
592irrational functions now handle some special cases for exactness e.g. zero (as
593encouraged but not required).
594
595New privileged builtins:
596 toplevel-environment
597 set-car/unchecked!
598 fx</unchecked
599 fx<=/unchecked
600 fixnum->bin/unsigned/unchecked
601 flo=/unchecked
602 flo</unchecked
603 flo<=/unchecked
604 fraction/exponent/unchecked
605 load-exponent/unchecked
606 inf/unchecked?
607 flonum->fixnum/unchecked
608 floor/unchecked
609 ceiling/unchecked
610 truncate/unchecked
611 round/unchecked
612 exp/unchecked
613 log/unchecked
614 sin/unchecked
615 cos/unchecked
616 tan/unchecked
617 asin/unchecked
618 acos/unchecked
619 atan/unchecked
620 atan2/unchecked
621 sqrt/unchecked
622 make-bignum
623 bignum?
624 bignum-negative?
625 bignum-set-negative!
626 bignum-ref
627 bignum-set!
628 bignum-length
629 bignum
630 bignum/unsigned
631 bignum2
632 bignum-truncate!
633
634Renamed privileged builtins:
635 fxdiv/unchecked -> fxdiv/unsigned/unchecked
636 fxdiv/ext/unchecked -> fxdiv/ext/unsigned/unchecked
637
638(They were already unsigned; I think I'd been trying to avoid the crazy long
639names, but it was a hazard.)
640
641Core:
642- Grabbed the last extended type slot to fit the bignum sign bit
643- Type assertions added to fixnum_val, new counterpart unsigned_fixnum_val, and
644 flonum_val, expanding coverage while reducing boilerplate
645- Bounds check assertion added to vector_ref and vector_set
646- With flonum coercion headaches out of core, finally replaced safe_fixnum_val
647 and exact_fixnum_val with something simple and correct
648- is_number optimized based on extended number type tag values being contiguous
649- is_integer made possibly more standard conformant by using ROUND (nearbyint)
650 instead of FLOOR for flonums (don't see how this could make a difference but
651 neither am I sure it can't)
652- Made shallow_print report particular environment specifiers, the internal
653 specials, immutability, and vector lengths
654- make_str and make_vector size checks simplified based on the unsigned trick
655
656Compiler:
657- Removed fairly useless vector support from macro language
658- Fixed old bug: improper rejection of macros expanding to #f
659- Removed trivial dependency on generic <
660- Switched to storing error context as symbol, avoiding SYMBOL->STRING calls in
661 the normal case
662
663Toplevel:
664- Pretty "evaluates to" symbol prefixing REPL results
665- Tracing for library procedure calls, allowing removal of the growing sprawl
666 of ad-hoc error context reporting
667- Filled in stubs for bignum to hex, octal and binary conversion
668- Handled bignum status in EXIT by remaindering there rather than in core
669
670asm-generic:
671- Replaced "seems right but can't prove" implementation of signed double-width
672 multiply with ugly but more obvious method
673
674August 2018:
675
67639.
677Serious bugfix: plug leaks of uncompiled subtrees in named LET and DO, while
678simplifying, by feeding the full expansions back through compilation as is done
679for ordinary macros. (Less seriously, the same for lambda annotation in plain
680LET, at worst a performance issue.)
681
682Core:
683- Add is_port assertions to R_PORT-based I/O routines
684- Remove unnecessary variable pre-check in SET, allowing resolve_variable_ref
685 to operate on unresolved refs only, saving a few branches
686- Remove fairly pointless and expensive is_list assertion in EVAL
687- Remove redundant is_fixnum assertion from builtin_make_bignum
688
689Compiler:
690- More consistently unquote self-evaluating objects
691- Reject non-readable objects (possible through EVAL)
692
693Syntax library:
694- OR: optimize by avoiding unnecessary temporary binding (multiple evaluation
695 is safe for non-list expressions as they're all side-effect free and O(1))
696- Explain how the hardcoded temporary names are safe
697- COND: simplify by handling the temporary binding case with OR
698- CASE: optimize by using EQV? instead of MEMV for the single-datum case
699
70040.
701Core/compiler:
702- Prevent integer overflows by limiting parameter list length (number of
703 bindings per lexical frame)
704- Save a word in the procedure object and a pair in the annotated lambda form
705 by encoding variadic status in the sign of the arity
706
707Core:
708- Avoid possibly undefined overflow behavior in untag_signed by doing the left
709 shift as unsigned
710- Note a hazard in add_tag/ext_add_tag and audit
711
712Compiler:
713- Slight simplifications/optimizations: filterize CHECK-IDENT; avoid repeated
714 SYMBOL->STRING in duplicate search
715
71640.maint1.
717
718Starting a maintenance branch as the crucial variable lookup optimization has
719not yet made it back after the compiler overhaul of revision 41.
720
721Core:
722- Remove assertions in stack ops, redundant since adding type assertions to
723 car/cdr long ago
724- Remove invalid assertion added in r39: input_port_ready doesn't use R_PORT
725- Remove mostly redundant is_list assertions in the full environment lookups
726
727March 2020:
728
72940.maint2.
730
731Overall:
732- Restructure tree for slashpackage
733- Trim Makefile
734- Write install + check scripts and README
735
736Main (backports):
737- Make default heap size build-time tunable (isolating magic numbers)
738- Report build configuration in help text
739- Remove "strtol" stdlib dependency
740
74140.maint3.
742
743Bulk reindent & reflow.
744- Tabs: good
745- Non-meaningful newlines in human text: bad
746- "if" as a special "lisp word" producing less indentation: bad
747- Code width: mostly sticking to 80 columns