Copyright 1998 Lars T Hansen.                -*- Indented-Text -*-

$Id: TODO 2917 2006-04-27 21:25:06Z tov $


			Grand Unified TO-DO List


This is the Grand Unified To-do List for Larceny, and lists all desired
features and fixes I know of, except actual bugs (see the file BUGS) and
large projects (see the file TODO-RAINYDAY).

** = High priority.
 * = Normal priority.
 + = Ultra-low priority.


----------------------------------------------------------------------

Possibly subtle bug: if the standard library uses EVAL internally,
then it must be careful about which macro environment and variable
environment it picks up.

Currently the only internal use of EVAL is in the macro expander and
it simply uses it to convert a transformer expression to a procedure.


----------------------------------------------------------------------

Miscellaneous
 * SPARC larceny does not currently compile with LCC because LCC
   picks up LCC header files rather than system header files.  
   Larceny requires the system header files for the native system
   (for proprietary signal handling extensions).  It is no doubt
   possible to tell LCC about the system header files, although 
   they may not conform to ANSI C.
 * Need to rename some files:
     Util/std-heap.sch    ->   Util/larceny-heap.sch
     Util/init-comp.sch   ->   Util/larceny-heap-init.sch
 * From Will:
     >Compiler/pass2.aux.sch and Lib/procinfo.sch both contain magic
     >constants, accessors, and setters for the documentation slot.
     >This information should exist in only one place, and it has to
     >be part of the development environment.
 * Must create a larceny mailing list archive and a convenient way of
   adding stuff to it.
 * FASL format: both Petit Larceny and SPARC larceny FASL files have
   type .fasl, but they have different structure.  One way of coping 
   with this (to reduce errors) is to have an initial expression
   in each FASL file:
	(.fasl-type 'sparc)
   or
	(.fasl-type 'standard-c)
   where the definition of .fasl-type could be
	(define (.fasl-type x)
	  (eq? x (cdr (assq 'architecture-name (system-features)))))
   if system-features is fixed to return not a string but a symbol
   for the architecture name.
 * Heap images should contain information about binary format in
   addition to version, eg, PETIT-BE, PETIT-EL, SPARC-NATIVE, ..., and
   should also encode the control transfer method used for Petit Larceny
   -- libpetit.so needs to be built with the appropriate #define.
   The first word of the image needs to be in a fixed endianness.

Development system & compiler
 * Make-development-environment does not compile the .imp.sch file
   for other targets than the current.  This should not be a problem
   once the build system is up to snuff.  (See separate section.)
 * Extend compile313 and others to record file name and position;
   see section on debugging.
 * Change the syntax of MAL files so that _eval_ is not required; 
   hack assembler drivers correspondingly.
 * The definition of PROC_HDR is wrong because the tag bits are all
   set rather than all cleared.
 * Lib/makefile.sch:
   - There are still Unix-dependent path names; if you use the make 
     facility with a non-Unix OS, there will be problems.  This can
     be fixed w/o too much trouble.  Don't fix this yet, as checkins
     from many places will take care of it.
   - We need to use nbuild-files more extensively to set up file lists.
  * Assemble-file is only so-so useful in larceny.heap because it can't do
    MAL files -- the MAL names are not bound, and EVAL is used.  We can
    either:
      - bind the MAL names -- gratuitous namespace pollution.
      - change the MAL syntax to be all-symbolic -- attractive.
      - remove the binding of assemble-file -- it really only belongs
        in the development environment anyway.
      - elaborately hack assemble-file to create an environment that
        contains the MAL names and use this for EVAL -- way too elaborate.

Build system:
 * Configuration mechanism:

   With Petit Larceny, configuration becomes complicated, because it's 
   supposed to run on a number of operating systems; indeed, since it
   doesn't need much OS support, it would be silly if the configuration
   mechanism restricts how the system is moved.  At the same time, it's
   useful to make configuration as convenient as possible, so some 
   systems should be supported as special cases.  The major classes of
   systems are:

     Unix   -- many variations, but we can use GNU autoconf
     Win32  -- only a few variations (WinNT, Win95, Win98, Win32s); how
               do we handle this?
     MacOS  -- only a few variations (OS6 vs OS7 vs OS8 vs ...); how do
               we handle this?

   One can _always_ hack Rts/Sys/config.h.

 * Setup mechanism: Right now we have "make setup_<HOST>".  In the same
   way that the configuration system is being restructured to not allow
   rebuilding for a different architecture without re-configuration, it 
   would make sense for setup to hardwire a lot more things than it 
   hardwires right now.  This is particularly so because it makes things 
   easier overall.  Thus we should not run "make setup" but rather, on 
   Unix systems,  

      build -setup target=sparc os=sunos4 host=larceny
      build -setup target=ppc   os=... host=...
      build -setup target=petit-el-32 os=... host=...

 * Right now there is one set of config files in Rts/, but this set 
   depends on the target architecture, so we need to fix that when we
   have more target architectures.

Twobit
  * Clean up mess around primitives that are rewritten by compiler
    but also coded in millicode (abs, positive?, negative?).
  * Generate only as long documentation structures as needed.
  * Real implementation of multiple values
  * Need inline procedures and constant folding for fixnum operations.
  * Need inline procedures and constant folding for flonum operations.
  * Should rename `define-inline' as `define-compiler-macro', because
    `define-inline' is much more useful as a proper inline-procedure
    definer.  The current define-inline has the wrong semantics for
    everyday use (it can be made to evaluate its arguments more
    than once, or not at all).
  * Need a way to restrict primitive tables to a given set.

Foreign-function interface
  * Standard-FFI
    - STD-FFI is not portable between SunOS 4 and SunOS 5, thus
      there must be a set of heap images for each operating system.  We
      can fix this by loading both FFIs and using the FFI
      restore-handler to setup the correct interface based on the OS.
      I doubt it's worth the hassle, as in general, different OSs will
      have different capabilities, thus different heaps.
    - Consider changing the semantics so that foreign-file loads the 
      foreign file immediately -- gives better opportunities for error 
      messages.
    - We want an FFIGEN back-end.
  * Lowlevel FFI
    - Clean up Larceny Note #7 -- incorporate Ffi/README, and finish
      the writeup.  This is a biggish job.
    - Inspect the code and clean it up -- it grew quickly.
  * Heap dump/restore
    - FFI should exit if errors are discovered in the relinking phase.
  * Callbacks
    - finish implementation
    - call/cc must work right (to handle errors correctly in callbacks)
    - larceny_call() must deal with stack overflow.
  * Performance
    - Profile and see if it's worth getting rid of or optimizing some layers.

Common RTS
  * RTS clean-up:
    - Get rid of the file Sys/gc.c, which is a holdover from way back and
      is really just clutter.  This means some code that now uses the 
      global variable 'globals' must receive it as a parameter.  [Mostly 
      done in Petit Larceny, just a matter of merging.]
    - Factor out larceny_init() from main().
    - Simplify the remembered set:
      - go from a linked-list representation to an extensible hash-table 
        representation (maybe)
    - low-level allocation code:
      - split out free block management from low-level allocation by
        having one piece of code that does most of the management and then
        simple procedures that do low-level allocation with malloc, valloc,
        and so on
      - in what is now posix-alloc (low-level allocation based on malloc),
        profile the pointer registry to make sure it's not slowing us
        down.  (It'll make less difference if a higher-level module manages
        free blocks intelligently.)
  * Must deal with more signals (on Unix, especially).
    The right design here seems to be pretty much what we're doing now:
    - Synchronous interrupts (SIGFPE, SIGSEGV, SIGBUS) are handled as
      exceptions -- they're really errors.  
    - Asynchronous interrupts (SIGHUP, SIGIO, SIGINT, SIGQUIT, ...) are 
      handled by the current low-level mechanism, which delivers the 
      signal to the interrupt handler, which then handles it.  In a 
      simple system that means raising it as an exception; in a threaded 
      system they can be put on a queue.  Since access to the queue can 
      be protected by a critical section, and delivery may be delayed
      until after the critical section by some low-level buffering
      (if you trust all the critical sections...) then there should be
      no trouble.
  * In-system heap dumper for generational system.
  * In-system heap dumper for conservative system (maybe).
  * Garbage collector
    - Features
      - weak cells
      - finalization
    - Implementation
      - consider building an allocator on top of memalign or mmap (maybe)
  * Representation changes
    - Unicode strings and characters
    - Support for new write barrier
    - Support for dual code vectors
  * New write barrier.
  * For compatibility with the conservative collector and 
    no-interior-pointers, we must fix all code that allocates a single
    block of memory and parititons it up into multiple objects.  The
    places that do this are:
      - argv.c          args vector-of-strings -- not fixed
      - ffi.c           ffi callback arguments -- not fixed
      - stats.c         stats vector -- fixed
      - cglue.c         rest args -- fixed
    The correct way to implement this is to implement a _simple_ handle
    system:
       typedef word *w_handle;
       w_handle gc_make_handle( gc_t gc, word tagged_pointer );
       void gc_destroy_handle( gc_t gc, w_handle handle );
    and to use this to avoid premature collection of objects referred to
    from C code only.  (The handle system has been implemented.  Must
    use it to fix remaining trouble spots.  See BUGS, #128.)

SPARC RTS
  * dzero should be in globals[].

Macros
  * Integrate macros with top-level environments.

Assembler performance (general and SPARC)
  * Label lookup can be hashed (pass5p1)
  * Peephole optimizer:
    - make it table-driven, that is, have a primitive table for 
      when peephole opt. is on and one for when it is off.  The table
      for when it is on does what the peephole optimizer does now,
      except that it doesn't generate new primitives: it just calls
      the right assembler procedure.
    - use a generator to generate peephole code that retains state 
      in a state machine to have even less overhead.
  * It is possible to do more work before assembly by emitting
    partially-completed instruction streams that are efficiently
    cloned and patched, but it's a lot of work to restructure 
    it to do this.
  * [SPARC] The searching of the not-dsi slot of the assembler-value list 
    may be expensive, especially during block compilation.  This can be 
    fixed with a bit vector, I think, and should be, especially since 
    most of the searches in the list will fail.  (Or use hash table)

SPARC Assembler
  * More singlestepping fixes:
    - want to preserve labels.
    - does not work well with peephole optimization.
    - want to show load with destination 0.
  * Peephole optimization:
    - might want to use Will's peephole optimizer.
    - in any case get rid of all the internal: primitives and 
      implement a faster strategy.
  * Better delay slot filling (maybe).
  * Maybe instruction scheduling.
  * The code for op2imm generates slow code for some primitives: it emits 
    the constant into SECOND and then does a non-imm operation.  It gets
    + and - right; it would be nice to get =, <, <=, >, >= also, although
    the savings is one (static or dynamic) instruction, and the peephole
    optimizer gets most of the cases -- it's only where the datum is in
    RESULT and the result is being left in RESULT where this optimization
    matters.  Payoffs are slightly better for char=?, etc, since it's 
    costly to generate a character constant (2 instructions).  Still
    I expect most operations to work on operands in register, so the
    peephole optimizer will take care of it.
  * Fixnum-only arithmetic -- see Asm/Sparc/sparcprim-part4.sch.
    Remaining tasks:
      - optimize fx+ and fx- when it's possible to undo.
      - fxquotient, fxremainder
  * Peephole optimization (from in-line expansion of fast path of READ-CHAR):
    - make-cell: with source register and target register
    - vector-like? for control
    - bytevector-like? for control
    - Generally: more primitives for control:
       vector?, string?, bytevector?, flonum?, compnum?, bignum?
    - const + skip -- if the const is an immediate, the setup can go in
      the delay slot.  AND uses this construction.  
    - Generally: we can peephole
           any instruction
           ba target
           nop
      as long as <any instruction> is not in a delay slot.  We can also
      peephole any non-branch instruction from the target of a BA into
      its slot.
    - Generally: Ditto jmpl, call.  This will take care of RETURN.
    - Consider the following code (unsafe expansion of vector-like-ref
      with constant index):
	136	or	%g0, 16, %r5	! 0x10
	140	or	%g0, %r7, %result
	144	add	%result, 1, %tmp0
	148	ld	[ %tmp0+%r5 ], %result
	152	or	%g0, %result, %r5
      The move at #140 is clearly not necessary; #144 could add from r7 
      into tmp0.  Similarly, the move at #152 is not necessary, as the load
      at #148 could load directly into r5.  Finally, the setup of the
      constant at #136 is not necessary, as it could be used directly
      at #148.  The best instruction sequence is a single instruction (!):
	136	ld	[ %r7+17 ], %r5
      The instruction at #136 is due to the bad op2imm implementation;
      the instructions at #140 and at #152 are due to not having implemented
      vector-like-ref with source-register and destination-register.  Both
      are easy to fix.
  * More peephole optimizations
    - Unimplemented peephole operations
        bytevector operations
          bytevector-length
          bytevector-ref          (also op2imm)
          bytevector-set!
          bytevector-like-length
          bytevector-like-ref     (also op2imm)
          bytevector-like-set!
        vector-like operations
          vector-like-length
          vector-like-ref         (also op2imm)
          vector-like-set!
        others
          char->integer
          integer->char
          logand logior logxor lognot sll srl sra
    - Implement const/setreg/skip peephole optimization for simple constants
      and any target register -- allows the delay slot of the branch to be
      filled.
  * Support flonum-specific operations.
  * Fixnum-only arithmetic -- see Asm/Sparc/sparcprim-part4.sch.
    - optimize fx+ and fx- when it's possible to undo.
  * In-line _typetag_ in unsafe mode.

Interpreter
  * Debug support (via *evalhook* or some other mechanism), esp. environment
    display/change, and single-stepping of expressions.

Debugging
  * Document the debugger.
  * Record source file name in debug info, if available.
  * Record source code location in debug info, if available.
    See Experimental/read-source.sch for an example implementation.
  * Print variable names
    - The compiler must support variable name maps in compiled code.
      We need to map three kinds of locations to variable names: closure
      slots, stack frame slots, and registers.  
      - Closure slots are easy, as they never change; the compiler need
        only emit documentation as part of a procedure's documentation 
        string.
      - Stack slots are somewhat easy, because their contents need only
        be known at non-tail-call boundaries (I think).  Still, this
        requires that the compiler create, for each procedure, a map
        from return points (.cont) to live register contents at that
        point.  Compression techniques can be applied to the information.
      - Registers are somewhat hard, as their contents may need to be
        known at every point where an exception may be signalled.
        Thus, this information may be more voluminous that for stack
        slots, but are otherwise the same.  I think the general abstract
        structure of the information is a list of the following items for
        each procedure:
            (variable-name (Rn loc1 loc2) (Rm loc3 loc4) ...)
        which says that between code offsets loc1 and loc2, inclusive,
        variable variable-name is in Rn; between offsets loc3 and loc4
        it is in Rm, and so on.  Again, compression and structuring tricks
        can be used to reduce the cost of storing this information.
        (MIT Scheme stores debugging information on disk separate from
        the compiled code in .BCH files.  We can do this too.  A related 
        trick is to dynamically shuffle debugging info to disk as FASL files
        are loaded.)
  * Create a debugvsm primitive that does what break used to do.
  * Graph printing and reading could vastly reduce the amount of 
    source code emitted as part of the documentation, where code may now be
    duplicated during writing and reading.  (Not a problem for in-memory
    compilation.)  (Better to just support source file locations.)
  * Full support for interpreted code.
  * A more generalized object inspector (a la what Chez Scheme has).
  * Single-stepping, especially in interpreted code.

Library / primitives
  * FILE-MODIFICATION-TIME should signal an error if the file does
    not exist, like the (unexported) version in Auxlib/io.sch. 
  * make enable-interrupts, disable-interrupts sane.
  * I/O system is not thread safe.
  * Top-level environments must also hold syntax definitions.
  * Move Experimental functionality to Auxlib
     - applyhooks
  * Replace hash tables in top-level environments and symbol table with
    the new hash tables.
  * Performance: use define-inline judiciously to see if we can wring
    more speed out of the bignum code, and possibly other code (reader).
  * Arguably the intepreter's wacky notion of legal environment arguments
    should not be the default.  This should be a switch that's called by
    std-heap.sch and otherwise undocumented. Could call it 

       (interpreter/allow-illegal-use-of-environments)

    Better to fix this properly by integrating environments and syntax
    environments the way it "should" be done.
  * I/O system high priority
    - Performance [see fast-read-char.txt for details]
      - peek-char should maybe be coded in MAL, like read-char and write-char.
      - read-char, write-char, and peek-char should be compiler macros that
        call fast-read-char et al and, if that fails, call the 'normal'
        versions
      - the normal versions of read-char, write-char, and peek-char should
        manipulate the port directly rather than calling io/read-char 
        and io/write-char; this avoids extra call overhead.
  * I/O system normal priority
    - Support non-blocking I/O (see Larceny Note).
    - Faster reader [faster read-char and better compiler will help].
    - Faster printer [maybe].
    - Reader and printer should be able to read and print graph structures.
    - Switch from Dragon4 to Dybvig's algorithm.
    - Re-implement string I/O in terms of the extensible I/O system.
    - Read tables (a la Interlisp where the read table can be an argument
      to 'read').
    - Print tables [maybe].
  * Define "repl-reader" so that the reader can be replaced in the REPL.
  * Define "load-reader" so that a reader that does circular objects
    can be installed?
  * Move _format_ out from Lib -- it's not used there, and should go in 
    Auxlib.  Needs to be loaded by compiler.  Make sure it supports a 
    proper subset of SLIBs `format' so that Larceny code (eg debugger) 
    that uses format can live with the substitute.
  * Type tags really should be gotten from the auto-generated stuff.
    As it is, they come from Lib/typetags.sch.
  * Documentation structures should not be required to all be of the same
    length -- the proc-info procedures should deal with different-length
    vectors.
  * Bignums
    - speedup
    - decent test suite
    - remove dependencies on bigit size 
    - abandon the bogus bignum-truncate-length!; see comments in bignum code.
  * Flonums
    - Names like flonum:infinity are being defined and used all
      over the place.  Better to have one copy of these that everyone can
      reference?
    - it's called make-flonum but float-sign, etc: this inconsistency
      is common.  Better to fix it once and for all?
  * Speed up make-compnum (see comments in Lib/flonums.sch).
  * Compnum->string (in num2str.sch) can be made to handle other radices
    than 10 (see comments in Lib/num2str.sch).
  * Separate _loading_ and _linking_.  
    - Requires support for graph reading in the reader, and for graph
      printing in makefasl, at least, because it's useful to perform linking
      without traversing the entire structure, but a link map instead.
      Also, the link map makes 'un-linking' possible.
    - The FASL format will then change, and #^G will go away from the reader.
    - Allows disassembling FASL files.
  * Implement a dump-handler (procedures run before a dump)
  * Implement a restore-handler (procedures run after restore -- partially
    exists already in the form of add-init-procedure!.)
  * Want a system-environment procedure that returns the system name space.  
    That namespace should be disjoint from the others, but it would allow
    wizards much more flexible access than the current system-function
    functionality (which should go away).
  * The millicode support vector (aka 'callouts') should be initialized
    element-by-element using defined constants, not in a huge call to
    'vector' like it is now. (Lib/millicode-support.sch.)
  * `Sort' order of arguments is different from Chez and MacScheme, which
    violates the Prime Directive.  On the other hand, it's compatible with
    most other systems!  Here's a survey:
       Chez Scheme 5.0:	predicate, list
       MacScheme 3.0 Student Edition: predicate, list
       Scheme48 0.36: list, predicate
       SLIB 2c4: list, predicate
       Larceny 1.0a1: list, predicate (also vector, predicate)
       MIT Scheme 7.3: list, predicate
       PC Scheme 3.3: list, predicate, where predicate is optional; if 
         predicate is not given, sorts by object type and then by the 
         "obvious" ordering within each type
       MzScheme 53 (?) `quicksort': list, predicate 
       MzScheme 53 (?) `sort': predicate, list
       STk 3.99.3: list, predicate (also vector, predicate)
       Bigloo 1.9: no sort built-in
       Gambit-C 3.0: no sort built-in
       RScheme 0.7.?: manual lists no sort procedure, but manual is incomplete
    The order (predicate list) is more natural because it allows code to
    be indented more reasonably:
       (sort (lambda (a b) (< (foo a) (foo b)))
             (... big hairy expression that generates list ...))
  * Would be nice to print bit pattern when printing WEIRD OBJECT.

Testing
  * Test suite must be completed.
  * GC test suite must be completed.
    - test coverage automation
    - additional tests to provide good coverage :-)
  * Create Larceny Note about how to run tests.

Performance and code generation
  * Speed
    - keep the return address in a register when possible
    - use more HW registers on the SPARC
    - use HW divide in-line
    - use HW divide in millicode [done for quotient]
    - open-code multiplication by simple constant (fixnum/fixnum case).
    - in-line boxing code for bignum boxing in generic.s
    - number? should check for fixnum in-line, ditto other predicates 
      and exact?
    - Function cell
    - Once-only globals checking
    - Cache global cells and symbols.
  * Space
    - Operation-specific error callouts, to avoid having to set up
      the error code in-line.
    - Pass register mask rather than register contents -- should
      save instructions in most cases.  In particular, if we have no more
      than 17 registers (plus RESULT, SECOND, THIRD) then the following
      method can be used:
       * One or two words of raw data follows the callout to the exception
         handler.  The first word is the first and second argument, the
         second word is the third and fourth (if present).
       * The low half of the word is a bitmap for argument 1 (3), the high
         half is a bitmap for argument 2 (4).
       * If the low half is 0, then the argument is in RESULT (THIRD),
         otherwise it is one of the registers R1..R16.
       * If the high half is 0, then the argument is in SECOND (FOURTH),
         otherwise it is one of the registers R1..R16.
       * If the exception handler needs to return, it can skip over the
         data as required.
      The method can be used for other millicode calls, too, to reduce
      code size, but it increases the number of instructions executed
      because millicode must decode the masks.
  * Possible primops (RTS hooks)
    - sys$bvl-copy-into!
    - sys$bvl-fill!
    - sys$vl-fill!
  * Stack use optimization
    - don't copy the stack during GC.
    - lazy frame initialization.
  * Arithmetic and numbers
    - Support fixnum, flonum, compnum-specific operations.
    - Support flonum, compnum vectors.
  * Improve speed of context switching code.
  * Can we improve the speed of a syscall?
  * Bignum speedups (patience, patience...)
  * Predicates that should be primops but aren't:
    [none currently]
  * Predicates for control that need to be but aren't:
    - representation predicates, especially flonum?, compnum?.
  * Generic I/O performance (see I/O item earlier).
  * We should perhaps define bytevector-set! so that it chops off 
    high bits; this makes code easier to write and is faster (but is 
    it slower on other kinds of architectures, e.g. Alpha?).

Auxiliary library (directory Auxlib)
  * Pretty printer should support structure printer.
  + Object pickler

Documentation
  * Debugger
  * Larceny Note #7: FFI

Bootstrap heap dumper (extremely low priority)
  * Speedups (they matter some on slow systems):
    - Use hash tables rather than assq everywhere
    - Optimize output procedures like makefasl2

Notes on a bytecoded (word-coded) system:
  [This in v0.41]

  Estimates show that about 55000 words of object code will be emitted 
  for the standard library; that's 220KB of code, down from 917KB in the
  SPARC image (undumped), a reduction by a factor of more than 4.  
  Still, in the SPARC image there's 411KB of data, so a bytecoded image 
  would still be almost 650KB in size.

  Turning off include-variable-names saves only about 40KB.  Shortening
  all the documentation vectors where possible would save more space.
  Rearranging the vectors (to put arity before source code) would help
  some more.  Not including any documentation would help most: it saves
  100KB of data.  Turning off generate-global-names saves very little 
  more.

  In any case, in a bytecode heap, it's data size that's currently the
  issue, not code size.


**********************************************************************

Older stuff removed from TODO-RELEASE


Release 2
---------

This is the second release of the SPARC version, and a "beta" release of
Petit Larceny on some platforms.  In order to ever finish this release,
I have pruned this list brutally.

Major features of this release
  * Compiler improvements (pass 3, bug fixes, performance)
  * Library improvements (bug fixes, performance)
  * Better top-level environments
  * FFI
  * Record package
  * SRFIs
  * Petit Larceny on some platforms
  * CVS access to source

Platforms:
  * Sparc Larceny on
      - Solaris
  * Petit Larceny on
      - Unix/BSD/Linux/MacOS X with GCC or native C compiler
      - Win32 with MetroWerks

Known bugs that should be fixed:
	(None remaining)

Issues that must be addressed
  * Clean up the build setups in Util for Petit Larceny
  * Update build documentation
  * Update documentation generally
  * Update help text as necessary (switch values and names?)
  * SRFI system -- really ought work with new environments


******** Move things above this line to include them in the release ********


[Twobit]
  * BUG: The flonum primitives fl+, fl-, fl--, fl*, fl=, fl<=, fl>, fl>= 
    should check that their arguments are flonums and signal an error if 
    not; at present they are mapped to the generic operations in the 
    primitive table.
  * DEBUG: Better debug information would be nice
     - source position / source file name [lth knows how]
     - lth must write spec first [done, see Debugger/debug-info.txt]
  * CLEANUP: fix these, or don't
    - Some primitives are obsolete in sparc.imp.sch (only available to MAL):
      - creg, creg-set!
    - The parameters FIXNUM-PRIMITIVES, FLONUM-PRIMITIVES (used in sparc.imp)
      are not exported to the std environment, should be removed when
      primitive handling is cleaned up

[Library]
  * Remove these from the toplevel env and the library after checking
    that they're not used by compiler or assembler
	call-with-error-handler	[ use parameterize or exception system ]
	call-without-errors	[ use parameterize or exception system ]
	call-with-reset-handler	[ use parameterize ]
	system-function		[ obsolete ]
	with-*-*-binary-file    [ not useful ]

[SRFI]
  * Definite: SRFI 0  (basic)          [ done, modulo adding SRFIs ]
              SRFI 6  (string I/O)     [ done -- built-in ]
              SRFI 11 (LET-VALUES)     [ done -- built-in ]
  * Probable: SRFI 12 (Exceptions)     [ done -- pending exception 
					 hierarchy definition ]
  * Possible: SRFI 7  (Program-based configuration language)  [ done ]
              SRFI 9  (DEFINE-RECORD-TYPE syntax)             [ done ]

[Run-time system]
  * [lth] Provide more accurate data to memstats: it is possible to provide
    up-to-date data for allocation volume and currently allocated heap,
    not just data accurate to the last GC.  
  * [lth] memstats: must compute words reclaimed.
  * [lth] Must deal with more signals on Unix systems (important for buggy 
    foreign code)
  * [lth] Would be nice if NP remset could be flagged as such with (x,1)
    identity.
  * [lth] Must fix simulated barrier stats (in memmgr.c)

[Debugging]
  * Print variable names where convenient.
     - must have info from compiler first.
  * Revise the command set, and update the documentation to reflect
    the revisions.

[Util and other benchmarking code]
  * Must fix Util/process-stats.sch
  * Must fix/convert crunch, process-output to use new format?

[General clean-up]
  * Compiler/pass2.aux.sch and Lib/procinfo.sch both contain magic
    constants, accessors, and setters for the documentation slot.
    This information should exist in only one place, and it has to
    be part of the development environment.
  * Remove some of the weirder list and string procs and macros in Auxlib.

[Scripts/options]
  * Scripts may have to be aware of the new command line arguments,
    because the scripts process command line arguments too.
  * The help printed by larceny is pertinent to running the binary
    directly but not to running the shell script (which accepts 
    -small, does not accept heap file, adds -args implicitly, and
    accepts files to load (because the heap runs the REPL)).  Perhaps
    we should have the script print an appropriate help text that is
    independent of the binary's (and shorter, not mentioning all the
    GC options).
  * Really do need a -noinit file that avoids loading .larceny.
    The messy part of this is that the REPL does that loading but
    the binary interprets the options... so the -noinit must be
    passed _after_ -args, which is just not intuitive.  Instead the
    binary could recognize that -noinit needs to be passed as
    an argument to the Scheme program, when it is run, but that 
    is a mess also.  The best seems to be for the script to pass
    -noinit after -args.

[Standard builds]
  * No longer any need to load Auxlib/vector.sch since vector-copy is
    in the bootstrap heap.
  * Need to hide the nbuild internals in Util/std-heap.sch
  * Need to hide the FFI internals in Util/std-heap.sch
  * Need to avoid loading FFI source so we don't include the source code.
  * Need to not load Experimental/exception.sch in std-heap.sch, as it
    will be replaced by SRFI 12.
  * [discussion item]
    Rename `r5rs.heap' as `interpreter.heap' (since it's more than R5RS).
    Consider making a `r5rs.heap' that contains only r5rs procedures.
  * The debugger needs to be part of interpreter.heap.
  * Should create scripts that setup correct compiler switches before
    compiling all files for standard heaps; automate the entire process
    of building the heaps.  Eg., Scripts/build-larceny-heap.

[Documentation]
  * The following non-R5RS procedure are not in the User Manual's 
    procedure index, at least.  Must add them and create documentation
    for the ones that have none.

    I/O:
	readtable-ref
	readtable-set!
	open-binary-*-file
	call-with-binary-*-file
	print-length
	print-level
	write-bytevector-like
	lowlevel-write
	format			[ Park it or move it ]

	interpreted-*?, interpreted-expression-source

	make-environment
	environment*
	fl+, fl-, fl--, fl*, fl=, fl<, fl<=, fl>, fl>=
	make-parameter
	macro-expand
	sys$C-ffi-*		[ Should probably be .c-ffi-* ]
        sys$codevector-iflush	[ Should probably be .c-ffi-codevector-iflush ]
	memstats-*
	repl
	unspecified, undefined

  * Fix reported documentation bugs (to be determined)
     - BUG: remove claim that all optional functionality is supported,
       because transcript ports are currently not supported (they are
       in Experimental and depend on the experimental user-level I/O 
       system).
     - BUG: some bugs were reported on the mailing list but are not recorded
       anywhere.
     - BUG: CHECK, POPSTK, TRAP are not documented in the instruction set 
       manual.
     - Language: the low-level macro system and the extensions to the 
       high-level system are not documented.
     - New stuff
         PARAMETERIZE, MAKE-PARAMETER
         LET-VALUES
     - manual/intro.html: 
        - debugging info
        - compiler switches
        - "make setup" will no longer work.
     - manual/ffi.html:
        - add -uint versions (and perhaps deprecate -unsigned versions)
        - ditto uint type name
        - document FOREIGN-FUNCTION-POINTER
     - manual/io.html:
       - introduced PRINT-LENGTH, PRINT-LEVEL  [ Also parameters! ]
       - introduced binary i/o procedures
     - manual/syscontrol.html:
       - memstats now accessed via accessor functions
       - memstats vector changes:
         - some fields no longer present
         - some new fields
         - remembered-set and generation identity fields
     - manual/auxlib.html:
       - This file is a mess.  Should abandon, and fold into the other
         files?
     - manual/ephemeral.html:
       - remove debug stuff
       - clean up or move record stuff
     - manual/compiling.html -- read and redo 
       - note Rts/Sys/config.h
       - note change in 'make setup'
     - manual/starting.html -- many more switches now
     - manual/repl.hmtl
       - clean up according to comments in file
     - manual/developing.html:
       - build probably has more switches now?
     - manual/bdw.html:
       - setup process now more complicated since there is a lot of 
         support inside the (modified) collector.  How to deal with that?
     - manual/concept.html:
       - needs some cleanup (see the file).

----------------------------------------------------------------------

Release process checklist etc

Bug to watch out for: The binary archives have a symbolic link to the
binary, rather than the binary, due to the directory structure's use of
links.

Observe that the Standard-FFI is _not_ portable between operating
systems, not even between SunOS 4 and SunOS 5.  The reason is different
name mangling (prepended underscore on SunOS 4, none on SunOS 5).  Thus
larceny.heap must be built for each system.  Annoying but it's the way
it is for now (see TODO for more info).

[Release]
  * Source freeze (in this order):                                
    - Branch source tree as branch-1-0-a1                         
      cvs rtag -b branch-1-0-a1 larceny_src                       
      cvs rtag -b branch-1-0-a1 larceny_doc                       
  * Source archive                                                
    - move version number on branch to 1.0a1                      
    - iterate until it works:
      - cvs export on branch-1-0-a1                               
      - run Scripts/release-1.0a1                                 
        *** It was necessary to fix the script to
            use rm -rf rather than rm -f on directories.
      - run ( cd Rts; BUILD_HOST=chez make config )               
        *** It was necessary to run `make setup' first to
            create directories, setup links, edit `build'.
            Then it was necessary to remove .o files in 
            Compat/Chez.
      - make source archive  larceny-1.0a1-src.tar.gz             
        *** It was necessary to manually remove RELEASE-NOTES,
            which doesn't go in the archive (wasn't finished,
            either).
      - install, rebuild, run some simple tests.                  
        *** `make setup' gives harmless error messages because
            the cfg files are already in the Build directory
            when linking happens; we should check before linking.
  * Doc archive                                                   
    - create archive
  * Archives:
    - Get binary distributions from the source archive builds     
    - Archive names and contents
      larceny-1.0a1-src.tar.gz                                    
        pruned src tree
      larceny-1.0a1-sunos4-bin.tar.gz                             
        binary, heaps, Scripts/*, COPYRIGHT
      larceny-1.0a1-sunos5-bin.tar.gz                             
        binary, heaps, Scripts/*, COPYRIGHT
      larceny-1.0a-doc.tar.gz                                     
        (pruned?) doc tree
  * Finish release notes (do not go in ARCHIVE).                  
  * Put release date on download page.                            
  * Add archive sizes on download page.                           
  * Move archives and files to FTP directory
  * Test that FTP works the way it's supposed to.
  * Install documentation somewhere useful; put a permanent 
    link to it on the home page.
  * Backup archives onto MO-disk.                                 
  * Install Larceny in /proj/will/Apps/larceny!                   

