Prototype analyzer.

The design isn't right yet, but this is a checkpoint for a
partially-working implementation. Need to iterate on this design a bunch
more before merging it.
Further iteration on the analyzer design.

Still not right but includes some notes about what to try next.
Make simplification of temporaries an implementation detail.

Previously this was exposed in the public interface and callers were
required to call it themselves before building a control flow graph. Now
we just do it automatically before we build a control flow graph, since
there's no reason not to.
Clean up some mess made by earlier refactoring.
Move the control flow graph bits into a separate module.
Add the concept of a "Unit".

A Unit is a subprogram of some kind e.g. a function or the initialization
code for a module. In practice this just means a container for shipping
around a control flow graph along with its associated symbol table and
a placeholder for a description of its parameters, which will be filled
out once we implement the instantiation of function templates.
More work-in-progress analyzer (now called "preprocessor") work.

This is not a working state: the main analysis functions still need to be
moved from "analyzer" into the preprocessor.Executor class, as indicated
in the TODO comment inline.
Support retrieving a flattened set of symbols from a symbol table.

This introduces the concept of a "disconnected" child symbol table, which
is one that should not participate in flattening. The use-case for this
is cases where a child symbol table represents a separate execution
context like a function, where we expect the function to be able to reach
into the global scope but not for the locals to roll up into the global
scope.
Further ad-hoc progress on the preprocessor.

The basics of the preprocessor are now working, but a bit missing part
is the merge operation on the DataState class which is supposed to create
an entry data state based on the exit states of the predecessor blocks.
Currently this is not done and so the preprocessor's type analysis is
incorrect and incomplete.
Implement the merging of data states.

This allows values and types to propagate through the program correctly so
that the preprocessor can figure out which operator implementations to
use, and eliminate branches we know can't be visited at runtime.
Fix up and test the Lifetime class.
Fix up and test the CallFrame class.
Test and fix up the Cell class.
Test most of DataState.

update_from_predecessors remains to be tested.
Test DataState.update_from_predecessors.
Remove defunct alamatic.analyzer module.

This functionality has been replaced by alamatic.preprocessor.execute.
Merge the initial preprocessor work