Rz language

(This compiler is still a work in progress.)

Try Rz on your browser here. (version 1.0) Type in the source and watch the output in assembly language.
Rz version 3.6 targets S2 instruction set  
S2 version 3 simulator runs in web browser
Rz compiler tools kit (old, historical interest only)

Rz is aimed to be a teaching language for system programming and computer architecture subjects, which emphasises a small language that can be used to illustrate all the "inner" working parts of a computer system (compilation, code generation, ISA simulation), in other words it allows students to "play" with the system.  In a way, Rz "looks like" C (without type).

Short description

The language is a small subset of C look-alike language. It has no type (or having only one type which is "int").  Global variables must be declared but local variables are automatic.  A variable can be either a scalar or an array.  There is no user defined data type.  An array is one dimension.  Rz language can be summarised as follows:
For C programmer, please note, no: for, break, do, missing many operators especially ++, -- 
In version 3.5 onward, it has a new syntax, using indentation instead of { }  and newline instead of ;

Examples

It is easier just to look at an example to know most of the syntax.  Here is an example of Rz (v 3.5)

    //  find max in an array
    a[10], N

    init()

      i = 0
      while ( i < N )
        a[i] = i
        i = i + 1

    main()
      N = 10
      init()
      max = a[0]
      i = 1
      while( i < N )
        if( max < a[i] ) max = a[i]
        i = i + 1
      print( "the max value is ", max )

The variables a[], N are globals, max, i are locals.  For an array, the size must be known at compile time.  (A note of C user, there is no ++, --, and no "break", "print" is not "printf"). "print" knows only integer and string.  The size of basic unit (integer) depends on the target machine.   In short, you can think of Rz syntax as C without type declaration.

History

Rz is a descendant of R1, a concurrent language  for small control applications.  (Have a look at full report and implementation from my research work web page).   R1 is a concurrent language.  Rz simplifies that by eliminating all the real-time concurrency language features and retains only the most basic language constructs.

The original Rz is compiled into its own byte-code.  The original system also included a byte-code interpreter. For more information about the original system please visit old Rz-language.  Another old Rz compiler that targets S2 processor can be found here (old Rz compiler tools kit page).

Current state of implementation

Rz (version 3)  is a work in progress.  This is a new implementation of Rz language.  The new parser generator is written.  The grammar of Rz language is simplified.  The compiler is modified to output a parse-tree.  The parse-tree is an intermediate and explicit representation.  A separate code generator can be written for any desired target processor.

rz3 included:
comp:  the whole compiler
lexgen:  lexical analyser generator
pgen-c:  parser generator, the input is "rz-grammar9.txt"

rz3 version 1.0  include its "meta-interpreter".   readme
rz3 version 2.0  is an excercise in code generation.  It outputs a linear-code (assembly-like) to illustrate how to traverse and transform Rz parse-tree.  See example of output.
rz3 version 3.3 outputs s-code (version som-v2).  The output object code is run under Som-v2 virtual machine.
rz3 version 3.5 with pre-processing of input to use indentation as { }  and \n as ";".  The output is s-code (som-v2). 
rz3 version  3.6  add two language features: interrupt, asm.  They are used to support the writing of an operating system in Rz.  The compiler outputs S2 assembly language.
rz3 version 3.7  put effort into generate code of * and & operators including macro.

A session in Rz (version 3.5)

It has a new syntax, using indentation instead of { }  and newline instead of ;
Here is an example of the new form:

fac(n)
  if( n == 0 ) return 1
  else return n * fac(n-1)

main()
  print(fac(6))
    Try to compile "fac.txt" shown here:
 
    Here is the command line and the output at the screen:

D:\prabhas\bag\rz35\test>rz35 fac.txt
fac
main
(fun main (print (call fac 6 )))
(fun fac (else (== #1 0 )(return 1 )(return (* #1 (call fac (- #1 1 ))))))

:main
    fun.1
    lit.6
    call.fac
    sys.1
    ret.1
:fac
    fun.1
    get.1
    lit.0
                    . . . 
     You will get the file "fac.obj" as an output file.  It is an object file that is executable under Som VM (a kind of virtual machine similar to JVM). You can "run" it under somv2x.

D:\prabhas\bag\rz\rz33\test>somv2x fac.obj
720

Rz version 3.6

Rz 3.6 earlier version, compile to S2.3

This version target the output to S2 processor version 1.  The compiler outputs the S2 assembly language which can be converted to machine codes with S21 assembler.  The output object file can be run with S21 simulator. 

Three language features are added to this version.  The first one is "int0()..int3()".  This function is used to hold an interrupt service routines.  S21 has four interrupts.  The second one is "asm(...)".  This is used to insert an assembly code into the final output.  It allows the mix of assembly language into Rz.  The last one is the pragma "#noframe", it denotes not generating the frame of the current function (use in some special case, especially when wanting to implement operating system functions).

Rz 3.6 has the following reserve words

print()        // print int and constant string "..."

printc(c)      // print char
prints(s)      // print string
x = input()    // input returns string
x = malloc(n)  // allocate n words from heap

int0()         // interrupt service routine 0..3

int1()
int2()
int3()
di(n)          // disable int n (0..3)
ei(n)          // enable int n (0..3)
doze()         // sleep and wait intasm(s)         // insert assembly string into asm source

#noframe       // not generate frame

They are compiled into S2.1 trap instructions:

0  stop

1  print int
2  print char
3  print string (array of char, terminate by 0)
4  input returns address of string (default at 15000)

15  disable int
16  enable int
17  sleep and wait for int
19  malloc

Example session with Rz 3.6

Here is an example session of compiling and running a Rz program with S21 simulator, (quicksort example).

Compile quick.txt, put the output in out.txt (s21 assembly)
C:\rz36-3\test>rz36 quick.txt > out.txt

Assemble out.txt.  The output is a machine code out.obj and the listing (for human inspection) out.lis
C:\rz36-3\test>as21 out.txt

Run the object code with S21 simulator

C:\rz36-3\test>sim21 out.obj
load program, last address 200
>g
5  1  8  3  4  0  6  7  2  9
0  1  2  3  4  5  6  7  8  9
stop, clock 1418, execute 1418 instructions
>q

Rz version 3.7

In this version, I put effort into the code generation for * & operator and add the macro to the language.  The macro is unlike C. Defining a simple expression has the same structure as defining a function, but it can not have any non-free variable in the body.  The macro performs textual substitution of its free variables, so the only variables allowed in the body of definition are global and formal parameters. Other local variable can not have a substitution, therefore it is illegal.

The call by reference can be achieved using the * and & operators just like in C.  For &v, v must be global because we map local to a register which cannot be dereferenced.

increment(x)
  *x = *x + 1

main()
  a = 1
  increment(&a)
  print(a)

Define symbolic constant

     def  MYMAX   100

Define simple expression

def getRef(ref)
    return record[ref]

def setRef(ref,x)
    record[ref] = x
main()
  a = MYMAX + 10
  c = getRef(a+1)
  setRef(a, a+c)
That's it.  Enjoy!

Code Release

12 Nov 2010    rz3.zip
16 Nov 2010    rz31.zip    readme 
28 Nov 2010    rz32.zip
28 Aug 2011     rz33.zip   rz33-1.zip  (bug fix)
1 Sept 2011      rz35.zip   with a new look see example bubble.txt
26 Sept 2011    rz35-1.zip  (bug fix and include "syscall")  readme
13 July 2013    rz35-2.zip  (refresh, no executable)
28 Feb 2013     rz37-2.zip    include pointer to function 
1 Apr 2015       rz36x.zip     generate S2 assembly code, run with S23 simulator
13 Feb 2017     rz36-3.zip    improve symbol table, fix bugs in code generator (include as21 and sim21)
15 Aug 2017    rz35-3.zip    use hash in symbol table. (improve rz35 for teaching, gencode for s-code, no syscall)

last update 15 Aug 2017