Compiler “raspc-rasp”
RASP compiler has a very simple assembler-like language, consisting of direct reading/writing from/to registers or input/output tape. Also, there are three control-flow instructions. Syntax is very similar to RAM machine, just RASP doesn’t support indirect addressing.
Source code files end with .rasp
extension; compiler output uses extension .brasp
.
Language syntax
A program written for RASP is composed of three sections, which can be intermixed and repeated in any order, but the preferred order is as follows:
INPUT section
ORG section
INSTRUCTIONS section
Input section
The INPUT
section contains definitions the content of input tape - one or more lines in the form:
<input> ITEMS
where ITEMS
is a space-separated list of inputs. Each input is one word - it might be any number or string. Strings must be in quotes - single ('
) or double ("
).
For example, the input section might be:
<input> 1 2 3 'hello' 'world!'
In this case, there are five inputs: numbers 1,2,3, then word “hello” and the last one is “world!”. Note floating-point numeric values are not supported.
ORG section
The ORG
pseudo-instruction sets the address of the following instruction to a specified value. For example:
org 5 ; sets next address to 5
read 0
By default, if ORG is not specified in the beginning of the program, it is added implicitly as ORG 20
. It is because registers in RASP are stored in memory (R0 at address 0, etc.), so this implicit ORG pre-allocates 20 registers.
Instructions section
There exist many variations of RASP instructions, unfortunately, the syntax is not very unified. The reason might be that RASP is not a real machine.
Each instruction must be on a separate line, in the following form:
[LABEL:] INSTRUCTION [; optional comment]
Each instruction position can be optionally labeled with some identifier (LABEL
field), followed by a colon (:
) character. The labels can be then referred to in other instructions.
Comments can be one-line or multi-line. One-line comments begin with a semicolon (;
), hash sign (#
), double-dash (--
) or double-slash (//
). A one-line comment continues to the end of the line. Multi-line comments start with /*
characters and end with */
characters. In-between there can be multiple lines of text, all treated as comment.
An instructions consists of the operation code, optionally followed by an operand separated with at least one space (
), but not with a newline.
Operation code is expressed as an abbreviation of corresponding operation (e.g. SUB
for SUBtraction). An operand can be one of three types: constant (=i
), direct operand (i
), where i
specifies the register index on tape and label, pointing to the address in memory.
The following table describes all possible instructions, usable in the RASP simulator:
Instruction | Constant (=i ) | Direct (i ) | Label |
---|---|---|---|
READ | Ri ← next input | ||
WRITE | output ← i | output ← Ri | |
LOAD | R0 ← i | R0 ← Ri | |
STORE | Ri ← R0 | ||
ADD | R0 ← R0 + i | R0 ← R0 + Ri | |
SUB | R0 ← R0 - i | R0 ← R0 - Ri | |
MUL | R0 ← R0 * i | R0 ← R0 * Ri | |
DIV | R0 ← R0 / i | R0 ← R0 / Ri | |
JMP | IP ← label | ||
JZ | if R0 == 0 then IP ← label | ||
JGTZ | if R0 > 0 then IP ← label | ||
HALT | halts the simulation |
Code example
For example, this is a valid program:
; N! (factorial)
; Program reads an integer number from the input tape, calculates its factorial and prints the result
; onto the output tape.
org 5 ; reserve 5 registers
;saves the constant 1 into R2 and R3 registers
load =1
store 2
store 3
;reads a number from the input tape
read 1
;if the number is greater than 0, jump to "ok", otherwise, jump to "finish"
load 1
jgtz ok
jmp finish
;the loop to calculate the factorial value
ok:
load 3
sub 1
jz finish
load 3
add =1
store 3
mul 2
store 2
jmp ok
;print the result
finish:
write 2
halt