|
0 |
<html>
|
|
1 |
<head>
|
|
2 |
<title>Funge-98 Final Specification</title>
|
|
3 |
</head>
|
|
4 |
<body bgcolor="#FFFFC0">
|
|
5 |
<center><h1>Funge-98 Final Specification</h1>
|
|
6 |
Chris Pressey, Sept 11, 1998<br>
|
|
7 |
<font size=-2>revised for clarity: Sept 30 1998</font><br>
|
|
8 |
</center>
|
|
9 |
<hr><a name="toc"><h3>Table of Contents</h3>
|
|
10 |
<ul>
|
|
11 |
<p><li><h4><A HREF="#Introduction">Introduction</A></h4>
|
|
12 |
<ul>
|
|
13 |
<li><A HREF="#Whatis">What is a Funge?</A>
|
|
14 |
<li><A HREF="#About">About this Document</A>
|
|
15 |
</ul>
|
|
16 |
<p><li><h4><A HREF="#Machine">The Funge Virtual Machine</A></h4>
|
|
17 |
<ul>
|
|
18 |
<li><A HREF="#Code_Data">Code and Data</A>
|
|
19 |
<li><A HREF="#Space">Funge-Space</A>
|
|
20 |
<li><A HREF="#Stack_Stack">Stack Stack</a>
|
|
21 |
<li><A HREF="#Format">Funge Source File Format</A>
|
|
22 |
</ul>
|
|
23 |
<p><li><h4><A HREF="#Code">Code: Program Flow</A></h4>
|
|
24 |
<ul>
|
|
25 |
<li><A HREF="#IP">Instruction Pointer</A>
|
|
26 |
<li><A HREF="#Instructions">Instructions</A>
|
|
27 |
<li><A HREF="#Direction">Direction Changing</A>
|
|
28 |
<li><A HREF="#Wrapping">Wrapping</A>
|
|
29 |
<li><A HREF="#Flow">Flow Control</A>
|
|
30 |
<li><A HREF="#Decision">Decision Making</A>
|
|
31 |
</ul>
|
|
32 |
<p><li><h4><A HREF="#Data">Data: Cell Crunching</A></h4>
|
|
33 |
<ul>
|
|
34 |
<li><A HREF="#Integers">Integers</A>
|
|
35 |
<li><A HREF="#Strings">Strings</A>
|
|
36 |
<li><A HREF="#Stack_Manipulation">Stack Manipulation</A>
|
|
37 |
<li><A HREF="#Stack_Stack_Manipulation">Stack Stack Manipulation</A>
|
|
38 |
</ul>
|
|
39 |
<p><li><h4><A HREF="#Media">Media: Communications and Storage</A></h4>
|
|
40 |
<ul>
|
|
41 |
<li><A HREF="#Storage">Funge-Space Storage</A>
|
|
42 |
<li><A HREF="#Stdio">Standard Input/Output</A>
|
|
43 |
<li><A HREF="#Fileio">File Input/Output</A>
|
|
44 |
<li><A HREF="#System">System Execution</A>
|
|
45 |
<li><A HREF="#Sysinfo">System Information Retrieval</A>
|
|
46 |
</ul>
|
|
47 |
<p><li><h4><A HREF="#Scale">Scale: Extension and Customization</A></h4>
|
|
48 |
<ul>
|
|
49 |
<li><A HREF="#Handprints">Handprints</A>
|
|
50 |
<li><A HREF="#Fingerprints">Fingerprints</A>
|
|
51 |
<li><A HREF="#Registry">Funge Central Registry</A>
|
|
52 |
</ul>
|
|
53 |
<p><li><h4><A HREF="#Appendix">Appendix</A></h4>
|
|
54 |
<ul>
|
|
55 |
<li><A HREF="#Quickref">Instruction Quick Reference</A>
|
|
56 |
<li><A HREF="#Concurrent">Concurrent Funge-98</A>
|
|
57 |
<li><A HREF="#Lahey">Lahey-Space</A>
|
|
58 |
<li><A HREF="#Topologies">Other Topologies</A>
|
|
59 |
</ul>
|
|
60 |
</ul>
|
|
61 |
|
|
62 |
<hr><a name="Introduction"><h2>Introduction</h2>
|
|
63 |
|
|
64 |
<a name="Whatis"><h3>What is a Funge?</h3>
|
|
65 |
|
|
66 |
<p>Funges are programming languages whose programs are
|
|
67 |
typically expressed in a given topological pattern and
|
|
68 |
number of dimensions.
|
|
69 |
|
|
70 |
<p>Funge-98 is currently an official prototype standard for Funges.
|
|
71 |
Funge-98 has evolved from Funge-97, which was a generalization of
|
|
72 |
Befunge-97, which was an improvement over Befunge-96, which was
|
|
73 |
an update of the original Befunge-93 language definition.
|
|
74 |
|
|
75 |
<p>Funge-98 is a <i>class</i> of three real and
|
|
76 |
officially sanctioned programming languages
|
|
77 |
(Unefunge, Befunge, and Trefunge) and provides a
|
|
78 |
paradigm for describing any number of imaginary ones
|
|
79 |
with different topologies and any number of dimensions.
|
|
80 |
|
|
81 |
<p>The most popular Funge by far is Befunge, which
|
|
82 |
is two-dimensional and based on a Cartesian Lahey-Space
|
|
83 |
(or Cartesian Torus, in Befunge-93 only) topology.
|
|
84 |
Other Cartesian Lahey-Space Funges include Unefunge (one-dimensional)
|
|
85 |
and Trefunge (three-dimensional.) Since not all Funge instructions
|
|
86 |
are appropriate in all Funges, comparison to Befunge is often
|
|
87 |
used to clarify points in this document.
|
|
88 |
|
|
89 |
<hr><a name="About"><h3>About this Document</h3>
|
|
90 |
|
|
91 |
<p>This is a final document. The information it contains has been formally
|
|
92 |
approved and it is endorsed by its supporters as the 'official'
|
|
93 |
technical specification of the Funge language family.
|
|
94 |
|
|
95 |
<p>This document is suitable for an
|
|
96 |
audience not already familiar with any Funge of any kind or year.
|
|
97 |
|
|
98 |
<hr><h2><a name="Machine">The Funge Virtual Machine</h2>
|
|
99 |
|
|
100 |
<a name="Code_Data"><h3>Code and Data</h3>
|
|
101 |
|
|
102 |
<p>Any given piece of code or data in a Funge
|
|
103 |
can be stored in one of two places (called a <i>cell</i>):
|
|
104 |
|
|
105 |
<ul>
|
|
106 |
<li><i>Funge-Space</i>, a matrix appropriate to the
|
|
107 |
dimensionality, topology and tiling pattern of the Funge,
|
|
108 |
where each <i>node</i> in its topological net contains a cell; or
|
|
109 |
|
|
110 |
<li>the <i>stack</i> in Befunge-93
|
|
111 |
or the <i>stack stack</i>
|
|
112 |
in Funge-98; either way, it's often called <i>the stack</i>
|
|
113 |
and it's accessed as a last-in, first-out (LIFO) stack of cells.
|
|
114 |
</ul>
|
|
115 |
|
|
116 |
<P>Befunge-93 defines signed 32-bit stack cells and unsigned
|
|
117 |
8-bit Funge-Space cells. In Funge-98, stack and Funge-Space cells
|
|
118 |
alike should be treated as signed integers of the same size.
|
|
119 |
|
|
120 |
<p>What size exactly is left up to the implementer.
|
|
121 |
32 bits is typical. 16 bit and 8 bit versions are discussed as
|
|
122 |
separate variations on Funge-98.
|
|
123 |
More than 32 bits is just fine. The important thing is that the
|
|
124 |
stack cells have the same memory size as the Funge-Space cells.
|
|
125 |
|
|
126 |
<hr><a name="Space"><h3>Funge-Space</h3>
|
|
127 |
|
|
128 |
<p>In Befunge-93, Funge-Space is restricted to 80 cells in the
|
|
129 |
<i>x</I> dimension and 25 cells in the <i>y</i> dimension. No
|
|
130 |
such limits are imposed on Funge-98 programs. A Funge-98
|
|
131 |
interpreter, ideally, has an addressing range equal to that
|
|
132 |
of its cell size. i.e. A 32-bit implementation of Funge-98
|
|
133 |
uses signed 32-bit integers as each of its coordinate indices.
|
|
134 |
|
|
135 |
<p>With such a large typical addressing range, the Funge-98-Space
|
|
136 |
is generally considered to be dynamically allocated
|
|
137 |
by some behind-the-scenes mechanism in the compiler.
|
|
138 |
It <i>needn't</i> be, of course, but in practice, it usually is.
|
|
139 |
|
|
140 |
<p>So, the storage mechanism has be consistently trustworthy about
|
|
141 |
how it provides Funge-Space to the running program.
|
|
142 |
A Funge-98 program should be able to rely on all code and data
|
|
143 |
that it puts in Funge-Space through this mechanism not disappearing.
|
|
144 |
A Funge-98 program should also be able to rely on the memory mechanism
|
|
145 |
acting as if a cell contains blank space (ASCII 32) if it is
|
|
146 |
unallocated, and setting memory to be full of blank space cells upon
|
|
147 |
actual allocation (program load, or <code>p</code> instruction).
|
|
148 |
If the underlying memory mechanism cannot provide this (e.g. no more
|
|
149 |
memory is available to be allocated,) the interpreter should complain
|
|
150 |
with an error and do what it can to recover, (but not necessarily
|
|
151 |
gracefully).
|
|
152 |
|
|
153 |
<p>The co-ordinate mapping used for both Befunge-93 and Funge-98
|
|
154 |
reflects the "Computer Storage" co-ordinate system used in screen
|
|
155 |
graphics and spreadsheets; a larger <i>y</i> coordinate means
|
|
156 |
further down the page. Compared to a standard mathematical
|
|
157 |
representation of the usual Cartesian co-ordinate system,
|
|
158 |
it is upside-down.
|
|
159 |
|
|
160 |
<p><table><tr><td><pre>
|
|
161 |
Befunge-93 32-bit Befunge-98
|
|
162 |
========== =================
|
|
163 |
0 <i>x</i> 79 |-2,147,483,648
|
|
164 |
0+-------------+ |
|
|
165 |
| | <i>x</i>
|
|
166 |
| -----+-----
|
|
167 |
<i>y</i>| -2,147,483,648 | 2,147,483,647
|
|
168 |
| |
|
|
169 |
| <i>y</i>|2,147,483,647
|
|
170 |
24+
|
|
171 |
</pre></td></tr></table>
|
|
172 |
|
|
173 |
<hr><a name="Stack_Stack"><h3>Stack Stack</h3>
|
|
174 |
|
|
175 |
<p>The Funge stack stack is a LIFO stack of typical LIFO stacks
|
|
176 |
of cells. In Befunge-93, only two operations
|
|
177 |
are possible on only one stack (referred to as <i>the stack</i>):
|
|
178 |
to <i>push</i> a cell onto the top of
|
|
179 |
the stack, and to <i>pop</i> a cell off the top of the stack.
|
|
180 |
|
|
181 |
<p>In the case of Funge-98, however, <i>the stack</i> refers
|
|
182 |
to the topmost stack on the stack stack. The push and pop operations
|
|
183 |
are possible on the stack stack as well, but they push and pop entire
|
|
184 |
stacks.
|
|
185 |
|
|
186 |
<p>There is also a Funge-98 instruction to rid the stack
|
|
187 |
(that is, the topmost stack of the stack stack) of cells,
|
|
188 |
completely emptying it.
|
|
189 |
|
|
190 |
<p>If a program attempts to pop a cell off the stack when it is empty, no
|
|
191 |
error occurs; the program acts as if it popped a 0.
|
|
192 |
|
|
193 |
<p>In this document, short stacks are generally notated
|
|
194 |
left to right to mean <b>bottom to top</b>. The <b>leftmost</b>
|
|
195 |
values listed in the documentation are the
|
|
196 |
<b>bottommost</b> and the <b>first</b> to be pushed onto the stack.
|
|
197 |
Long stacks
|
|
198 |
are notated top to bottom, to mean precisely that, <b>top to bottom.</b>.
|
|
199 |
|
|
200 |
<hr><a name="Format"><h3>Funge Source File Format</h3>
|
|
201 |
|
|
202 |
<p>A Befunge-93 source (program) file name, by common convention, ends in
|
|
203 |
the extension <tt>.bf</tt>. There is no enforced convention for
|
|
204 |
what any given Funge-98 source file name ends in (e.g. you could
|
|
205 |
easily write a C-Befunge polyglot whose file name ends in <tt>.c</tt>), but
|
|
206 |
<tt>.b98</tt> is a good choice for Befunge-98 sources
|
|
207 |
- "standard" example programs use this suffix.
|
|
208 |
|
|
209 |
<p>Befunge-93 source files are plain text files containing only printable
|
|
210 |
ASCII characters and the end-of-line controls described below.
|
|
211 |
|
|
212 |
<p>Funge-98 source files are made up of Funge characters. The
|
|
213 |
Funge-98 character set overlays the ASCII subset used by Befunge-93
|
|
214 |
and may have characters greater than 127 present in it (and greater
|
|
215 |
than 255 on systems where characters are stored in multiple bytes;
|
|
216 |
but no greater than 2,147,483,647.) The Funge character set is 'display-independent.'
|
|
217 |
That is to say, character #417 may look like a squiggle on system
|
|
218 |
Foo and a happy face on system Bar, but the meaning is always the
|
|
219 |
same to Funge, 'character #417', regardless of what it looks like.
|
|
220 |
|
|
221 |
<p>In other words, what Funge characters look like on a particular computer or
|
|
222 |
OS depends entirely on that computer or OS. However, when
|
|
223 |
characters are not generally considered to be printable, they can
|
|
224 |
have special meaning to Funge-98:
|
|
225 |
|
|
226 |
<ul>
|
|
227 |
<li>0..31 : "ASCII controls" (only 10 is currently defined to mean EOL)
|
|
228 |
<li>32..126 : "ASCII printable characters" (all are input/output and fixed-width)
|
|
229 |
<li>127 : "delete control" (undefined)
|
|
230 |
<li>128..2bil: "extended printable characters" (machine and font specific)
|
|
231 |
</ul>
|
|
232 |
|
|
233 |
<p>In Befunge-93, each line ends with the current operating system's
|
|
234 |
"end of line" character, which may be a line feed (10) (Linux),
|
|
235 |
carriage return (13) (MacOS), or carriage return-line feed (13, 10)
|
|
236 |
(MS-DOS).
|
|
237 |
|
|
238 |
<p>In Funge-98, however, <i>any</i> of the following sequences
|
|
239 |
should, ideally, be recognized by the interpreter as an end-of-line marker,
|
|
240 |
no matter <i>what</i> operating system it's running on:
|
|
241 |
<ul>
|
|
242 |
<li>Line Feed (10)
|
|
243 |
<li>Carriage Return (13)
|
|
244 |
<li>Carriage Return, Line Feed (13, 10)
|
|
245 |
</ul>
|
|
246 |
|
|
247 |
<p>If an interpreter cannot support all three varieties of end-of-line marker,
|
|
248 |
it should be clearly noted in that interpreter's documentation.
|
|
249 |
|
|
250 |
<p>End-of-line markers do <b>not</b> appear in Funge-Space once the
|
|
251 |
program is loaded.
|
|
252 |
|
|
253 |
<p>In Befunge-93, each line can contain up to 80 significant characters
|
|
254 |
before the "End of Line" marker. There can be up to 25 such lines in
|
|
255 |
the source file. There are no such restrictions on Befunge-98 and the
|
|
256 |
user can reasonably expect to be able to have as many lines of as many
|
|
257 |
characters as they want, for non-contrived cases.
|
|
258 |
|
|
259 |
<p>Before load, every cell in Funge-Space contains a space (32) character.
|
|
260 |
These default contents are written over by characters in the program
|
|
261 |
source when it is loaded. However, spaces in the program source
|
|
262 |
do not overwrite anything in Funge-Space; in essence the space
|
|
263 |
character is transparent in source files. This becomes important when
|
|
264 |
the <code>i</code> "Input File" instruction is used to include overlapping files.
|
|
265 |
|
|
266 |
<p>The source file begins at
|
|
267 |
the <i>origin</i> of Funge-Space. Subsequent columns of characters
|
|
268 |
increment the <i>x</i> coordinate, and subsequent lines increment
|
|
269 |
the <i>y</i> coordinate (if one is present) and reset the <i>x</i>
|
|
270 |
coordinate to zero. Subsequent lines in Unefunge are simply appended
|
|
271 |
to the first, and the end of the source file indicates the end
|
|
272 |
of the (single) line. End-of-line markers are never copied
|
|
273 |
into Funge-Space.
|
|
274 |
|
|
275 |
<p>In Trefunge-98, the Form Feed (12) character increments the <i>z</i>
|
|
276 |
coordinate and resets the <i>x</i> and <i>y</i> coordinates to zero.
|
|
277 |
|
|
278 |
<hr><h2><a name="Code">Code: Program Flow</h2>
|
|
279 |
|
|
280 |
<a name="IP"><h3>Instruction Pointer</h3>
|
|
281 |
|
|
282 |
<p>The <i>instruction pointer</i> (IP) can be thought of as a <i>vector</i>
|
|
283 |
(set of co-ordinates) which represents the "current position" of a running Funge program. It
|
|
284 |
holds the same function as the instruction pointer (or <i>program
|
|
285 |
counter</i> (PC)) in any other language or processor - to indicate
|
|
286 |
where the currently executing instruction is located.
|
|
287 |
|
|
288 |
<p>In most other languages and machines (both virtual and real,)
|
|
289 |
the IP/PC is restricted to unidirectional travel in a single
|
|
290 |
dimension, with random jumps. However, in Funge, the IP keeps
|
|
291 |
track of another vector called the <i>delta</i>. Every <i>tick</i>,
|
|
292 |
the IP executes its current instruction (that is, the instruction
|
|
293 |
at the location pointed to by the IP), then travels to a new location, by
|
|
294 |
adding its delta vector to its position vector.
|
|
295 |
|
|
296 |
<p>At the beginning of a program, in Funge-98 as in Befunge-93,
|
|
297 |
the IP always begins at the origin and
|
|
298 |
starts with a delta of (1, 0). The origin is
|
|
299 |
(0, 0) in Befunge, (0) in Unefunge, and (0, 0, 0) in Trefunge.
|
|
300 |
|
|
301 |
<p>In two dimensions, we have the following terminology.
|
|
302 |
|
|
303 |
<p>If the IP's delta is either (0,-1) (<i>south</i>), (1,0)
|
|
304 |
(<i>east</i>), (0,1) (<i>north</i>), or (-1,0) (<i>west</i>),
|
|
305 |
it is said to be traveling <i>cardinally</i>. This is the
|
|
306 |
same as how a rook moves in chess and this
|
|
307 |
is in fact the only way the IP can move in Befunge-93.
|
|
308 |
|
|
309 |
<p>Any IP with a nonzero delta is considered <i>moving</i>.
|
|
310 |
Any IP with a zero delta is said to be <i>stopped</i>.
|
|
311 |
Any moving IP that is not traveling cardinally is said
|
|
312 |
to be <i>flying</i>.
|
|
313 |
|
|
314 |
<hr><a name="Instructions"><h3>Instructions</h3>
|
|
315 |
|
|
316 |
<p>All standard instructions are one character long and range from
|
|
317 |
ASCII 32 (space) to ASCII 126 (<code>~</code>). There are no
|
|
318 |
multicharacter instructions in Funge.
|
|
319 |
|
|
320 |
<p>An instruction is executed by an IP every tick. The IP
|
|
321 |
executed is the one at the current position of the IP.
|
|
322 |
Only after that does the IP moves by its delta to a new position.
|
|
323 |
|
|
324 |
<p>Instructions <code>A</code> to <code>Z</code> all initially act like the
|
|
325 |
<code>r</code> "Reflect" instruction. However, other instructions
|
|
326 |
assign semantics to these instructions dynamically, allowing
|
|
327 |
the Funge programmer to use libraries of both standard and proprietary
|
|
328 |
instruction sets tagged with unique ID's (or <i>fingerprints</i>.)
|
|
329 |
|
|
330 |
<p>However, a Funge-98 interpreter may also expose any number of
|
|
331 |
proprietary instructions above ASCII 127 or below ASCII 0.
|
|
332 |
|
|
333 |
<p>For all these reasons, when encountering any unimplemented
|
|
334 |
instruction (this includes instructions like <code>|</code> in
|
|
335 |
Unefunge,) the Funge interpreter should at least provide an option
|
|
336 |
for informing the user that it was told to execute an instruction
|
|
337 |
that isn't implemented, and possibly
|
|
338 |
warning the user that this file might be an incorrect language or
|
|
339 |
version.
|
|
340 |
|
|
341 |
<p>An unimplemented instruction must otherwise act as
|
|
342 |
if <code>r</code> was executed, and must not touch the stack.
|
|
343 |
All undefined or otherwise unimplemented
|
|
344 |
instructions must be considered unimplemented.
|
|
345 |
|
|
346 |
<p>Also, any of the instructions <code>t</code>
|
|
347 |
(concurrent execution,) <code>=</code> (execute,)
|
|
348 |
<code>i</code> (input-file,)
|
|
349 |
and <code>o</code> (output-file)
|
|
350 |
may be unavailable in different interpreters for many reasons, and
|
|
351 |
are routinely bound to (i.e. act just like) <code>r</code> as well.
|
|
352 |
However, they may also act like <code>r</code> when they fail to execute.
|
|
353 |
To test if they are actually supported, execute <code>1y</code> and examine
|
|
354 |
the cell it produces.
|
|
355 |
|
|
356 |
<hr><a name="Direction"><h3>Direction Changing</h3>
|
|
357 |
|
|
358 |
<p>A few instructions are essential for changing the delta of the IP.
|
|
359 |
The <code>></code> "Go East" instruction causes the IP to travel
|
|
360 |
east; the <code><</code> "Go West" instruction causes the IP to
|
|
361 |
travel west. These instructions are valid in all Funges.
|
|
362 |
|
|
363 |
<p>The <code>^</code> "Go North" instruction causes the IP to travel north;
|
|
364 |
the <code>v</code> "Go South" instruction causes the IP to travel south.
|
|
365 |
These instructions are not available in Unefunge.
|
|
366 |
|
|
367 |
<p>The <code>h</code> "Go High" instruction causes the IP to travel up (delta <- (0,0,1));
|
|
368 |
the <code>l</code> "Go Low" instruction causes the IP to travel
|
|
369 |
down (delta <- (0,0,-1)). These instructions are not available
|
|
370 |
in Unefunge or Befunge.
|
|
371 |
|
|
372 |
<p>The <code>?</code> "Go Away" instruction causes the IP to travel in
|
|
373 |
a random cardinal direction appropriate to the number of
|
|
374 |
dimensions in use: east or west in Unefunge; north, south,
|
|
375 |
east or west in Befunge, etc.
|
|
376 |
|
|
377 |
<p>The following instructions are not in Befunge-93, but they are in
|
|
378 |
Funge-98.
|
|
379 |
|
|
380 |
<p>The <code>]</code> "Turn Right" and <code>[</code> "Turn Left"
|
|
381 |
instructions rotate by 90 degrees the delta of the IP which
|
|
382 |
encounters them. They always rotate on the <i>z</i> axis.
|
|
383 |
These instructions are not available in Unefunge.
|
|
384 |
|
|
385 |
<p>To remember which is which, visualize
|
|
386 |
yourself on the seat of a bicycle, looking down at the handlebars:
|
|
387 |
|
|
388 |
<center><table border=1><tr>
|
|
389 |
<td align=center><code>+-<br>| <br>+-</code></td>
|
|
390 |
<td align=center><code>+-+<br>| |</code></td>
|
|
391 |
<td align=center><code>-+<br> |<br>-+</code></td>
|
|
392 |
</tr><tr>
|
|
393 |
<td align=center><code>[</code></td>
|
|
394 |
<td align=center><code> </code></td>
|
|
395 |
<td align=center><code>]</code></td>
|
|
396 |
</tr><tr>
|
|
397 |
<td align=center><code>Turn Left</code></td>
|
|
398 |
<td align=center><code>Go Forward</code></td>
|
|
399 |
<td align=center><code>Turn Right</code></td>
|
|
400 |
</tr></table></center>
|
|
401 |
|
|
402 |
<p>The <code>r</code> "Reverse" instruction multiplies
|
|
403 |
the IP's delta by -1. In two dimensions, this is
|
|
404 |
the equivalent of reflecting the delta of
|
|
405 |
the IP about the z-axis.
|
|
406 |
|
|
407 |
<p>The <code>x</code> "Absolute Vector" instruction pops a vector off
|
|
408 |
the stack, and sets the IP delta to that vector.
|
|
409 |
|
|
410 |
<p>A vector on the stack is stored bottom-to-top, so that in
|
|
411 |
Befunge, <code>x</code> (and all other vector-popping instructions)
|
|
412 |
pops a value it calls <i>dy</i>, then pops a
|
|
413 |
value it calls <i>dx</i>, then sets the delta to (<i>dx</i>, <i>dy</i>).
|
|
414 |
|
|
415 |
<hr><a name="Wrapping"><h3>Wrapping</h3>
|
|
416 |
|
|
417 |
<p>Befunge-93 handles the case of the IP travelling
|
|
418 |
out of bounds (off the map of Funge-Space) by treating the space
|
|
419 |
as a torus. If the IP leaves the west edge, it reappears on the
|
|
420 |
east edge at the same row; if it leaves the south edge, it
|
|
421 |
reappears at the north edge at the same column, and vice
|
|
422 |
versa in both cases.
|
|
423 |
|
|
424 |
<p>For various reasons, toroidal wrapping is problematic
|
|
425 |
in Funge-98. Instead, we use a special wrapping technique that
|
|
426 |
has more consistent results in this new, more flexible
|
|
427 |
environment where Funge-Space can have an arbitrary size
|
|
428 |
and the IP can fly. It is called <i>same-line wrapping</i>.
|
|
429 |
|
|
430 |
<p>Same-line wrapping can be described in several ways,
|
|
431 |
but the crucial idea it encompasses is this: unless the delta
|
|
432 |
or position of the IP were to be changed by an intervening instruction,
|
|
433 |
the IP will always wrap such that it would eventually
|
|
434 |
return to the instruction it was on before it wrapped.
|
|
435 |
|
|
436 |
<p>The mathematical description of same-line wrapping is
|
|
437 |
known as <i>Lahey-space</i> wrapping, which defines a special
|
|
438 |
topological space. It is generally of more interest to
|
|
439 |
topologists and mathematicians than programmers. We won't
|
|
440 |
cover it here, but it is included in the
|
|
441 |
<a href="#Lahey">Appendix</a> for completeness.
|
|
442 |
|
|
443 |
<p>The algorithmic description of same-line wrapping can
|
|
444 |
be described as <i>backtrack wrapping</i>. It is more of
|
|
445 |
interest to Funge interpreter implementers than Funge
|
|
446 |
programmers. However, it does describe exactly how the
|
|
447 |
wrapping <i>acts</i> in terms that a programmer can
|
|
448 |
understand, so we will include it here.
|
|
449 |
|
|
450 |
<p>When the IP attempts to travel into the whitespace
|
|
451 |
between the code and the end of known, addressable space, it backtracks.
|
|
452 |
This means that its delta is reversed and it ignores
|
|
453 |
(skips over without executing) all instructions. Travelling thus, it finds the other 'edge' of
|
|
454 |
code when there is again nothing but whitespace in front of it. It
|
|
455 |
is reflected 180 degrees once more (to restore its original delta)
|
|
456 |
and stops ignoring instructions. Execution then resumes normally
|
|
457 |
- the wrap is complete.
|
|
458 |
|
|
459 |
<p><center><img src="wrap.jpg" alt="(wrap.jpg - Wrapping pictorial diagram)"></center>
|
|
460 |
|
|
461 |
<p>It is easy to see at this point that the IP remains on the same
|
|
462 |
line: thus the name. (Also note that this <b>never</b> takes any
|
|
463 |
ticks in regards to multithreading, as would be expected from any
|
|
464 |
wrapping process.)
|
|
465 |
|
|
466 |
<p>Same-line wrapping has the advantage of being
|
|
467 |
backward-compatible with Befunge-93's toroidal wrapping. It also works
|
|
468 |
safely both when the IP delta is flying (non-cardinal), and when the
|
|
469 |
size of the program changes.
|
|
470 |
|
|
471 |
<p>As noted, by default every cell in Funge-Space contains a space (32)
|
|
472 |
character. (This holds true with most decent Befunge-93 interpreters,
|
|
473 |
too, although it was not in the original.)
|
|
474 |
|
|
475 |
<p>In Befunge-93, when interpreted as an instruction, a space is treated
|
|
476 |
as a "no operation" or <i>nop</i>. The interpreter does nothing and
|
|
477 |
continues on its merry way.
|
|
478 |
|
|
479 |
<p>Funge-98 acts much the same way, except
|
|
480 |
technically, Funge-98 processes any number of spaces in "no time
|
|
481 |
whatsoever", and this becomes important when you have more than one
|
|
482 |
IP in Funge-Space at the same time (<i>multithreading</i>), which
|
|
483 |
you'll read about later. For an explicit nop instruction in
|
|
484 |
Funge-98, use <code>z</code>.
|
|
485 |
|
|
486 |
<p>Space also takes on special properties (in Funge-98) with a special
|
|
487 |
<i>mode</i> of the interpreter called stringmode, which you'll also
|
|
488 |
read about later.
|
|
489 |
|
|
490 |
<hr><a name="Flow"><h3>Flow Control</h3>
|
|
491 |
|
|
492 |
<p>The <code>#</code> "Trampoline" instruction moves the IP one position beyond
|
|
493 |
the next Funge-Space cell in its path.
|
|
494 |
|
|
495 |
<p>The <code>@</code> "Stop" instruction kills the current IP.
|
|
496 |
In non-Concurrent Funge, there is only a single IP.
|
|
497 |
Either way, when no IP's are left alive,
|
|
498 |
the program will subsequently end with no error (returning error code 0).
|
|
499 |
|
|
500 |
<p>The following instructions and markers are not in Befunge-93, but they are
|
|
501 |
in Funge-98.
|
|
502 |
|
|
503 |
<p>The <code>;</code> "Jump Over" marker causes the IP to
|
|
504 |
jump over all subsequent
|
|
505 |
instructions until the next <code>;</code> marker. Like space, this
|
|
506 |
takes zero ticks to execute, so that subroutines, comments,
|
|
507 |
and satellite code can be insulated by surrounding it with
|
|
508 |
<code>;</code> markers, with no effect on multithreading.
|
|
509 |
|
|
510 |
<p><code>;</code> is truly ethereal; like space, it cannot ever
|
|
511 |
be truly executed, in the sense of it taking up a tick and
|
|
512 |
doing something.
|
|
513 |
|
|
514 |
<p>The <code>j</code> "Jump Forward" instruction pops a
|
|
515 |
value off the stack, and jumps over that many spaces.
|
|
516 |
If there is a 1 on the stack, <code>j</code> will work like <code>#</code> does.
|
|
517 |
e.g. <code>2j789.</code> would print 9 and leave an empty stack.
|
|
518 |
Negative values are legal arguments for <code>j</code>, such
|
|
519 |
that <code>04-j@</code> is an infinite loop.
|
|
520 |
|
|
521 |
<p>The <code>q</code> "Quit" instruction, only in Funge-98,
|
|
522 |
ends the entire program immediately
|
|
523 |
(regardless of the number of IPs active in Concurrent Funge).
|
|
524 |
It also pops a cell off the stack and uses that value as
|
|
525 |
the return value of the Funge interpreter to the
|
|
526 |
operating system.
|
|
527 |
|
|
528 |
<p>Note that most operating systems will only look at
|
|
529 |
the least significant byte your return value, unsigned.
|
|
530 |
But you can return a full cell, and the OS will interpret
|
|
531 |
as much of it as it can handle, treating it as
|
|
532 |
signed or unsigned as the OS demands.
|
|
533 |
|
|
534 |
<p>The <code>k</code> "Iterate" instruction pops a value <i>n</i>
|
|
535 |
off the stack. Then it finds the next instruction
|
|
536 |
in Funge-space in the path of the IP (note that this cannot
|
|
537 |
be a marker such as space or <code>;</code>), treats it as an instruction,
|
|
538 |
executing it <i>n</i> times. This takes only one tick with
|
|
539 |
respect to concurrent operation.
|
|
540 |
|
|
541 |
<p>Note that some instructions don't make much sense within
|
|
542 |
the context of <code>k</code> unless you include zero as one
|
|
543 |
of the possibilities for how many times the instruction
|
|
544 |
is repeated. For example, no matter how
|
|
545 |
many times after the first time <code>k</code> execute <code>^</code>,
|
|
546 |
the result is the same.
|
|
547 |
However, you may pass a zero count to <code>k</code>, and
|
|
548 |
the <code>^</code> instruction will not be executed; this can be a valuable
|
|
549 |
behaviour.
|
|
550 |
|
|
551 |
<p>Also, note <code>k</code> will never, ever actually execute
|
|
552 |
instruction #32, space, or <code>;</code>.
|
|
553 |
|
|
554 |
<hr><a name="Decision"><h3>Decision Making</h3>
|
|
555 |
|
|
556 |
<p>The <code>!</code> "Logical Not" instruction pops a value off
|
|
557 |
the stack and pushes a value which is the logical negation of it.
|
|
558 |
If the value is zero, it pushes one; if it is non-zero, it pushes
|
|
559 |
zero.
|
|
560 |
|
|
561 |
<p>The <code>`</code> "Greater Than" instruction pops two cells off the
|
|
562 |
stack, then pushes a one if second cell is greater than the
|
|
563 |
first. Otherwise pushes a zero.
|
|
564 |
|
|
565 |
<p>Funge has instructions that act like directional 'if' statements.
|
|
566 |
The <code>_</code> "East-West If" instruction pops a value off the
|
|
567 |
stack; if it is zero it acts like <code>></code>, and if non-zero
|
|
568 |
it acts like <code><</code>.
|
|
569 |
|
|
570 |
<p>The <code>|</code> "North-South If" instruction pops a value off the stack; if it is
|
|
571 |
zero it acts like <code>v</code>, and if non-zero it acts like <code>^</code>. <code>|</code>
|
|
572 |
is not available in Unefunge.
|
|
573 |
|
|
574 |
<p>The <code>m</code> "High-Low If" (think <i>middle</i>)
|
|
575 |
instruction pops a value off the
|
|
576 |
stack; if it is zero it acts like <code>l</code>, and if non-zero it
|
|
577 |
acts like <code>h</code>. <code>m</code> is not available in Unefunge
|
|
578 |
or Befunge.
|
|
579 |
|
|
580 |
<p>The <code>w</code> "Compare" instruction pops a value <i>b</i>
|
|
581 |
off the stack, then pops a value <i>a</i>,
|
|
582 |
then compares them. (<i>a</i> is called <i>a</i> because it was
|
|
583 |
the first of the two values to be <i>pushed</i> onto the stack.)
|
|
584 |
If the <i>a</i> is smaller, <code>w</code> acts like <code>[</code>, and
|
|
585 |
turns left. If the <i>a</i> is greater, <code>w</code> acts like
|
|
586 |
<code>]</code>, and turns right.
|
|
587 |
If <i>a</i> and <i>b</i> are equal, <code>w</code> does not affect the IP's
|
|
588 |
delta. This instruction is not available in Befunge-93, nor
|
|
589 |
Unefunge.
|
|
590 |
|
|
591 |
<hr><h2><a name="Data">Data: Cell Crunching</h2>
|
|
592 |
|
|
593 |
<a name="Integers"><h3>Integers</h3>
|
|
594 |
|
|
595 |
<p>Instructions <code>0</code> "Push Zero" through <code>9</code> "Push Niner"
|
|
596 |
push the values zero
|
|
597 |
through nine onto the stack, respectively.
|
|
598 |
In Funge-98, <code>a</code> through <code>f</code> also push 10
|
|
599 |
through 15 respectively.
|
|
600 |
|
|
601 |
<p>The <code>+</code> "Add" instruction pops two cells from the stack, adds
|
|
602 |
them using integer addition,
|
|
603 |
and pushes the result back onto the stack.
|
|
604 |
|
|
605 |
<p>The <code>*</code> "Multiply" instruction pops two cells
|
|
606 |
from the stack, multiplies them using integer multiplication,
|
|
607 |
and pushes the result back onto the stack. In this way numbers
|
|
608 |
larger than 9 (or 15) can be pushed onto the stack.
|
|
609 |
|
|
610 |
<p>For example, to push the value 123 onto the stack, one might write
|
|
611 |
<pre>
|
|
612 |
99*76*+</pre>
|
|
613 |
|
|
614 |
or
|
|
615 |
|
|
616 |
<pre>
|
|
617 |
555**2-</pre>
|
|
618 |
|
|
619 |
<p>Funge also offers the following arithmetic instructions:
|
|
620 |
<ul>
|
|
621 |
<li>the <code>-</code> "Subtract" instruction, which pops two values, subtracts the
|
|
622 |
first from the second using integer subtraction, and pushes the result;
|
|
623 |
<li>the <code>/</code> "Divide" instruction, which pops
|
|
624 |
two values, divides the second by the first using integer division,
|
|
625 |
and pushes the result (note that division by zero produces
|
|
626 |
a result of zero in Funge-98, but Befunge-93 instead is
|
|
627 |
supposed to <i>ask</i> the user what they want the result of
|
|
628 |
the division to be); and
|
|
629 |
<li> the <code>%</code> "Remainder" instruction,
|
|
630 |
which pops two values, divides the
|
|
631 |
second by the first using integer division,
|
|
632 |
and pushes the remainder, of those.
|
|
633 |
Remainder by zero is subject to the same rules as division by zero,
|
|
634 |
but if either argument is negative, the result is implementation-defined.
|
|
635 |
</ul>
|
|
636 |
|
|
637 |
<hr><a name="Strings"><h3>Strings</h3>
|
|
638 |
|
|
639 |
<p>The instruction <code>"</code> "Toggle Stringmode"
|
|
640 |
toggles a special mode of the Funge
|
|
641 |
interpreter called <i>stringmode</i>. In stringmode, every cell
|
|
642 |
encountered by the IP (except <code>"</code> and in Funge-98, space)
|
|
643 |
is not interpreted as an instruction, but rather as a Funge
|
|
644 |
character, and is pushed onto the stack. A subsequent <code>"</code>
|
|
645 |
toggles stringmode once more, turning it off.
|
|
646 |
|
|
647 |
<p>In Funge-98 stringmode, spaces are treated "SGML-style";
|
|
648 |
that is, when any contiguous series of spaces is processed,
|
|
649 |
it only takes one tick and pushes one space onto the stack. This
|
|
650 |
introduces a small backward-incompatibility with
|
|
651 |
Befunge-93; programs that have multiple spaces and/or wrap while
|
|
652 |
in stringmode will have to be changed to work the same under
|
|
653 |
Funge-98.
|
|
654 |
|
|
655 |
<pre>
|
|
656 |
Befunge-93 Befunge-98
|
|
657 |
|
|
658 |
"hello world" "hello world"
|
|
659 |
"hello world" "hello "::"world"</pre>
|
|
660 |
|
|
661 |
<p>There is also a <code>'</code> "Fetch Character"
|
|
662 |
instruction in Funge-98. This pushes the Funge character value
|
|
663 |
of the next encountered cell (position + delta) onto the stack,
|
|
664 |
then adds the delta to the position (like <code>#</code>), skipping
|
|
665 |
over the character (in no ticks). For example, the
|
|
666 |
following two snippets perform the same function, printing a Q:
|
|
667 |
|
|
668 |
<p><code>"Q",</code>
|
|
669 |
|
|
670 |
<p><code>'Q,</code>
|
|
671 |
|
|
672 |
<p><code>s</code> "Store Character" is the mirror image of the
|
|
673 |
<code>'</code> instruction: this instead pops a value off
|
|
674 |
the stack and writes it into (position + delta).
|
|
675 |
|
|
676 |
<p>Some instructions expect a Funge string on the stack as one of
|
|
677 |
their arguments. The standard format for these strings is called
|
|
678 |
<i>0"gnirts"</i> - that is, a null-terminated string with the
|
|
679 |
start of the string at the top of the stack and the null
|
|
680 |
termination at the bottom.
|
|
681 |
|
|
682 |
<hr><a name="Stack_Manipulation"><h3>Stack Manipulation</h3>
|
|
683 |
|
|
684 |
<p>The <code>$</code> "Pop" instruction pops a cell off the stack and
|
|
685 |
discards it.
|
|
686 |
|
|
687 |
<p>The <code>:</code> "Duplicate" instruction pops a cell off the stack, then pushes it
|
|
688 |
back onto the stack twice, duplicating it.
|
|
689 |
|
|
690 |
<p>The <code>\</code> "Swap" instruction pops two cells off the stack, then pushes
|
|
691 |
the first cell back on, then the second cell, in effect swapping the
|
|
692 |
top two cells on the stack.
|
|
693 |
|
|
694 |
<p>The <code>n</code> "Clear Stack" instruction (not available in Befunge-93)
|
|
695 |
completely wipes the stack (popping and discarding elements
|
|
696 |
until it is empty.)
|
|
697 |
|
|
698 |
<hr><a name="Stack_Stack_Manipulation"><h3>Stack Stack Manipulation</h3>
|
|
699 |
|
|
700 |
<p>The stack stack transparently overlays
|
|
701 |
the stack - that is to say, the top stack of
|
|
702 |
Funge-98's stack stack is treated the same as
|
|
703 |
Befunge-93's sole stack. The Funge programmer
|
|
704 |
will never notice the difference unless they
|
|
705 |
use the <code>{</code>, <code>}</code>, or <code>u</code>
|
|
706 |
instructions of Funge-98.
|
|
707 |
|
|
708 |
<p>When working with different stacks on the stack
|
|
709 |
stack, though, it's useful to give two of them
|
|
710 |
names: the <i>top of stack stack</i> or TOSS,
|
|
711 |
which indicates the topmost stack on
|
|
712 |
the stack stack, which works to emulate the
|
|
713 |
sole stack of Befunge-93;
|
|
714 |
and the <i>second on stack stack</i> or
|
|
715 |
SOSS, which is the stack directly under
|
|
716 |
the TOSS.
|
|
717 |
|
|
718 |
<p>The <code>{</code> "Begin Block" instruction pops a cell
|
|
719 |
it calls <i>n</i>, then pushes a new stack on the
|
|
720 |
top of the stack stack,
|
|
721 |
transfers <i>n</i>
|
|
722 |
elements from the SOSS to the TOSS,
|
|
723 |
then pushes the storage offset
|
|
724 |
as a vector onto the SOSS,
|
|
725 |
then sets the new storage offset to the location to be
|
|
726 |
executed next by the IP (storage offset <- position + delta).
|
|
727 |
It copies these elements as a block, so order is preserved.
|
|
728 |
|
|
729 |
<p>If the SOSS contains <i>k</i> elements, where <i>k</i> is less than <i>n</i>, the
|
|
730 |
<i>k</i> elements are transferred as the top <i>k</i> elements and the remaining
|
|
731 |
bottom (<i>n-k</i>) elements are filled in with zero-value cells.
|
|
732 |
|
|
733 |
<p>If <i>n</i> is zero, no elements are transferred.
|
|
734 |
|
|
735 |
<p>If <i>n</i> is negative, |<i>n</i>| zeroes are pushed onto the SOSS.
|
|
736 |
|
|
737 |
<p>The corresponding <code>}</code> "End Block" instruction pops a cell off
|
|
738 |
the stack that it calls <i>n</i>, then pops a vector off the SOSS which
|
|
739 |
it assigns to the storage offset, then transfers <i>n</i> elements (as a block)
|
|
740 |
from the TOSS to the SOSS, then pops the top stack off the stack stack.
|
|
741 |
|
|
742 |
<p>The transfer of elements for <code>}</code> "End Block" is in all respects
|
|
743 |
similar to the transfer of elements for <code>{</code> "Begin Block", except
|
|
744 |
for the direction in which elements are transferred. "Transfer" is used
|
|
745 |
here in the sense of "move," not "copy": the original cells are removed.
|
|
746 |
|
|
747 |
<p>If <i>n</i> is zero, no elements are transferred.
|
|
748 |
|
|
749 |
<p>If <i>n</i> is negative, |<i>n</i>| cells are popped off of the (original) SOSS.
|
|
750 |
|
|
751 |
<p><code>{</code> makes the current TOSS the new SOSS.
|
|
752 |
<code>}</code> makes the current SOSS the new TOSS.
|
|
753 |
|
|
754 |
<p><code>{</code> may act like <code>r</code> if no more memory is available for another stack.
|
|
755 |
<code>}</code> acts like <code>r</code> if a stack-stack underflow would otherwise occur (i.e. when there is only one stack on the stack-stack.)
|
|
756 |
|
|
757 |
<p>The practical use of these instructions is to "insulate"
|
|
758 |
and "localize" procedures or other blocks of Funge code.
|
|
759 |
|
|
760 |
<p>The <code>u</code> "Stack under Stack" instruction pops a
|
|
761 |
<i>count</i> and transfers that many
|
|
762 |
cells from the SOSS to the TOSS.
|
|
763 |
It transfers these cells in a pop-push loop.
|
|
764 |
In other words, the order is not preserved during transfer,
|
|
765 |
it is reversed.
|
|
766 |
|
|
767 |
<p>If there is no SOSS (the TOSS is the only stack), <code>u</code>
|
|
768 |
should act like <code>r</code>.
|
|
769 |
|
|
770 |
<p>If <i>count</i> is negative, |<i>count</i>| cells are
|
|
771 |
transferred (similarly in a pop-push loop) from the TOSS to the
|
|
772 |
SOSS.
|
|
773 |
|
|
774 |
<p>If <i>count</i> is zero, nothing happens.
|
|
775 |
|
|
776 |
<hr><h2><a name="Media">Media: Communications and Storage</h2>
|
|
777 |
|
|
778 |
<a name="Storage"><h3>Funge-Space Storage</h3>
|
|
779 |
|
|
780 |
<p>The <code>g</code> "Get" and <code>p</code> "Put" instructions are used to
|
|
781 |
store and retrieve data and code in Funge-Space.
|
|
782 |
|
|
783 |
<p>In Befunge-93, <code>g</code> pops a vector (that is, it pops a y value,
|
|
784 |
then an x value,) and pushes the value (character)
|
|
785 |
in the Befunge-Space cell
|
|
786 |
at (x, y) onto the stack.
|
|
787 |
<code>p</code> pops a vector, then it pops a value, then it
|
|
788 |
places that value in the Funge-Space cell at (x, y).
|
|
789 |
|
|
790 |
<p>In Funge-98, each IP has an additional vector property called the
|
|
791 |
<i>storage offset</i>. Initially this vector is the set to the
|
|
792 |
origin. As such, it works to emulate Befunge-93. The arguments
|
|
793 |
to <code>g</code> and <code>p</code> are the same, but instead of pointing
|
|
794 |
to absolute locations in Funge-Space, they reference a cell relative
|
|
795 |
to the storage offset.
|
|
796 |
|
|
797 |
<hr><a name="Stdio"><h3>Standard Input/Output</h3>
|
|
798 |
|
|
799 |
<p>The <code>.</code> "Output Decimal"
|
|
800 |
and <code>,</code> "Output Character"
|
|
801 |
instructions provide numeric and Funge
|
|
802 |
character/control output, respectively; they pop a cell off the stack
|
|
803 |
and send it in numeric or Funge character format to the <i>standard
|
|
804 |
output</i>, which is usually displayed by the interpreter in an
|
|
805 |
interactive user terminal.
|
|
806 |
|
|
807 |
<p>Outputting character number 10 will result in a new line being
|
|
808 |
displayed on the standard output.
|
|
809 |
|
|
810 |
<p>Numeric output is formatted as a decimal integer followed by a space.
|
|
811 |
|
|
812 |
<p>These instructions will act as <code>r</code> does, should the standard
|
|
813 |
output fail for any reason.
|
|
814 |
|
|
815 |
<p>The <code>&</code> "Input Decimal"
|
|
816 |
and <code>~</code> "Input Character"
|
|
817 |
instructions provide numeric and Funge
|
|
818 |
character/control input, respectively. They each suspend the
|
|
819 |
program and wait for the user to enter a value in numeric or Funge
|
|
820 |
character format to the <i>standard input</i>, which is usually
|
|
821 |
displayed with the standard output. They then push this value
|
|
822 |
on the stack.
|
|
823 |
|
|
824 |
<p>An input of character number 10 indicates that the user pressed
|
|
825 |
the 'Enter' key, or the equivalent key on their keyboard.
|
|
826 |
|
|
827 |
<p>Decimal input reads and discards characters until it encounters
|
|
828 |
decimal digit characters, at which point it reads a decimal
|
|
829 |
number from those digits, up until (but not including)
|
|
830 |
the point at which input characters stop being digits,
|
|
831 |
or the point where the next digit would cause a cell overflow,
|
|
832 |
whichever comes first.
|
|
833 |
|
|
834 |
<p>Although the standard input and output are generally displayed
|
|
835 |
in some sort of interactive user terminal, they needn't be;
|
|
836 |
many operating systems support <i>redirection</i>. In the
|
|
837 |
case of an end-of-file or other file error condition, the <code>&</code>
|
|
838 |
and <code>~</code> both act like <code>r</code>.
|
|
839 |
|
|
840 |
<hr><a name="Fileio"><h3>File Input/Output</h3>
|
|
841 |
|
|
842 |
<p>File I/O is done with the <code>i</code> "Input File"
|
|
843 |
and <code>o</code> "Output File" instructions, which
|
|
844 |
are only available in Funge-98.
|
|
845 |
|
|
846 |
<p><code>i</code> pops a null-terminated 0"gnirts" string for the filename,
|
|
847 |
followed by a flags cell, then a
|
|
848 |
vector Va telling it where to operate. If the file can be opened
|
|
849 |
for reading, it is inserted into Funge-Space at Va, and immediately closed.
|
|
850 |
Two vectors are then pushed onto the stack, Va and Vb, suitable arguments to
|
|
851 |
a corresponding <code>o</code> instruction.
|
|
852 |
If the file open failed, the instruction acts like <code>r</code>.
|
|
853 |
|
|
854 |
<p><code>i</code> is in all respects similar to the procedure used
|
|
855 |
to load the main Funge source code file, except it may specify
|
|
856 |
any file, not necessarily Funge source code,
|
|
857 |
and at any location, not necessarily the origin.
|
|
858 |
|
|
859 |
<p>Also, if the least significant bit of the flags cell is high,
|
|
860 |
<code>i</code> treats the file as a binary file; that is, EOL and FF
|
|
861 |
sequences are stored in Funge-space instead of causing the
|
|
862 |
dimension counters to be reset and incremented.
|
|
863 |
|
|
864 |
<p><code>o</code> first pops a
|
|
865 |
null-terminated 0"gnirts" string to use for a filename.
|
|
866 |
Then it pops a flags cell.
|
|
867 |
It then pops a vector Va indicating a <i>least point</i>
|
|
868 |
(point with the smallest numerical coordinates of a region;
|
|
869 |
also known as the upper-left corner, when used in the context
|
|
870 |
of Befunge) in space, and another vector Vb
|
|
871 |
describing the size of a rectangle (or a rectangular prism in
|
|
872 |
Trefunge, etc).
|
|
873 |
If the file named by the filename can be opened
|
|
874 |
for writing, the contents of the rectangle of Funge-Space
|
|
875 |
from Va to Va+Vb are written into it, and it is immediately closed.
|
|
876 |
If not, the instruction acts like <code>r</code>.
|
|
877 |
|
|
878 |
<p>The first vectors popped by both of these instructions
|
|
879 |
are considered relative to the storage offset.
|
|
880 |
(The size vector Vb, of course, is relative to the least point Va.)
|
|
881 |
|
|
882 |
<p>Note that in a greater-than-two-dimensional environment,
|
|
883 |
specifying a more-than-two-dimensional size such as (3,3,3)
|
|
884 |
is not guaranteed to produce sensical results.
|
|
885 |
|
|
886 |
<p>Also, if the least significant bit of the flags cell is high,
|
|
887 |
<code>o</code> treats the file as a linear text file; that is, any spaces
|
|
888 |
before each EOL, and any EOLs before the EOF, are not written
|
|
889 |
out. The resulting text file is identical in appearance and takes
|
|
890 |
up less storage space.
|
|
891 |
|
|
892 |
<hr><a name="System"><h3>System Execution</h3>
|
|
893 |
|
|
894 |
<p>The <code>=</code> "Execute" instruction
|
|
895 |
pops a string off the stack, and attempts to execute it.
|
|
896 |
How it executes it is implementation dependant.
|
|
897 |
However, an implementation may support one of several
|
|
898 |
standardized ways of interpreting the string,
|
|
899 |
and which routine it uses can be determined by querying <code>y</code>.
|
|
900 |
Typically methods include treating it as a
|
|
901 |
C system() call would, or on a platform such as MacOS,
|
|
902 |
for example, treating the string as AppleScript would be in order.
|
|
903 |
|
|
904 |
<p>After execution, a failure value is pushed onto the stack.
|
|
905 |
If this value is zero, everything went as expected. If the
|
|
906 |
value is non-zero, it may be the return-code of the program
|
|
907 |
that was executed; at any rate it means that the attempt to
|
|
908 |
execute the program, or the program itself, did not succeed.
|
|
909 |
|
|
910 |
<hr><a name="Sysinfo"><h3>System Information Retrieval</h3>
|
|
911 |
|
|
912 |
<p>The <code>y</code> "Get SysInfo" instruction, only available in Funge-98,
|
|
913 |
pops one value off the stack. If the value is zero
|
|
914 |
or negative, <code>y</code> tells you far more than you
|
|
915 |
ever really want to know about the underlying Funge
|
|
916 |
interpreter, operating system, and computer
|
|
917 |
(and is thus usually followed soon after
|
|
918 |
by a <code>n</code> instruction).
|
|
919 |
|
|
920 |
<p>Each cell of information retrieved by <code>y</code>, only applies to
|
|
921 |
either the current IP, the current environment (that is,
|
|
922 |
the interpreter of the current IP,) or the global environment
|
|
923 |
(the environment of every IP in the same Funge-space, regardless
|
|
924 |
of which interpreter it's running on.)
|
|
925 |
|
|
926 |
<p>After an execution of <code>y</code> with a non-positive argument,
|
|
927 |
the stack contains many more cells (listed from top to bottom:)
|
|
928 |
|
|
929 |
<ol>
|
|
930 |
<li>1 cell containing flags (env).
|
|
931 |
<ul>
|
|
932 |
<li>Least Significant Bit 0 (0x01): high if <code>t</code> is implemented. (is this Concurrent Funge-98?)
|
|
933 |
<li>Bit 1 (0x02): high if <code>i</code> is implemented.
|
|
934 |
<li>Bit 2 (0x04): high if <code>o</code> is implemented.
|
|
935 |
<li>Bit 3 (0x08): high if <code>=</code> is implemented.
|
|
936 |
<li>Most Significant Bit 4 (0x10): high if unbuffered standard I/O
|
|
937 |
(like <code>getch()</code>) is in effect, low if the usual
|
|
938 |
buffered variety (like <code>scanf("%c")</code>) is being used.
|
|
939 |
<li>Further more significant bits: undefined, should all be low in Funge-98
|
|
940 |
</ul>
|
|
941 |
<li>1 cell containing the number of bytes per cell (global env).
|
|
942 |
<ul>aka cell size. Typically 4, could also be 2, 8, really really large, infinity, etc.
|
|
943 |
</ul>
|
|
944 |
<li>1 cell containing the implementation's handprint (env).
|
|
945 |
<li>1 cell containing the implementation's version number (env).
|
|
946 |
<ul>If the version number contains points,
|
|
947 |
they're stripped. v2.01 == 201, v1.03.05 = 10305, v1.5g = 1507.
|
|
948 |
Don't use non-numbers in the version number to indicate 'personalizations' - change the handprint instead.</ul>
|
|
949 |
<li>1 cell containing an ID code for the Operating Paradigm (global env)
|
|
950 |
<ul>
|
|
951 |
<li>0 = Unavailable
|
|
952 |
<li>1 = Equivalent to C-language system() call behaviour
|
|
953 |
<li>2 = Equivalent to interpretation by a specific shell or program
|
|
954 |
<ul>This shell or program is specified by the interpreter but should ideally be customizable
|
|
955 |
by the interpreter-user, if applicable. Befunge programs that run under this
|
|
956 |
paradigm should document what program they expect to interpret the string
|
|
957 |
passed to <code>=</code>.</ul>
|
|
958 |
<li>3 = Equivalent to interpretation by the same shell as started this Funge interpreter, if applicable
|
|
959 |
<ul>If the interpreter supports this paradigm, then in this manner, the user executing a
|
|
960 |
Befunge source can easily choose which shell to use for <code>=</code> instructions.</ul>
|
|
961 |
</ul>
|
|
962 |
This value is included so the program can have a reasonable idea of what <code>=</code> will do.
|
|
963 |
The values shown here are only the most basic set available at the time of publication.
|
|
964 |
See the <a href="#Registry">Registry</a> for any late-breaking headway into further Operating Paradigms.
|
|
965 |
<li>1 cell containing a path seperator character (global env)
|
|
966 |
<ul>
|
|
967 |
This is what path seperators for <code>i</code> and <code>o</code> filenames should look like.
|
|
968 |
</ul>
|
|
969 |
<li>1 cell containing the number of scalars per vector (global env)
|
|
970 |
<ul>aka number of dimensions. 2 for Befunge, 1 for Unefunge, 3 for Trefunge.</ul>
|
|
971 |
<li>1 cell containing a unique ID for the current IP (ip)
|
|
972 |
<ul>Only significant for Concurrent Funge.
|
|
973 |
This ID differentiates this IP from all others currently in the IP list.</ul>
|
|
974 |
<li>1 cell containing a unique team number for the current IP (ip)
|
|
975 |
<ul>Only significant for NetFunge, BeGlad, and the like.</ul>
|
|
976 |
<li>1 vector containing the Funge-Space position of the current IP (ip)
|
|
977 |
<li>1 vector containing the Funge-Space delta of the current IP (ip)
|
|
978 |
<li>1 vector containing the Funge-Space storage offset of the current IP (ip)
|
|
979 |
<li>1 vector containing the least point which contains a non-space cell, relative to the origin (env)
|
|
980 |
<li>1 vector containing the greatest point which contains a non-space cell, relative to the least point (env)
|
|
981 |
<ul>These two vectors are useful to give to the o instruction to output the entire program source as a text file.</ul>
|
|
982 |
<li>1 cell containing current ((year - 1900) * 256 * 256) + (month * 256) + (day of month) (env)
|
|
983 |
<li>1 cell containing current (hour * 256 * 256) + (minute * 256) + (second) (env)
|
|
984 |
<li>1 cell containing the total number of stacks currently in use by the IP (size of stack stack) (ip)
|
|
985 |
<li><i>size-of-stack-stack</i> cells containing size of each stack, listed from TOSS to BOSS (ip)
|
|
986 |
<ul>Stack sizes are pushed as if they were measured <b>before</b> <code>y</code> began pushing elements onto the stack.</ul>
|
|
987 |
<li>a series of sequences of characters (strings), each terminated by a null, the series terminated by an additional double null, containing the command-line arguments. (env)
|
|
988 |
<ul>This means any isolated argument can be a null string, but no two consecutive arguments
|
|
989 |
may be null strings - a rather contrived scenario, null string arguments being rare in themselves.</ul>
|
|
990 |
<ul>The first string is the name of the Funge source program being run.</ul>
|
|
991 |
<li>a series of strings, each terminated by a null, the series terminated by an additional null, containing the environment variables. (env)
|
|
992 |
<ul>The format for each variable setting is <tt>NAME=VALUE</tt>.</ul>
|
|
993 |
</ol>
|
|
994 |
|
|
995 |
<p>If <code>y</code> is given a positive argument, all these cells are
|
|
996 |
pushed onto the stack as if the argument was non-positive.
|
|
997 |
However, <code>y</code> then goes on to copy the <i>argument</i>th
|
|
998 |
stack cell (counting from the top) into a temporary location,
|
|
999 |
subsequently removing all the cells
|
|
1000 |
it pushed onto the stack. It then pushes the temporary cell
|
|
1001 |
onto the stack. For example, <code>3y</code> will act as if only
|
|
1002 |
the handprint was pushed onto the stack.
|
|
1003 |
|
|
1004 |
<p>An interesting side-effect of this behaviour is that if
|
|
1005 |
<code>y</code> is given an argument that exceeds the number of
|
|
1006 |
cells it pushes onto the stack, it can act as a 'pick'
|
|
1007 |
instruction on data that was on the stack before <code>y</code>
|
|
1008 |
was even executed.
|
|
1009 |
|
|
1010 |
<hr><h2><a name="Scale">Scale: Extension and Customization</h2>
|
|
1011 |
|
|
1012 |
<p>Funge-98 is totally customizable and scalable in terms of functionality, and
|
|
1013 |
non-trivial programs can now be written portably in it without any sort of
|
|
1014 |
directives. The fingerprint mechanism allows for the definition of a
|
|
1015 |
virtually unlimited number of libraries in the form of fingerprinted extensions. The
|
|
1016 |
handprint mechanism allows a program to identify exactly what interpreter it's
|
|
1017 |
running on.
|
|
1018 |
|
|
1019 |
<hr><a name="Handprints"><h3>Handprints</h3>
|
|
1020 |
|
|
1021 |
<p>A handprint is a bitstring which uniquely identifies
|
|
1022 |
a particular implementation (interpreter, compiler, etc.)
|
|
1023 |
of Funge-98.
|
|
1024 |
|
|
1025 |
<p>These should really only be used by Funge-98 programs which know about <b>bugs</b>
|
|
1026 |
in a known interpreter, and want to work around them when their portable source
|
|
1027 |
is run on that interpreter.
|
|
1028 |
(<i>Features</i>, on the other hand, should be
|
|
1029 |
fingerprints: if everything is properly implemented, the current handprint <b>should</b> be
|
|
1030 |
irrelevant. Fingerprints should always be used in preference to handprints
|
|
1031 |
when making a design decision - handprints are a fallback for the less-than-ideal case.)
|
|
1032 |
|
|
1033 |
<p>Handprints
|
|
1034 |
generally stay they same between revisions of an interpreter. They are
|
|
1035 |
accompanied by a version number when retrieved from <code>y</code>.
|
|
1036 |
|
|
1037 |
<hr><a name="Fingerprints"><h3>Fingerprints</h3>
|
|
1038 |
|
|
1039 |
<p>Extension and customization of Funge-98 are accomplished
|
|
1040 |
through the so-called "fingerprint mechanism". No such mechanism
|
|
1041 |
exists for Befunge-93.
|
|
1042 |
|
|
1043 |
<p>To be more precise, a fingerprint is a unique ID code which indicates a library
|
|
1044 |
of routines (a <i>fingerprinted extension</i>) to be assigned temporarily to what the instructions <code>A</code> to <code>Z</code> do.
|
|
1045 |
Multiple loaded fingerprints can overlap and overload, so even
|
|
1046 |
object-oriented-like inheritance is possible.
|
|
1047 |
|
|
1048 |
<p>Generally speaking, these new semantics and instructions are only available
|
|
1049 |
to and only apply to the IP which loaded them. The fingerprint spec itself may
|
|
1050 |
make exceptions to this rule, but it must clearly specify what they are.
|
|
1051 |
|
|
1052 |
<p>The semantics of any given extension are generally
|
|
1053 |
coded directly into the interpreter. There is
|
|
1054 |
no reason, however, they may not be made available in a dynamically-loadable form;
|
|
1055 |
but there is no convenient, standard format for such a form.
|
|
1056 |
|
|
1057 |
<p>Whether the semantics are dynamically loaded from a disk file containing some
|
|
1058 |
form of executable code, or hard-wired into the Funge interpreter, is really a
|
|
1059 |
moot point from the Funge programmer's perspective.
|
|
1060 |
|
|
1061 |
<p>However, it is useful to explain at this point for the benefit of both Funge
|
|
1062 |
programmers and potential Funge extension writers, that there are two classes of
|
|
1063 |
fingerprinted extensions: those that interact with and change the behaviour of the underlying
|
|
1064 |
Funge Virtual Machine and/or are not re-entrant (<i>feral extensions</i>), and
|
|
1065 |
those which are self-contained and re-entrant (<i>tame extensions</i>).
|
|
1066 |
|
|
1067 |
<p>The main difference is that a feral extension cannot simply or easily be "dropped into" a Funge interpreter which is not aware of it. When specifying fingerprinted extensions for public use, please try to make them as tame as possible - although many times it is unavoidable to have a feral fingerprint in order to accomplish a certain semantic goal, such as program control of proprietary interpreter features.
|
|
1068 |
|
|
1069 |
<p>The <code>(</code> "Load Semantics" instruction
|
|
1070 |
loads the semantics for a given fingerprint
|
|
1071 |
onto any or all of the
|
|
1072 |
instructions <code>A</code> to <code>Z</code>.
|
|
1073 |
<code>(</code> pops a <i>count</i>.
|
|
1074 |
It then pops <i>count</i> cells.
|
|
1075 |
For each cell that it pops, it
|
|
1076 |
multiplies a temporary value
|
|
1077 |
(which is initially zero) by 256,
|
|
1078 |
and adds the cell value to it.
|
|
1079 |
|
|
1080 |
<p>In this way, <code>(</code>
|
|
1081 |
builds a fingerprint. This mechanism makes it
|
|
1082 |
simple to express large fingerprints
|
|
1083 |
like 0x452e472e in printable ASCII
|
|
1084 |
such as <code>".G.E"4( ... )</code>, while not
|
|
1085 |
requiring the use of ASCII as the medium for all fingerprints.
|
|
1086 |
|
|
1087 |
<p><code>(</code> then uses this fingerprint to
|
|
1088 |
locate and load a set of semantics for the
|
|
1089 |
instructions <code>A</code> to <code>Z</code>. If the Funge implementation
|
|
1090 |
cannot find the correct library for the given
|
|
1091 |
fingerprint, <code>(</code> acts like <code>r</code>.
|
|
1092 |
If, however, the semantic library load is successful,
|
|
1093 |
the new fingerprint, then a 1, are pushed onto
|
|
1094 |
the stack (to be accepted by a subsequent <code>)</code> instruction.)
|
|
1095 |
|
|
1096 |
<p>The corresponding <code>)</code> "Unload Semantics" instruction
|
|
1097 |
unloads the semantics for a given fingerprint
|
|
1098 |
from any or all of the
|
|
1099 |
instructions <code>A</code> to <code>Z</code>
|
|
1100 |
(even if that fingerprint had never been loaded before).
|
|
1101 |
It pops a <i>count</i> and builds a fingerprint in exactly
|
|
1102 |
the same way.
|
|
1103 |
|
|
1104 |
<p><code>()</code> in Funge are kind of like "use x ... no x" in Perl.
|
|
1105 |
The interpreter-writer or interpreter-customizer is allowed to make
|
|
1106 |
fingerprints do anything they like, and they may implement
|
|
1107 |
fingerprints however they like, but they have to follow some general rules
|
|
1108 |
as a 'contract' between the fingerprint and the fingerprint user.
|
|
1109 |
|
|
1110 |
<ul>
|
|
1111 |
<li>A fingerprint should not affect the semantics of any instructions
|
|
1112 |
besides <code>A</code> to <code>Z</code>, except under exceptional circumstances
|
|
1113 |
which must be clearly documented in the fingerprint's spec.
|
|
1114 |
<li>When loaded, a fingerprint which implements <code>A</code> and <code>B</code>
|
|
1115 |
semantics should act something like:
|
|
1116 |
|
|
1117 |
<ul>save(<code>A</code>); bind(<code>A</code>, myAsemantic()); save(<code>B</code>); bind(<code>B</code>, myBsemantic());</ul>
|
|
1118 |
|
|
1119 |
<li>When unloaded, the same fingerprint should act something like
|
|
1120 |
|
|
1121 |
<ul>restore(<code>B</code>); restore(<code>A</code>);</ul>
|
|
1122 |
|
|
1123 |
<li>In this sense, 'bind' means to change what the execution of an instruction does in the current Funge-98 program.
|
|
1124 |
<li>'save' means to save (push onto a stack) the semantics of an instruction for later use.
|
|
1125 |
<li>'restore' means to recall (pop from a stack) the semantics of an instruction from the last saved version.
|
|
1126 |
</ul>
|
|
1127 |
|
|
1128 |
<p>This allows 'overloading' fingerprints.
|
|
1129 |
Say three fingerprints are implemented on your interpreter,
|
|
1130 |
|
|
1131 |
<ul>
|
|
1132 |
<li><code>E.G.</code> which implements <code>D</code> as 'Destroy' and <code>R</code> as 'Restore'
|
|
1133 |
<li><code>TEST</code> which implements <code>S</code> as 'Send', <code>R</code> as 'Receive', and <code>E</code> as 'Encrypt'
|
|
1134 |
<li><code>WORK</code> which implements <code>S</code> as 'Slice', <code>D</code> as 'Dice', <code>P</code> as 'Puree'
|
|
1135 |
</ul>
|
|
1136 |
|
|
1137 |
<p>With these, the Funge programmer ought to be able to make code like:
|
|
1138 |
|
|
1139 |
<p><code>".G.E"4( ... "TSET"4( ... "KROW"4( ... S ... ) ... ) ... )</code>
|
|
1140 |
|
|
1141 |
<p>Here, the <code>S</code> instruction indicates the 'Slice' instruction in the
|
|
1142 |
WORK fingerprint, not 'Send' in TEST. But if it was written as:
|
|
1143 |
|
|
1144 |
<p><code>"KROW"4( ... "TSET"4( ... ".G.E"4( ... S ... ) ... ) ... )</code>
|
|
1145 |
|
|
1146 |
<p>The <code>S</code> would indicate 'Send' from TEST, since there is no <code>S</code> in E.G.,
|
|
1147 |
and a <code>D</code> instruction in the same location would indicate 'Destroy'
|
|
1148 |
in E.G., but <code>P</code> would be a 'Puree' from WORK, because it's not
|
|
1149 |
defined in either TEST or E.G.
|
|
1150 |
|
|
1151 |
<hr><a name="Registry"><h3>Funge Central Registry</h3>
|
|
1152 |
|
|
1153 |
<p>The Funge Central Registry is an online database located
|
|
1154 |
at <code><A HREF="http://www.catseye.mb.ca/esoteric/befunge/">http://www.catseye.mb.ca/esoteric/befunge/</A></code>.
|
|
1155 |
Before developing and releasing your own Funge-98 implementation
|
|
1156 |
or extension, please register all applicable handprints
|
|
1157 |
and fingerprints you will require here.
|
|
1158 |
|
|
1159 |
<p>This system is in place both to reduce conflicts between fingerprints
|
|
1160 |
and handprints world-wide, ensuring their uniqueness, and to
|
|
1161 |
provide a quick reference to all known extant handprints and
|
|
1162 |
fingerprints.
|
|
1163 |
|
|
1164 |
<p>There really are no standard libraries in Befunge.
|
|
1165 |
A Funge-98 interpreter need not implement any fingerprints whatsoever.
|
|
1166 |
Funge-98 "standard" libraries are no more than "officially sanctioned"
|
|
1167 |
extensions, catalogued in the Registry by their fingerprints. Since
|
|
1168 |
extensions are forever accumulating, see the registry for a list of
|
|
1169 |
"standard" fingerprints.
|
|
1170 |
|
|
1171 |
<hr><a name="Appendix"><h2>Appendix</h2>
|
|
1172 |
<a name="Quickref"><h3>Instruction Quick Reference</h3>
|
|
1173 |
|
|
1174 |
<p><code>/</code> modifiers:
|
|
1175 |
|
|
1176 |
<ul>
|
|
1177 |
<li><code>98</code> Funge-98 only, not in Befunge-93.
|
|
1178 |
<li><code>2D</code> Minimum 2 dimensions (not in Unefunge).
|
|
1179 |
<li><code>3D</code> Minimum 3 dimensions (not in Unefunge or Befunge).
|
|
1180 |
<li><code>c</code> Concurrent Funge. Check <code>y</code> to see if these instructions are implemented.
|
|
1181 |
<li><code>f</code> Filesystem Funge. Check <code>y</code> to see if these instructions are implemented.
|
|
1182 |
</ul>
|
|
1183 |
|
|
1184 |
<p><table border=1>
|
|
1185 |
<tr><th rowspan=2>Decimal</th><th rowspan=2>ASCII</th><th rowspan=2>Instruction </th><th>Stack Before</th><th>Stack After</th><th rowspan=2>Other Effects</th></tr>
|
|
1186 |
<tr><td colspan=2 align=center><i>(bottom ... top)</i></td></tr>
|
|
1187 |
<tr><td>32 </td><td>space </td><td>Space </td><td> </td></td><td> </td><td>not normally executed</td></tr>
|
|
1188 |
<tr><td>33 </td><td><code>!</code> </td><td>Logical Not </td><td>b </td><td>NOT b</td><td> </td></tr>
|
|
1189 |
<tr><td>34 </td><td><code>"</code> </td><td>Toggle Stringmode </td><td> </td><td> </td><td>stringmode <- NOT stringmode</td></tr>
|
|
1190 |
<tr><td>35 </td><td><code>#</code> </td><td>Trampoline </td><td> </td><td> </td><td>pos <- pos + delta</td></tr>
|
|
1191 |
<tr><td>36 </td><td><code>$</code> </td><td>Pop </td><td>n </td><td> </td><td> </td></tr>
|
|
1192 |
<tr><td>37 </td><td><code>%</code> </td><td>Remainder </td><td>a b </td><td>a REM b </td><td> </td></tr>
|
|
1193 |
<tr><td>38 </td><td><code>&</code> </td><td>Input Integer </td><td> </td><td>a </td><td>a = readint()</td></tr>
|
|
1194 |
<tr><td>39 </td><td><code>'</code> </td><td>Fetch Character/98 </td><td> </td><td>c </td><td>pos <- pos + delta</td></tr>
|
|
1195 |
<tr><td>40 </td><td><code>(</code> </td><td>Load Semantics/98 </td><td>en..e1 n </td><td>f 1 </td><td>overloads A-Z</td></tr>
|
|
1196 |
<tr><td>41 </td><td><code>)</code> </td><td>Unload Semantics/98 </td><td>en..e1 n </td><td> </td><td>unloads last A-Z</td></tr>
|
|
1197 |
<tr><td>42 </td><td><code>*</code> </td><td>Multiply </td><td>a b </td><td>a * b </td><td> </td></tr>
|
|
1198 |
<tr><td>43 </td><td><code>+</code> </td><td>Add </td><td>a b </td><td>a + b </td><td> </td></tr>
|
|
1199 |
<tr><td>44 </td><td><code>,</code> </td><td>Output Character </td><td>c </td><td> </td><td>writechar(c)</td></tr>
|
|
1200 |
<tr><td>45 </td><td><code>-</code> </td><td>Subtract </td><td>a b </td><td>a - b</td><td> </td></tr>
|
|
1201 |
<tr><td>46 </td><td><code>.</code> </td><td>Output Integer </td><td>a </td><td> </td><td>writeint(a)</td></tr>
|
|
1202 |
<tr><td>47 </td><td><code>/</code> </td><td>Divide </td><td>a b </td><td>a / b</td><td> </td></tr>
|
|
1203 |
<tr><td>48 </td><td><code>0</code> </td><td>Push Zero </td><td> </td><td>0 </td><td> </td></tr>
|
|
1204 |
<tr><td>49 </td><td><code>1</code> </td><td>Push One </td><td> </td><td>1 </td><td> </td></tr>
|
|
1205 |
<tr><td>50 </td><td><code>2</code> </td><td>Push Two </td><td> </td><td>2 </td><td> </td></tr>
|
|
1206 |
<tr><td>51 </td><td><code>3</code> </td><td>Push Three </td><td> </td><td>3 </td><td> </td></tr>
|
|
1207 |
<tr><td>52 </td><td><code>4</code> </td><td>Push Four </td><td> </td><td>4 </td><td> </td></tr>
|
|
1208 |
<tr><td>53 </td><td><code>5</code> </td><td>Push Five </td><td> </td><td>5 </td><td> </td></tr>
|
|
1209 |
<tr><td>54 </td><td><code>6</code> </td><td>Push Six </td><td> </td><td>6 </td><td> </td></tr>
|
|
1210 |
<tr><td>55 </td><td><code>7</code> </td><td>Push Seven </td><td> </td><td>7 </td><td> </td></tr>
|
|
1211 |
<tr><td>56 </td><td><code>8</code> </td><td>Push Eight </td><td> </td><td>8 </td><td> </td></tr>
|
|
1212 |
<tr><td>57 </td><td><code>9</code> </td><td>Push Niner </td><td> </td><td>9 </td><td> </td></tr>
|
|
1213 |
<tr><td>58 </td><td><code>:</code> </td><td>Duplicate </td><td>v </td><td>v v </td><td> </td></tr>
|
|
1214 |
<tr><td>59 </td><td><code>;</code> </td><td>Jump Over/98 </td><td> </td><td> </td><td>nothing executed until next semicolon</td></tr>
|
|
1215 |
<tr><td>60 </td><td><code><</code> </td><td>Go West </td><td> </td><td> </td><td>delta <- (-1,0)</td></tr>
|
|
1216 |
<tr><td>61 </td><td><code>=</code> </td><td>Execute/98/f </td><td>STR </td><td>r</td><td>r = system-execute(STR)</td></tr>
|
|
1217 |
<tr><td>62 </td><td><code>></code> </td><td>Go East </td><td> </td><td> </td><td>delta <- (1,0)</td></tr>
|
|
1218 |
<tr><td>63 </td><td><code>?</code> </td><td>Go Away </td><td> </td><td> </td><td>delta <- (1,0)?(-1,0)?(0,1)?(0,-1)</td></tr>
|
|
1219 |
<tr><td>64 </td><td><code>@</code> </td><td>Stop </td><td> </td><td> </td><td>halt IP</td></tr>
|
|
1220 |
<tr><td>65-90 </td><td><code>A-Z</code> </td><td> </td><td> </td><td> </td><td>Fingerprint-Defined/98</td></tr>
|
|
1221 |
<tr><td>91 </td><td><code>[</code> </td><td>Turn Left/98/2D </td><td> </td><td> </td><td>delta <- rot(-90, delta)</td></tr>
|
|
1222 |
<tr><td>92 </td><td><code>\</code> </td><td>Swap </td><td>a b </td><td>b a </td><td> </td></tr>
|
|
1223 |
<tr><td>93 </td><td><code>]</code> </td><td>Turn Right/98/2D </td><td> </td><td> </td><td>delta <- rot(90, delta)</td></tr>
|
|
1224 |
<tr><td>94 </td><td><code>^</code> </td><td>Go North/2D </td><td> </td><td> </td><td>delta <- (0,-1)</td></tr>
|
|
1225 |
<tr><td>95 </td><td><code>_</code> </td><td>East-West If </td><td> b </td><td> </td><td>delta <- if (b) (-1,0) else (1,0)</td></tr>
|
|
1226 |
<tr><td>96 </td><td><code>`</code> </td><td>Greater Than </td><td> a b </td><td>a > b </td><td>either 1 or 0 </td></tr>
|
|
1227 |
<tr><td>97 </td><td><code>a</code> </td><td>Push Ten/98 </td><td> </td><td>10 </td><td> </td></tr>
|
|
1228 |
<tr><td>98 </td><td><code>b</code> </td><td>Push Eleven/98 </td><td> </td><td>11 </td><td> </td></tr>
|
|
1229 |
<tr><td>99 </td><td><code>c</code> </td><td>Push Twelve/98 </td><td> </td><td>12 </td><td> </td></tr>
|
|
1230 |
<tr><td>100 </td><td><code>d</code> </td><td>Push Thirteen/98 </td><td> </td><td>13 </td><td> </td></tr>
|
|
1231 |
<tr><td>101 </td><td><code>e</code> </td><td>Push Fourteen/98 </td><td> </td><td>14 </td><td> </td></tr>
|
|
1232 |
<tr><td>102 </td><td><code>f</code> </td><td>Push Fifteen/98 </td><td> </td><td>15 </td><td> </td></tr>
|
|
1233 |
<tr><td>103 </td><td><code>g</code> </td><td>Get </td><td>Va </td><td>v </td><td>v = fetch-funge-space(offset+Va)</td></tr>
|
|
1234 |
<tr><td>104 </td><td><code>h</code> </td><td>Go High/98/3D </td><td> </td><td> </td><td>delta <- (0,0,-1)</td></tr>
|
|
1235 |
<tr><td>105 </td><td><code>i</code> </td><td>Input File/98/f </td><td>Va f STR </td><td>Va Vb </td><td>inputs file</td></tr>
|
|
1236 |
<tr><td>106 </td><td><code>j</code> </td><td>Jump Forward/98 </td><td>s </td><td> </td><td>pos <- pos + delta * s</td></tr>
|
|
1237 |
<tr><td>107 </td><td><code>k</code> </td><td>Iterate/98 </td><td>n </td><td> </td><td>execute next instruction now, n times</td></tr>
|
|
1238 |
<tr><td>108 </td><td><code>l</code> </td><td>Go Low/98/3D </td><td> </td><td> </td><td>delta <- (0,0,1)</td></tr>
|
|
1239 |
<tr><td>109 </td><td><code>m</code> </td><td>High-Low If/98/3D </td><td>b </td><td> </td><td>delta <- if (b) (0,0,-1) else (0,0,1)</td></tr>
|
|
1240 |
<tr><td>110 </td><td><code>n</code> </td><td>Clear Stack/98 </td><td>en..e1 </td><td> </td><td> </td></tr>
|
|
1241 |
<tr><td>111 </td><td><code>o</code> </td><td>Output File/98/f </td><td>Va Vb f STR </td><td> </td><td>outputs file</td></tr>
|
|
1242 |
<tr><td>112 </td><td><code>p</code> </td><td>Put </td><td>v Va </td><td> </td><td>store-funge-space(offset+Va,v)</td></tr>
|
|
1243 |
<tr><td>113 </td><td><code>q</code> </td><td>Quit/98 </td><td>r </td><td> </td><td>immediate exit, returncode = r</td></tr>
|
|
1244 |
<tr><td>114 </td><td><code>r</code> </td><td>Reflect/98 </td><td> </td><td> </td><td>delta <- delta * -1</td></tr>
|
|
1245 |
<tr><td>115 </td><td><code>s</code> </td><td>Store Character/98 </td><td>c </td><td> </td><td>store-funge-space(position+delta,v) </td></tr>
|
|
1246 |
<tr><td>116 </td><td><code>t</code> </td><td>Split/98/c </td><td> </td><td> </td><td>Split IP</td></tr>
|
|
1247 |
<tr><td>117 </td><td><code>u</code> </td><td>Stack Under Stack/98 </td><td>n </td><td>(en..e1) </td><td> </td></tr>
|
|
1248 |
<tr><td>118 </td><td><code>v</code> </td><td>Go South/2D </td><td> </td><td> </td><td>delta <- (0,1)</td></tr>
|
|
1249 |
<tr><td>119 </td><td><code>w</code> </td><td>Compare/98/2D </td><td>a b </td><td> </td><td>if (a>b) ']' elsif (a<b) '[' else 'z'</td></tr>
|
|
1250 |
<tr><td>120 </td><td><code>x</code> </td><td>Absolute Delta/98 </td><td>Va </td><td> </td><td>delta <- Va</td></tr>
|
|
1251 |
<tr><td>121 </td><td><code>y</code> </td><td>Get SysInfo/98 </td><td>c </td><td>en(..e1) </td><td> </td></tr>
|
|
1252 |
<tr><td>122 </td><td><code>z</code> </td><td>No Operation/98 </td><td> </td><td> </td><td> </td></tr>
|
|
1253 |
<tr><td>123 </td><td><code>{</code> </td><td>Begin Block/98 </td><td>en..e1 n </td><td>(en..e1) </td><td>offset <- pos + delta, etc</td></tr>
|
|
1254 |
<tr><td>124 </td><td><code>|</code> </td><td>North-South If/2D </td><td>b </td><td> </td><td>delta <- if (b) (0,-1) else (0,1)</td></tr>
|
|
1255 |
<tr><td>125 </td><td><code>}</code> </td><td>End Block/98 </td><td>en..e1 n </td><td>(en..e1) </td><td>offset <- SOSS Va, etc</td></tr>
|
|
1256 |
<tr><td>126 </td><td><code>~</code> </td><td>Input Character </td><td> </td><td>c </td><td>c = readchar()</td></tr>
|
|
1257 |
</table>
|
|
1258 |
|
|
1259 |
<hr><a name="Concurrent"><h3>Concurrent Funge-98</h3>
|
|
1260 |
|
|
1261 |
<p>Befunge-93 does not allow for multithreaded execution.
|
|
1262 |
However, Concurrent Funge-98, a superset of Funge-98,
|
|
1263 |
defines a list of any number of
|
|
1264 |
concurrently running instruction pointers called the
|
|
1265 |
<i>IP list</i>. In Concurrent Funge, IP's are sometimes
|
|
1266 |
called <i>threads</i> and each has its own
|
|
1267 |
location, delta, and stack.
|
|
1268 |
|
|
1269 |
<p>You can also think of a Concurrent Funge-98 interpreter as having
|
|
1270 |
an internal and imaginary <i>clock</i> which produces
|
|
1271 |
<i>ticks</i> sequentially. Each tick, the
|
|
1272 |
IP list is processed: instructions encountered by each IP are dealt with
|
|
1273 |
in the sequence the IPs appear on the list, and each IP then moves
|
|
1274 |
as specified by its delta.
|
|
1275 |
|
|
1276 |
<p>The list is always processed repetitively, sequentially, and in the same
|
|
1277 |
direction, and when IP's are deleted they fall out and the next one which
|
|
1278 |
would normally execute anyway actually executes.
|
|
1279 |
|
|
1280 |
<p>Creating additional IP's is done with the <code>t</code> "Split" instruction,
|
|
1281 |
available in Concurrent Funge-98 only. It
|
|
1282 |
causes the current IP to be duplicated, and this duplicate is added to the
|
|
1283 |
IP list such that it is executed for the first time <i>before</i>
|
|
1284 |
the parent IP is next executed.
|
|
1285 |
|
|
1286 |
<p>When a child IP is borne unto Funge-Space thus, its location, storage
|
|
1287 |
offset, and stack are all copied verbatim from the parent IP's. The child
|
|
1288 |
IP's delta is reversed (a la <code>r</code>) from its parent's, though.
|
|
1289 |
|
|
1290 |
<p>The <code>@</code> "Stop" instruction kills the current IP.
|
|
1291 |
If the current IP is the only active IP in the IP list,
|
|
1292 |
the program ends. If it
|
|
1293 |
was not the last in the IP list, there would then be a gap in
|
|
1294 |
the list: in this case the top part of the list "shifts down" and the
|
|
1295 |
next thread in the list is executed.
|
|
1296 |
|
|
1297 |
<hr><a name="Lahey"><h3>Lahey-Space</h3>
|
|
1298 |
|
|
1299 |
<p>Lahey-Space is a mathematical model of the space used in Funge-98.
|
|
1300 |
|
|
1301 |
<p>The requirements for a line in Lahey-space are the following:
|
|
1302 |
Starting from the origin,
|
|
1303 |
no matter what direction you head, you eventually reach the origin.
|
|
1304 |
If you go the other way you reach the origin from the other direction.
|
|
1305 |
|
|
1306 |
<p>We surmise that if you head out on a Lahey-line, you would eventually
|
|
1307 |
return along the same Lahey-line, heading in the same direction,
|
|
1308 |
but coming from the other direction.
|
|
1309 |
This would mean you would eventually repeat your path, and (in Funge terms)
|
|
1310 |
have consistant wrapping through unlimited space.
|
|
1311 |
|
|
1312 |
<p>Now, imagine a sphere of radius one centered one unit above the origin.
|
|
1313 |
Imagine a plane placed two units above the origin, i.e. resting on top of the sphere.
|
|
1314 |
|
|
1315 |
<p><center><img src="laheys.jpg" alt="(laheys.jpg - Chris Hall's POVRay rendering of Lahey-Space)"></center>
|
|
1316 |
|
|
1317 |
<p>One thing you might notice is that when you draw a straight line from the
|
|
1318 |
origin to any point on the plane, you intersect the sphere
|
|
1319 |
exactly twice, once at the origin, once in a unique location.
|
|
1320 |
In this manner, you can map the plane uniquely onto the sphere.
|
|
1321 |
|
|
1322 |
<p>Now, each normal line from a point A on the plane to a point B on the plane can be
|
|
1323 |
transformed into a Lahey-line, which in our model is represented as an arc
|
|
1324 |
of the sphere containing both point A' on the sphere and point B' on the sphere.
|
|
1325 |
This arc can then be extended into a full circle, going 'around' the sphere to wrap.<P>
|
|
1326 |
|
|
1327 |
<hr><A name="Topologies"><h3>Other Topologies</h3>
|
|
1328 |
|
|
1329 |
<p>As mentioned, Funge is a family of programming languages, and Befunge has many relatives and descendants. This document only covers Cartesian Funges. Other Funges, such as Honefunges (hex-net topology) and Kleinefunges (Klein-bottles) are certainly possible.
|
|
1330 |
|
|
1331 |
<p>However, Advanced Funges may not find either torodial space <i>or</i> Lahey-space sufficient
|
|
1332 |
for complex topologies, so this spec provides a language for
|
|
1333 |
defining wrapping behaviour in a mathematical way.
|
|
1334 |
|
|
1335 |
<p>We can define an a <i>wrapping function</i> W()
|
|
1336 |
along the lines of:
|
|
1337 |
<ul><code>W(x,y) = (x<0 -> x:=79,
|
|
1338 |
x>79 -> x:=0, y<0 -> y:=24, y>24 -> y:=0)</code></ul>
|
|
1339 |
|
|
1340 |
for Befunge-93. Complex topologies can define their own
|
|
1341 |
wrapping functions. If these functions are strictly and clearly specified in the documentation of the Advanced Funge in question, it will save a lot of confusion to users, and is highly recommended.
|
|
1342 |
|
|
1343 |
<hr>
|
|
1344 |
<br>Copyright <img src="/img/copyright.gif" alt="(c)">2000 Chris Pressey, <a href="http://www.catseye.mb.ca/">Cat's Eye Technologies</a>.
|
|
1345 |
Permission is granted to republish this work on the condition that the
|
|
1346 |
above copyright message and this message remain included unchanged in all copies.
|
|
1347 |
</body>
|
|
1348 |
</html>
|