MineFriff

From Esolang
Jump to navigation Jump to search

MineFriff brings the joy of traditional esolangs such as Befunge and ><> into the blocky pixelated world of Minecraft. Much like fungeoid languages, MineFriff allows code to be set out in a 2D code area, which can range from a 100*100 grid (allowing for 10,000 instructions) to any size of square (or cube).

As aforementioned, MineFriff allows for free-form code to be written in any size cube (meaning that 3D code is allowed).

MineFriff comes in three flavours: Strict, Freeform and Textual. Strict MineFriff is contained in a 100 by 100 block grid, and can be exported to a .mf file. However, strict MineFriff is only available in the official MineFriff interpreter world. Freeform MineFriff is available in any world but is unexportable to an actual file – code is run using

/py MineFriff

Textual MineFriff is a text based ascii version of the blocky esolang, which is avaliable to everyone – all one needs is the python based MineFriff interpreter.

Concepts

Code Box

Like most fungeoidal esolangs, MineFriff has a code box in which the program is placed. In strict MineFriff, this code box is as shown:

100 x 100 block code

In freeform MineFriff, this code box is essentially non-existant; programs can take any form they want and can be even 3d. In textual MineFriff, the code box spans an infinite amount of space, both vertically and horizontally.

Instruction pointer (IP)

The instruction pointer is what drives the interpreting of MineFriff programs. It starts in the top left corner of the program (strict and textual) or wherever the player is standing in freeform. It can move left, right, up, down, and in the case of freeform MineFriff, up layers and down layers. In strict MineFriff, when the IP reaches the edge of the code box, the IP “wraps around” to the other side (e.g. if it reaches the far right side, it will go to the far left side and continue). This doesn’t in happen in freeform MineFriff, as there isn’t any code box to wrap around. This functionality is being worked on for textual MineFriff.

The temporary register

Rather than having literals pushed directly onto the stack, MineFriff has a temporary register (temp reg) in which literals are constructed. This allows for any value to be created without having to worry about impacting the stack. The temp reg can be treated as either an integer, a character or a float.

Creating literals

To create characters and integers in MineFriff, they must be constructed using the values 0 to f (a = 10, b = 11, c = 12, d = 13, e = 14, f = 15). By default, values are added to each other in the temp reg -- for example, ffe will result in 44 (15 + 15 + 14). Different mathematical operations can be used (namely, */%-+).

Interpreting modes

When pushing the value stored in the temp reg onto the stack (and recently, when getting input), it will, by default, push it as an integer. This can be changed with the C, I and F

The stack

The stack in MineFriff is like the stack in most other fungeoids – it can have values pushed to it, it can have stack operations performed, it can be shifted left and right – all of the usual stuff. However, when popping values from the stack, they are placed back into the temp reg (hence, overwriting the current value), rather than deleted into nowhere.

Commands

MineFriff has 33 commands:

Command Symbol Minecraft Block Equivalent
Move the IP left. < Oak Wood Planks
Move the IP right. > Spruce Wood Planks
Move the IP up. ^ Birch Wood Planks
Move the IP down. v Jungle Wood Planks
Print the top value on the stack. o Sponge
Add a literal to the temp reg. 0123456789abcdef Wool (block data gives the value)
Reverse the contents of the stack. r Netherrack
Push the temp reg onto the stack and reset it to 0. , Piston
Pop the top item from the stack and place it in the temp reg. . Sticky Piston
Push the length of the stack onto the stack. l Stone
Pop `x` and `y` off the stack. Push `y == x` back on (1 if true, 0 if false). = Bedrock
Duplicate the top item of the stack. : Hopper
Swap the top two items of the stack. $ Obsidian
Skip the next instruction (trampoline). # Slime Block
Pop the top value from the stack and skip the next instruction if it is zero (conditional trampoline). ? Redstone Lamp (off)
End the program ; Glass Block
Pop `x` and `y` off the stack. Push `y > x` back on (1 if true, 0 if false). ) Diamond Block
Pop `x` and `y` off the stack. Push `y < x` back on (1 if true, 0 if false). ( Coal Block
Pop `x` and `y` off the stack. Push `y * x` back on. * Podzol
Pop `x` and `y` off the stack. Push `y / x` back on. / Diorite (raw)
Pop `x` and `y` off the stack. Push `y + x` back on. + Andesite (raw)
Pop `x` and `y` off the stack. Push `y - x` back on. - Granite (raw)
Change the direction of the IP to a random direction. x Dispenser
Go back to the start of the current line in the same direction. ~ Hay Block
Go to the start of the next line. ` End Bricks
Treat the temp reg as an integer. I Packed Ice
Treat the temp reg as a character. C Birch Wood
Treat the temp reg as a float. F Furnace
Right shift the stack by 1. ] Dirt Block
Left shift the stack by 1. [ Cobblestone
Pop `x` and `y` off the stack. Push `y % x` back on. % Sand (normal)
Start/end a comment { } N/A
Delete the last item on the stack (pop it, without saving it) ! Not implemented yet
Print the contents of the stack up to a certain point (determiend the last item on the stack) p Not implemented yet

Examples

Hello World

Cff3,a*a,9*c,a*b4,a*b1,8*a7,ff2,ffe,a*b1,9*c,:a*a1,9*8,`
>l?#;o~
The Hello World program in blocks

Or, using the new print command - prints it reversed however.

C9*8,a*a1,9*c,:a*b1,ffe,ff2,8*a7,a*b1,a*b4,9*c,a*a,ff3,p;

Explanation (degolfed)

C9*8,` [Push the letter H (ascii value of 72) to the stack]
a*a1,` [Push the letter e (ascii value of 101) to the stack]
9*c,` [Push the letter l (ascii value of 108) to the stack]
:` [Duplicate the l]
a*b1,` [Push the letter o (ascii value of 111) to the stack]
ffe,` [Push a comma (ascii value of 44) to the stack]
ff2,` [Push a space (ascii value of 32) to the stack]
8*a7,` [Push the letter w (ascii value of 87) to the stack]
a*b1,` [Push the letter o (ascii value of 111) to the stack]
a*b4,` [Push the letter r (ascii value of 114) to the stack]
9*c,` [Push the letter l (ascii value of 108) to the stack]
a*a,` [Push the letter d (ascii value of 100) to the stack]
ff3,` [Push the letter ! (ascii value of 33) to the stack]
r` [Reverse the stack (not in the block version -- accidentally left out]
>l?#;o~ [Push the length of the stack onto the stack, and if it is zero, end the program. Otherwise, print the top char on the stack and continue]

Fizzbuzz

0,`
>I1,+:a*a1,=?;`~o,aC                         <  
>:f,%?`Ca*c2,:a*b7,7*e,a*c2,:f*7,a*7,oooooooo^
>:5,%?`Ca*c2,:a*b7,6*b,oooo                  ^
>:3,%?`Ca*c2,:f*7,a*7,oooo                   ^
>:o                                          ^
The FizzBuzz program in blocks

Explanation

0,` [Push a 0 onto the stack to act as the count]
>I1,+:a*a1,=?;`~o,aC                         <  [Change the push mode to Int, increment the count by 1, and if it equals 100, stop. Otherwise, continue to the next line (~o,aC prints a newline after branching)]
>:f,%?`Ca*c2,:a*b7,7*e,a*c2,:f*7,a*7,oooooooo^ [See if the count can be divded by 15 with no remainder, if so, print FizzBuzz and continue.]
>:5,%?`Ca*c2,:a*b7,6*b,oooo                  ^ [See if the count can be divded by 5 with no remainder, if so, print Buzz and continue.]
>:3,%?`Ca*c2,:f*7,a*7,oooo                   ^  [See if the count can be divded by 3 with no remainder, if so, print Fizz and continue.]
>:o                                          ^ [Simply print the number and continue]

99 bottles of beer

Ia*a,`
>I1,-:0,=?;`                                                                                                                                   ~
>Cff2,ffe,c*9,c*9,a*97,a*b9,ff2,a*a1,d*8,a*b6,ff2,a*b,a*b1,ff2,a*b4,a*a1,a*a1,e*7,ff2,a*a2,a*b1,ff2,a*b5,a*a1,c*9,a*b6,a*b6,a*b1,e*7,ff2,`
>r:or`
>lI1,=?`o~
>Ca,a*46,a*b4,a*a1,a*a1,e*7,ff2,a*a2,a*b1,ff2,a*b5,a*a1,c*9,a*b6,a*b6,a*b1,e*7,ff2,`
>r:or`
>lI1,=?`o~
>Cff2,ffe,a*a,a*b,d*9,a*b1,a*b4,a*97,ff2,a*b6,f*7,ff2,a*b5,a*b5,a*97,e*8,ff2,ffe,a*b,a*b9,a*b1,a*a,ff2,a*a1,a*b,a*b1,ff2,a*a1,a*a7,a*97,c*7,`
>lI1,=?`o~
>Ca*46,c*9,c*9,a*97,a*b9,ff2,a*a1,d*8,a*b6,ff2,a*b,a*b1,ff2,a*b4,a*a1,a*a1,e*7,ff2,a*a2,a*b1,ff2,a*b5,a*a1,c*9,a*b6,a*b6,a*b1,e*7,ff2,`
>r:I1,-or`
>l1,=?`o~                                                                                                                                  
>Ca,a,oo                                                                                                                                       ^

Blocks coming soon

Deadfish Interpreter

` [MineFriff Deadfish Interpreter]
0,` [The first item in the stack will always be the accumulator]
>Ca*62,a*62, oo i` [Output the interpreter prompt and then accept input]
 r.rI, Cffc, $` [Switch the stack around, adding a star on]
 v
^>r:Cffc,=?#v!~ 
            >r:I8*8*4,= ?#v.*0,` [Check the 256 requirement]
            v             >:I1-2,=?#~.*0,~ [Check the -1 requirement]
 ^          >r:Cf*7,=?#v!rI1,+~ [i(ncrement the accumulator)]
 ^                     >:Ca*a,=?#v!rI1,-1~ [d(ecrement the accumulator)]
 ^                               >:Ca*b1,=?#v!r:oCa,o~ [o(utput the accumulator)]
 ^                                          >:Ca*b5,=?#v!r:*~ [s(quare the accumulator)]
                                                      ;

Blocks coming soon

Cat Program (take and print input)

Cip;

Blocks coming soon

External Resources

  • Offical github repository -- use main.py for textual MineFriff and MineFriff.py for freeform and strict MineFriff (requires the installaiton of a mod, which is described at the link). Note that for textual MineFriff, ConstLib.py must also be downloaded
  • Official Javascript MineFriff interpreter -- official javascript/html5 interpreter and runner of textual MineFriff (WIP)

See also