This is my second attempt at a project I had put aside some years ago, which
was to use C as an intermediate language for code generation via ICODE.  This
is *not* an imp to C translator, because the C is not for the users to look at;
it would be unmaintainable - that's what my main imptoc project is for.  But
this is an alternative that seeks to use any C compiler as a back end rather
than having to interface to some C compiler's IL.

I'm now at the point where I can generate C code for most constructs, which
means I now have a framework in place for a relatively portable Imp77 compiler
that is written 100% in standard C.  The last time I did this, I implemented
the ICODE opcodes first and never got a handle on the data types properly. 
Now, with a few years more experience under my belt, I'm doing things in a more
sensible order and am generating more sensible constructs for records,
pointers, and arrays etc!

The generated code does have to be compiled under GCC.  This is unfortunate but
no other C compilers seem to support Imp/Algol/Pascal-style nested procedure
definitions.

The code here is definitely 'Work In Progress' and is online just for you to
look at - please don't develop anything from this, as it will be changing
underfoot as I work on it.  I'm updating the zip file nightly on each
checkpoint.  There are still a lot of areas that I have not yet written code
for.  Look for parts of the source files marked "TO DO"...

I am trying to keep the three components separated although I will confess
there may be a couple of places where they cross over in a less than pristine
way.  Those parts are:

1) pass1-flat.c   - more or less standard Imp77 pass1.  Converted to C and
   flattened for portability.

2) i2c.c - main control program and icode reader - handles the IMP side and
   passes all code generation to...

3) ast.c - works from AST tuples (vaguely reminiscent of the ERCC's "trimp"
   style) and generates the C.

The code *could* be shortened and simplified by mixing these phases more than
they are, but I think that this split should make the compiler more
maintainable than otherwise.

As of now there is no system-specific library interface (other than calling
standard C code) and the Imp perms are fairly generic and should be
recognisable to old Imp programmers.

Building the compiler is one step ('make') and it does attempt to adapt to the
user's environment a little.

Gnu C is currently a hard and fast requirement.  Valgrind if present is used in
an attempt to emulate Imp's traditional runtime error checking.

G
(P.S. At some distant point in the future I will consider adding 'cosmopolitan c'
support which builds a sort of 'fat binary' that can run on multiple systems,
albeit only 64 bit ones.)
