Patternfuck

From Esolang
Jump to navigation Jump to search
This is still a work in progress. It may be changed in the future.

Patternfuck is an esolang made by Robolta. It uses a tape-based memory that resembles brainfuck but differs in how it uses the square brackets. The Pattern feature is heavily inspired by Kuggo who originally came up with the idea of patterns for URCL (known as bit patterns).

Overview

Patternfuck, like brainfuck, operates on a tape-based memory.

Unlike brainfuck, Patternfuck specifies the tape to be infinite in length (both left and right) with cell values that can be any integer (initialized with 0s).

Anything that isn't an instruction is ignored during execution.

Command Description
> Move the pointer to the right
< Move the pointer to the left
+ Increment the current cell
- Decrement the current cell
[ Mark the beginning of a pattern
] Mark the end of a pattern
( Mark the start of a repeated pattern
) Mark the end of a repeated pattern
? Ask user for an integer and store the value in the current cell
! Ask user for a unicode character and store the value in the current cell
. Output the value of the current cell
, Output the unicode character corresponding to the value of the current cell
@ Halt execution

Patterns

Basic Patterns

The key feature of Patternfuck is patterns. A pattern is defined between two matching square brackets. Below are a few examples of how patterns are specified:

Given the following pattern (with a current cell value of 5)

[>(+)]

First, we would start with characters outside parenthesis

>

Then, we repeat the section within the parenthesis until the length of the resulting instructions is the same as the current cell's value

>++++

Multiple Parenthesis

This is the basis for how patterns work, but it gets more complicated.

For example, if we wanted the following pattern (with a current cell value of 12)

[<<(++)>(--.)]

We would start with things outside parenthesis

<<>

Then start with the first parenthesis (left to right)

<<++>

And then the second parenthesis

<<++>--.

Up until we reach this point

<<++++>--.

Adding 3 more instructions would be more than 12 (the current cell's value) so we ignore characters after the 12th

<<++++>--.--

Additional Rules

If the current cell's value is less than the number of instructions outside parenthesis, then the rightmost instructions are removed until the length fits.

If the current cell's value is negative, then it is treated as infinity for the patterns.

If the pattern has no parenthesis and the current cell's value is larger than the length of the instructions in the pattern, then the pattern is treated as if the current cell's value is the same as the length of the instructions within the pattern.

Algorithms

Within Patternfuck, it helps to be familiar with a few basic algorithms in order to abstract and make larger programs.

Double Current Cell

[(+)]

Add Current Cell to Left Cell

> and < can be swapped to use the Right Cell instead.

+[<(+)]>-

Copy Current Cell to Left Cell

This clears the value of the Left Cell then Writes in the value of the Current Cell.

<[(-)]>+[<(+)]>-

Multiplication by a Constant

The code changes based on the constant, but using only 2 cells (the Left Cell and Current Cell in this case) you can reach any constant multiplication.

For example, let's try 6. First we copy the Current Cell to the Left Cell.

<[(-)]>+[<(+)]>-

Then, we double the Current Cell to get 2x its original value.

<[(-)]>+[<(+)]>-  [(+)]

Next we add in the value from the Left Cell to the Current Cell.

<[(-)]>+[<(+)]>-  [(+)]  <+[>(+)]<->

And lastly we double again.

<[(-)]>+[<(+)]>-  [(+)]  <+[>(+)]<->  [(+)]

You might have noticed that this works somewhat similar to binary.

In this case the binary value of 6 is 110.

So that means for every 1 we add in the original value, then at each bit we double the cell.

The way we do it ends up being in reverse, because the original cell's value ends up being doubled first.

Examples

Truth Machine

?[+][<-]<+>[<(.)].

Fibonacci

The program repeats forever and the memory tape would look like: -1, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144...

+<<-[>>(.<++[>>(+)]<<-->+[>(+)]<->)]

Negative to Positive

Input a negative integer and it outputs the same value but positive

?[(+>+<<->[<+]<[>]>[.@]>)]

Interpreters

Patternfuck files typically use the extension .pf

Robolta's Patternfuck Interpreter