compiler: Introduce constant boolean types

These are specific types for #t and #f. The primary importance of this is
our type system can now implicitly track the truthiness of values. This
means, for example, that (if) can be treated like type predicate for #f
and propagate that truthiness information in to its branches without any
special handling by the planner.

(not) can already be replaced with a type predicate for #f here. This
generates slightly better IR and doesn't require any explicit runtime
or reportproc planner support.
compiler: Remove the reducer

The reducer was complex but worked well enough with the limited
information it had before the introduction of explicit typing. However,
to fully resolve types it would require nearly as much information as
the planner has. This doesn't scale very well.

In the future the type system and planner intermediates should be able
to express much of the information the reducer was tracking (e.g. if
something is a proper list of a given length). This means the planner
can accomplish the same things the reducer was doing at plan time. For
now remove the reducer completely to reduce the complexity of the
compiler while working towards that goal.
compiler: Add static branch logic to planner

This builds on top of the new constant boolean types for #t/#f to do
static type checks on (if) conditions and only planning the taken branch
when possible. This is the first (and likely easiest) step in replacing
the functionality of the reducer

The most interesting part of this is the assertStaticPlan function. This
attempts to assert that a plan collapses down to a single compile-time
determined value. This should be useful for replacing the previous
reducer tests which attempted to do something similar at the expression
level.
compiler: Inline some self-executing lambdas

This is the beginning of re-introducing inline support. Right now it has
the following temporary restrictions:

- Only self-executing lambdas are inlined

- Rest args are not supported

Additionally, the following language features will prevent inlining with
no immediate plans to support them:

- Immediate returns (et.Return generated from a call/cc)

- Any procedure that requires a closure

- Mutable arguments
compiler: Remove resultWithUserProc

This function is now unused
compiler: Remove ps.UnboxAsTruthy

This can be done by the planner itself now using a type check for
constant false and inverting the result
compiler: Remove ps.AssertRecordLikeClass

This is unused since the introduction of PlanTypeCheck
compiler: Simple inlining for bound procedures

This introduces a new codegen.CostForPlanSteps function that attempts to
calculate an approximate cost for this plan. The values are fairly
arbitrary and untuned at the moment but it should be significantly
better than the old reducer's heuristics.

Whenever a lambda is planned we attach the original lambda expr and some
other metadata to a new KnownSchemeProc intermediate value. This gives
the planner enough information to re-plan the procedure inline the next
time it's encountered.

Inside PlanApplication the invoke and inline plans are separately
planned in two forks of the PlanWriter. The cost for both plans is
calculated and the cheaper plan is used.
compiler: hasDefiniteCellType => hasDefiniteType

Cell types are mostly an implementation detail for the planner at this
point. The hasDefiniteCellType is a legacy from before the SchemeType
refactoring.
compiler: Static exact integer math planning

This extends NumberProcPlanner to support integer +, - and *. This is a
fairly simple extension of the existing constant integer instruction
planning.
compiler: Static comparsion planning

This will allow static integer comparisons (=, <, etc) of constants
compiler: Reintroduce (call/cc) reduction

This rescues the old (call/cc) reducer which itself was rescued from the
old optimizer. This works the same as it does previously with a bug fix
for dealing with mutable exit procedures.
compiler: Re-add inlining tests

This re-adds many of the reducer tests for inlining in the form of
static plan tests. Nothing had to be changed in the compiler to allow
these tests to pass which is a strong endorsement of the robustness of
the planner's value tracking.