ROOP

From Esolang
Jump to: navigation, search

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.

Implementation

C++ Implementation in GitHub

Online interpreter