ROOP
ROOP (Real Object-Oriented Paradigm) is a two-dimensional language created by User:-Dark-Phantom- on December, 2015. The language uses a rectangular grid of objects represented as characters in the source code. Some objects are static and others can move.
Grid
In each slot of the grid can be only one object, or be empty.
The width of the grid is determined by the line of code with more characters. Lines with fewer characters are filled with empty spaces on the right.
The grid is implicitly surrounded by blocks (#
). The following code:
2A3
becomes:
##### #2A3# # # #####
Note: The above example had no spaces under the characters, there was just one newline character after 3
. This creates a line of empty spaces.
Objects
The objects are divided into a few categories: Data, Operators, Pipes, Block. In turn, the operators are divided between Normal Operators and Special Operators.
Data
Objects of this type can contain one of the following four types of data: signed integer, string, input, output. They also have a direction of movement: left or right (starting to the right). And they also have gravity, so if there is a space below, will fall.
Their position is updated in phase two of each update.
They can be empty or not empty. It is considered an empty object to an integer equal to zero and a string without characters. Are considered non-empty objects nonzero integers, strings with at least one character, input and output.
Normal Operators
Operators run on the phase one of each update.
Operators get several objects from up, left or right and create a new object with the result. Some operate separately on each axis (grab an object above and put the result below, take an object on the left and put the result on the right).
Except some special cases, operators have two versions. In uppercase mark the objects to disappear for the next update. In lowercase do not.
If the operator attempts to use objects with wrong types or the result could not be delivered, then the operation is considered failed and objects are left unchanged.
The created objects can be placed in an empty space or in a pipe.
In the table below you can see every normal operator with the kind of object that needs at each place and a description of what it does. Those who say mixed means that they can be numbers or strings. Those who say "any" means that it can be any type of data.
Character | Objects that are needed | Description |
---|---|---|
A |
up, left, right = number | Add the numbers. It can operate with only two of the three numbers. |
up, left, right = mixed | Concatenate the strings. The numbers are converted into strings. It can operate with only two of the three strings. | |
S |
up, left, right = number | Subtract the numbers. It can operate with only two of the three numbers. |
up, left, right = mixed | Removes all occurrences of the strings in the first string. The numbers are converted into strings. It can operate with only two of the three strings. | |
M |
up, left, right = number | Multiply the numbers. It can operate with only two of the three numbers. |
up, left, right = mixed | Repeats the string. Need only one string and one or two numbers. | |
D |
up, left, right = number | Divide the numbers. It can operate with only two of the three numbers. If the divisor is zero, the operation is not performed. |
up, left = string | Finds the first occurrence of the string on the left in the string above. Cut the first part of the string and put it under. Cut the second part and puts it on the right. The string on the left is not in any of the two results. If the string to search is empty or can not be found then the first result has all the string of above and the second is empty. | |
up = string left = number |
Cut the string at the specified position. Put the first part of the string below. Put the second part on the right. If the number is negative, it is calculated from the end of the string. If it is greater than the size of the string then the first result has all the string of above and the second is empty. | |
R |
up, left, right = number | Divide numbers and calculates the remainder. It can operate with only two of the three numbers. If the divisor is zero, the operation is not performed. |
up, left, right = string | Replaces all the occurrences of the string on the left in the string of above by the string of the right. The numbers are converted into strings. | |
F |
up, left = number | Calculates the greatest common divisor between two numbers. |
up, left = mixed | Find the first occurrence of the string on the left in the string of above, puts the index below. If a string is empty or can not be found, the result is -1. The numbers are converted into strings. | |
P |
Separate axes first = number |
If there is a prime number puts a one, else puts a zero. |
Separate axes first = string |
Calculates the length of the string. | |
Z |
Separate axes first = number |
Reverse the number. The leading zeros are not part of the number. |
Separate axes first = string |
Reverse the string. | |
N |
Separate axes first = any |
If there is a empty object puts a one, else puts a zero. |
E |
up, left, right = any | If the objects are equal puts a one, else puts a zero. It can operate with only two of the three objects. |
G |
up, left, right = number | If the number of above is greater than the left which in turn is greater than the right puts a one, else puts a zero. It can operate with only two of the three numbers. |
up, left, right = mixed | If the string of above is greater than the left which in turn is greater than the right puts a one, else puts a zero. They are compared lexicographically. The numbers are converted into strings. It can operate with only two of the three strings. | |
K |
Separate axes first = number |
Creates a random number. The range used depends on the number received. If greater than zero [0, n), if less than zero (n, 0], if zero (minimum, maximum). |
Separate axes first = string |
Creates a string with a single character, chosen at random from the string received. If empty creates an empty string. | |
Y |
Separate axes first = number |
Convert number to string. |
Separate axes first = string |
Convert string to number. If it is unable to convert, the operator fails. | |
Separate axes first = input |
Creates a output object. | |
Separate axes first = output |
Creates a input object. | |
L |
Separate axes first = number |
Calculates the absolute value. |
Separate axes first = string |
Converts letters to lowercase. | |
U |
Separate axes first = number |
If the number is greater than zero returns 1, if it is less than zero returns -1, and if it is zero returns zero. |
Separate axes first = string |
Converts letters to uppercase. | |
C |
up, left, right = any | Reverses the direction of the object that is above and the object that is on the sides pointing to this operator. It works with any number of objects, no need all three. |
c |
Separate axes first, second = any |
Swap the objects. |
W |
up = input | Get string from Input above. Put the object below. If there is an output object below, send it to the screen. |
up = mixed | If there is an output object below, send it to the screen. | |
w |
up = input | Get number from Input above. Put the object below. If there is an output object below, send it to the screen. |
up = mixed | If there is an output object below, send it to the screen. |
Special Operators
Special operators work like normal operators but also can receive objects from the pipes.
Character | Objects that are needed | Description |
---|---|---|
V |
up = any | Get object from above (or pipe), put object below. |
X |
up, left, right, down = any | Erase objects of the four sides. The lowercase x is not an operator but a pipe.
|
T |
up = any | If it receives a non-empty object, puts the number of the current tick below. |
H |
up = any | If it receives a non-empty object, the program ends after phase one of the upgrade. |
h |
up = any | If it receives a non-empty object, the program ends after phase one of the upgrade. Prints all the numbers and strings that remain. |
Pipes
The pipes are objects in which data objects can travel. The whole trip is made in the same update, sending objects up to a special operator. If the object can not be delivered, then the operator that put the object in the pipe fails.
Creating an infinite loop is undefined behavior. The interpreter is not required to detect it and can stay in an infinite loop or produce a stack overflow.
The direction in which the objects move depends on the pipe and operator rather than the direction in which the objects points. Objects created under an operator will go down. Objects created on the right will go to the right.
Character | Name | Description |
---|---|---|
- |
Horizontal pipe | Objects that come from the right will go to the left, the others will go to the right. |
| |
Vertical pipe | Objects that come from below will go upwards, the others will go to down. |
+ |
Intersection | The objects continue in the direction they go. |
* |
Bouncer | The objects go in the opposite direction in which they arrive. |
> |
Turn right | The objects rotate 90 degrees to the right (ie clockwise). |
< |
Turn left | The objects rotate 90 degrees to the left (ie counterclockwise). |
% |
Duplicator | Duplicates the object and sends one 90 degrees to the left and the other 90 degrees to the right. The second waits for the first to complete the trip before traveling. The operator fails if both objects can not be delivered. |
! |
Teleporter | Search in the direction of the object another teleporter. If found, the object gets there keeping its direction. |
x |
Eraser | Delete the object. It never fails. |
Block
It is the #
character. It does nothing.
Updates
Each update is divided into two phases. After the two, the current tick is increased by one.
Phase one
Operators are updated one by one, starting at the top left, line by line. Objects created by the operators do not appear in the grid until the phase is not over. The objects can only be created in areas that are now empty and that no other operator used in this phase.
The objects used do not appear in the next phase if at least one of the operators put them to removal (normally uppercase versions).
In this same phase it is where the objects run through the pipes.
If there is no object at the end of the phase, the program ends.
Phase two
The positions of the objects are updated one by one, starting at the top left, line by line. Each object tries first to go down, if it can not then try to go in the direction where it points.
All positions are updated at the same time, those who go down have priority over those who go to the right, which have priority over those who go to the left. Here's an example:
######## #1 2#12# ######## # #1## # 1 #3## #3 2#5 # ######## # 1 9 # #35735 # ########
Assuming that the odd numbers point to the right and even numbers to the left:
######## # 12#12# ######## # # ## # #1## #312#35# ######## # 1 # #357935# ########
Literals
When the source code is converted, the literals are replaced by objects. There are single character literals and multiple characters.
Single character
The digits (0
to 9
) are individually replaced by a numeric object containing that value.
The character I
is replaced by the input object.
The character O
is replaced by the output object.
Multiple character
They can be horizontal or vertical. All the characters are replaced by empty spaces except for the first (top left) which is replaced by the object with the corresponding value.
Horizontal | Vertical | Description |
---|---|---|
() |
[] |
It contains an integer. Can have a - sign.
|
"" |
'' |
It contains a string. Can be used the escape character (\ ) as in C.
|
// |
\\ |
It contains a string that identifies one of the constants described below. |
{} |
It contains a comment. Does not create any object and can not be vertical. |
Constants
ID | Name | Type | Content |
---|---|---|---|
ll |
Lowercase letters | String | abcdefghijklmnopqrstuvwxyz |
ul |
Uppercase letters | String | ABCDEFGHIJKLMNOPQRSTUVWXYZ |
al |
All letters | String | abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ |
aa |
All ASCII | String | Contains all ASCII characters (0 to 127) |
pa |
Printable ASCII | String | Contains all printable ASCII characters (32 to 126) |
dd |
Decimal digits | String | 0123456789 |
od |
Octal digits | String | 01234567 |
lhd |
Lowercase hexadecimal digits | String | 0123456789abcdef |
uhd |
Uppercase hexadecimal digits | String | 0123456789ABCDEF |
ahd |
All hexadecimal digits | String | 0123456789abcdefABCDEF |
b64 |
Base64 | String | ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ |
b58 |
Base58 | String | 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz As in bitcoin. |
b36 |
Base36 | String | 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ |
rn |
Roman numerals | String | IVXLCDM |
min |
Minimum | Number | minimum integer that the interpreter can represent. |
max |
Maximum | Number | maximum integer that the interpreter can represent. |
number | Character | String | Use the number to calculate n % 128, then creates a string with the corresponding ASCII character. The number may only be composed of decimal digits (0 to 9). |
Examples of literals
(-123) ' /dd/ [ a \ 4 b l {This is a comment} 5 "zcy\"" l 6 d \ ] '
The first object contains the number -123
. The second object contains the number 456
. The third object contains the string abcd
. The fourth object contains the string z y"
(Note that the second character was replaced by a space by the previous literal). The fifth object contains the string 0123456789
. The sixth object contains the string abcdefghijklmnopqrstuvwxyz
.
Examples
Hello, World!
"Hello, World!" h
Cat
Infinite
I W O
Infinite Loop
1
Truth-machine
I wX nw hO
Is prime
I w#H P w O
Quine
It has a trailing newline character
"##V ---V\n ---%\n V-< -V\n/92/ | |\nA/110/X| |\n|/10/d-< |\n||---> |\n|V /10/A |\n| #### |\nV X # |\n a /34/A |\n# v### |vH\n X X | #\n W W V |W\n O#O# --<O#\n # # #\n" ##V ---V ---% V-< -V /92/ | | A/110/X| | |/10/d-< | ||---> | |V /10/A | | #### | V X # | a /34/A | # v### |vH X X | # W W V |W O#O# --<O# # # #
Computational class
ROOP is turing complete, as it is possible to translate any brainfuck code to it, using the following table. Each section of code goes under the previous. Use a stack with cells of 7 bits, unsigned and without wrapping.
Brainfuck | ROOP | Comments |
---|---|---|
Start |
\0 0 \ VV |
It goes in the beginning of the program. |
>
|
||1# ||v |V -V | A| |#-%##V V V \| #0| p E \| # #v| M V A #C ##|# |-> | V ||----> |
|
<
|
|| 1# VV v S # |># V| || |
|
+
|
|| -+V V # D-V V # X |V1d----| ||# /aa/! || # || f1# || X a V| #| | | | |/aa/ | V # | d | X# X | 1d# | # ! | V V A # V V----># |A # |+># || |
|
-
|
|| -+V V # D-V V # X |V1d----| ||# /aa/! || # || f(-1) || X aC V| #| | | | |/aa/ | V # | d | X# X | 1d# | # ! | V V A # V V----># |A # |+># || |
|
.
|
|| |-| -|| |%+V | V # | D | V# VV>1dX # WX V O# V| # || |
|
,
|
|| -----V"" || | # C -+V | V### V # %--> D-V |--< V| X V I%--< ||1d # V | ||## A | V| #|# ###V| | | -< | | WX | | | | | |1dX | |-+-> | V V | A # | #|# V V> V A # |+-># || |
Read a string ending with a new line but takes only the first character. |
[
|
|| |+-------- { <- A } ||-------- { <- B } ||--V -+% |V V ## DV V V# X! |>1d#/aa/ | #-V # | f | X| | |--> | T ! V #V> U V%V MV M |------ { -> C } | |------ { -> D } V| || -+--+< |+--> || |
You have to connect the inputs and outputs with the corresponding |
]
|
|| -+------ { -> A } ------- { -> B } |------- { <- C } ||------ { <- D } || |
You have to connect the inputs and outputs with the corresponding |
End |
H |
It goes in the end of the program. |