MAJOR CHANGES TO SIMPLE LITTLE COMPILER (in reverse order)

28-Dec-2000  v0.04 released


27-Dec-2000  'switch' statement added. This is more like the BASIC
             version of 'select case'. The format is:

               switch (expression) {
                 case (expression) {
                   ...
                 }
                 case (expression) {
                   ...
                 }
                 case else {
                   ...
                 }
               }

             Note that as soon as a case expression is matched and the
             conditional code for that case is executed, it exits rather
             than continuing to further case statements in that block.
             'case else' is optional, it is executed if no other case
             expressions are matched.


14-Dec-2000  'pragma signed' and 'pragma unsigned' added. These
             directives control whether certain operations such as
             multiplication, division and compare is considered to be
             signed or unsigned. These can appear multiple times in the
             source file, dynamically switching between signed and
             unsigned code generation. See lib\uitostr.slc for a simple
             example.


08-Dec-2000  'if' statement now supports 'else', for example:
                if (x == 1) {
                  y = 10
                } else {
                  puts("x doesn't equal 1.\n")
                }


22-Nov-2000   'define' command added, currently permitted:
                 define BLAH 1234        /* numerical constant */
                 define BLAH myvar       /* variable */
                 define BLAH 'xy'        /* alpha constant */
              Anywhere that BLAH appears in the code, it is replaced
              with what has been previously defined.


16-Nov-2000   Array code fixed up, now supports char size arrays as well
              as int size. Example:
                 char *a
                 a = malloc(10)  /* in real code we check return value */
                 a[1] = 255      /* same as *(a+1) = 255 */
              Note that this memory MUST be allocated prior to using the
              array, as there is no way of specifying the array size in the
              variable definition yet.


11-Nov-2000   You can now do: *(somefunc(...)) = expression. This
              currently assumes the return will be an INT pointer
              because SLC does not yet support function prototyping.
              somefunc() should return an int pointer or int variable.


10-Nov-2000   All memory references in the output ASM file had a "ds:"
              prefix which resulted in an extra opcode byte for each
              access of local variables, which are by default in the
              "ss:" segment. This has been removed and local accesses
              are (correctly!) assumed to be in the stack segment. No
              functional difference since in a COM file CS, DS, ES and
              SS are identical, but the code will be a little smaller.


09-Nov-2000   v0.03 released


08-Nov-2000   Some changes to parsing code so that SLC gets the size of
              multiple pointers on a line right (hopefully). A line such
              as "void blah (char *x, char *y)" previously incorrectly
              decided *y was an int sized pointer. See entry for
              14-Mar-1999 for more information.

              "<<" (shift left) and ">>" (shift right) operators added.


31-Oct-2000   External functions no longer need to be explicitly
              defined, but a warning will be issued for any functions
              that are called without being defined as "extern". A
              warning will also be issued if a function is defined as
              "extern" but not actually called anywhere in the source.
              Simply: if what you define and what you use does not match
              exactly, SLC will tell you.


15-Mar-1999   v0.02 released


14-Mar-1999   Added &variable address references - the address of the
              variable is passed rather than the value, for example: int
              v / blah(&v) allows the function blah() to directly alter
              the contents of v. Note: this WON'T work properly if you
              try to pass the address of a global variable between
              functions, due to globals being stored in the data segment
              rather than on the stack. However, since global variables
              are visible and accessable from all functions and modules
              this is a moot point!

              The &variable changes also allowed me to rewrite the
              negative constant handling (eg a = b - -1) code.

              Fixed some problems with *(variable+...) style expressions
              where the pointer variable was a char size (int was being
              assumed). This still needs some work and in some cases
              what should be a byte load or save may use a word instead.

              Added hard coded TASM and TLINK calls to automatically
              assemble and optionally link. tlink will be called only if
              a main() function is detected in the file you are
              compiling. This will be configurable in a future version
              but is not important for this bootstrap.


30-Jan-1999   Added an audit trail of evaluation functions, compile with
              !AUDIT to use. This is mainly to help track problems with
              states, where the compiler gets caught at a particular
              level repeatedly passing over the same element.


24-Jan-1999   The processing for escaped string literal "\\" incorrectly
              inserted a forward slash rather than a back slash into the
              ASM output file.

              /* ... */ style comments code now complete. This will
              become the official comment style and the # comments will
              be phased out whenever I decide to code something like
              #define that needs that character.


14-Jan-1999   Lots of compare code changed AGAIN. It's quite difficult
              getting it right with the "simplistic" compare system that
              SLC currently uses, for example "if (i == 0 || i == 1)"
              evaluates each part separately to 0 (false) or 1 (true)
              then logically ORs the two results together to get a final
              false or true. Things get very complicated with double
              negatives and results cancelling out. A future version
              will use direct jumps out of false evaluations to prevent
              fiddling around with logical ORs and ANDs in conditional
              statements.

              Code for lower than and greater than was also comparing
              the 2 sides in the wrong order.

              Logical OR and ANDs had the registers the wrong way around
              to match the L->R flow of the source code - a register
              exchange prior to the OR/AND has fixed this. (Not relevant
              for OR, but important for AND). What a mess!

              Constants can now be in ascii 'a' or 'aa' form (including
              the quote), eg: if (x == 'C')

              I'm moving to C style /* .. */ comments as using a #
              (hash) for comments is lazy programming on my part, and
              makes it somewhat difficult to use it for future
              directives like #ifdef. This part of the code not yet
              functional though, work in progress. I will probably move
              the comment code out of the main body and into the "Parse"
              sub.


02-Jan-1999   Compare code for == and != TOTALLY broken, I tried to be
              smart and implement the actual compare without any jumps
              but it didn't work too well. This wasn't even noticed
              until I started work on the memory allocation library
              routines.

