git @ Cat's Eye Technologies Specs-on-Spec / e12268b
For now, let's put Funge-98 here, too. catseye 12 years ago
14 changed file(s) with 1966 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
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>&gt;</code> "Go East" instruction causes the IP to travel
360 east; the <code>&lt;</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 &lt;- (0,0,1));
368 the <code>l</code> "Go Low" instruction causes the IP to travel
369 down (delta &lt;- (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>|&nbsp;<br>+-</code></td>
390 <td align=center><code>+-+<br>|&nbsp;|</code></td>
391 <td align=center><code>-+<br>&nbsp;|<br>-+</code></td>
392 </tr><tr>
393 <td align=center><code>[</code></td>
394 <td align=center><code>&nbsp;</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>&gt;</code>, and if non-zero
568 it acts like <code>&lt;</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 &lt;- 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>&nbsp;</td></td><td>&nbsp;</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>&nbsp;</td></tr>
1189 <tr><td>34 </td><td><code>"</code> </td><td>Toggle Stringmode </td><td>&nbsp;</td><td>&nbsp;</td><td>stringmode &lt;- NOT stringmode</td></tr>
1190 <tr><td>35 </td><td><code>#</code> </td><td>Trampoline </td><td>&nbsp;</td><td>&nbsp;</td><td>pos &lt;- pos + delta</td></tr>
1191 <tr><td>36 </td><td><code>$</code> </td><td>Pop </td><td>n </td><td>&nbsp;</td><td>&nbsp;</td></tr>
1192 <tr><td>37 </td><td><code>%</code> </td><td>Remainder </td><td>a b </td><td>a REM b </td><td>&nbsp;</td></tr>
1193 <tr><td>38 </td><td><code>&amp;</code> </td><td>Input Integer </td><td>&nbsp;</td><td>a </td><td>a = readint()</td></tr>
1194 <tr><td>39 </td><td><code>'</code> </td><td>Fetch Character/98 </td><td>&nbsp;</td><td>c </td><td>pos &lt;- 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>&nbsp;</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>&nbsp;</td></tr>
1198 <tr><td>43 </td><td><code>+</code> </td><td>Add </td><td>a b </td><td>a + b </td><td>&nbsp;</td></tr>
1199 <tr><td>44 </td><td><code>,</code> </td><td>Output Character </td><td>c </td><td>&nbsp;</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>&nbsp;</td></tr>
1201 <tr><td>46 </td><td><code>.</code> </td><td>Output Integer </td><td>a </td><td>&nbsp;</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>&nbsp;</td></tr>
1203 <tr><td>48 </td><td><code>0</code> </td><td>Push Zero </td><td>&nbsp;</td><td>0 </td><td>&nbsp;</td></tr>
1204 <tr><td>49 </td><td><code>1</code> </td><td>Push One </td><td>&nbsp;</td><td>1 </td><td>&nbsp;</td></tr>
1205 <tr><td>50 </td><td><code>2</code> </td><td>Push Two </td><td>&nbsp;</td><td>2 </td><td>&nbsp;</td></tr>
1206 <tr><td>51 </td><td><code>3</code> </td><td>Push Three </td><td>&nbsp;</td><td>3 </td><td>&nbsp;</td></tr>
1207 <tr><td>52 </td><td><code>4</code> </td><td>Push Four </td><td>&nbsp;</td><td>4 </td><td>&nbsp;</td></tr>
1208 <tr><td>53 </td><td><code>5</code> </td><td>Push Five </td><td>&nbsp;</td><td>5 </td><td>&nbsp;</td></tr>
1209 <tr><td>54 </td><td><code>6</code> </td><td>Push Six </td><td>&nbsp;</td><td>6 </td><td>&nbsp;</td></tr>
1210 <tr><td>55 </td><td><code>7</code> </td><td>Push Seven </td><td>&nbsp;</td><td>7 </td><td>&nbsp;</td></tr>
1211 <tr><td>56 </td><td><code>8</code> </td><td>Push Eight </td><td>&nbsp;</td><td>8 </td><td>&nbsp;</td></tr>
1212 <tr><td>57 </td><td><code>9</code> </td><td>Push Niner </td><td>&nbsp;</td><td>9 </td><td>&nbsp;</td></tr>
1213 <tr><td>58 </td><td><code>:</code> </td><td>Duplicate </td><td>v </td><td>v v </td><td>&nbsp;</td></tr>
1214 <tr><td>59 </td><td><code>;</code> </td><td>Jump Over/98 </td><td>&nbsp;</td><td>&nbsp;</td><td>nothing executed until next semicolon</td></tr>
1215 <tr><td>60 </td><td><code>&lt;</code> </td><td>Go West </td><td>&nbsp;</td><td>&nbsp;</td><td>delta &lt;- (-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>&gt;</code> </td><td>Go East </td><td>&nbsp;</td><td>&nbsp;</td><td>delta &lt;- (1,0)</td></tr>
1218 <tr><td>63 </td><td><code>?</code> </td><td>Go Away </td><td>&nbsp;</td><td>&nbsp;</td><td>delta &lt;- (1,0)?(-1,0)?(0,1)?(0,-1)</td></tr>
1219 <tr><td>64 </td><td><code>@</code> </td><td>Stop </td><td>&nbsp;</td><td>&nbsp;</td><td>halt IP</td></tr>
1220 <tr><td>65-90 </td><td><code>A-Z</code> </td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>Fingerprint-Defined/98</td></tr>
1221 <tr><td>91 </td><td><code>[</code> </td><td>Turn Left/98/2D </td><td>&nbsp;</td><td>&nbsp;</td><td>delta &lt;- 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>&nbsp;</td></tr>
1223 <tr><td>93 </td><td><code>]</code> </td><td>Turn Right/98/2D </td><td>&nbsp;</td><td>&nbsp;</td><td>delta &lt;- rot(90, delta)</td></tr>
1224 <tr><td>94 </td><td><code>^</code> </td><td>Go North/2D </td><td>&nbsp;</td><td>&nbsp;</td><td>delta &lt;- (0,-1)</td></tr>
1225 <tr><td>95 </td><td><code>_</code> </td><td>East-West If </td><td>&nbsp;b </td><td>&nbsp;</td><td>delta &lt;- if (b) (-1,0) else (1,0)</td></tr>
1226 <tr><td>96 </td><td><code>`</code> </td><td>Greater Than </td><td>&nbsp;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>&nbsp;</td><td>10 </td><td>&nbsp;</td></tr>
1228 <tr><td>98 </td><td><code>b</code> </td><td>Push Eleven/98 </td><td>&nbsp;</td><td>11 </td><td>&nbsp;</td></tr>
1229 <tr><td>99 </td><td><code>c</code> </td><td>Push Twelve/98 </td><td>&nbsp;</td><td>12 </td><td>&nbsp;</td></tr>
1230 <tr><td>100 </td><td><code>d</code> </td><td>Push Thirteen/98 </td><td>&nbsp;</td><td>13 </td><td>&nbsp;</td></tr>
1231 <tr><td>101 </td><td><code>e</code> </td><td>Push Fourteen/98 </td><td>&nbsp;</td><td>14 </td><td>&nbsp;</td></tr>
1232 <tr><td>102 </td><td><code>f</code> </td><td>Push Fifteen/98 </td><td>&nbsp;</td><td>15 </td><td>&nbsp;</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>&nbsp;</td><td>&nbsp;</td><td>delta &lt;- (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>&nbsp;</td><td>pos &lt;- pos + delta * s</td></tr>
1237 <tr><td>107 </td><td><code>k</code> </td><td>Iterate/98 </td><td>n </td><td>&nbsp;</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>&nbsp;</td><td>&nbsp;</td><td>delta &lt;- (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>&nbsp;</td><td>delta &lt;- 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>&nbsp;</td><td>&nbsp;</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>&nbsp;</td><td>outputs file</td></tr>
1242 <tr><td>112 </td><td><code>p</code> </td><td>Put </td><td>v Va </td><td>&nbsp;</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>&nbsp;</td><td>immediate exit, returncode = r</td></tr>
1244 <tr><td>114 </td><td><code>r</code> </td><td>Reflect/98 </td><td>&nbsp;</td><td>&nbsp;</td><td>delta &lt;- delta * -1</td></tr>
1245 <tr><td>115 </td><td><code>s</code> </td><td>Store Character/98 </td><td>c </td><td>&nbsp;</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>&nbsp;</td><td>&nbsp;</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>&nbsp;</td></tr>
1248 <tr><td>118 </td><td><code>v</code> </td><td>Go South/2D </td><td>&nbsp; </td><td>&nbsp;</td><td>delta &lt;- (0,1)</td></tr>
1249 <tr><td>119 </td><td><code>w</code> </td><td>Compare/98/2D </td><td>a b </td><td>&nbsp;</td><td>if (a&gt;b) ']' elsif (a&lt;b) '[' else 'z'</td></tr>
1250 <tr><td>120 </td><td><code>x</code> </td><td>Absolute Delta/98 </td><td>Va </td><td>&nbsp;</td><td>delta &lt;- 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>&nbsp;</td></tr>
1252 <tr><td>122 </td><td><code>z</code> </td><td>No Operation/98 </td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
1253 <tr><td>123 </td><td><code>{</code> </td><td>Begin Block/98 </td><td>en..e1 n </td><td>(en..e1)&nbsp;</td><td>offset &lt;- pos + delta, etc</td></tr>
1254 <tr><td>124 </td><td><code>|</code> </td><td>North-South If/2D </td><td>b </td><td>&nbsp;</td><td>delta &lt;- 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)&nbsp;</td><td>offset &lt;- SOSS Va, etc</td></tr>
1256 <tr><td>126 </td><td><code>~</code> </td><td>Input Character </td><td>&nbsp;</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&lt;0 -&gt; x:=79,
1338 x&gt;79 -&gt; x:=0, y&lt;0 -&gt; y:=24, y&gt;24 -&gt; 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>
Binary diff not shown
0 <html><head>
1 <title>Cat's Eye Technologies: Funge-98</title>
2 <meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
3 <meta NAME="Keywords" Content=" Befunge,Befunge,Befunge,Funge,Funge,
4 Unefunge,Programming,Language,Programming Language,Bizarre,Esoteric,
5 Multidimensional,Bidirectional,Multidirectional,Multiple Directions,
6 Two Dimensions,Three Dimensions,2D,3D,Spatial,Polycoding,Source Code,
7 Single Character Instructions,Weird,Wierd,Twisted,Demented,Befunged,
8 Funged,Messed,Original,Entertaining,Orthogonal,Metric,Metro,Grid,Cell,
9 Topology,Topologies,Topography,Topographies,Wrapping,Torus,Cartesian,
10 Stack,Stack Based,Reverse Polish Notation,RPN,ASCII">
11 </head>
12 <body bgcolor="#FFFFFF" text="#000000" link="#1c3f7f"
13 vlink="#1c7f3f" background="/img/sinewhite.gif">
14 <center>
15 <font size=-2>The URL of this page is <font face="Courier Web,Courier New,Courier"><a href="http://www.catseye.mb.ca/esoteric/befunge/98/index.html">http://www.catseye.mb.ca/esoteric/befunge/98/index.html</a></font></font>
16 <table border=0><tr>
17 <td align=CENTER valign=CENTER bgcolor="#000000" BACKGROUND="/img/sineblack.gif"><A
18 HREF="/index.html"><img ALIGN=ABSMIDDLE
19 src="/img/3qtrsize.gif" ALT="Cat's Eye Technologies" BORDER=0></A></TD>
20 <TD ALIGN=CENTER VALIGN=CENTER>
21 &nbsp;&nbsp;&nbsp;
22 <font size=+3 color=#995533>Funge-98</font></TD></TR>
23 </TABLE>
24 <table border=1><tr>
25 <td><a href="/esoteric/befunge/index.html">Befunge Programming Language</A>
26 | <img src="/img/happyicon.gif" width=14 height=14 alt=":-)"><a href="/lala/index.html">Language Lab</A>
27 | <img src="/img/happyicon.gif" width=14 height=14 alt=":-)"><a href="/esoteric/index.html">Esoteric Topics in Computer Programming</A></td></tr></table>
28
29 <TABLE border=0><TR><TD WIDTH="50%" ALIGN=CENTER VALIGN=TOP>
30 <p><FONT SIZE=+2 COLOR="#FF0000">Funge-98</FONT>
31
32 <p>The most elaborate update so far of the Befunge
33 language, <A HREF="/esoteric/befunge/98/spec98.html">Funge-98</A>
34 generalizes Befunge for one, two, or three
35 dimensions, and provides a paradigm for Funges of
36 any number of dimensions and topologies. It also provides arbitrary
37 program flow direction on a virtually limitless playfield,
38 and a richer, scalable instruction set with an optional Concurrent version
39 for multithreading.
40
41 <p>While Funge-98 <i>is</i> explicitly designed as a multidimensional
42 language, it retains many properties of Befunge-93
43 when it comes to compiling to machine code: it is, if
44 anything, more difficult to compile.
45 It is still fully self-modifying; no strict distinction
46 is made between code and data, nor code storage space
47 and data storage space, and both can be read and written
48 (at run-time) to a storage medium such as a hard drive.
49
50 </TD><TD WIDTH="50%" VALIGN=CENTER ALIGN=CENTER>
51
52 <p><FONT SIZE=+2 COLOR="#FF0000">Registry</FONT>
53
54 <p>In a vain attempt to inject automated democracy into language
55 design, Funge-98 had, at one point, a "Central Registry"
56 for standardizing implementations and extensions.
57
58 <p>In retrospect, the authour feels this was probably
59 a mistake. The Central Registry no longer exists, and
60 any news of new interpreters or libraries must be exchanged
61 manually. But there are plenty of libraries for which
62 at least the semantics are available (even if they can sometimes be vague.)
63
64 <p>Included below, however, is a list of extant implementations
65 and extensions for Funge-98.
66
67 </TD></TR>
68 <tr>
69 <td colspan=2 align=center>
70 <p><FONT SIZE=+2 COLOR="#FF0000">Implementations</FONT>
71
72 <table border=1 cellpadding=5>
73 <tr><td align=center><b>Handprint</b></td><td align=center><b>Name</b></td><td align=center><b>Author/Location</b></td></tr>
74 <tr><td>46424249</td><td>Flaming Bovine Befunge-98 Interpreter</td><td><a href="/esoteric/befunge/98/fbbi/">Cat's Eye Technologies</a></td></tr>
75 <tr><td>52435355</td><td>RC/Funge-98 Interpreter</td><td><a href="http://homer.span.ch/~spaw1088/funge.html"><img src="/img/webicon.gif" alt="[WWW]" width=12 height=12 border=0>Mike Riley</a></td></tr>
76 <tr><td>620075c2<br>504ba68c</td><td>Paul's JavaScript Funge interpreter</td><td><a href="http://dufflebunk.iwarp.com"><img src="/img/webicon.gif" alt="[WWW]" width=12 height=12 border=0>Paul Mahon</a></td></tr>
77 <tr><td>7a463938</td><td>zinx funge interpreter</td><td><a href="http://www.zebra.net/~dm/funge/"><img src="/img/webicon.gif" alt="[WWW]" width=12 height=12 border=0>Zinx Verituse</a></td></tr>
78
79 </table>
80
81 <p><FONT SIZE=+2 COLOR="#FF0000">Extensions</FONT>
82
83 <p>Cat's Eye Technologies' extensions can be found at
84 <a href="/esoteric/befunge/98/library/">http://www.catseye.mb.ca/esoteric/befunge/98/library/</a>.
85
86 <p>Mike Riley's extensions can be found at
87 <a href="http://homer.span.ch/~spaw1088/funge.html"><img src="/img/webicon.gif" alt="[WWW]" width=12 height=12 border=0>http://homer.span.ch/~spaw1088/funge.html</a>.
88
89 </td></tr>
90 </TABLE>
91 <hr>
92 <font size=-1>Last Updated Jul 4 <IMG BORDER=0
93 HEIGHT=12 WIDTH=12 SRC="/img/copyright.gif" ALT="(c)"></A>2000
94 <A HREF="/index.html">Cat's Eye Technologies</A>.</font>
95
96 </CENTER>
97
98 </BODY>
99 </HTML>
Binary diff not shown
0 <html>
1 <head>
2 <title>Funge-98 Documentation: HRTI fingerprint</title>
3 </head>
4 <body bgcolor="#FFFFC0">
5 <center><h1>High-Resolution Timer Interface</h1>
6 <h3>Fingerprint 0x48525449 ('HRTI')</h3>
7 </center>
8
9 <p>Under development.
10
11 <p>The HRTI fingerprint allows a Funge program to
12 measure elapsed time much more finely than the
13 clock values returned by <tt>y</tt>.
14
15 <p>After successfully loading HRTI, the instructions
16 <tt>E</tt>, <tt>G</tt>, <tt>M</tt>, <tt>S</tt>, and <tt>T</tt>
17 take on new semantics.
18
19 <p><tt>G</tt> 'Granularity' pushes the smallest clock
20 tick the underlying system can reliably handle, measured
21 in microseconds.
22
23 <p><tt>M</tt> 'Mark' designates the timer as having
24 been read by the IP with this ID at this instance in time.
25
26 <p><tt>T</tt> 'Timer' pushes the number of microseconds
27 elapsed since the last time an IP with this ID marked the
28 timer. If there is no previous mark, acts like <tt>r</tt>.
29
30 <p><tt>E</tt> 'Erase mark' erases the last timer mark by this IP
31 (such that <tt>T</tt> above will act like <tt>r</tt>)
32
33 <p><tt>S</tt> 'Second' pushes the number of microseconds
34 elapsed since the last whole second.
35
36 <p>The timer and mark-list are considered global and static,
37 shared amongst all IP's, in order to retain tame behaviour.
38
39 <p>This timer is not affected by 'time travel' contrivances.
40
41 </body>
42 </html>
0 <html>
1 <head>
2 <title>Funge-98 Documentation: MODE fingerprint</title>
3 </head>
4 <body bgcolor="#FFFFC0">
5 <center><h1>Funge-98 Standard Modes</h1>
6 <h3>Fingerprint 0x4d4f4445 ('MODE')</h3>
7 </center>
8
9 Currently under development.<P>
10
11 After successfully loading MODE, the instructions
12 <tt>H</tt>, <tt>I</tt>, <tt>Q</tt>, and <tt>S</tt>
13 take on new semantics, which alter four new states or
14 'modes' of the current IP.<P>
15
16 <tt>H</tt> toggles an internal flag called hovermode on and off. In hovermode, the
17 instructions <tt>&gt;</tt>, <tt>&lt;</tt>, <tt>^</tt>,
18 <tt>v</tt>, <tt>|</tt>, and <tt>_</tt> treat the IP's delta
19 relatively - instead of setting the dx to 0 and dy to -1,
20 <tt>^</tt> would instead simply subtract 1 from dy.<p>
21
22 The <tt>I</tt> "Toggle Invertmode" instruction toggles an internal flag called
23 <i>invertmode</i>. When invertmode is active, cells are <b>pushed</b> on the
24 stack onto the <b>bottom</b> instead of the top.<p>
25
26 The <tt>Q</tt> "Toggle Queuemode" instruction toggles an internal flag called
27 <i>queuemode</i>. When queuemode is active, cells are <b>popped</b> off the
28 stack from the <b>bottom</b> instead of the top.<p>
29
30 <tt>S</tt> toggles switchmode on and off. In switchmode, the pairs of
31 instructions <tt>[</tt> and <tt>]</tt>, <tt>{</tt> and <tt>}</tt>,
32 and <tt>(</tt> and <tt>)</tt> are treated as switches. When one is
33 executed, the cell it is located in is immediately overwritten with
34 the other instruction of the pair, providing a switching mechanism
35 and a way to seperate coincident IP's.<p>
36
37 </body>
38 </html>
0 <html>
1 <head>
2 <title>Funge-98 Documentation: MODU fingerprint</title>
3 </head>
4 <body bgcolor="#FFFFC0">
5 <center><h1>Modulo Arithmetic Extension</h1>
6 <h3>Fingerprint 0x4d4f4455 ('MODU')</h3>
7 </center>
8
9 <p>Under development.
10
11 <p>The MODU fingerprint implements some of the finer,
12 less-well-agreed-upon points of modulo arithmetic. With
13 positive arguments, these instructions work exactly the
14 same as <tt>%</tt> does. However, when negative values
15 are involved, they all work differently:
16
17 <p><tt>M</tt>: signed-result modulo:
18 <ul>x MOD y = x - FLOOR(x / y) * y</ul>
19 <p><tt>U</tt>: Sam Holden's unsigned-result modulo
20 <p><tt>R</tt>: C-language integer remainder
21
22 </body>
23 </html>
0 <html>
1 <head>
2 <title>Funge-98 Documentation: Null Fingerprint</title>
3 </head>
4 <body bgcolor="#FFFFC0">
5 <center><h1>Funge-98 Null Fingerprint</h1>
6 <h3>Fingerprint 0x4e554c4c (Null)</h3>
7 </center>
8
9 After successfully loading fingerprint 0x4e554c4c,
10 all 26 instructions <tt>A</tt> to <tt>Z</tt>
11 take on the semantics of <tt>r</tt>.<P>
12
13 This can be loaded before loading a regular
14 transparent fingerprint to make it act opaquely.<p>
15
16 </body>
17 </html>
0 <html>
1 <head>
2 <title>Funge-98 Documentation: ORTH fingerprint</title>
3 </head>
4 <body bgcolor="#FFFFC0">
5 <center><h1>Orthogonal Easement Library</h1>
6 <h3>Fingerprint 0x4f525448 ('ORTH')</h3>
7 </center>
8
9 Under development.<p>
10
11 The ORTH fingerprint is designed to ease transition
12 between the Orthogonal programming language and
13 Befunge-98 (or higher dimension Funges.) Even if
14 transition from Orthogonal is not an issue, the ORTH
15 library contains some potentially interesting
16 instructions not in standard Funge-98.<P>
17
18 After successfully loading ORTH, the instructions
19 <tt>A</tt>, <tt>E</tt>, <tt>G</tt>,
20 <tt>O</tt>, <tt>P</tt>, <tt>S</tt>,
21 <tt>V</tt>, <tt>W</tt>, <tt>X</tt>, <tt>Y</tt>, and <tt>Z</tt>
22 take on new semantics. The following table, which
23 can be used to translate Orthogonal to Funge-98 and
24 back, includes which Orthogonal instructions they
25 emulate:<p>
26
27 <pre>
28 Funge Orthogonal Semantic
29
30 + + add
31 * * multiply
32 - - subtract
33 / / divide
34 % % modulo (positive values only)
35 >>> A & bitwise AND
36 >>> O | bitwise OR
37 >>> E ^ bitwise EXOR
38 ! ! logical negate
39 \ ~ swap
40 : @ duplicate
41 $ $ pop
42 < L go west
43 > H go east
44 ^ K go north
45 v J go south
46 ] cw rotate right
47 [ ccw rotate left
48 r rev reverse
49 >>> X x change x
50 >>> Y y change y
51 >>> V dx change dx
52 >>> W dy change dy
53 >>> G = ortho get
54 >>> P # ortho put
55 >>> Z ? ramp if zero
56 , c output character
57 >>> S s output string
58 . d output decimal
59 z nop no operation
60 q ret quit
61 </pre>
62
63 </body>
64 </html>
0 <html>
1 <head>
2 <title>Funge-98 Documentation: PERL fingerprint</title>
3 </head>
4 <body bgcolor="#FFFFC0">
5 <center><h1>Generic Interface to the Perl Language</h1>
6 <h3>Fingerprint 0x5045524c ('PERL')</h3>
7 </center>
8
9 <p>Under development.
10
11 <p>The PERL fingerprint is designed to provide a basic,
12 no-frills interface to the Perl language.
13
14 <p>After successfully loading PERL, the instructions
15 <tt>E</tt>, <tt>I</tt>, and <tt>S</tt>
16 take on new semantics.
17
18 <p><tt>S</tt> ('Shelled')
19 pushes a 0 on the stack if the Perl language
20 is already loaded (e.g. the interpreter is written in Perl).
21 It pushes a 1 on the stack otherwise, indicating that the
22 Perl language will be shelled when needed.
23
24 <p><tt>E</tt> ('Eval') pops a 0gnirts string and
25 performs a Perl <code>eval()</code> on it, possibly (or
26 not) shelling Perl as indicated by S above.
27 The result of the call is pushed as a 0gnirts string
28 back onto the stack.
29
30 <P><tt>I</tt> ('Int Eval') acts the same as <tt>E</tt>, except that
31 the result of the call is converted to an integer and
32 pushed as a single cell onto the stack.
33
34 </body>
35 </html>
0 <html>
1 <head>
2 <title>Funge-98 Documentation: REFC fingerprint</title>
3 </head>
4 <body bgcolor="#FFFFC0">
5 <center><h1>Referenced Cells Extension</h1>
6 <h3>Fingerprint 0x52454643 ('REFC')</h3>
7 </center>
8
9 <p>Under development.
10
11 <p>The REFC fingerprint allows vectors to be encoded into
12 and decoded from single scalar cell values.
13
14 <p>After successfully loading REFC, the instructions
15 <tt>D</tt> and <tt>R</tt>
16 take on new semantics.
17
18 <p><tt>R</tt> 'Reference' pops a vector off the stack,
19 and pushes a scalar value back onto the stack, unique
20 within an internal list of references, which refers
21 to that vector.
22
23 <p><tt>D</tt> 'Dereference' pops a scalar value off the
24 stack, and pushes the vector back onto the stack which
25 corresponds to that unique reference value.
26
27 <p>The internal list of references is considered
28 shared among all IP's, so a global static can be used
29 to store this list, so that this extension remains tame.
30
31 </body>
32 </html>
0 <html>
1 <head>
2 <title>Funge-98 Documentation: ROMA fingerprint</title>
3 </head>
4 <body bgcolor="#FFFFC0">
5 <center><h1>Funge-98 Roman Numerals</h1>
6 <h3>Fingerprint 0x524f4d41 ('ROMA')</h3>
7 </center>
8
9 After successfully loading ROMA, the instructions
10 <tt>C</tt>, <tt>D</tt>, <tt>I</tt>, <tt>L</tt>,
11 <tt>M</tt>, <tt>V</tt>, and <tt>X</tt>
12 take on new semantics.<P>
13
14 <ul>
15 <li><tt>C</tt> pushes 100 onto the stack.
16 <li><tt>D</tt> pushes 500 onto the stack.
17 <li><tt>I</tt> pushes 1 onto the stack.
18 <li><tt>L</tt> pushes 50 onto the stack.
19 <li><tt>M</tt> pushes 1000 onto the stack.
20 <li><tt>V</tt> pushes 5 onto the stack.
21 <li><tt>X</tt> pushes 10 onto the stack.
22 </ul>
23
24 Note that these are just digits, you still have
25 to do the arithmetic yourself.
26 Executing <tt>MCMLXXXIV</tt> will not leave
27 1984 on the stack. But executing
28 <tt>MCM\-+LXXX+++IV\-++</tt> should.<p>
29
30 </body>
31 </html>
0 <html>
1 <head>
2 <title>Funge-98 Documentation: TOYS fingerprint</title>
3 </head>
4 <body bgcolor="#FFFFC0">
5 <center><h1>Funge-98 Standard Toys</h1>
6 <h3>Fingerprint 0x544f5953 ('TOYS')</h3>
7 </center>
8
9 <p>Under development.
10
11 <p>After successfully loading TOYS, the instructions
12 <tt>A</tt>, <tt>B</tt>, <tt>C</tt>, <tt>D</tt>,
13 <tt>E</tt>, <tt>F</tt>, <tt>G</tt>,
14 <tt>H</tt>, <tt>I</tt>, <tt>J</tt>, <tt>K</tt>,
15 <tt>L</tt>, <tt>M</tt>, <tt>N</tt>, <tt>O</tt>,
16 <tt>P</tt>, <tt>Q</tt>,
17 <tt>R</tt>, <tt>S</tt>, <tt>T</tt>, <tt>U</tt>, <tt>V</tt>, <tt>W</tt>,
18 <tt>X</tt>, <tt>Y</tt>, and <tt>Z</tt>
19 take on new semantics (and INTERCAL-esque names).
20
21 <P><tt>C</tt> ('bracelet')
22 pops three vectors off the stack and performs
23 a low-order copy of Funge-Space.
24
25 <p><tt>K</tt> ('scissors')
26 pops three vectors off the stack and performs
27 a high-order copy of Funge-Space.
28
29 <p><tt>M</tt> ('kittycat')
30 pops three vectors off the stack and performs
31 a low-order move (copy & erase original) of Funge-Space.
32
33 <p><tt>V</tt> ('dixiecup')
34 pops three vectors off the stack and performs
35 a high-order move of Funge-Space.
36
37 <p><tt>S</tt> ('chicane')
38 pops two vectors off the stack, then a cell,
39 then fills that area of Funge-Space homogenously with that cell's
40 value.
41
42 <p>Which order a copy or move takes is important if you copy
43 or move to an overlapping area. Ensure when implementing these
44 that the order is preserved in all dimensions.
45
46 <p>The first two vectors are like the arguments to <tt>o</tt>.
47 In all except <tt>S</tt>, the third is the destination, relative
48 to the origin.
49
50 <p><tt>J</tt> ('fishhook')
51 pops a value off the stack, and causes the current
52 column (y coordinate) of Funge-space
53 to be translated north (if value is negative) or south (if positive)
54 that many rows.
55
56 <p><tt>O</tt> ('boulder')
57 pops a value off the stack, and causes the current
58 row (x coordinate) of Funge-space
59 to be translated west (if value is negative) or east (if positive)
60 that many columns.
61
62 <p><tt>L</tt> ('corner')
63 works like <tt>'</tt> except it picks up the cell
64 to the "left" of the IP's line and does not skip over anything.
65 (Historians may note that this works like "Get Left Hand" did
66 in Befunge-97.) The cell to the "left" of the IP is the IP's
67 position, plus its delta rotated -90 degrees about the Z axis
68 (a la <tt>[</tt>)
69
70 <p><tt>R</tt> ('can opener')
71 is a corresponding instruction that mirrors <tt>L</tt>
72 and works to the right, rotated 90 degrees about the Z axis
73 ("Get Right Hand" from Befunge-97)
74
75 <p><tt>I</tt> ('doric column')
76 pops a value off the stack, increments it,
77 and pushes it back onto the stack.
78
79 <p><tt>D</tt> ('toilet seat')
80 pops a value off the stack, decrements it,
81 and pushes it back onto the stack.
82
83 <p><tt>N</tt> ('lightning bolt')
84 pops a value off the stack, negates it,
85 and pushes it back onto the stack.
86
87 <p><tt>H</tt> ('pair of stilts')
88 pops a value <i>b</i> off the stack, then a value
89 <i>a</i>, then binary-shifts <i>a</i> <i>b</i> places left if <i>b</i>
90 is positive, or |<i>b</i>| places right if <i>b</i> is negative.
91
92 <p><tt>A</tt> ('gable')
93 pops a cell <i>n</i> off the stack, then another cell,
94 then pushes <i>n</i> copies of that cell onto the stack.
95
96 <p><tt>B</tt> ('pair of shoes')
97 pops two cells off the stack and pushes the result
98 of a "butterfly" bit operation.
99
100 <p><tt>E</tt> ('pitchfork head')
101 pops all values off the stack and pushes their sum
102 back onto it.
103
104 <p><tt>P</tt> ('mailbox')
105 pops all values off the stack and pushes their product
106 back onto it.
107
108 <p><tt>F</tt> ('calipers')
109 pops a vector, then a value <i>i</i>. Treating
110 the rest of the
111 stack as <i>j</i> groups of <i>i</i> cells each, it writes this
112 2D matrix into Funge-space in row-major order,
113 with it's least point as the given vector.
114
115 <p><tt>G</tt> ('counterclockwise')
116 pops a vector, then a value <i>i</i>. It then
117 pushes onto the stack <i>j</i> groups of <i>i</i> cells each
118 which it retrieves as a 2D matrix in Funge-space in row-major
119 order, the least point of which being the vector supplied to it.
120
121 <p><tt>Q</tt> ('necklace')
122 pops a value off the stack and places it into the cell
123 directly behind the IP (kind of like <tt>s</tt>, except behind, and
124 no cell is skipped over.)
125
126 <p><tt>T</tt> ('barstool')
127 pops a dimension number off the stack; if it's
128 a 0, acts like <tt>_</tt>; if it's 1, acts like <tt>|</tt>;
129 if it's 2, acts like <tt>m</tt>; etc. depending on
130 the number of available dimensions as appropriate of course.
131
132 <p><tt>U</tt> ('tumbler')
133 is like <tt>?</tt> but one-shot. When executed, it
134 randomly transmutes into one of <tt>&lt;</tt>, <tt>&gt;</tt>,
135 <tt>^</tt>, <tt>v</tt>, <tt>h</tt>, or <tt>l</tt>, depending on
136 the number of available dimensions as appropriate of course.
137
138 <p><tt>W</tt> ('television antenna')
139 pops a vector off the stack, then a value.
140 If the cell at that vector (plus the storage offset)
141 in Funge-Space (a la <tt>g</tt>)
142 is equal to that value, nothing happens. If the cell in space
143 is less than the value, it pushes the value and the vector (inverted)
144 back onto the stack, and backs up the IP (subtracts the IP's
145 delta from it's position, sort of a 'wait to try again'
146 condition, useful mainly in Concurrent Funge.) If
147 the cell in space is greater than that value, acts like <tt>r</tt>.
148
149 <p><tt>X</tt> ('buried treasure')
150 increments the IP's x coordinate.
151
152 <p><tt>Y</tt> ('slingshot')
153 increments the IP's y coordinate.
154
155 <p><tt>Z</tt> ('barn door')
156 increments the IP's z coordinate.
157
158 <p>These three instructions are useful at the end of a line, to
159 indicate "proceed to next line then wrap". Note the IP's delta
160 motion is still fully in effect.
161 </body>
162 </html>
0 <html>
1 <head>
2 <title>Funge-98 Documentation: TURT fingerprint</title>
3 </head>
4 <body bgcolor="#FFFFC0">
5 <center><h1>Simple Turtle Graphics Library</h1>
6 <h3>Fingerprint 0x54555254 ('TURT')</h3>
7 </center>
8
9 <p>Under development.
10
11 <p>The TURT fingerprint provides a simple interface to a simple
12 "drawing turtle-robot simulator".
13
14 <p>After successfully loading TURT, several instructions
15 take on new semantics.
16
17 <p>These instructions pop one value off the stack:
18
19 <ul>
20 <li><tt>L</tt> 'Turn Left' (angle in degrees)
21 <li><tt>R</tt> 'Turn Right' (angle in degrees)
22 <li><tt>H</tt> 'Set Heading' (angle in degrees, relative to 0deg, east)
23 <li><tt>F</tt> 'Forward' (distance in pixels)
24 <li><tt>B</tt> 'Back' (distance in pixels)
25 <li><tt>P</tt> 'Pen Position' (0 = up, 1 = down)
26 <li><tt>C</tt> 'Pen Colour' (24-bit RGB)
27 <li><tt>N</tt> 'Clear Paper with Colour' (24-bit RGB)
28 <li><tt>D</tt> 'Show Display' (0 = no, 1 = yes)
29 </ul>
30
31 <p>These pop two values each:
32 <ul>
33 <li><tt>T</tt> 'Teleport' (x, y coords relative to origin; 00T = home)
34 </ul>
35
36 <p>These push one value each:
37 <ul>
38 <li><tt>E</tt> 'Query Pen' (0 = up, 1 = down)
39 <li><tt>A</tt> 'Query Heading' (positive angle relative to east)
40 </ul>
41
42 <p>These push two values each:
43 <ul>
44 <li><tt>Q</tt> 'Query Position' (x, y coordinates)
45 </ul>
46
47 <p>These push four values each:
48 <ul>
49 <li><tt>U</tt> 'Query Bounds' (two pairs of x, y coordinates)
50 </ul>
51
52 <p>And these don't even use the stack:
53 <ul>
54 <li><tt>I</tt> 'Print current Drawing' (if possible)
55 </ul>
56
57 <p>To keep this fingerprint tame, a single Turtle and display
58 is defined to be shared amongst all IP's. The turtle is not
59 defined to wrap if it goes out of bounds (after all this interface
60 might just as well be used to drive a <b>real</b> turtle robot.)
61
62 </body>
63 </html>