12th April 2005 (kwxm)
======================
Added higher-order stuff via defunctionalisation some time ago.
Lots of fiddling about with various things.

29th November 2004 (kwxm)
=========================
Finally added some code to rebuild funblocks after monomorphisation. Yay!
Damn.  It still doesn't work if you have "let f = ... and g = ..." where
g calls f but f doesn't call g.
OK, more (messy) code to do this.

Removed args adn superArgs from CLASSdef constructor.  These were unused,
perhaps left over from early stages of development.


28th November 2004 (kwxm)
=========================
Changed annotation scheme.  Now, instead of having "Location Program"
in some places and "(Location * ... * ...)" program in others we always
have Annotation program,  where the datatype 'Annotation' has constructors
for bare locations, locations with mono info, etc.  This has the advantage
that we don't have to keep stripping off the mono & phi info when we do
a new typecheck,  but it makes typechecking less robust because the
normalised absyn always has the same type.  It's conceivable that 
part of a program could slip through some phase unmodified: this would
previously have prevented the compiler from compiling,  but will now be 
unnoticed.


20th October 2004 (kwxm)
========================
Added various bitwise operators (land, lor &c)
Added new datatype for normalised syntax,  used in all 
of the later stages of the compiler.

29th February 2004 (kwxm)
=========================

Made various changes over the last couple of weeks, mostly
relating to predicate generation.  The compiler can now
import Steffen's rich types via ASDL;  there are functions in 
Predicate.sml to convert them into Isabelle form.

Rewrote Makefile to use symbolic links for stuff from gdf,  avoiding
multiple copies (still need to do this for GrailAbsyn).  Simplified 
Michal's scheme for repairing bad SML output from asdlGen.

Rewrote match compilation to eliminate various bugs (eg,  for
datatypes with three or more constructors, one being nil, thecompiler
would generate code which recalled the tag without checking that the 
relevant object wasn't null).


28th January 2004 (kwxm)
========================
Monomorphisation failed for muutally recursive polymorphic 
datatypes.  I've put a fix in Mono.MonoTypes,  but I'm not
entirely convinced by it.

At some point I modified the lexer to accept compiler-generated 
names (containing _, $, etc),  so that _#3 would be accepted as a 
valid id.  Unfortunately this allowed _ as an id,  so @_ would
use _ as a valid diamond name.  I've hopefully fixed this now.	
At some other point I also changed the # symbol to $ in names 
introduced by normalisation,  to avoid confusion with method
invocation that was causing trouble somewhere.

Added copy of Location.sml in Loc.sml:  pritns error messages
to stderr rather than stdout.

16TH JANUARY 2004 (kwxm)
========================
Fixed problems with classnames.  Rather than having to end in 'X'
now, they can be fairly arbitrary.  There was also a problem that
type constraints (in Camelot programs) featuring classes turned
into CONty, rather than OBJECTty.  They are now set to CONty
initially,  but this is resolved in a separate pass after parsing,
using the classname recorded by the parser.


12th January 2004 (kwxm)
========================
Reorganised Compile.sml and made modifications to typechecking
to fix the boolean/int problem.  Compile.sml is now identical
to the gdf version of Compile.sml.  As soon as possible I'll
enforce this via links.


5th January 2003 (kwxm)
=======================
Function arguments previously had empty names for unit
arguments,  causing problems with Michal's inference.
There's now a new UNITvar value to represent unit arguments.
Hah!  We finally have precise locations for function argument 
type errors.  The fix is rather inelegant,  however. Also,
it still causes trouble with bad valdecs.


End of 2003 (kwxm)
==================
Major changes,  using polymorphic abstract syntax to provide sapce
for annotations.  This gets rid of various long-standing bugs 
due to annotation lists being assembled in the wrong order.
Typechecking and monomorphisation are now much simpler.
We now have to use extra functions to translate to and from
ASDL syntax for Michal.  Camelot absyn and ASDL absyn must be
kept synchronised.  
Various other stuff has been done since the last entry,  but I forgot
to write it down here.


14th October 2003 (nicholaw)
============================
Oops, never finished that entry.

See Class.cmlt for an example of the concrete syntax for OO stuff, and
my TFP paper for the general shape of things.

Note that initialisers still cannot be written in Camelot (coming
soon), and class names are not distinguished from datatype names in a
nice way.

22th September 2003 (nicholaw)
==============================
Objects.

Abstract and (both flavours of) concrete syntax has obviously changed.


12th September 2003 (kwxm)
==========================
Added character constants.  
Provided builtin functions for manipulating characters;  also
library functions for file input.

Rewrote parts of Normalise.sml,  separating normalisation
and let-floating.  It's much easier to see what's going on now.

1st September 2003 (kwxm)
========================
Made the syntax look even more like OCaml;  in particular, added
'begin' and 'end'.
Fixed a normalisation problem for complex conditions in "if ... then".


27th August 2003 (kwxm)
=======================
Changed the parser (yet again) to conform with OCaml syntax after complaints.

Added parser and -sml option for SML-style syntax,  just to annoy people.

Modifed Diamond.getDiamondName so that it returns name of diamond class
for all inputs.  Strings in DIAMONDty are used inconsistently,  and 
this'll have to be addressed if we ever use multiple diamonds.  The
change to getDiamondName fixed the problem with passing diamonds as
arguments.

There were two copies of tyToString:  one in Util and one in Asyntfn.
Got rid of the one in Util.

3rd August 2003 (kwxm)
======================
Got fed up having type/Type in Parser.grm.  Now there's only one 
notion of type.  This allows the user to attempt to define datatypes
containing functions,  but Syncheck now catches this (and it gives a
more helpful error message).  However,  this doesn't work for built-in 
lists:  ()::[] gives a cryptic error message.  To catch this sort of 
thing we'd probably have to do a check after type inference since in 
things like (f(x))::[] it's not obvious what the type of f(x) will
be.

Added optimisation to compilation of if-expressions then removed it
again since it didn't work.


7th August 2003 (kwxm)
======================
Changed the parser again to eliminate conflicts.  Type parsing is more 
complicated again,  but previously there were conflicts for things like
int -> int list:  is this (int -> int) list or int -> (int list)?  
Constructor expressions with @ symbols are now handled a bit more nicely.
We can now write (h::t) without getting an error,  but the downside is that we 
can write h::t@d.  This means the same thing as (h::t)@d,  but doesn't
look very nice.  The only conflict left now is due to the lack of terminators
for matches.

Also modified the lexer:  I put the keywords into a hash table and look
the up there instead of getting the lexer to match lots of different
strings.  This is supposed to keep the size of the lexer down, but
didn't seem to make much difference.


3rd August 2003 (kwxm)
======================
Got fed up having type/Type in Parser.grm.  Now there's only one 
notion of type.  This allows the user to attempt to define datatypes
containing functions,  but Syncheck now catches this (and it gives a
more helpful error message).  However,  this doesn't work for built-in 
lists:  ()::[] gives a cryptic error message.  To catch this sort of 
thing we'd probably have to do a check after type inference since in 
things like (f(x))::[] it's not obvious what the type of f(x) will
be.

Added optimisation to compilation of if-expressions then removed it
again since it didn't work.


1st August 2003 (kwxm)
=====================
Added new comparisons (=. , <. , <=. etc) for floating point numbers
to avoid having to do overload resolution.  = can now only be used 
for integers.  Added corresponding binary operators (FEQUALS, FLESS,
FLTEQ) to the abstract syntax.  Also fixed a bug in compilation to JVML 
where if_acmpeq was being used to compare boolean (= int) values on the
stack.

14th July 2003 (nicholaw)
==============
Changed the Camelot bool type to use the Grail boolean type, and made
gdf consider int and boolean equal for typechecking. JVML has a
boolean type, which is basically used for variable/function types, and
uses values of type integer.

Heap optimisations. Haven't mentioned them here. Write ! before a
constructor to make it heap-free, if possible. Single nullary
constructor turned into null representation, or all-nullary into int
(so at the Grail level it just looks like you're using
integers). Typechecking for this. It's all in DataOpt.sml.

Some unsound changes may have escaped when I forgot to specify a
filename when doing "commit", not sure.

4th July 2003 (kwxm)
=============
Added code to automatically convert arg array into arg list
for "start" function.  Did some other stuff as well.  (eg
added some syntax so that diamonds can be used with built-in lists).

25th June 2003 (kwxm)
==============
Modified Perv.sml so that type information is only exported for
built in functions which are actually used.


25th June 2003 (nicholaw)
==============
Basic linearity checking works. It must have work to do, but it seems
okay just now. Use the "-l" flag, naturally. Doesn't consider
different kinds of matches or anything, just checks that heap-
allocated variables are used linearly (with exception for body of
if and match expressions).


24th June 2003 (nicholaw)
==============
Lists.

Lists are no longer built in to the heart of the compiler, they are
simply regarded as a predefined datatype. Lib.addStandard is called
from Camelot.sml to add predefined datatypes (just list for now) and
there is space for predefined functions too. Note this differs from
Perv.sml, which is for functions which must be builtins; the library
things in Lib are all things that could be written in Camelot.

The parser converts the usual list syntax to use the list datatype.

23rd June 2003 (nicholaw)
==============
I believe monomorphisation is now working. Any problems at this stage
are not known to me yet, reports encouraged. Various fairly small
changes were required, but they were a nightmare to find. 

In particular, mutually recursive functions with mutually recursive
datatypes should monomorphise with no problems. 

I've been playing with objects to give me ideas, unfortunately this
has escaped into a multitude of commented out code in the source.

Lastly, I believe the unit/void problem is fixed.

22nd June 2003 (kwxm)
==============
I rearranged things a bit.  I've now moved the stuff for checking
function arguments and validity of match rules into Syncheck.sml
because some of this has to be done before normalisation (eg,
disallowing repeated bindings in match rules.  Previously, repeated
bindings would be secretly renamed in Normalise.uniq; maybe it would
have been more sensible to let them through normalisation unchanged
and then find the error later.  Anyway, it's too late now).  To get
sensible error messages I moved the error-reporting stuff from
Type.sml to Util.sml (this also sllows us to use locations in error
messages originating in other files (Mono.sml for instance) by calling
Util.error.  I also tidied up error reporting a bit: most of the error
messages seen by the user now don't involve an exception showing up at
the top level.  To simplify this (maybe) I moved some of the things
required in MainParser into Util as well.

    While I was at it I added a new file Asyntfn.sml containing some 
functions for doing stuff to the abstract syntax (printing it out 
for example).  Absyn.sml now contains the abstract syntax definition 
and nothing else.  This should make things easier when Michal does
the ASDL stuff.


16th June 2003 (nicholaw)
==============
We can now call some external static methods by adding a 'val'
declaration at the top of a Camelot file. There will be issues with
the UNIT/void problem, and most things (e.g. trig) are unusable
because Camelot has fewer types than Java. 

These methods are basically treated as functions, as functions become
static methods anyway. The difference between static methods and
functions is the former have dots in their name. This will probably
change when objects and stuff come in.

See Ext.cmlt for examples that seem to work.

12th June 2003 (nicholaw)
==============
Added my CS4 project optimisations, all activated by the -o flag. One
might want to switch on a subset, but OTOH the compiler is
accumulating flags rapidly.

1. Tail recursion optimisation. Only for single functions, mutual tail
   recursion should wait until the external interface issue is
   decided, e.g. via modules or classes. See Optimise.sml.

2. "Local Variable Consolidation" - merging of temporary
   variables. Dataflow.sml does this. Currently this is slow, it will
   get faster once lists are replaced by other data structures.


4th June 2003 (kwxm)
=============
I may have fixed the bug relating to typechecking for constructors
(see 10th May) by inserting an error check in Type.unify.  I'm still 
not entirely happy about typechecking for function arguments though.

There was another problem with UNIT/void:

   let h() = 5
   let f(x) = x+2
   let main args = let _ = print_int_newline (f(h())) in ()

caused complaints about the wrong number of args for h.  
I fixed this by putting a special check at the start of 
Type.checkArgs.  I'll have to do this properly some time. 


29th May 2003 (kwxm)
=============
Last night: added freelist management to diamond class after
discussion at workshop. The diamond class now contains a freelist and
a private "alloc" method which returns the head of the freelist, or
creates a diamond using "new" which it then returns.  There's also 
a "free" method which returns a diamond to the head of the freelist.
For each possible set of contents of the diamond,  there's a "fill" 
method which inserts values into a pre-existing diamond;  there's 
also a corresponding "make" method which gets a diamond using 
"alloc" and fills it in with "fill".

After email comments,  the "free" method has been made visible in
Camelot (via Perv) since you might only want to really use a diamond
in one branch of an "if",  for example.  The code for this might be 
a bit dodgy.

Added debugging code to the diamond class so that we can watch the 
behaviour of the freelist.

Added "mod" as a Camelot builtin.

There was a problem with the order of mono info in the LETexp case 
of Type.recon.  I seem to have worked round it for the moment,  but
it would be worth thinking about this again.



20th May 2003 (kwxm)
=============
1. Reorganised stuff so that builtin functions are now isolated
   in a module rather than being individually wired into the 
   compiler.  I've bypassed monomorphisation for these things,
   so there may be problems with polymorphic functions such as the 
   array functions (REMEMBER to check up on this).  Luckily I may 
   have got away with this since the Grail versions are polymorphic 
   as well.  It's now (at last) possible to write a main method 
   which processes a list of arguments

2. Typechecking for diamonds seems to be OK now.  Still no linearity
   check.

*  There's still some confusion about Camelot's unit type versus
   Grail's void type.  Should we compile away units?  If so,  what 
   about void values in datatypes?

*  How about exporting type info from Perv only for those builtins
   which are actually used?

* BUG from Michal

   type a = A of b
   type b = B

   let f va = match va with A (vb) => vb



10th May 2003 (kwxm)
=============
(Attempting to fix things after losing a week's work - I may have
made other changes that I've forgotten about)

1. Modified Datatype.sml so that things are a bit more sensible.  This 
   is helped greatly by the requirement that constructor names are 
   unique.  Given a list of datatype declarations,  we can now 
   generate a Java class which is large enough to hold any instance 
   of any type from that list.  At the moment the input list contains
   all typedecs from the program,  but we may later wish to do things in
   a more refined way if we know something about dataflow for diamonds.

2. Removed all uses of Abysn2 (the one with no locations).  You now 
   have to deals with locations all through the compilation process.

3. Tidied up Camelot.sml a bit

4. Fixed a bug in Types.sml where types of variables bound in matches
   weren't recorded.

5. Put in some VERY preliminary code for dealing with diamonds.

6. There was a subtle bug in the one-rule case of matchTest is Phi.sml
   which led to code being emitted in the wrong order.  I've fixed
   this and optimised the one-rule case (omit the retrieval of the
   tag and insert the field extractions in-line);  it would be 
   nice to get the functions in a more readable order though,  and
   maybe we sometimes generate redundant jumps.

   OK, I've done this.  We now don't require separate functions 
   to extract fields;  instead we generate a sequence of valdecs
   and pass it on when we apply Phi to construct the code for
   evaluating the expression associated with the match rule.
   This corresponds to eliminating the call to rho_j in the
   document.

   Another optimisation is that we now don't generate a separate 
   function when the result of a match rule is a primop;  it's
   just built in to the "if" result.  [Damn:  this backfired
   because Camelot and Grail have different ideas about what
   unit is.  I've put in a temporary patch.  Should we try
   to compile units away?

   Note also that the L arguments to Phi now accumulate valdecs
   in reverse order and have to be reversed when you finally
   close a function definition.

*  The next thing to do is to optimise the above so that we 
   only extract fields which are actually used.

7.  Added function Type.checkArgs which checks that all function 
    and constructor applications hava the correct number of arguments.
    It also checks that in a match statement the rules are exhaustive 
    and irredundant and that all constructors belong to the same type.

*** BUGS ***

*   You can write stuff like "if x=A then ..." where A is a constructor.
    We shouldn't let this happen.  This can presumably be dealt with in
    the grammar.

*   [qi.gr: d#0#0 ????  : because of repeated normalisation.]

*   Every time we see @d we add a declaration for d:  far too many.

*   Typechecking for constructors doesn't seem to work properly:
    the program

     type t = A of int | B of string

     type u = Z of t

     let f x = Z(A(x))

     let main args
       = let p = f 2 in match p with
          A(w) => let _ = print_int (w) in ()
        | B(u) => let _ = print_string(u) in ()
    
   compiles successfully and runs (although erroneously) despite
   the fact that f returns a value of type u and the match is against
   type t.  Presumably we need to add a few more constraints




30th April 2003 (kwxm)
===============
1. Any classes which the compiler generates to represent datatypes
   are now named as for Java inner classes;  eg,  if the program
   contained in "test.cmlt" contains a (monomorphic) datatype
   "ilist",  this is represented by the Java class "test$ilist.class".
   For polymorphic datatypes there will be one class for each 
   instantiation,  eg "test$pair_1.class", "test$pair_2.class", ...

2. The typechecker now constructs a list containing the types of all
   variables in the program.  This is required when we need to recover 
   class names to generate method descriptors etc.  This means that 
   we can dispense with Repair.sml.  

3. Corrected bug (maybe) in IFexp case of Phi.phi.

4. Added "Utils.sml".  This mostly collects together some useful
   stuff from various modules.

5. Modified Normalise.uniq so that variables bound in matches 
   and in @-expressions have unique names.

*. Unused args are bad.
   = for strings is bad.
   Reuse of predefined identifiers?
   Is there any check that function applications have the 
   correct number of arguments? (No,  but this is now fixed).
   Is type-consistency checked for arguments?



3rd April 2003 (kwxm)
==============

1. Changed syntax to use parentheses round constructor arguments.
   (And for the time being, function arguments as well)

2. All constructor names must now begin with upper-case letters.
   Function names must begin with lower-case letters.  This means
   we can get rid of ConstructorHack.sml.

3. Added product type;  maybe this won't be used.

4. Removed location information from types.  This should simplify 
   typechecking considerably.  With luck there'll be enough information
   in surrounding context to produce sensible error messages.

5. Added "@" annotations for constructors to allow destructive pattern
   matching a la LFPL.  No typechecking yet.

6. The parser now rejects attempts to reuse function and constructor names.

7. To help with (4),  constraints used in the typechecker are now 
   triples of the form (t,t',loc) where t and t' are types which have to be 
   reconciled to give the type of the expression whose location is given by loc.
   This (mostly) seems to give sensible error messages.


18th January 2003 (kwxm)
=================

I've made several changes in the compiler to make it compile example programs
properly (whether it'll now compile any programs properly apart from my examples
is an good question). These are as follows.

1. Added Repair.sml to recover type information in the Grail abstract syntax.
   This information should really be preserved throughout the compilation 
   procedure.

2. I changed some of the names generated by the compiler.  Some of the 
   classes correpsonding to datatypes had colons in their names and
   the JVM didn't like this.  The names now have underscores.
   Incidentally,  we should probably make these classes look like inner
   classes of the defining program to avoid name clashes (in particular
   if prog.cmlt defines type prog then the class prog.class gets
   written twice:  we should probably call the datatype class prog$prog).

3. I modified the function Datatype.findFieldDescs.  This retrieves information
   from a Polyhash object and was leading to the type parameters in method
   descriptors appearing in a randomised order.  My new version is really 
   crude and this whole thing probably needs to be rethought a bit.

4. I also changed datatype.doConstructor since this was emitting initialisation
   instructions in reverse order and confusing me.

5. The function Mono.monoTypes changes the order of datatype constructors.
   For instance, [[a,b],[c,d,e],[f,g]] gets turned into [[g,f],[e,d,c],[b,a]].
   This was leading to bad constructor invocations so I inserted a small 
   function to rearrange things (didn't want to start messing about with 
   monoTypes).

6. When Phi.phi is generating instructions to retrieve the tag from a datatype
   instance it needs to know the type of the object involved.  For instance
   we need something like "getfield l <int list.$>".  I don't think this type
   info is available at that point (so you just get "getfield l <int $>",
   which fails to verify).  This needs to be fixed properly but for the moment
   I've put something into Repair.sml to recover the necessary info.  Also,
   the compiler was referring to "tag" instead of $.

7. I've added the file ConstructorHack.sml which attempts to modify the
   abstract syntax tree in such a way that Phi.phi processes zero-argument
   constructors properly.  This seems to work OK but it's a pretty bad
   solution and I'm not sure what effect it'll have on the rest of the program.

8. I've changed the back end so that it doesn't bother to check that variables
   which are used in local functions are actually in scope.  This is to overcome
   problems caused by the fact that the compiler doesn't generate parameter
   lists properly.

9. I changed the parser because a recent alteration to force you to write 
   let f () = ... instead of let f = ... was requiring you to put
   let f x y () = ...


19th January 2003 (kwxm)
=================
1. Added Camelotlib.java containing some simple library functions for
printing and type conversions.  The names are taken from OCaml and the functions
are now represented by keywords in Camelot which are translated into method 
invocations in Grail.  These functions now allow us to write self-contained
Camelot programs which can produce output.  In the temporary absence of array
operations I've put in a function array_head which allows you to get hold of the
first element of an array.  This allows us to provide command-line arguments
for programs.  I've just noticed that the technique of representing the unit
type by the Grail integer type doesn't allow us to write functions which translate
into JVM functions with void return type (except that they do because the compiler
doesn't handle unit values consistently at the moment).  We'll have to think about
how to get a "main" metho of the appropriate type.

2.  The parser contained code to strip the quotes from literal strings;  however
it looks as if the lexer already did this,  so strings were getting both ends
chopped off.  I think I've fixed this.