# Ora

Ora is a (semi)reversible language created by User:zeotrope, it is influenced heavily by 2D-Reverse.

## Instructions

• \$ : Start position of program, moving right. u, d, l and r may also be used instead of \$ to specify both a start position and direction.
• @ : Ends program.
• \ : Right reflector.
• / : Left reflector.
• - : Vertical reflector, does nothing if encountered when moving horizontally.
• | : Horizontal reflector, does nothing if encountered when moving vertically.
• C : Clockwise Rotate.
• A : Anti-clockwise Rotate.
• X : If current buffer element is non zero acts like a right reflector, otherwise it acts like a left reflector.
• x : If current buffer element is non zero acts like a left reflector, otherwise it acts like a right reflector.
• u : Set pointer direction to up.
• d : Set pointer direction to down.
• l : Set pointer direction to left.
• r : Set pointer direction to right.

## Operation

The program pointer starts travelling at the \$ symbol, moving towards the right. The starting direction may be altered by using the u, d, l and r instructions as a start instruction instead of \$.

If the program encounters a space or a "." as it moves it manipulates an infinite one dimensional buffer based on the direction it is travelling in the following manner:

• If the program is moving right the current buffer element is incremented.
• If the program is moving left the current buffer element is decremented.
• If the program is moving up the next (right) buffer element is set as the current element.
• If the program is moving up the previous (left) buffer element is set as the current element.

If a program move is performed without encountering a "." or a space, none of the above is executed.

## Examples

### Cell Clear

Decrement current buffer element until it is zero.

```     /.A
\$....r-x
@
```

Brainfuck equivalent:

```++++[-]
```

### Rewind

Move left along buffer until a zero element is encountered, increment it.

```      /.\/.@
. rX
/./ |.
.   \/
/./
.
\$-/
```

Brainfuck equivalent:

```>+>+>+[<]>
```

### Clear Previous Cell

Decrement current buffer cell and all previous buffer cells until zero, stop at first zero encountered.

```   /..\
.  |/.A
r../  \r-x
| .
\-x@
```

```     /...\/-----\
.   .|@    |
\$..../   \rX /.\|
/./ . .|
\---/ \/
```

## Interpreter

```class TwoD
attr_accessor :pos, :direction, :bpos, :buffer
def initialize(string)
@prog = string.split("\n").collect {|x| x.split("")}
@len = @prog.length
@direction = :right
@bpos = 0
@buffer = [0]
@bf = []
locate_start
end

def gen_bf(i)
@bf << i
end

def print_bf
puts ""
@bf.each {|x| print x}
puts ""
end

def locate_start
@pos = [0, 0]
(0..@len-1).each do |i|
case
when @prog[i].include?("\$") then
@pos = [i, @prog[i].index("\$")]
when @prog[i].include?("u") then
@pos = [i, @prog[i].index("u")]
@direction = :up
when @prog[i].include?("d") then
@pos = [i, @prog[i].index("d")]
@direction = :down
when @prog[i].include?("l") then
@pos = [i, @prog[i].index("l")]
@direction = :left
when @prog[i].include?("r") then
@pos = [i, @prog[i].index("r")]
@direction = :right
end
end
end

@current = @prog[@pos[0]][@pos[1]]
end

def buffer_right
if (@bpos += 1) >= @buffer.length
@buffer << 0
end
gen_bf(">")
end

def buffer_left
if (@bpos -= 1) < 0
@buffer =  [0]+@buffer
end
gen_bf("<")
end

def step
case @direction
when :up    then @pos[0] -= 1
when :down  then @pos[0] += 1
when :right then @pos[1] += 1
when :left  then @pos[1] -= 1
end
eval
end

def eval_spaces
case @direction
when :up    then buffer_right
when :down  then buffer_left
when :left  then @buffer[@bpos] -= 1; gen_bf("-")
when :right then @buffer[@bpos] += 1; gen_bf("+")
end
end

def eval
case @current
when "/" then
case @direction
when :up    then @direction = :right
when :down  then @direction = :left
when :left  then @direction = :down
when :right then @direction = :up
end
when "\\" then
case @direction
when :up    then @direction = :left
when :down  then @direction = :right
when :left  then @direction = :up
when :right then @direction = :down
end
when "C" then
case @direction
when :up    then @direction = :right
when :down  then @direction = :left
when :left  then @direction = :up
when :right then @direction = :down
end
when "A" then
case @direction
when :up    then @direction = :left
when :down  then @direction = :right
when :left  then @direction = :down
when :right then @direction = :up
end
when "X" then
if @buffer[@bpos] != 0
@current = "\\"
else
@current = "/"
end
eval
when "x" then
if @buffer[@bpos] != 0
@current = "/"
else
@current = "\\"
end
eval
when "u" then @direction = :up
when "d" then @direction = :down
when "r" then @direction = :right
when "l" then @direction = :left
when "|" then
case @direction
when :left  then @direction = :right
when :right then @direction = :left
end
when "-" then
case @direction
when :up    then @direction = :down
when :down  then @direction = :up
end
when ".", " " then eval_spaces
when "@" then disp; print_bf; exit(1)
end
end

def disp
puts "\tbuffer #{\$test.buffer}\tpos #{\$test.pos}\tcurrent #{\$test.current}\tdirection #{\$test.direction}"
end

def run
disp
step
end

def print_prog
(0..@len-1).each do |i|
(0..@prog[i].length).each do |j|
if ([i, j] == @pos)
print "\033[44;37;5m#{@current} \033[0m"
else
print @prog[i][j]
end
end
print "\n"
end
STDOUT.flush
sleep(0.3)
system("clear")
end
end

\$steps = ARGV[1]
system("clear")

if \$steps.nil?
loop do
\$test.print_prog
\$test.disp
\$test.step
end
else
\$steps.to_i.times do |x|
\$test.print_prog
\$test.disp
\$test.step
end
end
```
```ruby 2d.rb <file> <steps>
```

## Ideas

• Function definition using <,>, ^ and v. Code in between these symbols is stored as a named function, these symbols may also be used as entry point specifiers , note: function's 2d representation must be stored. If a function omits certain entry points, it will not be called if it is executed using that entry point. 2 entry points must be specified at a minimum.

Defines a function s which can be executed from the left or from the bottom:

``` >s]...\
.
^
```

Definition of the built-in clockwise operator C.

```  \$\
v
C     @
]     v
/>/<->C]\]C\
| ]     ^  |
| C     \--/
| ^
\-/
```