From Esolang
Jump to navigation Jump to search

Funge-98 is the successor to, and a generalization of, Befunge. It supports 1- and 3- dimensional funges, and includes many new commands.

Paradigm(s) imperative
Designed by Chris Pressey
Appeared in Category:1998
Memory system stack-based
Dimensions two-dimensional
Computational class Turing complete (Befunge-98)
Reference implementation
Dialects Befunge-93, Befunge-98
File extension(s) .b98,.tf,.uf


It started with a typo in 1993. Chatting at 4am, Curtis Coleman typed the word "before" as "befunge". Chris Pressey immediately knew that the typo needed to be made more famous and started pondering on an esoteric programming language (before esoteric was actually the common name for the field) deserving of the name. Some few weeks later, Befunge was born; an attempt to create a language that could be interpreted but would defy compilation. Get and Put commands allowed the program space to be modified at runtime and the instruction pointer is free to travel in multiple directions. Befunge was one of the first 2D programming languages. Chris didn't know at the time of invention, but Ward Cunningham, famous for conceptualizing the first Wiki (wiki wiki), had developed a 2 dimensional programming system, called Biota, a few years prior in 1991 as an experiment in cellular automata theory. Just after the early Befunge code was being written, Orthagonal was being independently developed by Jeff Epler (announced in September 1994) as another early multi dimensional programming system.

Befunge was revisited by Chris through the 1990s and specifications for an extended version went through a few iterations. Befunge-97 was not quite right, but Befunge-98 seemed to hit the sweet spot of esoteric yet practical. Funge-98 was born. Unefunge (1D programming), Befunge (2D programming - the most common case), Trefunge (3D programming - many Funge-98 implementations support 3D) and a spec that allowed for Nefunge higher dimensions. Since the release of the Funge-98 specification, original Befunge is now sometimes referred to as Befunge-93.

The first implementation of Befunge-98 was FBBI, the Flaming Bovine Befunge-98 Interpreter, written by Chris Pressey of Cat's Eye Technologies. It does not claim to be a reference implementation (as the language is defined by the Funge-98 Specification rather than any implementation) and was buggy and unmaintained for many years (FBBI version 1.0 was not released until 2011). Since the Funge-98 Specification's inception, many other implementations of the Funge-98 languages (Unefunge-98, Befunge-98, Trefunge-98) have been written by many people.

Interest in Befunge has been fairly steady over the last 20+ years, and quite a few Befunge-93 implementations are available. Befunge enjoys a respectable number of solutions to programming tasks on Rosetta Code, the language comparison site.

In 2006 Matti Niemenmaa started working on a Befunge-98 interpreter (CCBI) in the D programming language and developed a test suite that he called Mycology, to verify compliance with the Funge-98 spec. This test suite has been used for Funge-98 compliance validation for most of the Funge implementations ever since. While working with Mycology and CCBI, Matti worked with Arvid Norlander, the developer of cfunge and efunge, to iron out some of the kinks in the edge cases that are part and parcel of esoteric programming.

The existence of Mycology has helped create a very robust Funge-98 implementation environment, and practitioners of the fungal arts get to enjoy an arguably higher level of compatibility than is common in esoteric programming circles. Especially given that Funge-98 and the Fingerprint extensions can be somewhat complicated. Implementations have been developed in C, D, Erlang, ECMAScript, Clojure, to name a few of the available environments, and they are all closely compatible when executing complex Funge code.

OS Integration


There is a "t" command that splits an IP and allows concurrent operations using an IP list. Each IP in the list has a separate Position, Delta and Offset. Command sequences are defined by a tick concept, each IP in the list executing a tick for each step in a sequential circular loop (which is always in the same order until "threads" are created via the Split "t" command or end via the Stop "@" command.

When a Split occurs, the original IP continues along its delta and the new IP reflects.

"@" removes an IP from the list when stopping, further entries shuffled up to keep the same order. When there are no remaining IPs, a Funge program will end. The "q" quit command ends a Funge program regardless of how many active IPs are in the list.

Stack Stack

Along with the normal stack, Funge-98 defines Block Start/Block End "{" "}" operations that can manage a stack of stacks. TOSS is the Top of stack stack and SOSS becomes a Second to top of stack stack. The "u" under command provides a facility for moving SOS stack items up to the TOS stack. The block operators allow Funge routines to work on a stack without disturbing existing contents, and provides a method of digging down into a stack by copying parts of the TOSS to a SOSS (which effectively becomes TOSS as soon as the block command completes) and then manipulating items with judicious use of Under.



Cats eye, RC Funge


Funge-98 includes and expands on the original Befunge instruction set.

ASCII Instruction Before After Other Effects
space Space not normally executed; k iterator ignores multiples (unless 0)
! Logical Not a Not a Zero becomes one, non zero becomes zero
" Toggle Stringmode Pushes each value between quotes to stack
# Trampoline pos <- pos + delta (IP skips over one command position)
$ Pop a
% Remainder a b a%b Pop b, pop a, push remainder of dividing a by b (or push zero if b is zero). Negative arguments produce implementation-defined results.
& Input Integer a Signed range determined by cell size; reflect on EOF
' Fetch Character/98 c pos <- pos + delta (character is not executed)
( Load Semantics/98 en..e1 n f 1 overloads A-Z, given fingerprint; reflect on load error
) Unload Semantics/98 en..e1 n unloads A-Z overloaded by given fingerprint, may reflect
* Multiply a b ab Signed range determined by cell size
+ Add a b a+b Signed range determined by cell size
, Output Character c
- Subtract a b a-b Pop b, pop a, push a-b. Signed range determined by cell size
. Output Integer a
/ Divide a b a/b Pop b, pop a, push a/b (or push zero if b is zero).
0 Push Zero 0
1 Push One 1
2 Push Two 2
3 Push Three 3
4 Push Four 4
5 Push Five 5
6 Push Six 6
7 Push Seven 7
8 Push Eight 8
9 Push Nine 9
: Duplicate v v v
; Jump Over/98 nothing executed until next ;
< Go West delta <- Une(-1), Be(-1,0), Tre(0,-1,0)
= Execute/98/f 0gnirts r result-code = system-execute(string)
> Go East delta <- Une(1), Be(1,0), Tre(0,1,0)
? Go Away delta <- random direction, (1/-1), (-1,0/1,0/0,1/0,-1), (-1,0,0/.../-1,-1,-1)
@ Stop halt current IP, if last concurrent thread then end program
A-Z Fingerprint-Defined/98 Overloadable. If not overloaded, act as 'r'.
[ Turn Left/98/2D delta <- rot(-90, delta)
\ Swap a b b a Pop b, pop a, push b, push a
] Turn Right/98/2D delta <- rot(90, delta)
^ Go North/2D delta <- Be(0,-1), Tre(0,-1,0). Reflects in Unefunge
_ East-West If/2D n Act as '>' if n is zero, otherwise '<'.
` Greater a b a>b Pop b, pop a. If a is greater than b, push 1; otherwise push 0.
a Push Ten/98 10
b Push Eleven/98 11
c Push Twelve/98 12
d Push Thirteen/98 13
e Push Fourteen/98 14
f Push Fifteen/98 15
g Get x [y [z]] n Push contents of (x) Une, (x,y) Be, (x,y,z) Tre. Push 0 when out of bounds
h Go High/98/3D delta <- (0,0,-1). Reflects in Unefunge and Befunge
i Input File/98/f x [y [z]] f 0gnirts x [y [z]] x' [y' [z']] inputs file given string name. Low bit set in flag f for binary mode
j Jump Forward/98 s pos <- pos + delta * s
k Iterate/98 n execute next instruction now, 0 or n+1 times (k does not skip IP unless 0)
l Go Low/98/3D delta <- (0,0,1). Reflects in Unefunge and Befunge
m High-Low If/98/3D b delta <- if not zero, go high (0,0,-1) else (0,0,1)
n Clear Stack/98 en..e1 Top of stack stack for current thread is emptied
o Output File/98/f x [y [z]] x' [y' [z']] f 0gnirts outputs Funge space between start/end to named file, low bit set in f for binary
p Put n x [y [z]] n Pop vector, then pop n. Store n at that location in Funge space.
q Quit/98 r immediate exit, returncode = r
r Reflect/98 delta <- delta * -1
s Store Character/98 c store-funge-space(position+delta,v).
t Split/98/c Split IP. Position, delta, stacks copied, child reflects.
u Stack Under Stack/98 n (en..e1) Pushes extra zeros if SOSS contains less than n items.
v Go South delta <- (1) Une, (0, 1) Be, (0, 1, 0) Tre
w Compare/98/2D a b if (a>b) ']' elsif (a<b) '[' else 'z'
x Absolute Delta/98 x [y [z]] delta <- (x,[y,[z]])
y Get SysInfo/98 c en(..e1) Retrieve item n for n>0 else all items
z No Operation/98
{ Begin Block/98 en..e1 n (en..e1) offset <- pos + delta, etc
| North-South If/2D n Act as 'v' if n is zero, otherwise '^'. In Unefunge, act as 'r'.
} End Block/98 en..e1 n (en..e1) offset <- SOSS Va, etc
~ Input Character c reflect on EOF


The Funge-98 specification allows for extensions to the Funge instruction set via loadable Fingerprints. Capital A through Z instructions can be overloaded using the "(" Load Semantics/98 op-code and unloaded using ")". The specification allows arbitrary mixing of the redefinitions.

Some well known fingerprints

The FBBI (Flaming Bovine Befunge-98 Interpreter) supports some initial extensions that are defined along with the Funge-98 specification.

The Rc/Funge-98 and cfunge interpreters supports a wide range of overload semantics, many designed by the Rc/Funge-98 project.

gnirts form and character count is usually used to feed the Load Semantics op-code, "TOYS" being "SYOT"4. The "(" command reflects on load failure, or leaves two items on the stack on success. This pair can be used to ")" unload the fingerprint. The pair is an ID and a count of 1 that matches the fingerprint loader/unloader needs. This pair is often discarded, and the gnirts form used to feed the unload operation.

Common name Fingerprint New semantics Description More info
"3DSP" 0x33445350 A,B,C,D,L,M,N,P,R,S,T,U,V,X,Y,Z 3D space matrix manipulation.
"ARRY" 0x41525259 A,B,C,D,E,F,G Arrays. 1 to 3 dimensions; stored in funge-space.
"BASE" 0x42415345 B,H,I,N,O I/O for numbers in other bases
"BOOL" 0x424F4F4C A,N,O,X Logic functions
"CFFI" 0x43464649 B,C,D,F,G,I,L,M,O,P,S,T,U,W,Y C Foreign Function Interface
"CPLI" 0x43504C49 A,D,M,O,S,V Complex Integer extension
"DATE" 0x44415445 A,C,D,J,T,W,Y Date functions
"DIRF" 0x44495246 C,M,R Directory functions extension
"EMEM" 0x454d454d A,F,G,P,R Extended memory (basically malloc/free)
"EVAR" 0x45564152 G,N,P,V Environment variables extension
"EXEC" 0x45584543 A,B,G,K,R,X Various types of k-like iterators. (K will skip on one - woohoo!).
"FILE" 0x46494C45 C,D,G,L,O,P,R,S,W File I/O functions (usually sandboxed)
"FING" 0x46494e47 X,Y,Z Alter single fingerprint semantics
"FIXP" 0x46495850 A,B,C,D,I,J,N,O,P,Q,R,S,T,U,V,X Some useful math functions
"FNGR" 0x464E4752 A,B,C,D,F,K,N,O,R,S,T,X Fingerprint management
"FOBJ" 0x464f424a D,I,M,N Object Oriented Funge, yeeahh.
"FORK" 0x464F524B T Process fork
"FPDP" 0x46504450 A,B,C,D,E,F,G,H,I,K,L,M,N,P,Q,R,S,T,V,X,Y Double precision floating point
"FPRT" 0x46505254 D,F,I,L,S Formatted print ala printf
"FPSP" 0x46505350 A,B,C,D,E,F,G,H,I,K,L,M,N,P,Q,R,S,T,V,X,Y Single precision floating point
"FRTH" 0x46525448 D,L,O,P,R Some common forth stack commands
"HRTI" 0x48525449 E,G,M,S,T High resolution timer interface
"ICAL" 0x4943414c A,F,I,N,O,R,S,X Some Intercal-like functions ala unary AND
"IFFI" 0x49464649 A,C,D,F,G,L,M,N,R,S,V,X C-INTERCAL Foreign Function Interface
"IIPC" 0x49495043 A,D,G,I,L,P Inter IP communication for concurrent Funge
"IMAP" 0x494D4150 C,M,O Instruction remap (0 through 255 range)
"IMTH" 0x494d5448 A,B,C,D,E,F,G,H,I,L,N,R,S,T,I,U,X,Z Some integer math functions
"INDV" 0x494E4456 G,P,V,W Pointer functions for funge-space
"IPMD" 0x49504d44 B,D,Q,T,U IP dimension mode switching
"JSTR" 0x4a535452 G,P 3d P and G for 0gnirts
"LONG" 0x4c4f4e47 A,B,D,E,L,M,N,O,P,R,S,Z Long (two cell) integers
"MACR" 0x4d414352 A-Y,Z Macros. Z sets a macro block base.
"MODE" 0x4D4F4445 H,I,Q,S Standard modes
"MODU" 0x4D4F4455 M,U,R Modulo Arithmetic
"MSGQ" 0x4d534751 G,K,R,S,T SysV IPC message queues
"MVRS" 0x4d565253 B,C,F,G,J,N,P Multiverse funge, B is the big bang
"NCRS" 0x4E435253 B,C,E,G,I,K,M,N,P,R,S,U Ncurses Routines
"NULL" 0x4E554C4C A-Z Null (all overload semantics set to reflect)
"ORTH" 0x4F525448 A,E,G,O,P,S,V,W,X,Y,Z Orthogonal Easement Library
"PERL" 0x5045524C E,I,S Generic Interface to Perl
"RAND" 0x52414e44 I,M,N,R,S,T Random Numbers
"REFC" 0x52454643 R,D Referenced Cells
"REXP" 0x52455850 C,E,F Regular expression matches
"ROMA" 0x524F4D41 C,D,I,L,M,V,X Roman numerals extension
"SCKE" 0x53434b45 H,P Extensions to SOCK
"SETS" 0x53455453 A,C,D,G,I,M,P.R.S.U,W,X,Z Set operations
"SGNE" 0x53474E4C A,I,L,P,S,T Extensions to SGNL (alarms and sleep)
"SGNL" 0x53474E4C H,K,M,R,X,Y Signal handling
"SMEM" 0x534d454d G,K,R,T,W SysV IPC shared memory
"SMPH" 0x534d5048 A,D,G,K,M,N,R,W,Z SysV IPC Semaphores
"SOCK" 0x534F434B A,B,C,I,K,L,O,R,S,W tcp/ip sockets
"SORT" 0x534f5254 B,F,K,S Sorting
"STCK" 0x5354434b B,C,D,G,K,N,P,R,S,T,U,W,Z Stack manipulation
"STRN" 0x5354524E A,C,D,F,G,I,L,M,N,P,R,S,V String (0gnirts) functions
"SUBR" 0x53554252 A,C,J,O,R Subroutines
"TERM" 0x5445524D C,D,G,H,L,S,U Terminal extension
"TIME" 0x54494D45 D,F,G,H,L,M,O,S,W,Y Time and Date functions
"TOYS" 0x544F5953 A,C,D,E,I,H,K,L,M,N,P,Q,R,S,U,V,X,Y,Z Standard Toys
"TRDS" 0x54524453 C,D,E,G,I,J,P,R,S,T,U,V IP travel in time and space
"TRGR" 0x54524752 A-Y, Z Triggers (Z sets trigger table location)
"TURT" 0x54555254 A,B,C,D,E,F,H,I,L,N,P,Q,R,T,U Turtle Graphics
"UNIX" 0x554e4958 A,B,C,D,E,G,H,K,M,N,P,R,S,T,U Some Unix access functions
"WIND" 0x57494E44 B,C,D,E,I,K,L,M,O,P,R,S,T,W Windows extensions

rcfunge supports a -ux run option that opens an X11 window for on screen Turtle graphics display.

Example of fingerprint loading

v ;Overlapping fingerprint;

  ;Load BOOL and N takes on a Not semantic;
         >0a"detroppus ton LOOB">:#,_$@
             >0a"detcelfer N :DAB">:#,_$@
>"LOOB"4#^(7#^N7." toN"3k," si"2k,.a,    v

v ;Load TOYS and now N is Negate;        <
         >0a"detroppus ton SYOT">:#,_$@
             >0a"detcelfer N :DAB">:#,_$@
>"SYOT"4#^(7#^N7." detageN"7k," si"2k,.a,v

v ;Load NULL and N now reflects;         <
         >0a"detroppus ton LLUN">:#,_$@
                  >0a"LLUN edisni detcelfer N :DOOG">:#,_$ v
>"LLUN"4#^(:.\:.\#^N0"tcelfer t'ndid O :DAB">:#,_$@ 

  ;Fingerprints still on stack; 
v ;Unload NULL and restore N as Negate.;                   <
  >0"detcelfer daolnu LLUN :DAB">:#,_$@
>#^)                                     v
v                                        <
   >0a"detcelfer N :DAB">:#,_$@
>7#^N7." detageN"7k," si"2k,.a,          v

v ;Unload TOYS and restore N as Not;     <
  >0"detcelfer daolnu SYOT :DAB">:#,_$@
>#^)                                     v
v                                        <
   >0"detcelfer N :DAB">:#,_$@
>7#^N7." toN"3k," si"2k,.a,0a"gnixim tnirpregnif">:#,_$@

Sample run:

prompt$ cfunge fingerprint.b98 
7 Not is -8 
7 Negated is -7 
1 1314212940 GOOD: N reflected inside NULL
7 Negated is -7 
7 Not is -8 
fingerprint mixing


Hello World

<v"Hello World!"

Display y sysinfo

Works with Befunge and Trefunge, but not Unefunge. Requires BOOL fingerprint support.

v                                   >'t,v   >'i,v   >'o,v   >'=,v
>"LOOB"4#v($$0y0" stroppus">:#,_$:1A|   >:2A|   >:4A|   >:8A|   >$a,v
         >0a"LOOB on">:#,_1y.@      >   ^   >   ^   >   ^   >   ^
v           ,a.,k7"version ",a.,k9"handprint ",a,kd"bytes per cell".<
>" cexe"4k,:3-#v_"llehs emas"9k,          v
               >:2-#v_"llehs emos"9k,     v
                    >:1-#v_"metsys"5k,    v
v               ,a,,ke"path separator ",a$<
>" )snoisnemid( ezis rotcev"55*1-k,.a,                  v
v,a.k-1y7,kb"IP location ",a.,k7"team id ",a.,k5"IP id "<
>" atled"5k,7y1-k.a," tesffo"6k,7y1-k.a,  v
v,a.k-1y7,k7"largest ",a.k-1y7,k6"origin "<
>" raey"4k,:82*82**82*82***/a9+aa**+.   v
v./**28*28A*-1**28*28**28*28:,k5"month "<
>" yad"3k,82*82**1-A.        v
v./***28*28**28*28:,k4"hour "<
>" etunim"6k,:82*82**82*82**1-*A82*82**/.vv                 <
v               ,a.A-1**28*28,k6"second "<  >'",>:#,_$'",' ,^
v              v-1.\_$a," enil-dnammoc"ck,>:|  >          #v^#               <
>" skcats"6k,:.>   :^                       >$:|             >'",>:#,_$'",' ,^
                                               >a," vne"3k,>:|   >           ^
;display Funge-98 y sysinfo; BOOL fingerprint required;

Sample outputs (environment space display elided):

cfunge (sandbox)

prompt$ cfunge -S sysinfo.b98  'a b c' a b c
supports t
8 bytes per cell
handprint 1128682830
version 90
exec unavailable
path separator /
vector size (dimensions) 2
IP id 0
team id 0
IP location 1 14
delta 0 1
offset 0 0
origin 0 0
largest 23 77
year 2017 month 7 day 31 hour 20 minute 22 second 49
stacks 1 0
command-line "sysinfo.b98" "a b c" "a" "b" "c"
env "COLORTERM=truecolor" "LC_TIME=en_CA.utf8" ... "SHELL=/bin/bash"

rcfunge (in Trefunge mode)

prompt$ rcfunge -3 sysinfo.b98  'a b c' a b c
supports tio=
4 bytes per cell
handprint 1380143957
version 20300
exec same shell
path separator /
vector size (dimensions) 3
IP id 0
team id 0
IP location 0 5 14
delta 0 0 1
offset 0 0 0
origin 0 0 0
largest 0 23 77    
year 2017 month 7 day 31 hour 16 minute 35 second 1
stacks 1 0
command-line "sysinfo.b98" "a b c" "a" "b" "c"
env "COLORTERM=truecolor" ... "MANPATH=/usr/local/share/man:" "XDG_VTNR=1"

VM sysinfo.b98 ended
  Instructions Executed: 35148 in 35174 cycles
        Execution time : 0.04   seconds
Instructions per second: 799654.19 
Exiting with return code = 0

Rock Scissors Paper, on 3

v                       >  v
>a"3 no"4k,1.0"1 peels"#^=$>2.0"1 peels"#v=$v
          v                              <  <
          ,                                             @
          v             <                          >'y-#^_a,0by-8-0ay-x
>         >0"2 peels"#v=$>a," ?niaga yalp"ack,>~:a-|
                      >  ^                    ^ $  <
Rock Scissors Paper, on 3

Plays a game of Rock Scissors Paper with delay count (if system exec "=" is supported, if not, computer player displays choice immediately). Any response to play again? other than 'y' will terminate game. Any buffered newlines are eaten.


The Funge-98 specification was written by Chris Pressey of Cat's Eye Technologies. Chris invented the original Befunge back in 1993.

Incomplete list

Name Author(s) Source License Commentary
FBBI, Flaming Bovine Befunge-98 Interpreter Chris Pressey, inventor of Befunge C BSD license First implementation of Befunge-98. Not a reference implementation, but probably mistakenly used as a reference on at least one occasion.
CCBI, Conforming Concurrent Befunge-98 Interpreter Matti Niemenmaa (Deewiant) D 1.0 BSD (with Tango) Deewiant is also the author of the Mycology Funge-98 verification suite.
cfunge Arvid Norlander, (VorpalBlade) C GPL v3 A complete Funge-98 interpreter, many fingerprints supported.
rcfunge Michael Riley, Susan now listed as maintainer C Free for non commercial use Rc/Funge-98 is the source of many of the known Funge fingerprints.
jsfunge Pietu1998 ECMAScript, HTML, CSS Unknown In browser Funge-98 interpreter.
efunge Arvid Norlander, (VorpalBlade) Erlang GPL v3 An Erlang based interpreter by the author of cfunge.
pyfunge Kang Seonghoon Python permissive MIT/X11 Documentation hosted at
Clostridium Tom Parker Clojure AGPLv3 Development article.

See also

External resources

  • BefungeSharp A Funge-98 IDE being written in C#. Designed to have a strong editor and a complaint interpreter. Currently in development and well supported by its author.
  • Fungus (from the Wayback Machine; retrieved on 22 March 2007) - a nice Befunge-98 IDE for Win32. Warning: its interperter is not fully standards compliant.
  • mooz' Befunge page (from the Wayback Machine; retrieved on 25 September 2006) - contains a Javascript interpreter and several interesting Befunge programs.
  • BeQunge A cross-platform Funge-98 interpreter, code editor, and debugger. Works in any number of dimensions.
  • J^4: Befunge Jeffrey Lee's Befunge site, features plenty of interesting programs.
  • cfunge - Small fast Befunge-98 interpreter in C, standard compliant. Updated from SourceForge
  • efunge - Erlang implementation of Befunge-98, standard compliant. Has an experimental branch with a fingerprint for asynchronous threading.
  • Rc/Funge-98 - rcfunge, implementation in C, diagnostics, tutorials and documentation. Very complete; Une, Be, Tre, including the Time Travel fingerprint.
    • Archive of the above hosted on Github
  • Sponge - a compiler (in Common Lisp) from a tiny subset of Scheme to Befunge 98.
  • PyFunge - A Befunge-93/Funge-98 interpreter in Python. Its goal is a fully functional, compliant and optimizing implementation of Funge-98.
  • Fungi - A standards compliant Funge-98 interpreter and debugger written in Haskell.
  • Multilang - A shell supporting multiple languages, including Befunge-98.