"Cola" - A compiler for the Parrot/Perl6 VM

  V0.1.2

  I've started this compiler (I call it Cola) to simultaneously
  teach myself how to write a compiler (ok I admit I squeaked
  through Compiler Design in school because I was too busy
  playing online MUD and basketball), as well as help
  out a project that I love, Perl6/Parrot!

  To really start having fun with the Parrot runtime I wanted
  a language similar to C/C++/C#/Java.

  The Cola parser is LALR, developed with flex/bison. It targets
  an intermediate language (PIR) which can be found in
  parrot/imcc or alongside Cola on CPAN.
  IMCC does the register allocation/spill control, optimization
  and various other dirty things, before generating machine
  instructions. Currently the only target is Parrot.

Where to Get the Latest Compiler

    This was a quick 2-week project in 2002 to show how to compile
    to Parrot. Sometime in 2005 I plan to release a full implementation
    of Cola to CPAN and will update the README accordingly.
    http://cpan.org/authors/id/M/ME/MELVIN

The Syntax

  Who knows? C# and Perl mix.

  The easiest way to see what it currently looks like is
  to read the examples.

Supported Constructs

  For some quick samples, see the cola/examples/ subdirectory.

  Statements: FOR, WHILE, IF, ELSE, BREAK, CONTINUE, RETURN.

    All of these are limited in their current version but follow
    typical C-ish rules (break breaks out of current loop, continue
    shortcuts to the next iteration). return may return a value
    from anywhere inside a method.

    0.0.4 adds logical operators.
    Conditional expressions may now be compound and use logical
    operators (&& and ||).
    CAUTION: Assignments inside conditionals such as...

        if((i = 15) == 15)

    are still not supported. This sort of expression will be fixed
    in the next update.

  Types: int, float, string (classes and arrays coming soon) 
    Currently these map directly to the Parrot primitive types.
    Very simple type coercement and checking is supported.

  Variable Declarations:
    For now declare all your variables at the top of each method.
    Block scoping will be done soon.
    You may initialize your variables in the declaration.

  Expressions:  Parens, +, -, *, /, %, ++ and -- are supported in
    any combination or complexity. Post and pre-increment are also
    supported. You may use the + operator on strings for concatenation.

    The following works:

        Console.WriteLine("Hello Mr " + name + "\n");
    
    There is no support for concatenation with non-strings yet.    
    I need to whip up a few conversion routines.
 
  Comparisons:  <, >, <=, >=, !=, ==

  Bitwise operators:  <<, >>, |, &, ^, and ~ are now supported in 0.0.4

  Conditional expressions:  Commonly known as the ternary conditional...
    As I understand the Java and C# language spec,
    conditional expressions must be on the right hand side of an
    assignment or anywhere that uses the return value, however you
    cannot use ternaries standalone as a statement. So in Cola you can
    say:
           max = i > j ? i : j;
    or:
           max = i > j ? foo() : bar();

    But it is not proper (although C allows you) to say:

           i > j ? printf("max=i\n") : printf("max=j\n");

    If you think I have misread the C# grammar spec, please email me.

  Boolean: The boolean ! operator isn't yet supported.
 
  Objects and Methods:  
    Classic C++/Java style, recursion supported. Return types supported.
    Will be adding variable argument support per the C# spec.

    Member variables or "fields" aren't yet supported. You
    can use const definitions, but member variables
    are incomplete pending a little more work on Parrot.
    Its possible to do them now with PerlHash or PerlArray,
    but I'm working on something faster for strictly typed,
    non-dynamic languages.

    Currently instance methods are the same as class methods. So
    you could do:

        Console.WriteLine("");

    or  Console c = new Console();
        c.WriteLine("");

    The compiler doesn't yet differentiate between static or class
    methods and instance methods, and whether you are calling them
    as such.

    OOP is really just faked for now, enough for people to write
    in a high level language for Parrot. As everything, it is a work
    in progress. All objects are simply PerlString references for now.

  Current Builtin Subroutines

    Since I have yet to implement class importing, the system routines
    are just plain wrappers around the Parrot ops. Currently they are:

       strlen, substr, strchop, ord, puts, puti, putf, gets, sleep

    See gen.c and main() for the current kludgy way to patch in more wrappers.

    In calc.cola I also did a sample implementation of a string to int
    conversion called StrToInt().


  Arrays:
    Parrot now has a substr with replace op so we can emulate arrays
    on top of it. It is a hack but it works.

What you currently CANNOT do even though the Parser may eat it...
  Statement lists:          i = j, j = k;
  Nested assigns:           i = (j = 0);
  Fancy For loops:          for(i = 0; j++, j < 4; i++)
  Empty For headers:        for(;;) // use while(1)
    
Using the Compiler

  You will need Flex and Bison installed to build the compiler.
  These are the GNU versions of the classic lex and yacc, but
  are more modern. The grammars should work with standard lex/yacc
  but I've not tested this lately. parser.c is provided pre-generated
  so you do not actually need lex/yacc.

  Build Cola from the languages directory above this by typing:

	make languages

  Usage:

	colacc examples/mandelbrot.cola

  NOTE: colacc will expect you to have core.pir in the current directory
  when you execute it as it autoincludes it in generated code.

  This will call Parrot (and imcc) to generate 2 types of output. a.pasm
  and a.pbc. You can run the .pbc (bytecode) immediately with Parrot:

        parrot a.pbc

  You can also see the Parrot assembly in "a.pasm".

  Currently colac is a short Perl pre-processor that includes
  classes for any import statements (using System;)
  If you have trouble with colac you can just use colacc which
  is the raw compiler which ignores 'using' directives.

  Also, if you look in "a.pir" you will see an intermediate
  language. Debugging the compiler is easier by looking at the
  intermediate code. This language can be piped through imcc to
  re-generate the .pasm file, however this is done by default.

  Currently the compiler is very limited with a few warnings and
  a few simple type coercions.
  
  If you try to do something fancy, the grammar might accept
  it but the code will probably come out wrong or simply crash the
  compiler. Read all the samples before trying anything.
 
Intermediate Code


  Please see the README in the parrot/imcc directory.

  For a nice sample of intermediate code, compile mandelbrot.cola or
  calc.cola which actually does a limited form of parsing with Parrot.


Register Allocation

  Done via graph-coloring. Cola emits intermediate code that uses
  named locals/globals and symbolic temporary registers. IMCC
  handles the allocation and spilling.

  See parrot/imcc/README

Optimization

  Very limited. No explicit optimization phase yet.

  You might see dumb code generated in the form of:

    set I1, I0
    set I2, I1

  or..

    branch LABEL34
    LABEL34: ...

  generated between basic blocks or in situations where
  the generator is currently dumb.
 
  The plan is to convert intermediate code to SSA (Static
  Single Assignment) form before doing various optimization
  passes.

Coming Soon
  Some form of a printf()
  Full array support
    

Gaping Holes

  Arrays
    Strings can be treated as arrays, thats it for now.
    Will be adding full array support soon.
 
  Class/Struct instantiation
    Lotta work involved here, I won't go there for now.
    Parrot currently does not have an adequate bytecode "class format"
    in which to write symbol table information. This will change soon.

  Object Methods and Field references
    Again, a lot of work, but on the list. I'm sort of faking
    method calls for now, no instance calls.


