Manual for the il4c programming language
----------------------------------------

List of top level forms (capital ids are user given):
 - (asmfun NAME (PARAM PARAM PARAM) ASM_STRING ASM_STRING)
   - An assembly level intrinsic function. Compiled to one bytecode instruction.
   - Parameters are evaluated from left to right to the stack and the assembly
     function is jumped to directly (ie. not via the "call" assembly command).
     - This means "pop eax" would pop the rightmost parameter.
   - Every function must pop it's parameters and push one return value. Always.
   - Example: (asmfun add_one (a) "pop eax" "inc eax" "push eax")
 - (fun NAME (PARAM PARAM PARAM) STATEMENT STATEMENT STATEMENT)
   - Normal script function.
   - Example: (fun fact (n) (if (<=i n 0) 1 (*i n (fact (-i n 1)))))
 - (var NAME)
   - Uninitialized global parameter.
   - Takes no space in the exe (other than a unique index).
 - (var NAME VALUE)
   - Initialized global parameter.
   - Value must be an integer, a floating point or a string.
 - (const NAME VALUE)
   - Constant value. Cannot be changed (and doesn't really exist unless you
     use it).
   - Same values as with (var ..).
   - When you use a constant value, the value is placed directly to where it
     was invoked.
 - (heapsize INTEGER)
   - Sets the size of the memory heap the program uses.
   - Must be big enough for the whole program (no dynamic allocation).

Random notes:
 - Comments start with the '#' -character and continue to the end of the line.
 - Typeless language (well, the type is "32-bits")
   - You may give a number, floating point number, a string constant (seen as
     an array) or a custom array pointer
 - Every expression returns a value
   - If nodes return the value of the winning branch. If there is only branch,
     then the other branch is still generated and it generates a 0
   - While nodes return the last value of the last successful iteration
     - If no iterations were run, then 0 is returned.
   - Functions return the last evaluated value.


VM overview
-----------
The VM itself acts as a normal C-ish function. It inits ESI to the start of the
bytecode, reads one byte and jumps to its address. The function has parameters
and local variables just like a C function (accessed through EBP). The bytecode
commands act on a stack basis, pushing and popping values from the stack. Every
bytecode command should pop it's arguments and push an answer. Some answer must
always be pushed (unless it's a special function such as Pop, Return or
JumpIfNot).


Calling conventions
-------------------
When calling a script or C (cdecl/stdcall) function, the arguments are evaluated
from right to left. When calling an asm intrinsic function functions are evaluated
from left to right. This also means, that the first "pop" inside the assembly
intrinsic pops the rightmost argument.

The script handles calls to other script functions like cdecl C-functions.
Parameters are pushed to the stack in right-to-left order, then the VM function is
called again. The only difference is, that EBX is used to deliver the pointer to
the executable bytecode.


History
-------
9.10.2007: Initial release
