Refunge

From Esolang
Jump to navigation Jump to search

Refunge is a Befunge derivative esoteric programming language created by User:Happa that aims to be similar to Befunge-93 while allowing potentially more readable code and optional 1-dimensional style programming in lines. It is only partially compatible with Befunge-93 programs.

The biggest differences are that literals can be written with multiple characters, all numbers are considered double-precision floating points, labels can be used to keep track of positions, and callable functions can be created.

The Grid

The grid works the same way as in Befunge, where if the instruction pointer exits one side it jumps to the opposite side. The grid is initialized at the smallest size that can fit a loaded program. The program's entry point is at 0,0 (the top left corner of the program's grid) and the instruction pointer starts facing to the right.

The Stack

The stack can hold any kind of data in each index, as their actual value does not matter until they are popped from the stack. Values on the stack are cast on demand; for example the string "102" may be pushed and then later popped as the equivalent number 102.

Literals & Labels

All literals are written as either a single integer character (0-9) or multiple characters surrounded by {} (E.G. "{Hello, World}"). A literal is pushed to the stack when the instruction pointer enters the grid cell containing its left-most character (if it's a multiple-character literal this will be "{"), and the other grid cells that the literal covers are considered empty cells. Strings and numbers are written with no difference, as the type is not important when being pushed to the stack (see "The Stack" section above).

Labels are written with surrounding parentheses (E.G. "(LabelName)") and are simply used by the interpreter to store and retrieve locations in the grid for calls and jumps. The position of a label is the equal to the position of the cell to the right of its closing parenthesis ")". Every cell a label covers is considered empty.

Functions & Jumps

A function can be defined by writing a label and then creating a program that starts from there and ends with @ (equivalent to a return command in this case). The function is called by pushing its name to the stack then using the call command ("c"). The instruction pointer will jump to the position of the label and start moving rightwards and executing commands until it hits @ then it will return back to where the function was called from and return to its original direction. Functions can also be called recursively.

A label may also be jumped to with the jump command ("j"). This will move the instruction pointer to the label's position (its opening parenthesis) and keep the current direction intact.

Commands From Befunge-93

Note: Some commands work a little differently than the original Befunge-93 equivalents.

Command Description
+
Add: Pop two values A and B then push B + A.
-
Subtract: Pop two values A and B then push B - A.
*
Multiply: Pop two values A and B then push B * A.
/
Divide: Pop two values A and B then push B / A (all number values are doubles so decimals will not be cut off).
%
Modulo: Pop two values A and B then push B % A.
!
Not: Pop value A, and if A == 0.0 then push 1.0, otherwise push 0.0.
`
Greater: Pop two values A and B then push 1.0 if B is greater than A, otherwise push 0.0.
>
Right: Set the instruction pointer's direction to right.
<
Left: Set the instruction pointer's direction to left.
^
Up: Set the instruction pointer's direction to up.
v
Down: Set the instruction pointer's direction to down.
?
Random: Set the instruction pointer's direction to a random direction.
_
HIf: Pop value A, and if A == 0.0 then set the instruction pointer's direction to right, otherwise left.
|
VIf: Pop value A, and if A == 0.0 then set the instruction pointer's direction to down, otherwise up.
"
Stringmode: Toggle stringmode. Every character the instruction pointer finds will be pushed to the stack until another " is met.
:
Duplicate: Duplicate the value at the top of the stack.
\
Swap: Swap the 2 values at the top of the stack.
$
Pop: Pop the value at the top of the stack and discard.
.
OutNumber: Pop the value at the top of the stack and print as a number.
,
OutString: Pop the value at the top of the stack and print as a string.
#
Bridge: Make the instruction pointer skip the next command.
g
Get: Pop two values B and A then push the value at grid position (B,A).
p
Put: Pop three values C, B and A then set the value at grid position (B,C) to value A.
&
InLine: Read in a line from the user then push it.
~
InChar: Read in a single character from the user then push it.
@
Return: If the instruction pointer is in a function that was called, then return to where it was called from, otherwise exit the program.

New Commands

Note: Some commands are adapted from Befunge-98. More commands will likely be introduced with time.

Command Description
=
Equal: Pop two values A and B and if A == B then push 1.0, otherwise push 0.0.
'
Concatenate: Pop two string values A and B and concatenate them then push the result.
[
TurnCCW: Turn the instruction pointer once, counter-clockwise.
]
TurnCW: Turn the instruction pointer once, clockwise.
l
FindLabel: Pop a string value and push the X and Y of the matching label's position.
r
ReadLabel: Pop a string value and push the value at the position of the matching label.
w
WriteLabel: Pop two values A and B and set the value at the position of the label matching A to the value B.
j
Jump: Pop a string value and move the intruction pointer to the matching label's position.
c
Call: Pop a string value and call the function starting at the matching label's position.
n
NextLine: Shift the the instruction pointer down a row and move it all the way to the leftmost column.
i
Drawbridge: Pop a value and skip the next instruction if the value == 0.0.

99 Bottles Example Program

This version utilizes command "n" for style, and shows how labels can be used as variables.

{First98}c{Last}c@(TakeBottle){Bottles}r1-{Bottles}w@
(First98)>{Verse}c{Bottles}rv
      1-#^_@   (Bottles){99}>
(Verse)n(GetBottles){Bottles}r,@
{GetBottles}c{ bottles of beer on the wall, },n
{GetBottles}c{ bottles of beer.\n},n
{Take one down, pass it around, },{TakeBottle}cn
{GetBottles}c{ bottles of beer on the wall.\n\n},@
(Last){1 bottle of beer on the wall, 1 bottle of beer.\n},n
{Take one down and pass it around, no more bottles of beer},n
{ on the wall.\n\n},@

External resources