Todo now:

* ought to be able to treat the arguments to an enum constructor as a tuple
  in a pattern...

* need to start putting user's guide together.

* should port bison and lex

* should hack the popcorn front-end to spit out cyclone (or a close
  approximation thereof.)

* need to spit out an "interface" file for each .cyc file.  The interface
  should list all of the imported types and values, and all of the exported
  types and values.  At link-time, we should suck in all of these and make
  sure they're consistent.  

* better formatting support in printf & friends (i.e., deal with full
  %-specifiers)

* new { for i < x : ' ' }
  causes core dump for negative x.  (Not surprising -- x is treated as
  unsigned so that's a really big number and likely, malloc is returning
  null which we're not checking for when we allocate...)

* multi-dimensional arrays?

* parser/lexer is having trouble with floating point constants

* use garbage collector (we are using malloc right now, not GCmalloc)

* default array initializers, at top level and local, e.g., int x[4];

* functions should not be allowed as fields of enums or tuples, e.g.,
    $(int (int),bool) x;
    enum foo { Bar(int (int)) };
  Anyway the translation fails to go through gcc

* Consider this:     foo?"a":"bc"   won't typecheck because the arms
  are char[2] and char[3] which don't match.  Maybe we should promote
  to string in this case?

* multi-level initializers, e.g., {{0,1},{2,3}}

* more general casts, e.g., char[4] to int[1]

* better constant expressions (no doubles? no longs?)

* varargs (...) (integrate with printf, fprintf, xprintf?)

* scanf, sprintf, and any other vararg functions?

* better (deeper) coercions and casts -- perhaps a more general notion of
  subtyping and isomorphism?

* compound literals

* more designators for arrays literals

* better designators for structs

* qualifiers for arguments to enum/xenum constructors?

* xenum redeclarations in another namespace handled right?

* better implementation of unresolved mem

* deal with inline?

* lots of places where we're not sure what to do with the type qualifiers

* are we treating void properly?

* cut, fill, codegen, splice

* Support qualified identifier declarations (instead of just uses).

* nested functions (nested type declarations? nested exception declarations?
  nested using?)

* static local variables

* long long, short, float, and double constants (including 12s, 3l, etc.)

* lexer has not been carefully looked at.

* as patterns

* better evaluation in evexp.pop

* builtin list syntax: list(e1,e2,...,en) -- also for patterns

* string append operator (++)?

* qualifiers on tuples (how)?

* Maybe we should treat the following as the same in the
  type-checker/parser:
    void foo(int x[]) == void foo( int (@x)[] )
    void foo(int x[3]) == void foo( int (@x)[3] )
  Problem: this is incompatible with C.  Instead C uses
    void foo(int x[]) == void foo( int *x )
    void foo(int x[3]) == void foo( int *x )
  And, in C there is a difference between (int *x) and (int (*x)[]).
    Consider x[4].  If we have (int *x) then we obtain the (int *) to
    dereference by adding to x.  If we have (int (*x)[]), then
    we have to explicitly dereference x to get an (int[]), and then
    C does an implicit address-of to get the original pointer back,
    but at type (int *).  Only then does the final addition take
    place.
  Note that since [?] arrays are boxed we can already use the notation
    int f(int x[?])[?]
  so, this is really only a concern with C arrays.  We could simply
  live with the inconvenience of the verbose notation for these types
  of arrays -- force the programmer to write int (*f(int (*x[4]))[5].
  However, there is still the question of whether to DISallow things
  like   void f(int x[4])   which in C involves a cast to a int *.

Todo later:

* dependent types for arrays (and lots more?)
* anonymous structs and enums
* bit fields within structs
* unions (in the C sense)
* subtyping
* better comprehensions/iterators
* calling conventions for functions (C vs Cyclone)

-----------------------------------------------------------------------------
Things that have been done:

I've merged exp_synth and stmt_synth, generalized it to support
break/fallthru in switches.  This gets rid of the following todo
items:

  * check conformance of fallthru and break on switches

  * fix the exp_synth on tcStmtExp to get definitely assigned vars right
    (perhaps merge exp_synth and stmt_synth)

* check that where clauses are well-formed in switches/catches

* sizeof(?) -- need to really be able to check the size

* UnresolvedMem -- now resolves (based on the type of the declarator)
  to either an Array or a Struct expression.  Note that we still don't
  deal with full designators properly.

* printf, fprintf, xprintf

* size (for arrays)

* * in patterns to get the address of a value within a data structure
  $(int,int) x = $(1,2);
  let (*a,b) = x;  // a : int@, b : int
  *a = 3;
  printf("%d\n",x[0]);  // should print 3

* change [?] arrays into boxed types -- this will simplify strings and
  a bunch of other things and I don't see how we can really support
  [?] as an unboxed type anyway.


  typedef $(`a,`a) pair<`a>

* existentials

* string initializers at top level: string x = "hello"

