RRGGL Instruction set (Very short reference)
v. 1.00
author: Igor A. Maznitsa (igor.maznitsa@igormaznitsa.com)

(C) 2004-2006 Raydac Research Group Ltd. (http://www.coldcore.ru) 
==================================================================

Introduction
--------------

RRGGL (Raydac Research Group Game Language) was developed for using on J2ME platforms because security restrictions of the platforms don't enable to use any class loader but tasks of dinamically changing of executed codes happens. Thus, the language has been developed by Igor Maznitsa in 2004 in short time (a week).
The language is a FORTH like language so need very accurate programming because it actively use stack for its operations.
I'd like to say sorry because the instruction was written during very very short time (and sorry for my english too).

PLEASE REMEMBER THAT THE LANGUAGE IS A FORTH LIKE ONLY BUT NOT A FORTH, AS A MAIN DIFFERENCE BETWEEN A FORTH AND THE LANGUAGE IS THE ABSENT OF THE "TRANSLATION MODE" THERE IS THE "COMPILATION MODE" ONLY PRESENTED.

The Virtual machine can really help you in below cases:
1) You want to hide a part of your sources.
2) Your Java2ME programm need be loaded via internet or to be updated, thus you can write the changed part with the language and to send the modul via network to the device without any class loaders.
3) You need develop frequently changed parts (scripts for a game as an example).

The language can really save memory area because a compiled script is rated by Java VM as a binary block, thus a compiled binary script does not have any preverifier (for J2ME) data.

if you have found any problems in the use of the compiler and scripts, please contact me with email: igor.maznitsa@igormaznitsa.com

Using compiler
----------------

The compiler of RRGGL has been written in Java and need Java 1.4 or later for its work. The compiler is driven by command line options:

java -jar rrggl.jar ru.coldcore.RRGGL.Main [/d] [/c] [/s] [/h] [/v] [/a] [/in:<dir>] [/out:<dir>] file1 [file2 fileN]
file       - a file for either compilation or playing
/h         - to print the help
/d         - to include debug info (default not included)
/c         - to optimize instruction codes (to include only used commands) (default not optimized)
/s         - to play a compiled RRGGL file (contains not optimized instruction codes only), only file will be played
/w:addr    - start address of the main word for playing (default 0)
/in:<dir>  - the input dir
/out:<dir> - the output dir
/v         - verbose (print a lot of info during script playing)
/a         - to print disassembling list during compilation

The compiler generates the Java header which can be processed with the Java Comment Preprocessor utility (it can be downloaded from http://www.igormaznitsa.com)
The optimization with /c does optimize used command that enables to decrease the size of VM source with removing of unused commands (but it disables using of only VM for different compiled scripts) 


Inside of VM
----------------

The RRGGL Virtual Machine has two stacks:
1) The SP stack. It is used for both arithmetical operations and parameter passing. The maximum depth of the stack is 256 cells.
2) The RS stack. It is used for both user word calls and loop variables keeping. The maximum depth of the stack is 512 cells (to use recursive algorithms with the short stack is no so good idea).

So (as a big VM) the VM has a few special service registers:
1) The PC register. The register contains offset of the current executed instruction.
2) The SP depth register. The register contains the current depth of SP stack (when SP is empty, the register contains 0)
3) The RS depth register. The register contains the current depth of RS stack (when RS is empty, the register contains 0)

Data format
-------------

All stacks, variables and arrays can operate only with 32 bit signed data (int in Java). If you print 0x before number so you will tell the interpreter to interpret it as a hexadecimal number.
Examples:
 12345
 0xABCDEF

Strings must be presented as
 "String"
 "Hello world"

User words
--------------

All RRGGL program is a set of user defined words that contain VM instructions or links to other user words.

+===========================================================+
| WARNING                                                   |
|-------------                                              |
|                                                           |
|Please remember that all word names are case sensetives!!  |
|You must not use the symbol '$' as the first word name char| 
+===========================================================+

Any word named 'main' (or Main, MAIN, MaIn) will be placed at address 0.

Example of an user word:

       : main
            "Hello Word"
            #
       ;

The word 'main' will place the index of the "Hello word" string on the SP stack and to call the "native" Java function of a RRGGL Listener for processing the data
Because the compiler saves offsets of user defined words in the generated header interface, you can execute every defined word without any problem.
So as not to obstruct reading of the generated header files, the language has two special instructions "PUBLIC" and "PROTECTED". The instructions changes visibility area of next defined elements and PROTECTED elements will not printed in the header file. Default PUBLIC is turn on.

Example:
    PROTECTED
        : HELLO
            "Hello world"
        ;

    PUBLIC

        : MAIN
            HELLO #
        ;

The word HELLO won't be visible in the header but MAIN will be visible.

There are two ways to define user words:

1) With the ':' word.
2) With the '%' word

The words can not be used inside defined words. '%' enables define inline-words (remember that the language not a FORTH, but only a FORTH like). Any word that was defined with '%' will not be visibled in the header file and can not be executed because it will be inserted in the places where the name of the word weill be called.

Example:

    % ++ 1+ ;

    : MAIN 2 ++ # ;


You can make sets of your words and include they in your work scripts with the "LOAD" word.

Example:

file c:\forth.rfm

% I R@ ;
% LOOP 1 +LOOP ;
% THEN ENDIF ;

file c:\main.rfm

LOAD "c:\forth.rfm"

: MAIN
    10 0 DO
        I #
    LOOP
;

Of course your script must has links with "native" Java program that is executing it. There are two special words for it:
1) "SIGNAL".
2) "#"
There are not any different between the words but they call different processing functions that can help you in the separation of processing.

Debug of your script with the compiler
-----------------------------------------

You can debug your script with the RRGGL compiler, for that you need use /d argument for compilation and /s to play compiled script.
The word '#' will be printing the stack states in the place of the word.
The word 'SIGNAL' with 0 on the top of SP will print the next number on the SP and 1 on the top will print a string for the index as the next number on the SP.

After compilation
--------------------

After compilation you will get (usually) two files for every source file they are a java header (contains java interface with offsets of user defined words and VM instruction codes) and a compiled script binary file.
To play the script you need to connect the interface to VM source after that you can play script with the VM.

Arithmetical operations
-------------------------

"+" (SP: a b --> c where c=a+b   RS: --)
"-" (SP: a b --> c where c=a-b   RS: --)
"*" (SP: a b --> c where c=a*b   RS: --)
"/" (SP: a b --> c where c=a/b   RS: --)
"MOD" (SP: a b --> c where c=a%b   RS: --)
"1+" (SP: a --> b where b=a+1   RS: --)
"1-" (SP: a --> b where b=a-1   RS: --)
"2*" (SP: a --> b where b=a<<1   RS: --)
"2/" (SP: a --> b where b=a>>1   RS: --)
"ABS" (SP: a --> b where b=Abs(a)   RS: --)
"MIN" (SP: a b --> c where c=Min(a,b)   RS: --)
"MAX" (SP: a b --> c where c=Max(a,b)   RS: --)

Stack operations
--------------------
"SWAP" (SP: a b --> b a RS: --)
"DUP" (SP: a --> a a RS: --)
"?DUP" (SP: a --> a (a if a!=0)  RS: --)
"OVER" (SP: a b --> a b a  RS: --)
"ROT" (SP: a b c --> b c a  RS: --)
"DROP" (SP: a --> RS: --)
"DROPALL" (SP: a b .. n --> RS: --)

Return stack operations
-------------------------
">R" (SP: a -->  RS: --> a)
"R>" (SP: --> a  RS: a -->)
"R@" (SP: --> a  RS: a --> a)

Work with variables
--------------------------
"V@" (SP: addr --> value RS: --)
"V!" (SP: value addr --> RS: --)

Work with system registers
---------------------------
"P!" (SP: value regindex -->  (where regindex 0 - PC 1 - SPdepth 2 - RSdepth)  RS: --)
"P@" (SP: regindex -->  value (where regindex 0 - PC 1 - SPdepth 2 - RSdepth)  RS: --)

Branch operations
---------------------

construction IF <A> ELSE <B> ENDIF
"IF" (SP: a -->   [if a !=0 then <A> else <B>] RS: --)
"ELSE" (SP: -- RS: --)
"ENDIF" (SP: -- RS: --)

Example:
    IF
       2*
    ELSE
       2/
    ENDIF

construction SWITCH CASE DEFAULT ENDSWITCH
"SWITCH" (SP: a -->   RS: --)
"CASE" the instruction adds a case to a switch, format CASE <CONSTANT | NUMBER> , constant or number can be 0<= a <= 255, you can not have more than 256 cases in a switch
"BREAK" the instruction breaks a case (but it works and for loops)
"DEFAULT" the instruction begins the default section for a switch.
"ENDSWITCH" the instruction ends a switch

Examples:

    SWITCH
        CASE 0
           2 2 *
        BREAK
        CASE 1
           DROP
        BREAK
        CASE Const1
           DUP
        BREAK
        DEFAULT
           ROT
    ENDSWITCH    


Comparison operations
-----------------------
"="  (SP: a b --> c [ c = a == b ? -1 : 0] RS: --)
"<>" (SP: a b --> c [ c = a != b ? -1 : 0] RS: --)
"<"  (SP: a b --> c [ c = a < b  ? -1 : 0] RS: --)
">"  (SP: a b --> c [ c = a > b  ? -1 : 0] RS: --)
"0=" (SP: a --> c   [ c = a == 0 ? -1 : 0] RS: --)

Bitwise operations
----------------------
"AND" (SP: a b --> c [ c = a & b] RS: --)
"OR" (SP: a b --> c [ c = a | b] RS: --)
"NOT" (SP: a --> c [ c = ~a] RS: --)
"XOR" (SP: a b --> c [ c = a ^ b] RS: --)

Loop operations
-------------
construction DO +LOOP (You can use BREAK and CONTINUE in the loop construction)
DO (SP: a b --> RS: --> a b where a - limit b - start index) loop will be working while index<limit
+LOOP (SP: a --> RS: start index --> start index+a)

construction BEGIN UNTIL (You can use BREAK and CONTINUE in the loop construction)
BEGIN (SP: --  RS: --)
UNTIL (SP: a --> RS: --) if a ==0 then it will be jumped to the begin else the loop will be breaked

construction BEGIN WHILE REPEAT (You can use BREAK and CONTINUE in the loop construction)
BEGIN (SP: -- RS: --)
WHILE (SP: a --> RS: --) if a != 0 then next instructions will be processed else the loop construction will be breaked
REPEAT (SP: -- RS: --) makes jump to the begin instruction of the loop

Execute operations
-----------------
EXECUTE (SP: a --> RS: --> PC) makes jump to an offset from the SP and places the PC value of next instruction on the RS stack
['] (SP: --> a RS: --) Places on SP the offset of next word from stream and it can be executed with EXECUTE
NOOP (SP: -- RS: --) Not operation

Array operations
--------------------
"A!" (SP: index0 .. indexN value arrayID --> -- RS: -- )
"A@" (SP: index0 .. indexN arrayID --> value RS: --)

Interface instructions
-------------------------
SIGNAL (SP: ... --> ... RS: ... --> ...) send a signal to the native application
# (SP: ... --> ... RS: ... --> ...) the same as SIGNAL but call different function of the native application


Service instructions
-----------------------
PUBLIC - to make public (visibled with the header file) all defined words,constants, variables and arrays after  
PROTECTED - to make protected (invisibled in the header file) all defined words,constants, variables and arrays after
LOAD "<FILE NAME>" | CONSTANT - include the text from an external file
CONSTANT <name> <value> | STRING to define a numeric constant with <name> and set <value> to it
VARIABLE <name> to define a named variable with <name>
ARRAY [][][]<name> <dim0> <dim1> .. <dimN> to define a named array , symbols [] in the name show dimensions of the array
: <name> - to begin word compilation with the name
% <name> - to begin word compilation with the name, the word will be marked as inline, so it can not be used in ['] and EXECUTE because the instructions of the word will be placed in the call place
; - to end compilation of the current word


Comments
---------
( <block comments> )
// <one line comments>


FORMAT OF COMPILED FILE (version 1.00)
--------------------------------------

HEADER
---------------------------
ID - 0xCABABOCA (4 bytes)
Version - 0x0100 (2 bytes)

System flags (byte) 0x01 - debug info included, 0x02 - command code optimized
Variables area length (in cells) (2 bytes)

ARRAYS DATA
---------------------------
Arrays number (byte)

ONE ARRAY SECTION [Arrays number]
-----------------------------
Dimension number (byte)
DIMENSION SIZE [Dimension number] as short
-----------------------------

Strings area
-----------------------------
Strings number (short)
UTF String [strings number]

Quick user words section
-----------------------------
Quick user words number (byte)
The first quick user word code (byte)
offsets the words [number] as int

Program data
-----------------------------
Size of the block in bytes (int)
data[size] as byte

every instruction saved as
if (debuginfo)
{
    source file name index at the table of sources (byte)
    string index of the operation in the source file (short)
    position at the string of the operation (short)
}
opcode (byte)

if (debuginfo)
{
    TABLE OF SOURCES
    ------------------
    table length (short)
    Strings as UTF [table length]
}
instruction code (byte)
