Roco 20071014

Version of implementation Roco of programming language Roco

This is the last version of Roco interpreter and the only one currently available.

Examples:

Hello, World! - Roco (199):

This code uses only main coroutine; it outputs the message character by character, using their ASCII codes, and stops.

cout 72
cout 101
cout 108
cout 108
cout 111
cout 44
cout 32
cout 87
cout 111
cout 114
cout 108
cout 100
cout 33
ac

Fibonacci numbers - Roco (200):

This example uses iterative definition of Fibonacci numbers by saving them all in cells [2]..[17]. Cell [0] stores the index of the next number to be calculated, and cell [1] is used as temporary storage. Loops are implemented as coroutines, since by definition coroutines loop until another coroutine is called or execution is interrupted with ac command.

co calc{
/* break the loop when the counter is 2+16, since numbers start with cell 2 */
eq [1] [0] 18
if [1] ac

/* calculate next number and store it to [[0]]*/
sub [1] [0] 1
set [[0]] [[1]]
sub [1] [0] 2
add [[0]] [[0]] [[1]]

/* output */
iout [[0]]
cout 44
cout 32

/* increment counter */
add [0] [0] 1
}

/* initialize with first Fibonacci numbers */
set [0] 4
set [2] 1
set [3] 1

iout [2]
cout 44
cout 32
iout [3]
cout 44
cout 32

ca calc

cout 46
cout 46
cout 46
ac

Factorial - Roco (201):

This example uses iterative definition of factorial. Cell [0] stores the current number, cell [1] is temporary, and cell [2] stores factorial of current number.

co calc{
/* break the loop when the counter is 17 - the number for which we don't need factorial */
eq [1] [0] 17
if [1] ac

/* output current factorial */
iout [0]
cout 33
cout 32
cout 61
cout 32
iout [2]
cout 13
cout 10

/* calculate next number and store it to [2]*/
add [0] [0] 1
mul [2] [2] [0]
}

/* initialize with 0! = 1 */
set [0] 0
set [2] 1

ca calc

ac

CamelCase - Roco (328):

The example is commented in detail. Coroutine char reads characters from standard input one by one and checks whether they are letters. Coroutine letter is called for characters which turned out to be letters; it converts them into required case and prints them. Note that not command inverts all bits of the number, so it can’t be used to negate a logical value (which is stored as 0 or 1) — one has to subtract this value from 1.

/* [0] - current character 
   [1] - last character was space?
   rest are temporary variables (used within one iteration only)
*/

co letter{
/* coroutine to process the case of a known letter */
/* if it is uppercase, and last one was letter, change to lowercase */
sub [4] 1 [1]
and [5] [2] [4]
if [5]
    add [0] [0] 32
/* if it is lowercase, and last one was space, change to uppercase */
and [5] [3] [1]
if [5]
    sub [0] [0] 32
/* print the character */
cout [0]    
set [1] 0
ac
}

co char{
/* read next character to [0] */
cin [0]

/* break the loop when the next character is end-of-line (ASCII 10) */
eq [2] [0] 10
if [2] ac

/* check whether this character is a letter at all [2] - uppercase, [3] - lowercase, [4] - at all, [5]-[6] - temporary */
/* uppercase */
gt [5] [0] 64
lt [6] [0] 91
and [2] [5] [6]

/* lowercase */
gt [5] [0] 96
lt [6] [0] 123
and [3] [5] [6]

/* at all */
or [4] [2] [3]
sub [5] 1 [4]

/* if this is not a letter, ONLY change [1] */
if [5]
    set [1] 1
/* otherwise, call the coroutine to handle this */
if [4]
    ca letter
}

/* at the start mark that last character was space */
set [1] 1
ca char

ac