compiler: Allow conversion const int to inexact

Conversion to native double/float was handled but not to
<inexact-rational>. This handles the conversion as expected
compiler: Fix bogus IntermediateValue comment

The comment on restoreFromTempValue reflected when higher-ordered
function were use to implement restoring. Now restoreFromTempValue is a
simple function returning a value.
compiler: Move typeDescription to correct class

This should be part of IntermediateValue instead of
IntermediateValueHelpers. The former inherits the latter so this wasn't
noticed earlier.
compiler: (ann) improvements

- Add a concept of a "Scheme type" which is the same as
  vt.CellValueType. This are types that are distinguishable at a
  language level. For example <boolean-cell> and <exact-integer-cell>
  are distinguishable in a Scheme program not using the NFI, while
  <int64> and <int32> are not.

- Make <ann> only take Scheme types. This allows the compiler freedom in
  choosing the exact representation used - for example, both <int64> and
  <exact-integer-cell> can satisfy an annotation of <integer> (i.e.
  <exact-integer-cell>) without requiring any conversion.

- Add IntermediateValue.castToSchemeType. This will pass the value
  through unchanged if it already satisfies the Scheme type. This is
  useful for keeping extra information as tracked by KnownProcedure, for
  example.
compiler: Remove overqualification of import
Support for typed define (define:)

- Add StorageLocation.schemeType which indicates the user-provided type
  for a storage location

- Use the new IntermediateValue.castToSchemeType to cast binding and
  mutated values to the user-provided type

- Factor out duplicated logic from AnalyseExprs and ReduceExpr to
  TopLevelDefinitionRequired. Have it refuse to drop top-level
  definitions with type constraints

- Export the <numeric> type from (llambda typed). It was defined before
  but not exported due to an oversight
compiler: Rework undefined recursives

Instead of encoding undefined fields as null pointers add a new
"isUndefined" flag on the record itself. This should have approximately
the same performance characteristics but allows us to support undefined
values of non-pointer types. This will be useful for implementing more
efficient storage of typed mutables.
compiler: Only include GC'ed fields in typemaps

Typemaps are generated entirely for the benefit of the garbage
collector. We can save typemap space and GC collection overhead by
excluding preconstructed cell types (boolean, empty list, etc) from the
generated map
compiler: Add codegen.CompactRepresentationForType

This factors out the logic to chose low-overhead closure types from the
planner to codegen. There are two reasons for this:

- The fact that a certain unboxed type is lower overhead than a given
  boxed type is a function of how we generate code.

- Moving this out of the planner allows it to be reused elsewhere - this
  will be useful for typed mutables and more efficient user-defined
  record types
compiler: (define-record-type) improvements

- Only allow type annotations with a new define-type-record: form
  exposed through (llambda typed). This is consistent with what Typed
  Racket does and the newly introduced (define:)

- Make (define-record-type:) take Scheme types instead of native types
  and use the compact representation for the type. This means that
  <integer> will implicitly use <int64> even though <integer> is now
  defined as <exact-integer-cell>.
compiler: Efficient typed mutables

Instead of having one vt.MutableType record type for mutables
dynamically create them in the planner as we encounter mutables with new
type constraints. This behaves identically for the default <datum-cell>
mutables but has a few big wins for typed mutables:

- The value can be stored in the mutable in an unboxed form (e.g. 8-bit
  bool instead of a <boolean-cell>, <int64> instead of <exact-integer>
  etc.). This allows more dense packing of mutable values, less GC
  overhead and fewer pointer dereferences

- When the mutable is loaded the value is re-entered in to the planner
  with the appropriate type information from the storage location. This
  technically could have been done without changing the storage method
  of mutables but comes for free with this approach.