Two places to keep things
A Befunge program works with two separate data areas. The playfield is the two-dimensional grid of characters that holds the code. The stack is a pile of whole numbers that holds the values the program is working on. The pointer moves across the first and reads and writes the second, and nearly every Befunge program is a conversation between the two.
The program stack
A stack lets you do two things: put a value on top, or take the top value off. You cannot reach into the middle. Imagine a spring-loaded stack of plates; the last plate you put on is the first one you can take.
In Befunge, nearly every instruction is built around this. A digit pushes its value. Arithmetic commands pop their inputs and push the result. Printing commands pop a value to display it. Because commands act on whatever is on top, the order in which things are pushed matters a great deal.
Here is an example. Take 35-.@. The 3 goes on first, then 5, so the stack is 3 below, 5 on top. The - pops 5, then 3, and pushes 3 minus 5, which is negative 2. The . prints it. If you wanted 5 minus 3, you would write 53-. This is the postfix style described in the introduction to the language, and it is one of the first things beginners need to practice.
The stack has no declared size in the usual sense; it grows as values are pushed. If you try to pop from an empty stack, the original language treats the missing value as zero rather than reporting an error. That is convenient for loops, but it can also hide a bug, which is why the topic of stack underflow matters when writing interpreters. Funge-98 adds the idea of a stack of stacks, a more advanced feature.
Three commands tidy the stack up: : duplicates the top value, \ swaps the top two, and $ discards the top. These give you the main ways to reorder values without any named variables.
The playfield
The playfield is the grid where the code sits. In Befunge-93, it is commonly described as 80 columns wide and 25 rows tall, with each cell holding one character. Coordinates start at the top-left corner at (0, 0), with x increasing to the right and y increasing downward. That is the same convention used for most screen graphics, and it can feel upside-down if you are used to a math graph.
The pointer travels across this grid. When it reaches an edge, it wraps around to the other side. It reads the character in each cell, interprets it as an instruction, and acts. A cell with a digit pushes a number; a cell with an arrow changes the direction. Spaces are no-ops.
The important fact is that the grid is more than a program listing. It is also readable and writable memory.
Where they meet: g and p
Two commands connect the stack and the grid.
The g command (get) pops y and then x, and pushes the character code found in the grid at that position. Because y is popped first, you push x first and y second. So 5 3 g would look at column 5 on row 3.
The p command (put) pops y, then x, then a value, and stores that value in the grid at (x, y). To write you push the value, then x, then y.
For example, to store the number 7 at column 10 on row 5, you would push 7, then 10, then 5, and run p. That reads 7 followed by 55+, then 5, then p; the 55+ makes ten because there is no single digit for it. Later, pushing 55+ and 5 and running g brings the 7 back onto the stack. Programs that use this approach as variables, such as the ideas in grid variables, typically choose cells well away from the code.
Why the overlap is risky
Because code and data share the same grid, one can damage the other. If a p writes to a cell the pointer will later visit, the new value becomes an instruction. That is how self-modifying code works, and it can be used on purpose, but it can also cause strange results if the coordinates are wrong.
Some practical habits help:
- Reserve a block of empty cells, for example a corner, for storage.
- Double-check x and y order before running
p. - Remember that cell values are character codes, so printing needs the right command.
- Keep track of the grid size, since going outside it is not defined the same way everywhere.
Comparing the two areas
| Feature | Stack | Playfield |
|---|---|---|
| Holds | Whole numbers | Characters, which are also instructions |
| Access | Top only | Any cell by coordinates |
| Size | Grows as needed | Fixed in Befunge-93 |
| Typical use | Short-lived values | Code and longer-lived storage |
The stack is for quick work and the grid is for anything that has to stay around.
Putting it together
Most programs use the stack for nearly everything. Only when a value must be remembered across many steps, such as a counter that is needed later, does the grid come into play. Being clear about which area a value lives in makes both writing and following programs easier, and it is the first thing to check when something goes wrong.