Skip to main content Link Search Menu Expand Document (external link)

Compiler “ramc-ram”

RAM has a very simple assembler-like language, consisting of direct and indirect reading/writing from/to registers or input/output tape. Also, there are three control-flow instructions.

Source code files end with .ram extension; compiler output uses extension .bram.

Language syntax

A program written for RAM consists of two sections, which can be intermixed and repeated in any order, but the preferred order is as follows:

INPUT 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.

Instructions section

There exist many variations of RAM instructions, unfortunately, the syntax is not very unified. The reason might be that RAM 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 indirect operand (*i), where the address of operand specified is stored in register Ri.

The following table describes all possible instructions, usable in the RAM simulator:

Instruction Constant (=i) Direct (i) Indirect (*i)
READ   Ri ← next input  
WRITE output ← i output ← Ri output ← M[Ri]
LOAD R0i R0Ri R0M[Ri]
STORE   RiR0 M[Ri]R0
ADD R0R0 + i R0R0 + Ri R0R0 + M[Ri]
SUB R0R0 - i R0R0 - Ri R0R0 - M[Ri]
MUL R0R0 * i R0R0 * Ri R0R0 * M[Ri]
DIV R0R0 / i R0R0 / Ri R0R0 / M[Ri]
JMP   IPi  
JZ   if R0 == 0 then IPi  
JGTZ   if R0 > 0 then IPi  
HALT   halts the simulation  

The table describes also the behavior of each instruction. The compiler does not care about the behavior, but about the syntax of the instructions, which is also incorporated in the table.

Code example

For example, this is a valid program:

; Copy R(X) to R(Y)
; input tape:
;   destination register: X
;   source register: Y
; output:
;   R(X) = R(Y)
;   R(Y) = R(Y)

<input> 3 4 'hello' 'world'

; load X,Y
read 1
read 2

; load r.X, r.Y
read *1
read *2

; copy
load *2
store *1