Rain

From Esolang
Jump to: navigation, search
Rain
Paradigm(s) imperative
Designed by dok
Appeared in 2017
Memory system stack-based
Dimensions two-dimensional
Computational class
Reference implementation
Influenced by Befunge,><>
File extension(s) .rf


Rain is a two-dimensional fungeoidal esoteric programming language invented in 2017 by dok with the goal of being difficult to write while remaining possible to compile.

Concepts

Rain is a two-dimensional language, the code can be read in only two directions either up or down, left and right direction are used for function call. It is a stack-based language, so all operations are performed on a stack. In addition to the arithmetic stack a function call stack can be used to store information as one value can be stored and retrieved per function context. In a way each column can be considered as a method, thus libraries can be created and used with the necessity of doing the proper "placing and routing".

Code execution

Rain can be executed in two directions, from top to bottom or from bottom to top. The main program start out at (0,0), i.e. the top-left of the file. It initially moves down. Execution will not stop until a ; instruction is met (on the main program), or an error occurs. Trying to execute a space instruction will raise an error, trying to execute an instruction outside of the program bounds will raise an error too.

In the following example, the Instruction Pointer moves downwards :, make a jump to the right >, upwards | and return ;to the main program and stops ;.

: ;
> |
;  

Instructions

Rain has the following commands:

Cmd Description
: NOP: do nothing.
09 Push corresponding number onto the stack
+ Addition: Pop two values a and b, then push the result of a + b
- Subtraction: Pop two values a and b, then push the result of b - a
* Multiplication: Pop two values a and b, then push the result of a * b
/ Integer division: Pop two values a and b, then push the result of b / a, rounded down.
% Modulo: Pop two values a and b, then push the remainder of the integer division of b/a.
) Greater than: Pop two values a and b, then push 1 if b > a, otherwise 0.
( Lesser than: Pop two values a and b, then push 1 if b < a, otherwise 0.
= Equals: Pop two values a and b, then push 1 if y = x, otherwise 0.
| Intercept: only for left and right jump, else act as a NOP.
> Jump right: from the current position to the right, find the first intercept symbol, invert the direction and continue on the next instruction after the found intercept.
< Jump left: from the current position to the left, find the first intercept symbol, invert the direction and continue on the next instruction after the found intercept.
] and [ Tunnel: A jump outside of a tunnel will pass through the tunnel ignoring all intercept in it.
! Trampoline: jump over the following instruction in the current direction.
? Conditional trampoline: pop one value off the stack. The next instruction is only executed if the popped value is 0.
^ Duplicate top stack value
\ Swap top stack values
_ Over: push on the stack the value under the top element of the stack.
~ Push on the stack the length of the stack.
` Pop (remove) top stack value and discard
. Store: Pop one value off the stack to the local variable.
, Fetch: Push the value of the local variable.
# Pop top of stack and output as integer
$ Pop top of stack and output as ASCII character
" or ' Toggle stringmode (push each character's ASCII value all the way up respectively to the next " or ')
& Get integer from user and push it
@ Get character from user and push it
; End function call, return to cell next to last call (restore previous direction)

Examples

Hello, world!

:    
: ;  
: > |
: " $
: H $
: e $
: l $
: l $
: o $
: , $
:   $
: W $
: o $
: r $
: l $
: d $
: ! $
: " $
: + ;
: 5  
: 5  
: 0  
> |  
;

Cat program

: ;
| <
@ $
^ ;
0 ?
) )
? 0
; ^
$ @
> |
;

Factorial

Asks for a number n, and outputs it's factorial. Assumes the input is a non-negative integer.

& ;
^ > |
? 1 )
! ^ ?
> | ;
# : ^
5 : 1
5 : -
+ | <
$   *
;   ;


Fibonacci sequence

Asks for a number n, and outputs all the Fibonacci numbers up to fib(n), with n starting at 0 with fib(0) = 0 and fib(1) = 1.

0 ;   ;  
1 > | <  
& : . ,  
1 : : +  
+ : , _  
> | 0 > |
5   ) \ ^
5   ? . #
+   ; - "
$   , 1  
;   > | "
    ;   $
        ;

Ackermann function

Ask for two numbers an return the result of the Ackermann function.

& ;   ;
& > | < ;
> | _ : +
# : . : 1
5 : , : `
5 : ? : \
+ : > : |
$ : , :
; : ? :
  : ; :
  1 ^ :
  - . :
  1 , :
  ` ? :
  | < :
    , :
    ? :
    ; :
    _ :
    \ :
    1 :
    - :
    > |
    \ :
    1 :
    - :
    \ :
    > |
     ;


Pascal's Triangle

Ask for a number n and print the Pascal's Triangle up to n row

1       
1       ;
& ; ;   > |
| < ,   ; .
^ : > | ? ,
0 : + . ~ #
) : 5 > | 8
? : 5 , : 4
! , . $ : *
> 1 | ; : $
1 > | < | <
- . _ |   ,
^ : + :   ;
0 : . :
) : ~ :
^ : 1 :
? : = :
; : ? :
? : > |
! : ,  
> | ;  
;

print string

This method can be used to print the stack as characters up to the first null value.

         ;
call-> | <
       ^ :
       ? $
       ; :
       > |
       ;  

stack reverse

This method can be used to reverse the entire the stack.

         ; ;
call-> | < ,
       . | <
       ~ : ?
       1 : =
       = : 1
       ? : ~
       > | .
       , : \
       > > |
       ; ;

which is the same as :

public void reverse(Stack st) {
    int m = (int)st.Pop();
    if (st.Count != 1)
        reverse(st);
     Push(st , m);
}
public void Push(Stack st , int a) {
    int m = (int)st.Pop();
    if (st.Count != 0)
        Push(st , a);
     else
        st.Push(a);
     st.Push(m);
}