Befunge is an esoteric programming language by Chris Pressey.
Chris Pressey invented Befunge in 1993 with the goal of defining a language that is as difficult to compile as possible. A difficulty for compilers is for example the p-command, which can dynamically change the program at runtime.
The program consists of ASCII characters in an 80×25 character array. All functions are executed on a stack.
The basics of Befunge-93
Probably the most unique element of Befunge-93 programming is the program counter (PC). In almost all computer programming languages, the program counter moves continuously forward through the program, occasionally jumping to another location in the code (but continuing anyway).
However, different rules apply to the PC in Befunge-93. It can move forward, backward, left or right. A Befunge-93 program is treated like an 80×25 torus (a page that wraps around the edges) of ASCII text. Certain commands change the direction of the PC’s progress. By default, the PC points to the upper left corner of the program and is oriented to move from left to right.
Each command in Befunge-93 is a single character, as is the largest unit of data that can be specified in the program’s source code; Befunge-93 programs have a maximum total size of 80×25 commands and data bytes. There are no run-time variables, only a single run-time stack. Befunge-93 programs can be modified by themselves. Because of the 2-dimensional nature of the PC, they also allow some extremely whimsical code.
Similar to Forth and PostScript, Befunge-93 supports a LIFO, Reverse Polish Notation (RPN or Postfix) stack of signed long integer numbers (i.e., each cell of the stack can contain as much as a signed long integer in the C language on the same platform).
The operation of putting a value on the stack is called a “push”, and the operation of taking a value off the stack is called a “pop”.
The digits from 0 to 9 are valid Befunge-93 commands that push their respective values onto the stack. A double quote ” toggles string mode, and while string mode is active, the ASCII value of all character cells is pushed onto the stack until another ” is found.
There are a few basic calculation commands:
These are explained in more detail in the Commands section.
To push a number greater than 9 onto the stack, calculations must be performed with numbers less than or equal to 9. In any other language this would be a problem. In Befunge-93, it is a joy. For example, to push ‘123’ onto the stack, you could push 9, then 9, then multiply (leaving 81), then push 7, then 6, then multiply (leaving 81 and 42), then add (leaving 123.): 9976+.
This assumes, of course, that the pc starts at or before the first 9 and works to the right. If this section represents a complete Befunge-93 program, this assumption is correct: the pc starts at the top left of the torus and is initially oriented to the right.
If the stack is empty when you take something out of the stack, you should be aware that this will not lead to an underflow! It will simply push a value of 0 onto the stack.
The program counter in detail
There are 5 commands that unconditionally control the direction of the PC:
|>||Move the PC to the right|
|<||Move the PC to the left|
|v||Move the PC down|
|^||Move the PC up|
|?||Move the PC in a random direction|
If the PC hits the “edge” of the program, it simply continues on the other side.
The standard ‘if’ statement in Befunge-93 is either _ or |, depending on how you want to branch. Both statements take a value from the stack, check whether it is true (non-zero), and change the direction of the PC accordingly:
|_||behaves like < if the value is true or > if it is false|
||||behaves like ^ if the value is true, or like v if it is false|
While” loops can be created by inserting an “if” into an infinite loop. For example _@
This program fragment clears all non-zero values from the stack and the first zero value, then exits [@ is the exit command].
|&||Fetches a numeric value (decimal) from standard input and pushes it onto the stack|
|~||fetches the next ASCII character from standard input and pushes it onto the stack.|
&, outputs “A” when the user types “65”, and….
~. outputs “65 ” when the user enters “A”.
|.||takes a value from the stack and outputs it as a decimal integer followed by a space character|
|,||fetches a value from the stack, interprets it as an ASCII value of a character and outputs this character without following space character|
665+*1-, prints ASCII 65 (“A”.), and….
665+*1-. prints “65”.
|#||is the ‘bridge’ command… it causes the next command that would normally be executed to be skipped and not executed.|
123…@ would output “3 2 1”, but
123#…@ would output “3 2″, skipping one of the ‘. “s. Clever use of # can make for very interesting code!
|:||is the command for duplication. It creates a copy of the top element of the stack.|
|$||fetches a value from the stack, but does nothing with it. For example,|
123.$.@ results in “3 1”.
|\||swaps the top two elements of the stack. So,|
123...@ results in “2 3 1”.
|`||is the “greater than” command. It compares the top two values on the stack and returns “1” if the first value is greater than the second. For example,|
65`. displays “1” and…
25`. displays “0”
The last two commands to be explained are those that allow the contents of the torus in which the program is stored to be examined and modified. This “playing field” can be used as an auxiliary memory when the stack alone is not enough. But be careful, the torus also contains the running program.
|g||The g command checks the contents of the playfield. It fetches a y-coordinate from the stack, then an x-coordinate. It pushes the value found at (x, y) onto the stack. If (x, y) is a Befunge-93 instruction, the value pushed onto the stack is the ASCII value of that character. From the point of view of the program text, x determines the column and y the row; (0, 0) refers to the first (leftmost) column and the first (topmost) row of the program source.|
|p||The p command changes the contents of the playfield. It fetches a y-coordinate from the stack, then an x-coordinate and then a value. The value is inserted into the torus at (x, y). If the program executes the command at (x, y) at a later time, it will be interpreted in the ASCII character set as a Befunge command with the same value that was put there with the p command.|
|Command||Stack – ascendend||Stack (result)|
|+||add||<Value1> <Value2>||<Value1 + Value2>|
|–||sub||<Value1> <Value2>||<Value1 – Value2>|
|*||mult||<Value1> <Value2>||<Value1 * Value2>|
|/||div||<Value1> <Value2>||<Value1 / Value2>|
|%||mod||<Value1> <Value2>||<Value1 mod Value2>|
|!||not||<Value>||<0 wenn Value <> 0, sonst 1>|
|‘||greater||<Value1> <Value2>||<1 wenn Value1 > Value2 , sonst 0>|
|\||swap||<Value1> <Value2>||<Value2> <Value1>|
|.||display number||<Value>||displays <Value> as number|
|,||display character||<Value>||displays <Value> as character|
|g||get||<x> <y>||< Value of (x,y)>|
|p||put||<Value> <x> <y>||stores Value at (x,y)|