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:
- It has only integer as primitive data. (natural size depends on
implementation)
- Global variables must be declared before their use. Local
variables are automatic (not required to be declared).
- Global variables can be array. The size of array must be known
at compile time. An array has only one dimension. Local
variables can be only scalar.
- Reserved words are: if, else, while, return, print.
- Operators are: +, -, *,
/, ==, !=, <, <=, >, >=, !, &&, ||, *
(dereference), & (address).
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 int
asm(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
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