refract

From Esolang
Jump to navigation Jump to search
refract
Paradigm(s) imperative, multi-dimensional
Designed by User:Phase
Appeared in 2015
Dimensions two-dimensional
Computational class Turing complete
Major implementations Java
Influenced by Fish, GolfScript
File extension(s) .r

refract is a 2D, stack-based, esoteric language based off ><>, GolfScript, Portal, and a bunch of other languages. It was created by User:Phase in June 2015.

refract is a two-dimensional language, meaning the code is not necessarily executed in a linear manner. Using various instructions, the direction the code is read can be changed to one of 8 cardinal directions. It is also a stack-based language, so all operations are performed on a stack. You can also store and retrieve values in a register and create multiple stacks.

Examples

Hello World

"hello world"rv
          o;?m<

Hello World with blocks

{"hello world"r}h {o}phv
                   p;?m<

Fibonacci

0:n84*o1:nv
n:+@@:o*48<

2D movement

Here are some examples of 2D movement in refract.

v
2
n

v makes the interpreter start reading characters from the grid in the down direction. 2 is the next character hit, since we’re reading downwards, and we push a 2 onto the stack. n prints the top value of the stack as a number and pops it off. This program prints 2.

v;<
< ^

This example shows code wrapping and more movement. v sends the direction downwards, < makes it go to the left, then we hit the edge of the grid. The grid is wrapped, so we wrap around to the character on the opposite side of the grid and keep reading in the same direction, and ^ is read. ^ makes the direction up and we hit < which makes it go left again. ; halts the program.

v
\1n
\2n
;

Mirrors reflect the direction and push it in the opposite way. v makes it go down and we hit \. It goes right and prints 1, and then hits the mirror again and goes down. The next mirror makes it go right and it prints 2. We hit the mirror again and the program ends.

Mirrors act differently depending on which way they are hit.

v
1
\2

The mirror makes a downwards movement go right.

>    v
\    2
1
^    <

The mirror makes an upwards movement move left and wrap around.

x makes it a random direction.

x1n;
23
n n
;  ;

This x can go to 1, 2, or 3. It can also wrap around in the other directions.

This is a simple random number generator.

v  <  <
 n n n
  567
>  x1n
  432
 n n n
^  <  <

z and y reflect the direction of movement based on where it hits the letter. The stacks are printed after each example (not taking into account that code starts at the top left and wraps around forever).

2
 2
  2
111z

111222

z222
 1
  1
   1

111222

z111
 2
  2
   2

111222

1
z

11

z
1

11

111y
  2
 2
2

111222

y111
 2
  2
   2

111222

Blocks

Blocks can be made with {}.

{"hello world"r}h {o}phv
                   p;?m<

This creates a block called h that pushes "hello world" to the stack and reverses it. Then it creates another block called p that calls print. The h block is then called and movement goes downwards. Then we go left and halt the program if the stack is empty. Then we call p and print the top of the stack. It loops around and prints "hello world" using blocks!

Blocks can be assigned to any character and are checked before parsing each char.

{21+n;}__

This assigns the block to _, but it could be as abstract as a space.

Portals

Portals are made with Ø and O (Ø can be obtained on OSX/iOS with alt-shift-o).

Ø1nO;

This program prints 1 forever. Ø sets the portal to its position and O sets the position to the portal’s position. Ø isn’t needed in this example, as the portal position always starts at (0,0).

v
\112=?Ø
      >n;
\232)?Ø
O     >n;

Movement starts down and we push 1, 2, and 2 onto the stack. We then check if 1 and 2 are equal. If they are, we set the portal to that position. The next check fires because 3 is greater than 2, and the portal is set there. Movement then goes back downward and we hit O. Movement is kept when traveling through portals, so we go to the second Ø and print 2.

Multiple stacks

Multiple stacks can be useful when you want to modify a small amount of data without affecting everything.

To make a new stack, you use the [ command. This will pop a value off the first stack and get that amount from the first stack. Ok, let’s use an example.

0 1 2 3[;

This takes 0, 1, and 2 from "stack 1" and puts them on "stack 2" because the top of the stack was 3 when [ was called. You can use all the normal operations like reverse and pop, but they will only affect the values on the current stack.

Once you are done with your stack, you can merge the values back onto the original stack with ]. It takes the current stack and merges it with a stack whose id is one less than the current one, so they’re not always being merged to stack 1.

12345 3[  r  ] rnnnnn;
  • Numbers 1-5 are pushed onto the first stack.
  • A second stack is created, pulling 3 values from the first stack.
  • The second stack is reversed.
  • The second stack is removed, putting its values back on the first stack.
  • Output: 12543. The top three values were reversed!
12345 3[r 2[r]] rnnnnn;
  • Numbers 1-5 are pushed onto the first stack.
  • A second stack is created, pulling 3 values from the first stack.
  • The second stack is reversed.
  • A third stack is created, pulling 2 values from the first stack.
  • The third stack is reversed.
  • The third stack is removed, putting its values back on the second stack.
  • The second stack is removed, putting its values back on the first stack.
  • Output: 12534. This is a really long way to do @@.

Operators

Movement and execution

  • > < ^ v Change the direction (right, left, up, down respectively).
  • / \ | _ # Mirrors; the IP will change direction depending on what direction it already has.
  • y z Changes the direction diagonally depending on how it hits each letter.
  • x Random direction.
  • ! Trampoline - skip the following instruction.
  • ? Conditional trampoline - pop one value off the stack. The next instruction is skipped if the popped value is zero.
  • . Jump - pop y and x off the stack, and move the IP to (x,y) in the codebox. The current direction is retained.

Literals and operators

  • 0-9 a-f Push the corresponding value onto the stack. a = 10, ..., f = 15.
  • + - * , % Addition, subtraction, multiplication, division and modulo, respectively. Pop x and y off the stack, and push y operator x. Division is float division (meaning 94,n; outputs 2.25 and not 2). Division by 0 raises an error.
  • = Equals. Pop x and y off the stack, and push 1 if y = x, and 0 otherwise.
  • ) ( Greater than and less than, respectively. Pop x and y off the stack, and push 1 if y operator x, and 0 otherwise.
  • ' " Single and double quote - enable string parsing. String parsing pushes every character found onto the stack until it finds a closing quote.
  • E Push 1 if the top of the stack is even, 0 otherwise.
  • Pop the top value and push the square root of it.
  • π Push PI.

Stack manipulation

  • : Duplicate the top value on the stack.
  • ~ Remove the top value from the stack.
  • $ Swap the top two values on the stack.
  • @ Rotate the third value on the stack to the top.
  • r Reverse the stack.
  • l Push the length of the stack onto the stack.
  • m Push 1 if the stack is empty, 0 if not.
  • [ Pop x off the stack and create a new stack, moving x values from the old stack onto the new one.
  • ] Remove the current stack, moving its values to the top of the underlying stack.
  • Σ Pop everything off the stack, add all the values, and push the sum.
  • Π Pop everything off the stack, multiply all the values, and push the product.

Input/output

  • o n Pop and output as a character and a number, respectively. Output is written to stdout.
  • i Read one character from stdin and push it onto the stack. The character should not be shown when read from console. When no more input is available, -1 is pushed.
  • j Read the stdin as a number.

Reflection/miscellaneous

  • & Pop the top value off the stack and put it in the register. Calling & again will take the value in the register and put it back on the stack. See The register.
  • g Pop y and x off the stack, and push the value at x,y in the codebox. Empty cells are equal to 0.
  • p Pop y, x, and v off the stack, and change the value at x,y to v. E.g. 123p puts 1 at 2,3 in the grid.
  • ; Halt the program.
  • Ø Set the portal to the current position.
  • O Go to the current portal’s position.

The space character is simply a NOP and is allowed anywhere.

External resources