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>
|