parent
86b934fae3
commit
9e5b6424a1
480
CHANGES.html
480
CHANGES.html
|
@ -1,480 +0,0 @@
|
|||
<!-- :noWordSep=+-*\=><;.?/'()%,_|: -->
|
||||
|
||||
<html>
|
||||
<head><title>Factor change log</title></head>
|
||||
<body>
|
||||
|
||||
<h1>Factor 0.81:</h1>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>Solaris/x86 is now supported (Patrick Mauritz)</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h1>Factor 0.80:</h1>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>New help system, browsable in the UI and via the HTTP server (<code>/responder/help</code>). In the UI listener, invoke <code>handbook</code> to read the documentation root, and invoke <code>\ foo help</code> to look at documentation for the word <code>foo</code>.</li>
|
||||
|
||||
<li>Sequences:
|
||||
|
||||
<ul>
|
||||
<li>Association list words <code>assoc*</code>, <code>set-assoc</code>, <code>acons</code> and <code>remove-assoc</code> are gone.</li>
|
||||
<li>The <code>repeated</code> virtual sequence type is gone. Instead, the
|
||||
<code><array></code> word takes an initial element in addition to an
|
||||
initial size.</li>
|
||||
<li>The <code>fill</code> word to create a new string with an initial character
|
||||
repeated a certain number of times has been renamed to <code><string></code>.</li>
|
||||
<li>Add a new <code>interleave ( seq quot between -- )</code> combinator that applies
|
||||
a quotation to each element of a sequence, calling another quotation in between each
|
||||
pair.</li>
|
||||
<li>Add a new <code><=> ( obj1 obj2 -- n )</code> word for comparing two
|
||||
objects using an intrinsic order. For numbers this is the standard order, for strings
|
||||
this is lexicographic order, and for words, this compares word names.</li>
|
||||
<li>The <code>natural-sort ( seq -- seq )</code> word replaces <code>number-sort</code>,
|
||||
<code>string-sort</code> and <code>word-sort</code>.</li>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>Hashtables:
|
||||
<ul>
|
||||
<li><code>hash* ( key hash -- [[ key value ]] )</code> is now <code>hash* ( key hash -- value ? )</code></li>
|
||||
<li><code>hash-clear</code> is now <code>clear-hash</code></li>
|
||||
<li><code>hash-each</code>, <code>hash-each-with</code>, <code>hash-all?</code>, <code>hash-all-with?</code>, <code>hash-subset</code>, <code>hash-subset-with</code> now pass the key and value separately on the stack to the given quotation, instead of passing a cons cell</li>
|
||||
<li>Literal syntax change: <code>H{ [[ key value ]] ... }</code> is now <code>H{ { key value } }</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Math:
|
||||
|
||||
<ul>
|
||||
|
||||
<li>The <code>sum</code> and <code>product</code> words have been moved to
|
||||
<code>contrib/math/</code>.</li>
|
||||
<li>The <code>mod</code> word is now supported for ratios and floating point numbers.</li>
|
||||
<li>The <code>truncate</code>, <code>floor</code> and <code>ceiling</code> words are now supported for floating point numbers.</li>
|
||||
<li>The NaN, positive infinity and negative infinity floating point numbers now parse and unparse as <code>0.0/0.0</code>, <code>1.0/0.0</code>, and <code>-1.0/0.0</code> respectively.</li>
|
||||
<li>The NaN value is now equal to itself under <code>=</code>.</li>
|
||||
<li>Negative and postive zero are no longer equal under <code>=</code>. However, the new <code>zero?</code> word tests if the top of the stack is a zero, and it tests for both positive and negative zero.</li>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>Streams:
|
||||
|
||||
<ul>
|
||||
<li><code>stream-format ( string style stream -- )</code> now takes a hashtable
|
||||
rather than an association list for specifying style information.</li>
|
||||
<li><code>stream-write</code> and <code>stream-terpri</code> are now generic words, and there is a new <code>with-nested-stream</code> generic word. You can wrap your output streams in a <code><plain-writer></code> to avoid implementing these.</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
<li>C library interface:
|
||||
|
||||
<ul>
|
||||
<li>Some alien word changes:
|
||||
<pre><foo> ==> "foo" <c-object>
|
||||
<foo-array> ==> "foo" <c-array></pre>
|
||||
<li>Support for binding to Objective C libraries is now included.
|
||||
<ul>
|
||||
<li>Normal usage of Objective C classes and methods is done using the <code>OBJC-CLASS:</code>
|
||||
and <code>OBJC-MESSAGE:</code> parsing words. See the example in
|
||||
<code>examples/cocoa-speech.factor</code>.</li>
|
||||
<li>Objective C runtime introspection functions and structures are defined in the
|
||||
<code>objective-c</code> vocabulary.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Added a pair of words for between Factor strings and C strings, <code>alien>string</code> and <code>string>alien</code>.
|
||||
</li>
|
||||
|
||||
<li>Compiler changes:
|
||||
|
||||
<ul>
|
||||
<li>AMD64 compiler backend.</li>
|
||||
<li>Fixed some problems with compilation of inlined recursive words.</li>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>UI changes:
|
||||
|
||||
<ul>
|
||||
<li>Fixed invalid OpenGL calls which caused problems on Windows machines with ATI
|
||||
drivers, and Linux machines with the MesaGL implementation.</li>
|
||||
<li>The listener looks different now. An expandable top area is used for browsing objects, words and help, and the stack display has been shrunk to a single status line at the bottom of the window.</li>
|
||||
<li>A left click on a presentation now invokes the default command. A right click
|
||||
shows a menu of possibilities.</li>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>Bootstrap changes:
|
||||
|
||||
<ul>
|
||||
<li>Source files are no longer loaded in the stage-2 bootstrap. Since stage-2 bootstrap
|
||||
runs in the interpreter, this reduces bootstrap time by a few minutes. Instead, all
|
||||
source files, including the compiler backend, are loaded in stage-1 bootstrap, and thus
|
||||
boot images are now CPU-specific. Boot images can be created as follows:
|
||||
<pre>
|
||||
USE: image
|
||||
"x86" make-image
|
||||
"ppc" make-image
|
||||
"amd64" make-image
|
||||
</pre></li>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>Contributed libraries:
|
||||
|
||||
<ul>
|
||||
<li>All libraries in <code>contrib/</code> have been tested and updated for recent language
|
||||
changes, and you can run <code>contrib/load.factor</code> to load all of them at once (Trent Buck)</li>
|
||||
<li>Updated <code>contrib/x11/</code> with many more examples (Eduardo Cavazos)</li>
|
||||
<li>Added splay tree library in <code>contrib/splay-trees.factor</code> (Mackenzie Straight)</li>
|
||||
<li>Improved AJAX support in <code>contrib/httpd/</code>. The "prototype" JavaScript library is now included (Chris Double)</li>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h1>Factor 0.79:</h1>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>Incompatible changes:
|
||||
|
||||
<ul>
|
||||
<li>The <code>ifte</code> combinator has been renamed to <code>if</code>.</li>
|
||||
<li>Syntax changes:
|
||||
<pre>
|
||||
{ 1 2 3 } ! arrays
|
||||
V{ 1 2 3 } ! vectors
|
||||
H{ [[ key value ]] ... } ! hashtables
|
||||
C{ 1.02 -7.44 } ! complex numbers
|
||||
T{ class slots ... } ! tuple
|
||||
</pre>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<li>Compiler:
|
||||
|
||||
<ul>
|
||||
<li>New basic block optimizer performs more aggressive dead load and store elimination.</li>
|
||||
<li>Stack shuffles are compiled more efficiently.</li>
|
||||
<li>Pushing literals on either side of a stack shuffle is now compiled more efficiently.</li>
|
||||
<li>Fixed a problem with relocation of compiled code on PowerPC.</li>
|
||||
<li>Fixed various FFI issues on Mac OS X.</li>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>User interface:
|
||||
|
||||
<ul>
|
||||
<li>Graphics rendering is now done using OpenGL and text rendering is done via FreeType. SDL_gfx and SDL_ttf libraries are no longer required.</li>
|
||||
<li>Added expandable outliners. Used by the inspector, <code>.s</code>, <code>usage.</code>, <code>uses.</code>, <code>vocabs.</code>, and various other words.</li>
|
||||
<li>Added word completion to the listener pane; press <code>TAB</code>.</li>
|
||||
<li>Added word navigation shortcuts to the listener pane; press <code>C+LEFT</code> and <code>C+RIGHT</code> to move a word at a time, and <code>C+BACKSPACE</code> and <code>C+DELETE</code> to delete the previous and next word, respectively.</li>
|
||||
<lI>Added mouse-over help for presentations.</lI>
|
||||
<li>Previously-entered output is now clickable in the listener.</li>
|
||||
<li>New, better-looking widget theme.</li>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>Collections:
|
||||
|
||||
<ul>
|
||||
<li>Faster <code>map</code>, <code>2each</code> and <code>2map</code>.</li>
|
||||
<li>Arrays are now better supported and should be used instead of vectors where resizing is not desired.</li>
|
||||
<li>Some new sequence words that do not bounds check: <code>nth-unsafe</code> and <code>set-nth-unsafe</code>. These should only be used in special circumstances, such as inner loops (<code>each</code>, <code>map</code> and so on use them).</li>
|
||||
<li>New <code>replace-slice ( new from to seq -- seq )</code> word replaces a slice of a sequence with another sequence.</li>
|
||||
<li>Hashtables did not obey the rule that equal objects must have equal hashcodes, so using hashtables as hashtable keys did not work.</li>
|
||||
<li>New <code>mismatch ( seq seq -- i )</code> word returns first index where two sequences
|
||||
differ, or -1 if they have equal elements.</li>
|
||||
<li>New <code>drop-prefix ( seq seq -- seq seq )</code> word returns a pair of
|
||||
sequences which have the same elements as the two input sequences, with the common
|
||||
prefix removed.</li>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<li>Everything else:
|
||||
|
||||
<ul>
|
||||
|
||||
<li>On Mac OS X, signal 11 errors caused by stack under/overflow no longer trigger the
|
||||
OS X crash reporter dialog.</li>
|
||||
<li>Easier exception handling. The <code>cleanup ( try cleanup -- )</code> word encapsulates the following idiom:
|
||||
<pre>
|
||||
[ A ] [ B rethrow ] catch
|
||||
[ A ] [ B ] cleanup
|
||||
</pre>
|
||||
The <code>recover ( try recover -- )</code> word encapsulates the following idiom:
|
||||
<pre>
|
||||
[ A ] [ [ B ] when* ] catch
|
||||
[ A ] [ B ] recover
|
||||
</pre>
|
||||
The <code>catch ( try -- error/f )</code> word no longer takes a quotation that receives the error caught; rather, it just pushes the error that was caught on the stack. That is, the old way:
|
||||
<pre>
|
||||
[ A ] [ B ] catch
|
||||
</pre>
|
||||
Becomes:
|
||||
<pre>
|
||||
[ A ] catch B
|
||||
</pre>
|
||||
However, most uses of <code>catch</code> can be replaced by <code>cleanup</code> and <code>recover</code>.</li>
|
||||
<li>The distinct <code>t</code> type is gone. Now, the <code>t</code> object is just a symbol.</li>
|
||||
<li>A new <code>with-server ( port ident quot -- )</code> combinator takes care of listening on a network socket, logging client connections, spawning client handler threads, and error handling. The quotation is called for each client, in a new scope with the client socket as the default stream.</li>
|
||||
<li>New <code>1+</code>, <code>1-</code> words are a bit faster than <code>1 +</code> and <code>1 -</code> since there is one less generic dispatch involved.</li>
|
||||
<li>On Windows, FFI errors would raise a signal 11 instead of reporting a nice message.</li>
|
||||
</ul>
|
||||
|
||||
<li>Contributed code:
|
||||
|
||||
<ul>
|
||||
|
||||
<li>The HTTP server and client has been moved from <code>library/httpd/</code> to <code>library/contrib/</code>.</li>
|
||||
<li>Intel 8080 CPU and Space Invaders emulator in <code>contrib/space-invaders</code> (Chris Double)</li>
|
||||
<li>AOL Instant Messenger chat client library in <code>contrib/aim</code> (Doug Coleman)</li>
|
||||
<li>Cairo graphics library binding in <code>contrib/cairo</code>. (Sampo Vuori)</li>
|
||||
<li>Advanced math library with quaternions, matrices, polynomials, statistics and various
|
||||
functions in <code>contrib/math/</code>. (Doug Coleman)</li>
|
||||
<li>Dimensioned units in <code>contrib/units/</code>. (Doug Coleman)</li>
|
||||
<li>X11 binding in <code>contrib/x11/</code> (Eduardo Cavazos)</li>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h1>Factor 0.78:</h1>
|
||||
|
||||
<ul>
|
||||
<li>Consecutive stack operations are now composed into single shuffle expressions.</li>
|
||||
<li>The return stack pointer is now stored in a register on x86.</li>
|
||||
<li>Non-recursive inline words are compiled more efficiently.</li>
|
||||
<li>Fix PowerPC bootstrap issue, and <code>fixnum-shift</code>, <code>fixnum/i</code> overflow.</li>
|
||||
</ul>
|
||||
|
||||
<h1>Factor 0.77:</h1>
|
||||
|
||||
<ul>
|
||||
<li>Compiler:
|
||||
<ul>
|
||||
<li>Optimizing out conditionals where the test value is a constant.</li>
|
||||
<li>Optimizing out type checks that are always/never satisfied.</li>
|
||||
<li>Inlining method bodies when generic words are called on values with known compile-time types.</li>
|
||||
<li>Side-effect-free words that output immutable values are evaluated at compile time if all their inputs are literal. You can declare a word as having this condition by suffixing the definition with <code>foldable</code>, eg:
|
||||
<pre>: cube dup dup * * ; foldable</pre></li>
|
||||
<li>Various arithmetic identities such as <code>1 *</code> are optimized out.
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>Collections:
|
||||
|
||||
<ul>
|
||||
<li><code>sort ( seq quot -- | quot: elt elt -- -1/0/1 )</code> combinator now works with any sequence, not just a list. The comparator also has to return a signed integer, not just a boolean. It is much faster than the old sorting algorithm.</li>
|
||||
<li><code>binsearch ( elt seq quot -- i | quot: elt elt -- -1/0/1 )</code> and <code>binsearch ( elt seq quot -- elt | quot: elt elt -- -1/0/1 )</code> combinators perform a binary search on a sorted sequence.</li>
|
||||
<li><code>2each ( seq seq quot -- quot: elt -- elt )</code> combinator</li>
|
||||
<li><code>join ( seq glue -- seq )</code> word. Takes a sequence of sequences, and constructs a new sequence with the glue in between each sequence. For example:
|
||||
<pre> [ "usr" "bin" "grep" ] "/" join
|
||||
<b>"usr/bin/grep"</b></pre></li>
|
||||
<li>Integers now support the sequence protocol. An integer is an increasing sequence of its predecessors. This means the <code>count ( n -- [ 0 ... n-1 ] )</code> word is gone; just use <code>>vector</code> instead. Also, <code>project</code> has been made redundant by <code>map</code>.</li>
|
||||
<li>The <code>seq-transpose ( seq -- seq )</code> word is now named <code>flip</code>.
|
||||
</li>
|
||||
<li>The matrices library has been greatly simplified. Matrices are now represented as vectors of vectors, and matrix words have been moved to the <code>math</code> vocabulary.</li>
|
||||
<li>More descriptive "out of bounds" errors.</li>
|
||||
<li>New <code>make-hash ( quot -- namespace )</code> combinator executes quotation in a new namespace, which is then pushed on the stack.</li>
|
||||
<li>The <code><namespace></code> word is gone. It would create a hashtable with a default capacity. Now, just write <code>{{ }} clone</code>.</li>
|
||||
<li>Sequence construction words changed:
|
||||
<pre>
|
||||
make-list ==> [ ] make
|
||||
make-vector ==> { } make
|
||||
make-string ==> "" make
|
||||
make-rstring ==> "" make reverse
|
||||
make-sbuf ==> SBUF" " make
|
||||
</pre></li>
|
||||
<li>The <code>every?</code> word has been replaced with <code>monotonic? ( seq quot -- ? )</code>. Its behavior is a superset of <code>every?</code> -- it now accepts any transitive relation, and checks if the sequence is monotonic under this relation. For example,
|
||||
<code>[ = ] monotonic?</code> checks if all elements in a sequence are equal, and <code>[ < ] monotonic?</code> checks for a strictly increasing sequence of integers.</li>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>Development tools:
|
||||
|
||||
<ul>
|
||||
<li>In the UI, object slots are now clickable in the inspector.</li>
|
||||
<li>Inspector now supports a history and an interactive loop; it prints a brief help message when it starts describing usage.</li>
|
||||
<li>The prettyprinter has been merged with the unparser. The <code>unparse ( object -- string )</code> word has been moved to the <code>prettyprint</code> vocabulary, and can now produce a parsable string for any class supported by the prettyprinter.</li>
|
||||
<li>New <code>unparse-short ( object -- string )</code> returns a string no longer than a single line.</li>
|
||||
<li>The prettyprinter now supports many more configuration variables. See the handbook for details.</li>
|
||||
<li>New <code>profile ( word -- )</code> word. Causes the word's accumulative runtime to be stored in a global variable named by the word. This is done with the annotation facility, the word's definition is modified; use <code>reload ( word -- )</code> to get the old definition back from the source file.</li>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>User interface:
|
||||
|
||||
<ul>
|
||||
<li>Binary search is now used for spacial indexing where possible. This improves performance when there are a lot of lines of output in the listener.</li>
|
||||
<li>Scroll bars now behave in a more intuitive manner, closer to conventional GUIs.</li>
|
||||
<li>Menus now appear when the mouse button is pressed, not released, and dragging through the menu with the button held down behaves as one would expect.</li>
|
||||
<li>The data stack and call stack are now shown. In the single-stepper, these two display the state of the program being stepped. In the inspector, the call stack display is replaced with an inspector history.</li>
|
||||
<li>Pack layouts with gaps are now supported.</li>
|
||||
<li>Many bug fixes.</li>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>Everything else:
|
||||
|
||||
<ul>
|
||||
<li>New <code>sleep ( ms -- )</code> word pauses current thread for a number of milliseconds.</li>
|
||||
<li>New <code>with-datastack ( stack word -- stack )</code> combinator.</li>
|
||||
<li>New <code>cond ( conditions -- )</code> combinator. It behaves like a set of nested <code>ifte</code>s, and compiles if each branch has the same stack effect. See its documentation comment for details.</li>
|
||||
<li>Formally documented method combination (<code>G:</code> syntax) in handbook.</li>
|
||||
<li>Erlang/Termite-style concurrency library in <code>contrib/concurrency</code> (Chris Double).</li>
|
||||
<li>Completely redid infix algebra in <code>contrib/algebra/</code>. Now, vector operations are possible
|
||||
and the syntax doesn't use so many spaces. New way to write the quadratic formula:
|
||||
<pre>MATH: quadratic[a;b;c] =
|
||||
plusmin[(-b)/2*a;(sqrt(b^2)-4*a*c)/2*a] ;</pre>
|
||||
(Daniel Ehrenberg)</li>
|
||||
<li>Support for client sockets on Windows. (Mackenzie Straight)</li>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h1>Factor 0.76:</h1>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
UI framework:
|
||||
<ul>
|
||||
<li>Now uses 3-dimensional co-ordinates throughout</li>
|
||||
<li>Gradient paint, bevel border paint</li>
|
||||
<li>Split pane gadget</li>
|
||||
<li>Horizontal scroll bars and wheel mouse scrolling in scroller gadgets</li>
|
||||
<li>Incremental layout improves listener responsiveness</li>
|
||||
<li>The listener supports styled text output and presentations</li>
|
||||
<li>Slide-show tutorial with live code examples</li>
|
||||
<li>Performance improvements, code cleanups, bug fixes</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Sequences:
|
||||
<ul>
|
||||
<li>The following formely list-specific words are now generic:
|
||||
|
||||
<pre>all? ( seq quot -- ? | quot: elt -- ? )
|
||||
all-with? ( obj seq quot -- ? | quot: elt -- ? )
|
||||
subset ( seq quot -- seq | quot: elt -- ? )
|
||||
subset-with ( obj seq quot -- seq | quot: obj elt -- ? )
|
||||
fiber? ( seq quot -- ? | quot: elt elt -- ? )
|
||||
prune ( seq -- seq )</pre>
|
||||
|
||||
<li> The <code>contains?</code> word for testing membership in a sequence has been
|
||||
renamed to <code>member? ( elt seq -- ? )</code>.
|
||||
|
||||
<li> The list-specific <code>some?</code> and <code>some-with?</code> combinators are gone. Their replacements are generic:
|
||||
|
||||
<pre>contains? ( seq quot -- ? | quot: elt -- ? )
|
||||
contains-with? ( obj seq quot -- ? | quot: obj elt -- ? )
|
||||
find ( seq quot -- i elt | quot: elt -- ? )
|
||||
find* ( i seq quot -- i elt | quot: elt -- ? )
|
||||
find-with ( obj seq quot -- i elt | quot: elt -- ? )
|
||||
find-with* ( obj i seq quot -- i elt | quot: elt -- ? )</pre>
|
||||
|
||||
See the developer's handbook for details.
|
||||
|
||||
<li> The <code>nreverse ( seq -- )</code> word has been removed.
|
||||
|
||||
<li> <code>reverse-slice ( seq -- seq )</code> outputs a new sequence that shares
|
||||
structure with the given sequence, but presents elements in reverse
|
||||
order.
|
||||
|
||||
<li> The <code>string-compare</code> primitive has been replaced with the lexi word
|
||||
which now operates on any pair of sequences of numbers. The
|
||||
string> word has been replaced with <code>lexi></code>.
|
||||
|
||||
<li> The <code>,</code> word no longer accepts a string as input inside a <code>make-string</code>. In 0.75, the following
|
||||
two lines were equivalent:
|
||||
|
||||
<pre>[ "Hello" , " world" , ] make-string
|
||||
[ "Hello" % " world" % ] make-string</pre>
|
||||
|
||||
<li> Now, the former raises a type error. Use <code>,</code> with characters, and <code>%</code> with
|
||||
strings inside make-string.
|
||||
</ul>
|
||||
|
||||
<li>Streams:
|
||||
|
||||
<ul>
|
||||
<li>The following words have been renamed:
|
||||
|
||||
<pre>stream-auto-flush ==> stream-finish ( stream -- )
|
||||
stream-write-attr ==> stream-format ( string style stream -- )
|
||||
write-attr ==> format ( string style -- )</pre>
|
||||
|
||||
<li>The following words no longer accept character arguments:
|
||||
|
||||
<pre>stream-format ( string style stream -- )
|
||||
format ( string style -- )
|
||||
stream-write ( string stream -- )
|
||||
write ( string -- )
|
||||
stream-print ( string -- )
|
||||
print ( string -- )</pre>
|
||||
|
||||
<li>Use the new words to write characters:
|
||||
|
||||
<pre>stream-write1 ( char stream -- )
|
||||
write1 ( char -- )</pre>
|
||||
|
||||
Note that <code>stream-write1</code> is generic and your stream must implement it.
|
||||
|
||||
<li><code>with-string</code> word renamed to <code>string-out ( quot -- string )</code>
|
||||
|
||||
<li>New <code>string-in ( string quot -- )</code> word, calls <code>quot</code> with <code>stdio</code> bound to
|
||||
a stream that reads from the given string.
|
||||
</ul>
|
||||
|
||||
<li>Everything else:
|
||||
|
||||
<ul>
|
||||
|
||||
<li>Many improvements to the matrices library.
|
||||
|
||||
<li>Improved inspector. Call it with <code>inspect ( obj -- )</code>.
|
||||
|
||||
<li>The number of generations used for garbage collection can now be set
|
||||
with the +G command line switch. You must specify at least 2
|
||||
generations.
|
||||
|
||||
<li>Only 2 generations are used by default now, since there seems to be no
|
||||
performance benefit to having 3 after running some brief benchmarks.
|
||||
|
||||
<li>Fixed bug where images saved from the jEdit plugin would fail to
|
||||
start.
|
||||
|
||||
<li>md5 hashing algorithm in <code>contrib/crypto/</code> (Doug Coleman).
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
122
Makefile
122
Makefile
|
@ -1,122 +0,0 @@
|
|||
CC = gcc
|
||||
|
||||
BINARY = f
|
||||
|
||||
ifdef DEBUG
|
||||
DEFAULT_CFLAGS = -g
|
||||
STRIP = touch
|
||||
else
|
||||
DEFAULT_CFLAGS = -Wall -O3 -ffast-math -fomit-frame-pointer $(SITE_CFLAGS)
|
||||
STRIP = strip
|
||||
endif
|
||||
|
||||
DEFAULT_LIBS = -lm
|
||||
|
||||
UNIX_OBJS = native/unix/file.o \
|
||||
native/unix/signal.o \
|
||||
native/unix/ffi.o \
|
||||
native/unix/run.o \
|
||||
native/unix/memory.o \
|
||||
native/unix/mach_signal.o
|
||||
|
||||
WIN32_OBJS = native/win32/ffi.o \
|
||||
native/win32/file.o \
|
||||
native/win32/misc.o \
|
||||
native/win32/run.o \
|
||||
native/win32/memory.o
|
||||
|
||||
ifdef WIN32
|
||||
PLAF_OBJS = $(WIN32_OBJS)
|
||||
PLAF_SUFFIX = .exe
|
||||
else
|
||||
PLAF_OBJS = $(UNIX_OBJS)
|
||||
endif
|
||||
|
||||
OBJS = $(PLAF_OBJS) native/array.o native/bignum.o \
|
||||
native/s48_bignum.o \
|
||||
native/complex.o native/cons.o native/error.o \
|
||||
native/factor.o native/fixnum.o \
|
||||
native/float.o native/gc.o \
|
||||
native/image.o native/memory.o \
|
||||
native/misc.o native/primitives.o \
|
||||
native/ratio.o native/relocate.o \
|
||||
native/run.o \
|
||||
native/sbuf.o native/stack.o \
|
||||
native/string.o native/cards.o native/vector.o \
|
||||
native/word.o native/compiler.o \
|
||||
native/alien.o native/dll.o \
|
||||
native/boolean.o \
|
||||
native/debug.o \
|
||||
native/hashtable.o \
|
||||
native/icache.o \
|
||||
native/io.o \
|
||||
native/wrapper.o \
|
||||
native/ffi_test.o
|
||||
|
||||
default:
|
||||
@echo "Run 'make' with one of the following parameters:"
|
||||
@echo ""
|
||||
@echo "bsd"
|
||||
@echo "linux"
|
||||
@echo "linux-ppc"
|
||||
@echo "macosx"
|
||||
@echo "macosx-sdl -- if you wish to use the Factor GUI on Mac OS X"
|
||||
@echo "solaris"
|
||||
@echo "windows"
|
||||
@echo ""
|
||||
@echo "Also, you might want to set the SITE_CFLAGS environment"
|
||||
@echo "variable to enable some CPU-specific optimizations; this"
|
||||
@echo "can make a huge difference. Eg:"
|
||||
@echo ""
|
||||
@echo "export SITE_CFLAGS=\"-march=pentium4 -ffast-math\""
|
||||
|
||||
bsd:
|
||||
$(MAKE) $(BINARY) \
|
||||
CFLAGS="$(DEFAULT_CFLAGS) -export-dynamic -pthread" \
|
||||
LIBS="$(DEFAULT_LIBS)"
|
||||
$(STRIP) $(BINARY)
|
||||
|
||||
macosx:
|
||||
$(MAKE) $(BINARY) \
|
||||
CFLAGS="$(DEFAULT_CFLAGS)" \
|
||||
LIBS="$(DEFAULT_LIBS)"
|
||||
|
||||
macosx-sdl:
|
||||
$(MAKE) $(BINARY) \
|
||||
CFLAGS="$(DEFAULT_CFLAGS) -DFACTOR_SDL" \
|
||||
LIBS="$(DEFAULT_LIBS) -lSDL -lSDLmain -framework Cocoa -framework OpenGL"
|
||||
|
||||
linux linux-x86 linux-amd64:
|
||||
$(MAKE) $(BINARY) \
|
||||
CFLAGS="$(DEFAULT_CFLAGS) -export-dynamic" \
|
||||
LIBS="-ldl $(DEFAULT_LIBS)"
|
||||
$(STRIP) $(BINARY)
|
||||
|
||||
linux-ppc:
|
||||
$(MAKE) $(BINARY) \
|
||||
CFLAGS="$(DEFAULT_CFLAGS) -export-dynamic -mregnames" \
|
||||
LIBS="-ldl $(DEFAULT_LIBS)"
|
||||
$(STRIP) $(BINARY)
|
||||
|
||||
solaris solaris-x86:
|
||||
$(MAKE) $(BINARY) \
|
||||
CFLAGS="$(DEFAULT_CFLAGS) -D_STDC_C99 -Drestrict=\"\" " \
|
||||
LIBS="-ldl -lsocket -lnsl $(DEFAULT_LIBS) -R/opt/PM/lib -R/opt/csw/lib -R/usr/local/lib -R/usr/sfw/lib -R/usr/X11R6/lib -R/opt/sfw/lib"
|
||||
$(STRIP) $(BINARY)
|
||||
|
||||
windows:
|
||||
$(MAKE) $(BINARY) \
|
||||
CFLAGS="$(DEFAULT_CFLAGS) -DFFI -DWIN32" \
|
||||
LIBS="$(DEFAULT_LIBS)" WIN32=y
|
||||
|
||||
f: $(OBJS)
|
||||
$(CC) $(LIBS) $(CFLAGS) -o $@$(PLAF_SUFFIX) $(OBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS)
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) -o $@ $<
|
||||
|
||||
.S.o:
|
||||
$(CC) -c $(CFLAGS) -o $@ $<
|
|
@ -4,7 +4,6 @@
|
|||
- UI browser pane needs 'back' button
|
||||
- runtime primitives like fopen: check for null input
|
||||
- port ffi to win64
|
||||
- intrinsic char-slot set-char-slot for x86
|
||||
- fix up the min thumb size hack
|
||||
- the invalid recursion form case needs to be fixed, for inlines too
|
||||
- code walker & exceptions
|
||||
|
@ -23,9 +22,7 @@
|
|||
- stream server can hang because of exception handler limitations
|
||||
- better i/o scheduler
|
||||
- if two tasks write to a unix stream, the buffer can overflow
|
||||
- font problem: http://iarc1.ece.utexas.edu/~erg/font-bug.JPG
|
||||
- make 3.4 bits>double an error
|
||||
- 0./0. 0 0 ^ = . -> f floating point nan has different bit representations
|
||||
|
||||
- 2220.446049250313 [ dup float? [ tanh ] when ]
|
||||
- call and compile-1 give C{ 0.0/0.0 0.0/0.0 } 0.0/0.0
|
||||
|
|
|
@ -1,547 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Factor Concurrency Library</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Factor Concurrency Library</h1>
|
||||
<p class="note">The concurrency library here is based upon the style
|
||||
of concurrency used in systems like Erlang and Termite. It is
|
||||
currently at a very early stage and only supports concurrent
|
||||
processes within a single Factor image. The interface is very likely to
|
||||
change so it is quite experimental at this stage. The ability to
|
||||
have distributed processes is planned.</p>
|
||||
<h1>Overview</h1>
|
||||
<p>A concurrency oriented program is one in which multiple processes
|
||||
run simultaneously in a single Factor image. The processes can
|
||||
communicate with each other by asynchronous message sends. Although
|
||||
processes can share data via Factor's mutable data structures it is
|
||||
not recommended as the use of shared state concurrency is often a
|
||||
cause of problems.</p>
|
||||
<h1>Loading</h1>
|
||||
<p>The quickest way to get up and running with this library is to type the following into the listener:</p>
|
||||
<pre class="code">
|
||||
"/contrib/concurrency/load.factor" run-resource
|
||||
USE: concurrency
|
||||
USE: concurrency-examples
|
||||
</pre>
|
||||
<h1>Processes</h1>
|
||||
<p>A process is basically a thread with a message queue. Other
|
||||
processes can place items on this queue by sending the process a
|
||||
message. A process can check its queue for messages, blocking if none
|
||||
are pending, and process them as they are queued.</p>
|
||||
<p>Factor processes are very lightweight. Each process can take as
|
||||
little as 900 bytes of memory. This library has been tested running
|
||||
hundreds of thousands of simple processes.</p>
|
||||
<p>The messages that are sent from process to process are any Factor
|
||||
value. Factor tuples are ideal for this sort of thing as you can send
|
||||
a tuple to a process and the predicate dispatch mechanism can be used
|
||||
to perform actions depending on what the type of the tuple is.</p>
|
||||
<p>Processes are usually created using the 'spawn' word:</p>
|
||||
<pre class="code">
|
||||
IN: concurrency
|
||||
spawn ( quot -- process )
|
||||
</pre>
|
||||
<p>This word takes a quotation on the stack and starts a process that
|
||||
will execute that quotation asynchronously. When the quotation
|
||||
completes the process will die. 'spawn' leaves on the stack the
|
||||
process object that was started. This object can be used to send
|
||||
messages to the process using the 'send' word:</p>
|
||||
<pre class="code">
|
||||
IN: concurrency
|
||||
send ( message process -- )
|
||||
</pre>
|
||||
<p>'send' will return immediately after placing the message in the
|
||||
target processes message queue. A process can get a message from its
|
||||
queue using the 'receive' word:</p>
|
||||
<pre class="code">
|
||||
IN: concurrency
|
||||
receive ( -- message )
|
||||
</pre>
|
||||
<p>This will get the most recent message
|
||||
and leave it on the stack. If there are no messages in the queue the
|
||||
process will 'block' until a message is available. When a process is
|
||||
blocked it takes no CPU time at all.</p>
|
||||
<pre class="code">
|
||||
[ receive print ] spawn
|
||||
"Hello Process!" swap send
|
||||
</pre>
|
||||
<p>This example spawns a process that first blocks, waiting to receive
|
||||
a message. When a message is received, the 'receive' call returns
|
||||
leaving it on the stack. It then prints the message and exits. 'spawn'
|
||||
left the process on the stack so it's available to send the 'Hello
|
||||
Process!' message to it. Immediately after the 'send' you should see
|
||||
'Hello Process!' printed on the console.</p>
|
||||
<p>It is also possible to selectively retrieve messages from the
|
||||
message queue. The 'receive-if' word takes a predicate quotation on the stack
|
||||
and returns the first message in the queue that satisfies the
|
||||
predicate. If no items satisfy the predicate then the process is
|
||||
blocked until a message is received that does.
|
||||
</p>
|
||||
<pre class="code">
|
||||
: odd? ( n -- ? )
|
||||
2 mod 1 = ;
|
||||
|
||||
<span class="highlite">1 self send
|
||||
2 self send
|
||||
3 self send</span>
|
||||
|
||||
<span class="highlite">receive .</span>
|
||||
=> 1
|
||||
<span class="highlite">[ odd? ] receive-if .</span>
|
||||
=> 3
|
||||
<span class="highlite">receive .</span>
|
||||
=> 2
|
||||
</pre>
|
||||
<h2>Self</h2>
|
||||
<p>A process can get access to its own process object using the 'self'
|
||||
word so it can pass it to other processes. This allows the other processes to send
|
||||
messages back. A simple example of using this gets the current
|
||||
processes 'self' and spawns a process which sends a message to it. We
|
||||
then receive the message from the original process</p>
|
||||
<pre class="code">
|
||||
<span class="highlite">self .s</span>
|
||||
=> << process ... >>
|
||||
<span class="highlite">[ "Hello!" swap send ] cons spawn drop receive .</span>
|
||||
=> "Hello"
|
||||
</pre>
|
||||
<h1>Servers</h1>
|
||||
<p>A common idiom is to create 'server' processes that act on messages
|
||||
that are sent to it. These follow a basic pattern of blocking until a
|
||||
message is received, processing that message then looping back to
|
||||
blocking for a message.</p>
|
||||
<p>The following example shows a very simple server that expects a
|
||||
cons cell as its message. The 'car' of the cons should be the senders
|
||||
process object. If the 'cdr' is 'ping' then the server sends 'pong'
|
||||
back to the caller. If the 'cdr' is anything else then the server
|
||||
exits:</p>
|
||||
<pre class="code">
|
||||
: (pong-server0) ( -- )
|
||||
receive uncons "ping" = [
|
||||
"pong" swap send (pong-server0)
|
||||
] [
|
||||
"Pong server shutting down" swap send
|
||||
] ifte ;
|
||||
|
||||
: pong-server0 ( -- process)
|
||||
[ (pong-server0) ] spawn ;
|
||||
|
||||
<span class="highlite">pong-server0</span>
|
||||
<span class="highlite">self "ping" cons over send receive .</span>
|
||||
=> "pong"
|
||||
<span class="highlite">self "ping" cons over send receive .</span>
|
||||
=> "pong"
|
||||
<span class="highlite">self "shutdown" cons over send receive .</span>
|
||||
=> "Pong server shutting down"
|
||||
</pre>
|
||||
<p>Handling the deconstructing of messages and dispatching based on
|
||||
the message can be a bit of a chore. Especially in servers that take a
|
||||
number of different messages. One approach to factor this code out,
|
||||
and reduce the amount of stack juggling required, is to use tuples as
|
||||
messages. This allows using the generic dispatch mechanism. The
|
||||
following example implements the pong server but using tuples as
|
||||
messages:</p>
|
||||
<pre class="code">
|
||||
TUPLE: ping-message from ;
|
||||
TUPLE: shutdown-message from ;
|
||||
|
||||
GENERIC: handle-message
|
||||
|
||||
M: ping-message handle-message ( message -- bool )
|
||||
ping-message-from "pong" swap send t ;
|
||||
|
||||
M: shutdown-message handle-message ( message -- bool )
|
||||
shutdown-message-from "Pong server shutdown commenced" swap send f ;
|
||||
|
||||
: (pong-server1) ( -- )
|
||||
"pong-server1 waiting for message..." print
|
||||
receive handle-message [ (pong-server1) ] when ;
|
||||
|
||||
: pong-server1 ( -- process )
|
||||
[
|
||||
(pong-server1)
|
||||
"pong-server1 exiting..." print
|
||||
] spawn ;
|
||||
</pre>
|
||||
<p>Two tuples are created for a 'ping' and 'shutdown' message. Each
|
||||
has a 'from' slot which holds the process of the sender. The server
|
||||
loop, in '(pong-server1)', calls a generic method called
|
||||
'handle-message'. This has signature ( message -- bool ). These
|
||||
methods return a boolean.
|
||||
True means continue the server
|
||||
loop. False means exit and shut down the server.</p>
|
||||
<p>Two methods are added to the generic word. One for 'ping' and the
|
||||
other for 'pong'. Here's a sample run:</p>
|
||||
<pre class="code"> clear
|
||||
<span class="highlite">pong-server1</span>
|
||||
=> pong-server1 waiting for message...
|
||||
<span class="highlite">self <ping-message> over send receive .</span>
|
||||
=> "pong"
|
||||
pong-server1 waiting for message...
|
||||
<span class="highlite">self <ping-message> over send receive .</span>
|
||||
=> "pong"
|
||||
pong-server1 waiting for message...
|
||||
<span class="highlite">self <shutdown-message> over send receive .</span>
|
||||
=> "Pong server shutdown commenced"
|
||||
pong-server1 exiting...
|
||||
</pre>
|
||||
<p>The advantage of this approach is it is easy to extend the server
|
||||
without shutting it down. Adding a new message is as simple as
|
||||
defining the tuple and adding a method to 'handle-message' specialised
|
||||
on that tuple. Here's an example of adding an 'echo' message, without
|
||||
shutting the server down:</p>
|
||||
<pre class="code">
|
||||
<span class="highlite">pong-server1</span>
|
||||
=> pong-server1 waiting for message...
|
||||
<span class="highlite">self <ping-message> over send receive .</span>
|
||||
=> "pong"
|
||||
|
||||
TUPLE: echo-message from text ;
|
||||
|
||||
M: echo-message handle-message ( message -- bool )
|
||||
dup echo-message-text swap echo-message-from send t ;
|
||||
|
||||
<span class="highlite">self "Hello World" <echo-message> over send receive .</span>
|
||||
=>"Hello World"
|
||||
|
||||
</pre>
|
||||
<h2>Synchronous Sends</h2>
|
||||
<p>The 'send' word sends a message asynchronously, and the sending
|
||||
process continues immediately. The 'pong server' examples shown
|
||||
previously all sent messages to the server and waited for a reply back
|
||||
from the server. This pattern of synchronous sending is made easier
|
||||
with the 'send-synchronous' word:</p>
|
||||
<pre class="code">
|
||||
IN: concurrency
|
||||
send-synchronous ( message process -- reply )
|
||||
</pre>
|
||||
<p>This word will send a message to the given process and immediately
|
||||
block until a reply is received for this particular message send. It
|
||||
leaves the reply on the stack. Note that it doesn't wait for just any
|
||||
reply, it waits for a reply specifically to this send.</p>
|
||||
<p>To do this it wraps the requested message inside a 'tagged-message'
|
||||
tuple. This tuple is defined as:</p>
|
||||
<pre class="code">
|
||||
TUPLE: tagged-message data from tag ;
|
||||
</pre>
|
||||
<p>When 'send-synchronous' is called it will created a
|
||||
'tagged-message', storing the current process in the 'from' slot. This
|
||||
is what the receiving server will use to send the reply to. It also
|
||||
generates a random 'tag' which is stored in the 'tag' slot. The
|
||||
receiving server will include this value in its reply. After the send
|
||||
the current process will block waiting for a reply that has the exact
|
||||
same tag. In this way you can be sure that the reply you got was for
|
||||
the specific message sent.</p>
|
||||
<p>Here is the 'pong server' recoded to use 'send-synchronous' and the
|
||||
tagged-message type:</p>
|
||||
<pre class="code">
|
||||
GENERIC: handle-message2
|
||||
PREDICATE: tagged-message ping-message2 ( obj -- ? )
|
||||
tagged-message-data "ping" = ;
|
||||
PREDICATE: tagged-message shutdown-message2 ( obj -- ? )
|
||||
tagged-message-data "shutdown" = ;
|
||||
|
||||
M: ping-message2 handle-message2 ( message -- bool )
|
||||
"pong" reply t ;
|
||||
|
||||
M: shutdown-message2 handle-message2 ( message -- bool )
|
||||
"Pong server shutdown commenced" reply f ;
|
||||
|
||||
: (pong-server2) ( -- )
|
||||
"pong-server2 waiting for message..." print
|
||||
receive handle-message2 [ (pong-server2) ] when ;
|
||||
|
||||
: pong-server2 ( -- process )
|
||||
[
|
||||
(pong-server2)
|
||||
"pong-server2 exiting..." print
|
||||
] spawn ;
|
||||
|
||||
<span class="highlite">pong-server2</span>
|
||||
=> pong-server2 waiting for message...
|
||||
<span class="highlite">"ping" over send-synchronous .</span>
|
||||
=> "pong"
|
||||
pong-server2 waiting for message...
|
||||
<span class="highlite">"ping" over send-synchronous .</span>
|
||||
=> "pong"
|
||||
pong-server2 waiting for message...
|
||||
<span class="highlite">"shutdown" over send-synchronous .</span>
|
||||
=> "Pong server shutdown commenced"
|
||||
pong-server2 exiting...
|
||||
</pre>
|
||||
<p>The main difference in this example is that the 'handle-message2'
|
||||
methods are dispatched over predicate types. Two predicate types are
|
||||
set up both based on the 'tagged-message' tuple mentioned earlier. The
|
||||
first is for 'ping-message2' which is a tagged message where the
|
||||
message data is the string "ping". The second is also a tagged message
|
||||
but the message data is the string "shutdown".</p>
|
||||
<p>The implementation of the methods uses the 'reply' word. 'reply'
|
||||
takes a received tagged-message and a new message on the stack and replies to
|
||||
it. This means that it sends a reply back to the calling process using
|
||||
the same 'tag'
|
||||
as the original message. It is a convenience word so you don't have to
|
||||
manually unpack the tagged-message tuple to get at the originating
|
||||
process and tag. Its signature is:</p>
|
||||
<pre class="code">
|
||||
IN: concurrency
|
||||
reply ( tagged-message message -- )
|
||||
</pre>
|
||||
<h2>Generic Server</h2>
|
||||
<p>You'll probably have noticed that the general pattern of the pong
|
||||
server examples are the same. In a loop they receive a message,
|
||||
process it using a generic function, and either exit or go back to the
|
||||
beginning of the loop. This is abstracted in the 'spawn-server'
|
||||
word:</p>
|
||||
<pre class="code">
|
||||
IN: quotation
|
||||
spawn-server ( quot -- process )
|
||||
</pre>
|
||||
<p>This takes a quotation that has stack effect ( message -- bool ).
|
||||
'spawn-server' will spawn a server loop that waits for a message. When
|
||||
it is received the quotation is called on it. If the quotation returns
|
||||
false then the server process exits, otherwise it loops from the
|
||||
beginning again. Using this word you can write the previous
|
||||
'pong-server2' example as:</p>
|
||||
<pre class="code">
|
||||
GENERIC: handle-message2
|
||||
PREDICATE: tagged-message ping-message2 ( obj -- ? ) tagged-message-data "ping" = ;
|
||||
PREDICATE: tagged-message shutdown-message2 ( obj -- ? ) tagged-message-data "shutdown" = ;
|
||||
|
||||
M: ping-message2 handle-message2 ( message -- bool )
|
||||
"pong" reply t ;
|
||||
|
||||
M: shutdown-message2 handle-message2 ( message -- bool )
|
||||
"Pong server shutdown commenced" reply f ;
|
||||
|
||||
: pong-server3 ( -- process )
|
||||
[ handle-message2 ] spawn-server ;
|
||||
</pre>
|
||||
<p>The main change is that you no longer need the helper
|
||||
(pong-server2) word.</p>
|
||||
<h2>Exceptions</h2>
|
||||
<p>A process can handle exceptions using the standard Factor exception
|
||||
handling mechanism. If an exception is uncaught the process will
|
||||
terminate. For example:</p>
|
||||
<pre class="code">
|
||||
<span class="highlite">[
|
||||
1 0 /
|
||||
"This will not print" print
|
||||
] spawn</span>
|
||||
=>
|
||||
Division by zero
|
||||
:s :r show stacks at time of error.
|
||||
:get ( var -- value ) inspects the error namestack.
|
||||
</pre>
|
||||
<p>Processes can be linked so that a parent process can receive the
|
||||
exception that caused the child process to terminate. In this way
|
||||
'supervisor' processes can be created that are notified when child
|
||||
processes terminate and possibly restart them.</p>
|
||||
<p>The easiest way to form this link is using the 'spawn-link'
|
||||
word. This will create a unidirectional link, such that if an
|
||||
uncaught exception causes the child to terminate, the parent process
|
||||
can catch it:</p>
|
||||
<pre class="code">
|
||||
<span class="highlite">[
|
||||
[
|
||||
1 0 /
|
||||
"This will not print" print
|
||||
] spawn-link drop
|
||||
receive
|
||||
]
|
||||
catch [ "Exception caught." print ] when
|
||||
</span>
|
||||
=> "Exception caught."
|
||||
</pre>
|
||||
<p>Exceptions are only raised in the parent when the parent does a
|
||||
'receive' or 'receive-if'. This is because the exception is sent from
|
||||
the child to the parent as a message.</p>
|
||||
<p>To demonstrate how a 'supervisor' process could be created we'll
|
||||
use the following example 'rpc-server'. It processes 'add', 'product'
|
||||
and 'crash' messages. 'crash' causes a deliberate divide by zero error
|
||||
to terminate the process:</p>
|
||||
<pre class="code">
|
||||
GENERIC: handle-rpc-message
|
||||
GENERIC: run-rpc-command
|
||||
|
||||
TUPLE: rpc-command op args ;
|
||||
PREDICATE: rpc-command add-command ( msg -- bool )
|
||||
rpc-command-op "add" = ;
|
||||
PREDICATE: rpc-command product-command ( msg -- bool )
|
||||
rpc-command-op "product" = ;
|
||||
PREDICATE: rpc-command shutdown-command ( msg -- bool )
|
||||
rpc-command-op "shutdown" = ;
|
||||
PREDICATE: rpc-command crash-command ( msg -- bool )
|
||||
rpc-command-op "crash" = ;
|
||||
|
||||
M: tagged-message handle-rpc-message ( message -- bool )
|
||||
dup tagged-message-data run-rpc-command -rot reply not ;
|
||||
|
||||
M: add-command run-rpc-command ( command -- shutdown? result )
|
||||
rpc-command-args sum f ;
|
||||
|
||||
M: product-command run-rpc-command ( command -- shutdown? result )
|
||||
rpc-command-args product f ;
|
||||
|
||||
M: shutdown-command run-rpc-command ( command -- shutdown? result )
|
||||
drop t t ;
|
||||
|
||||
M: crash-command run-rpc-command ( command -- shutdown? result )
|
||||
drop 1 0 / f ;
|
||||
|
||||
: fragile-rpc-server ( -- process )
|
||||
[ handle-rpc-message ] spawn-server ;
|
||||
|
||||
: test-add ( process -- )
|
||||
[
|
||||
"add" [ 1 2 3 ] <rpc-command> swap send-synchronous .
|
||||
] cons spawn drop ;
|
||||
|
||||
: test-crash ( process -- )
|
||||
[
|
||||
"crash" f <rpc-command> swap send-synchronous .
|
||||
] cons spawn drop ;
|
||||
</pre>
|
||||
<p>An example of use:</p>
|
||||
<pre class="code">
|
||||
<span class="highlite">fragile-rpc-server</span>
|
||||
=> Waiting for message in server: G:13037
|
||||
<span class="highlite">dup test-add</span>
|
||||
=> 6
|
||||
Waiting for message in server: G:13037
|
||||
<span class="highlite">dup test-crash</span>
|
||||
=> Division by zero
|
||||
:s :r show stacks at time of error.
|
||||
:get ( var -- value ) inspects the error namestack.
|
||||
<span class="highlite">dup test-add</span>
|
||||
</pre>
|
||||
<p>After the crash, all other messages are ignored by the server as it
|
||||
is no longer running. The following is a way to re-use this code by
|
||||
running a 'supervisor' process that links with the 'worker' rpc-server. When
|
||||
the worker crashes the supervisor process restarts it. All
|
||||
messages sent to the supervisor are immediately forwarded to the
|
||||
worker:</p>
|
||||
<pre class="code">
|
||||
: (robust-rpc-server) ( worker -- )
|
||||
[
|
||||
#! Forward all messages to worker
|
||||
receive over send
|
||||
]
|
||||
catch
|
||||
[
|
||||
"Worker died, Starting a new worker" print
|
||||
drop [ handle-rpc-message ] spawn-linked-server
|
||||
] when
|
||||
(robust-rpc-server) ;
|
||||
|
||||
: robust-rpc-server ( -- process )
|
||||
[
|
||||
[ handle-rpc-message ] spawn-linked-server
|
||||
(robust-rpc-server)
|
||||
] spawn ;
|
||||
</pre>
|
||||
<p>This time when the 'robust-rpc-server' is run you'll notice that
|
||||
messages after the crash are still processed:</p>
|
||||
<pre class="code">
|
||||
<span class="highlite">robust-rpc-server</span>
|
||||
=> Waiting for message in server: G:13045
|
||||
<span class="highlite">dup test-add</span>
|
||||
=> 6
|
||||
Waiting for message in server: G:13045
|
||||
<span class="highlite">dup test-crash</span>
|
||||
=> Worker died, Starting a new worker
|
||||
Waiting for message in server: G:13050
|
||||
<span class="highlite">dup test-add</span>
|
||||
=> 6
|
||||
Waiting for message in server: G:13050
|
||||
</pre>
|
||||
|
||||
<h2>Futures</h2>
|
||||
<p>A future is a placeholder for the result of a computation that is
|
||||
being calculated in a process. When the process has completed the
|
||||
computation the future can be queried to find out the result. If the
|
||||
computation has not completed when the future is queried them the
|
||||
process will block until the result is completed.</p>
|
||||
<p>A future is created using the 'future' word:</p>
|
||||
<pre class="code">
|
||||
IN: concurrency
|
||||
future ( quot -- future )
|
||||
</pre>
|
||||
<p>The quotation will be run in a spawned process, and a future object
|
||||
is immediately returned. This future object can be resolved using the
|
||||
word '?future':</p>
|
||||
<pre class="code">
|
||||
IN: concurrency
|
||||
?future ( future -- result )
|
||||
</pre>
|
||||
<p>Futures are useful for starting calculations that take a long time
|
||||
to run but aren't needed to later in the process. When the process
|
||||
needs the value it can use '?future' to get the result or block until
|
||||
the result is available. For example:</p>
|
||||
<pre class="code">
|
||||
[ 30 fib ] future
|
||||
...do stuff...
|
||||
?future
|
||||
</pre>
|
||||
<h2>Promises</h2>
|
||||
<p>A promise is similar to a future but it is not produced by
|
||||
calcuating something in the background. It represents a promise to
|
||||
provide a value sometime later. A process can request the value of a
|
||||
promise and will block if the promise is not fulfilled. Later, another
|
||||
process can fulfill the promise, providing a value. All threads
|
||||
waiting on the promise will then resume with that value on the
|
||||
stack.</p>
|
||||
<p>The words that operate on promises are:</p>
|
||||
<pre class="code">
|
||||
IN: concurrency
|
||||
<promise> ( -- promise )
|
||||
fulfill ( value promise -- )
|
||||
?promise ( promise -- result )
|
||||
</pre>
|
||||
<p>A simple example of use is:</p>
|
||||
<pre class="code">
|
||||
<span class="highlite"><promise>
|
||||
[ ?promise "Promise fulfilled: " write print ] spawn drop
|
||||
[ ?promise "Promise fulfilled: " write print ] spawn drop
|
||||
[ ?promise "Promise fulfilled: " write print ] spawn drop
|
||||
"hello" swap fulfill</span>
|
||||
=> Promise fulfilled: hello
|
||||
Promise fulfilled: hello
|
||||
Promise fulfilled: hello
|
||||
</pre>
|
||||
<p>In this example a promise is created and three processes spawned,
|
||||
waiting for that promise to be fulfilled. The main process then
|
||||
fulfills that promise with the value "hello" and all the blocking
|
||||
processes resume, printing the value.</p>
|
||||
<h2>GUI</h2>
|
||||
<p>In the Alice programming system it's possible to display futures
|
||||
and promises in the inspector and the values will automatically change
|
||||
then the future is ready, or the promise fulfilled. It's possible to
|
||||
do similar things with the Factor GUI but there is nothing currently
|
||||
built-in. A simple example of how this might work is included in the
|
||||
concurrency-examples vocabulary, with the 'test-promise-ui' word.</p>
|
||||
<pre class="code">
|
||||
: test-promise-ui ( -- )
|
||||
<promise> dup <promised-label> gadget.
|
||||
[ 12 fib unparse swap fulfill ] cons spawn drop ;
|
||||
</pre>
|
||||
<p>This creates a 'promised-label' gadget. This is a gadget, also
|
||||
implemented in the examples, that has an attached promise. The gadget will display the text 'Unfulfilled
|
||||
Promise' while the promise is unfulfilled. When it is fulfilled the
|
||||
gadget will immediately redisplay the value of the promise (which will
|
||||
need to be a printable value for this example).</p>
|
||||
<p>The example above displays the gadget using 'gadget.' and then
|
||||
spawns a thread to compute the 12th fibonacci number and fulfill the
|
||||
promise with it converted to a string. As soon as the fulfill occurs
|
||||
the gadget redisplays with the new value.</p>
|
||||
<p>So running 'test-promise-ui' will displays 'Unfulfilled Promise'
|
||||
and a short time later change to the new computed value. You will need
|
||||
to have the Factor GUI listener for this to work:</p>
|
||||
<pre class="code">
|
||||
USE: shells
|
||||
[ ui ] in-thread
|
||||
</pre>
|
||||
<p class="footer">
|
||||
News and updates to this software can be obtained from the authors
|
||||
weblog: <a href="http://radio.weblogs.com/0102385">Chris Double</a>.</p>
|
||||
<p id="copyright">Copyright (c) 2004, Chris Double. All Rights Reserved.</p>
|
||||
</body> </html>
|
|
@ -1,28 +0,0 @@
|
|||
body { background: white; color: black; }
|
||||
p { margin-left: 10%; margin-right: 10%;
|
||||
font: normal 100% Verdana, Arial, Helvetica; }
|
||||
td { margin-left: 10%; margin-right: 10%;
|
||||
font: normal 100% Verdana, Arial, Helvetica; }
|
||||
table { margin-left: 10%; margin-right: 10%; }
|
||||
ul { margin-left: 10%; margin-right: 10%;
|
||||
font: normal 100% Verdana, Arial, Helvetica; }
|
||||
ol { margin-left: 10%; margin-right: 10%;
|
||||
font: normal 100% Verdana, Arial, Helvetica; }
|
||||
h1 { text-align: center; margin-bottom: 0; margin-top: 1em; }
|
||||
h2 { margin: 0 5% 0 7.5%; font-size: 120%; font-style: italic; }
|
||||
h3 { border: 2px solid blue; border-width: 2px 0.5em 2px 0.5em;
|
||||
padding: 0.2em 0.2em 0.2em 0.5em; background: #fafafa;
|
||||
margin-left: 10%; margin-right: 10%; margin-top: 2em;
|
||||
font-size: 100%; }
|
||||
.note { border: 2px solid blue; border-width: 2px 2px 2px 2em;
|
||||
padding: 0.5em 0.5em 0.5em 1em; background: #ffe; }
|
||||
.code { border: 1px solid black; border-width: 1px;
|
||||
padding: 0.5em; background: #ffe;
|
||||
margin-left: 10%; margin-right: 10%; }
|
||||
blockquote { margin-left: 25%; margin-right: 25%;
|
||||
font-style: italic; }
|
||||
.highlite { color: red; }
|
||||
.footer { margin-top: 2.5em; border-top: 1px solid gray; color:
|
||||
#AAA; font-size: 85%; padding-top: 0.33em; }
|
||||
#copyright { text-align: center; color: #AAA;
|
||||
font-size: 65%; }
|
|
@ -1,3 +0,0 @@
|
|||
gcc -c simple-error-handler.c
|
||||
gcc -L /usr/X11R6/lib -shared -o simple-error-handler.so \
|
||||
simple-error-handler.o -lX11
|
|
@ -1,6 +0,0 @@
|
|||
This is the infix minilanguage created by Daniel Ehrenberg, allowing you to do infix math in Factor. The syntax is simple: all infix are right-associative and parentheses may be used. There are also unary operators and operators which take arguments in square brackets seperated by semicolons. Infix operators are the ones that are made of non-alphabetic characters. To make a word that uses infix, the syntax is MATH: functionname[firstarg;secondarg;etc]=value ; Args are one or more variables that you use in the expression. Their values come from the stack. Variables are effectively substituted in to the expression. Any alphabetic string may be used as a variable. To make a new operator, just update the functions hashtable in the infix vocabulary. For more information, see the code or contact the author of this program. To close, here's an implementation of the quadratic formula using infix math. This is included in the module.
|
||||
|
||||
MATH: quadratic[a;b;c] =
|
||||
plusmin[(-b)/2*a;(sqrt(b^2)-4*a*c)/2*a] ;
|
||||
|
||||
If you find any bugs in this or have any questions, please contact me at microdan @ gmail . com, ask LittleDan@irc.freenode.net, or ask irc.freenode.net/#concatenative
|
|
@ -1,361 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Lazy Evaluation</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Lazy Evaluation</h1>
|
||||
<p>The 'lazy' vocabulary adds lazy lists to Factor. This provides the
|
||||
ability to describe infinite structures, and to delay execution of
|
||||
expressions until they are actually used.</p>
|
||||
<p>Lazy lists, like normal lists, are composed of a head and tail. In
|
||||
a lazy list the head and tail are something called a 'promise'.
|
||||
To convert a
|
||||
'promise' into its actual value a word called 'force' is used. To
|
||||
convert a value into a 'promise' the word to use is 'delay'.</p>
|
||||
<table border="1">
|
||||
<tr><td><a href="#delay">delay</a></td></tr>
|
||||
<tr><td><a href="#force">force</a></td></tr>
|
||||
</table>
|
||||
|
||||
<p>Many of the lazy list words are named similar to the standard list
|
||||
words but with an 'l' suffixed to it. Here are the commonly used
|
||||
words and their equivalent list operation:</p>
|
||||
<table border="1">
|
||||
<tr><th>Lazy List</th><th>Normal List</th></tr>
|
||||
<tr><td><a href="#lnil">lnil</a></td><td>[ ]</td></tr>
|
||||
<tr><td><a href="#lnilp">lnil?</a></td><td>Test for nil value</td></tr>
|
||||
<tr><td><a href="#lcons">lcons</a></td><td>cons</td></tr>
|
||||
<tr><td><a href="#lunit">lunit</a></td><td>unit</td></tr>
|
||||
<tr><td><a href="#lcar">lcar</a></td><td>car</td></tr>
|
||||
<tr><td><a href="#lcdr">lcdr</a></td><td>cdr</td></tr>
|
||||
<tr><td><a href="#lnth">lnth</a></td><td>nth</td></tr>
|
||||
<tr><td><a href="#luncons">luncons</a></td><td>uncons</td></tr>
|
||||
<tr><td><a href="#lmap">lmap</a></td><td>map</td></tr>
|
||||
<tr><td><a href="#lsubset">lsubset</a></td><td>subset</td></tr>
|
||||
<tr><td><a href="#leach">leach</a></td><td>each</td></tr>
|
||||
<tr><td><a href="#lappend">lappend</a></td><td>append</td></tr>
|
||||
</table>
|
||||
<p>A few additional words specific to lazy lists are:</p>
|
||||
<table border="1">
|
||||
<tr><td><a href="#ltake">ltake</a></td><td>Returns a normal list containing a specified
|
||||
number of items from the lazy list.</td></tr>
|
||||
<tr><td><a href="#lappendstar">lappend*</a></td><td>Given a lazy list of lazy lists,
|
||||
concatenate them together in a lazy manner, returning a single lazy
|
||||
list.</td></tr>
|
||||
<tr><td><a href="#list>llist">list>llist</a></td><td>Given a normal list, return a lazy list
|
||||
that contains the same elements as the normal list.</td></tr>
|
||||
</table>
|
||||
<h2>Reference</h2>
|
||||
<!-- delay description -->
|
||||
<a name="delay">
|
||||
<h3>delay ( quot -- <promise> )</h3>
|
||||
<p>'delay' is used to convert a value or expression into a promise.
|
||||
The word 'force' is used to convert that promise back to its
|
||||
value, or to force evaluation of the expression to return a value.
|
||||
</p>
|
||||
<p>The value on the stack that 'delay' expects must be quoted. This is
|
||||
a requirement to prevent it from being evaluated.
|
||||
</p>
|
||||
<pre class="code">
|
||||
( 1 ) [ 42 ] <a href="#delay">delay</a> dup .
|
||||
=> << promise [ ] [ 42 ] [ ] [ ] >>
|
||||
( 2 ) <a href="#force">force</a> .
|
||||
=> 42
|
||||
</pre>
|
||||
|
||||
<!-- force description -->
|
||||
<a name="force">
|
||||
<h3>force ( <promise> -- value )</h3>
|
||||
<p>'force' will evaluate a promises original expression
|
||||
and leave the value of that expression on the stack.
|
||||
</p>
|
||||
<p>A promise can be forced multiple times but the expression
|
||||
is only evaluated once. Future calls of 'force' on the promise
|
||||
will returned the cached value of the original force. If the
|
||||
expression contains side effects, such as i/o, then that i/o
|
||||
will only occur on the first 'force'. See below for an example
|
||||
(steps 3-5).
|
||||
</p>
|
||||
<p>If a promise is itself delayed, a force will evaluate all promises
|
||||
until a value is returned. Due to this behaviour it is generally not
|
||||
possible to delay a promise. The example below shows what happens
|
||||
in this case.
|
||||
</p>
|
||||
<pre class="code">
|
||||
( 1 ) [ 42 ] <a href="#delay">delay</a> dup .
|
||||
=> << promise [ ] [ 42 ] [ ] [ ] >>
|
||||
( 2 ) <a href="#force">force</a> .
|
||||
=> 42
|
||||
|
||||
#! Multiple forces on a promise returns cached value
|
||||
( 3 ) [ "hello" print 42 ] <a href="#delay">delay</a> dup .
|
||||
=> << promise [ ] [ "hello" print 42 ] [ ] [ ] >>
|
||||
( 4 ) dup <a href="#force">force</a> .
|
||||
=> hello
|
||||
42
|
||||
( 5 ) <a href="#force">force</a> .
|
||||
=> 42
|
||||
|
||||
#! Forcing a delayed promise cascades up to return
|
||||
#! original value, rather than the promise.
|
||||
( 6 ) [ [ 42 ] <a href="#delay">delay</a> ] <a href="#delay">delay</a> dup .
|
||||
=> << promise [ ] [ [ 42 ] delay ] [ ] [ ] >>
|
||||
( 7 ) <a href="#force">force</a> .
|
||||
=> 42
|
||||
</pre>
|
||||
|
||||
<!-- lnil description -->
|
||||
<a name="lnil">
|
||||
<h3>lnil ( -- lcons )</h3>
|
||||
<p>Returns a value representing the empty lazy list.</p>
|
||||
<pre class="code">
|
||||
( 1 ) <a href="#lnil">lnil</a> .
|
||||
=> << promise [ ] [ [ ] ] t [ ] >>
|
||||
</pre>
|
||||
|
||||
<!-- lnil description -->
|
||||
<a name="lnilp">
|
||||
<h3>lnil? ( lcons -- bool )</h3>
|
||||
<p>Returns true if the given lazy cons is the value representing
|
||||
the empty lazy list.</p>
|
||||
<pre class="code">
|
||||
( 1 ) <a href="#lnil">lnil</a> <a href="#lnilp">lnil?</a> .
|
||||
=> t
|
||||
( 2 ) [ 1 ] <a href="#list2llist">list>llist</a> dup <a href="#lnilp">lnil?</a> .
|
||||
=> [ ]
|
||||
( 3 ) <a href="#lcdr">lcdr</a> <a href="#lnilp">lnil?</a> .
|
||||
=> t
|
||||
</pre>
|
||||
|
||||
<!-- lcons description -->
|
||||
<a name="lcons">
|
||||
<h3>lcons ( car-promise cdr-promise -- lcons )</h3>
|
||||
<p>Provides the same effect as 'cons' does for normal lists.
|
||||
Both values provided must be promises (ie. expressions that have
|
||||
had <a href="#delay">delay</a> called on them).
|
||||
</p>
|
||||
<p>As the car and cdr passed on the stack are promises, they are not
|
||||
evaluated until <a href="#lcar">lcar</a> or <a href="#lcdr">lcdr</a>
|
||||
are called on the lazy cons.</p>
|
||||
<pre class="code">
|
||||
( 1 ) [ "car" ] <a href="#delay">delay</a> [ "cdr" ] <a href="#delay">delay</a> <a href="#lcons">lcons</a> dup .
|
||||
=> << promise ... >>
|
||||
( 2 ) dup <a href="#lcar">lcar</a> .
|
||||
=> "car"
|
||||
( 3 ) dup <a href="#lcdr">lcdr</a> .
|
||||
=> "cdr"
|
||||
</pre>
|
||||
|
||||
<!-- lunit description -->
|
||||
<a name="lunit">
|
||||
<h3>lunit ( value-promise -- llist )</h3>
|
||||
<p>Provides the same effect as 'unit' does for normal lists. It
|
||||
creates a lazy list where the first element is the value given.</p>
|
||||
<p>Like <a href="#lcons">lcons</a>, the value on the stack must be
|
||||
a promise and is not evaluated until the <a href="#lcar">lcar</a>
|
||||
of the list is requested.</a>
|
||||
<pre class="code">
|
||||
( 1 ) [ 42 ] <a href="#delay">delay</a> <a href="#lunit">lunit</a> dup .
|
||||
=> << promise ... >>
|
||||
( 2 ) dup <a href="#lcar">lcar</a> .
|
||||
=> 42
|
||||
( 3 ) dup <a href="#lcdr">lcdr</a> <a href="#lnilp">lnil?</a> .
|
||||
=> t
|
||||
( 4 ) [ . ] <a href="#leach">leach</a>
|
||||
=> 42
|
||||
</pre>
|
||||
|
||||
<!-- lcar description -->
|
||||
<a name="lcar">
|
||||
<h3>lcar ( lcons -- value )</h3>
|
||||
<p>Provides the same effect as 'car' does for normal lists. It
|
||||
returns the first element in a lazy cons cell. This will force
|
||||
the evaluation of that element.</p>
|
||||
<pre class="code">
|
||||
( 1 ) [ 42 ] <a href="#delay">delay</a> <a href="#lunit">lunit</a> dup .
|
||||
=> << promise ... >>
|
||||
( 2 ) <a href="#lcar">lcar</a> .
|
||||
=> 42
|
||||
</pre>
|
||||
|
||||
<!-- lcdr description -->
|
||||
<a name="lcdr">
|
||||
<h3>lcdr ( lcons -- value )</h3>
|
||||
<p>Provides the same effect as 'cdr' does for normal lists. It
|
||||
returns the second element in a lazy cons cell and forces it. This
|
||||
causes that element to be evaluated immediately.</p>
|
||||
<pre class="code">
|
||||
( 1 ) [ 1 ] <a href="#delay">delay</a> [ 5 6 + ] <a href="#delay">delay</a> <a href="#lcons">lcons</a> dup .
|
||||
=> << promise ... >>
|
||||
( 2 ) <a href="#lcdr">lcdr</a> .
|
||||
=> 11
|
||||
</pre>
|
||||
|
||||
<pre class="code">
|
||||
( 1 ) 5 <a href="#lfrom">lfrom</a> dup .
|
||||
=> << promise ... >>
|
||||
( 2 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
|
||||
=> 6
|
||||
( 3 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
|
||||
=> 7
|
||||
( 4 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
|
||||
=> 8
|
||||
</pre>
|
||||
|
||||
<!-- lnth description -->
|
||||
<a name="lnth">
|
||||
<h3>lnth ( n llist -- value )</h3>
|
||||
<p>Provides the same effect as 'nth' does for normal lists. It
|
||||
returns the nth value in the lazy list. It causes all the values up to
|
||||
'n' to be evaluated.</p>
|
||||
<pre class="code">
|
||||
( 1 ) 1 <a href="#lfrom">lfrom</a> dup .
|
||||
=> << promise ... >>
|
||||
( 2 ) 5 swap <a href="#lnth">lnth</a> .
|
||||
=> 6
|
||||
</pre>
|
||||
|
||||
<!-- luncons description -->
|
||||
<a name="luncons">
|
||||
<h3>luncons ( lcons -- car cdr )</h3>
|
||||
<p>Provides the same effect as 'uncons' does for normal lists. It
|
||||
returns the car and cdr of the lazy list.</p>
|
||||
<pre class="code">
|
||||
( 1 ) [ 5 ] <a href="#delay">delay</a> [ 6 ] <a href="#delay">delay</a> <a href="#lcons">lcons</a> dup .
|
||||
=> << promise ... >>
|
||||
( 2 ) <a href="#luncons">luncons</a> . .
|
||||
=> 6
|
||||
5
|
||||
</pre>
|
||||
|
||||
<!-- lmap description -->
|
||||
<a name="lmap">
|
||||
<h3>lmap ( llist quot -- llist )</h3>
|
||||
<p>Lazily maps over a lazy list applying the quotation to each element.
|
||||
A new lazy list is returned which contains the results of the
|
||||
quotation.</p>
|
||||
<p>When intially called nothing in the original lazy list is
|
||||
evaluated. Only when <a href="#lcar">lcar</a> is called will the item
|
||||
in the list be evaluated and applied to the quotation. Ditto with <a
|
||||
href="#lcdr">lcdr</a>, thus allowing infinite lists to be mapped over.</p>
|
||||
<pre class="code">
|
||||
( 1 ) 1 <a href="#lfrom">lfrom</a>
|
||||
=> < infinite list of incrementing numbers >
|
||||
( 2 ) [ 2 * ] <a href="#lmap">lmap</a>
|
||||
=> < infinite list of numbers incrementing by 2 >
|
||||
( 3 ) 5 swap <a href="#ltake">ltake</a> <a href="#llist2list">llist>list</a> .
|
||||
=> [ 2 4 6 8 10 ]
|
||||
</pre>
|
||||
|
||||
<!-- lsubset description -->
|
||||
<a name="lsubset">
|
||||
<h3>lsubset ( llist pred -- llist )</h3>
|
||||
<p>Provides the same effect as 'subset' does for normal lists. It
|
||||
lazily iterates over a lazy list applying the predicate quotation to each
|
||||
element. If that quotation returns true, the element will be included
|
||||
in the resulting lazy list. If it is false, the element will be skipped.
|
||||
A new lazy list is returned which contains all elements where the
|
||||
predicate returned true.</p>
|
||||
<p>Like <a href="#lmap">lmap</a>, when initially called no evaluation
|
||||
will occur. A lazy list is returned that when values are retrieved
|
||||
from in then items are evaluated and checked against the predicate.</p>
|
||||
<pre class="code">
|
||||
( 1 ) 1 <a href="#lfrom">lfrom</a>
|
||||
=> < infinite list of incrementing numbers >
|
||||
( 2 ) [ <a href="#primep">prime?</a> ] <a href="#lsubset">lsubset</a>
|
||||
=> < infinite list of prime numbers >
|
||||
( 3 ) 5 swap <a href="#ltake">ltake</a> <a href="#llist2list">llist>list</a> .
|
||||
=> [ 2 3 5 7 11 ]
|
||||
</pre>
|
||||
|
||||
<!-- leach description -->
|
||||
<a name="leach">
|
||||
<h3>leach ( llist quot -- )</h3>
|
||||
<p>Provides the same effect as 'each' does for normal lists. It
|
||||
lazily iterates over a lazy list applying the quotation to each
|
||||
element. If this operation is applied to an infinite list it will
|
||||
never return unless the quotation escapes out by calling a continuation.</p>
|
||||
<pre class="code">
|
||||
( 1 ) 1 <a href="#lfrom">lfrom</a>
|
||||
=> < infinite list of incrementing numbers >
|
||||
( 2 ) [ 2 mod 1 = ] <a href="#lsubset">lsubset</a>
|
||||
=> < infinite list of odd numbers >
|
||||
( 3 ) [ . ] <a href="#leach">leach</a>
|
||||
=> 1
|
||||
3
|
||||
5
|
||||
7
|
||||
... for ever ...
|
||||
</pre>
|
||||
|
||||
<!-- ltake description -->
|
||||
<a name="ltake">
|
||||
<h3>ltake ( n llist -- llist )</h3>
|
||||
<p>Iterates over the lazy list 'n' times, appending each element to a
|
||||
lazy list. This provides a convenient way of getting elements out of
|
||||
an infinite lazy list.</p>
|
||||
<pre class="code">
|
||||
( 1 ) : ones [ 1 ] delay [ ones ] delay <a href="#lcons">lcons</a> ;
|
||||
( 2 ) 5 ones <a href="#ltake">ltake</a> <a href="#llist2list">llist>list</a> .
|
||||
=> [ 1 1 1 1 1 ]
|
||||
</pre>
|
||||
|
||||
<!-- lappend description -->
|
||||
<a name="lappend">
|
||||
<h3>lappend ( llist1 llist2 -- llist )</h3>
|
||||
<p>Lazily appends two lists together. The actual appending is done
|
||||
lazily on iteration rather than immediately so it works very fast no
|
||||
matter how large the list.</p>
|
||||
<pre class="code">
|
||||
( 1 ) [ 1 2 3 ] <a href="#list2llist">list>llist</a> [ 4 5 6 ] <a href="#list2llist">list>llist</a> <a href="#lappend">lappend</a>
|
||||
( 2 ) [ . ] <a href="#leach">leach</a>
|
||||
=> 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
</pre>
|
||||
|
||||
<!-- lappend* description -->
|
||||
<a name="lappendstar">
|
||||
<h3>lappend* ( llists -- llist )</h3>
|
||||
<p>Given a lazy list of lazy lists, concatenate them together in a
|
||||
lazy fashion. The actual appending is done lazily on iteration rather
|
||||
than immediately so it works very fast no matter how large the lists.</p>
|
||||
<pre class="code">
|
||||
( 1 ) [ 1 2 3 ] <a href="#list2>llist">list>llist</a>
|
||||
( 2 ) [ 4 5 6 ] <a href="#list2llist">list>llist</a>
|
||||
( 3 ) [ 7 8 9 ] <a href="#list2llist">list>llist</a>
|
||||
( 4 ) 3list <a href="#list2llist">list>llist</a> <a href="#lappendstar">lappend*</a>
|
||||
( 5 ) [ . ] <a href="#leach">leach</a>
|
||||
=> 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
</pre>
|
||||
|
||||
<!-- list>llist description -->
|
||||
<a name="list2llist">
|
||||
<h3>list>llist ( list -- llist )</h3>
|
||||
<p>Converts a normal list into a lazy list. This is done lazily so the
|
||||
initial list is not iterated through immediately.</p>
|
||||
<pre class="code">
|
||||
( 1 ) [ 1 2 3 ] <a href="#list2llist">list>llist</a>
|
||||
( 2 ) [ . ] <a href="#leach">leach</a>
|
||||
=> 1
|
||||
2
|
||||
3
|
||||
</pre>
|
||||
|
||||
<p class="footer">
|
||||
News and updates to this software can be obtained from the authors
|
||||
weblog: <a href="http://radio.weblogs.com/0102385">Chris Double</a>.</p>
|
||||
<p id="copyright">Copyright (c) 2004, Chris Double. All Rights Reserved.</p>
|
||||
</body> </html>
|
|
@ -1,341 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Parser Combinators</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Parsers</h1>
|
||||
<p class="note">The parser combinator library described here is based
|
||||
on a library written for the Clean pure functional programming language and
|
||||
described in chapter 5 of the 'Clean Book' (<a
|
||||
href="ftp://ftp.cs.kun.nl/pub/Clean/papers/cleanbook/II.05.ParserCombinators.pdf">PDF
|
||||
available here</a>). Based on the description
|
||||
in that chapter I developed a version for Factor, a concatenative
|
||||
language.</p>
|
||||
<p>A parser is a word or quotation that, when called, processes
|
||||
an input string on the stack, performs some parsing operation on
|
||||
it, and returns a result indicating the success of the parsing
|
||||
operation.</p>
|
||||
<p>The result returned by a parser is known as a 'list of
|
||||
successes'. It is a lazy list of standard Factor cons cells. Each cons
|
||||
cell is a result of a parse. The car of the cell is the remaining
|
||||
input left to be parsed and the cdr of the cell is the result of the
|
||||
parsing operation.</p>
|
||||
<p>A lazy list is used for the result as a parse operation can potentially
|
||||
return many successful results. For example, a parser that parses one
|
||||
or more digits will return more than one result for the input "123". A
|
||||
successful parse could be "1", "12" or "123".</p>
|
||||
<p>The list is lazy so if only one parse result is required the
|
||||
remaining results won't actually be processed if they are not
|
||||
requested. This improves efficiency.</p>
|
||||
<p>The cdr of the result pair can be any value that the parser wishes
|
||||
to return. It could be the successful portion of the input string
|
||||
parsed, an abstract syntax tree representing the parsed input, or even
|
||||
a quotation that should get called for later processing.</p>
|
||||
<p>A Parser Combinator is a word that takes one or more parsers and
|
||||
returns a parser that when called uses the original parsers in some
|
||||
manner.</p>
|
||||
<h1>Example Parsers</h1>
|
||||
<p>The following are some very simple parsers that demonstrate how
|
||||
general parsers work and the 'list of sucesses' that are returned as a
|
||||
result.</p>
|
||||
<pre class="code">
|
||||
(1) : char-a ( inp -- result )
|
||||
0 over string-nth CHAR: a = [
|
||||
1 swap string-tail CHAR: a cons unit delay lunit
|
||||
] [
|
||||
drop lnil
|
||||
] ifte ;
|
||||
(2) "atest" char-a [ [ . ] leach ] when*
|
||||
=> [[ "test" 97 ]]
|
||||
(3) "test" char-a [ [ . ] leach ] when*
|
||||
=>
|
||||
</pre>
|
||||
<p>'char-a' is a parser that only accepts the character 'a' in the
|
||||
input string. When passed an input string with a string with a leading
|
||||
'a' then the 'list of successes' has 1 result value. The cdr of that
|
||||
result value is the character 'a' successfully parsed, and the car is
|
||||
the remaining input string. On failure of the parse an empty list is
|
||||
returned.</p>
|
||||
<p>The parser combinator library provides a combinator, <&>, that takes
|
||||
two parsers off the stack and returns a parser that calls the original
|
||||
two in sequence. An example of use would be calling 'char-a' twice,
|
||||
which would then result in an input string expected with two 'a'
|
||||
characters leading:</p>
|
||||
<pre class="code">
|
||||
(1) "aatest" [ char-a ] [ char-a ] <&> call
|
||||
=> < list of successes >
|
||||
(2) [ . ] leach
|
||||
=> [[ "test" [[ 97 97 ]] ]]
|
||||
</pre>
|
||||
<h2>Tokens</h2>
|
||||
<p>Creating parsers for specfic characters and tokens can be a chore
|
||||
so there is a word that, given a string token on the stack, returns
|
||||
a parser that parses that particular token:</p>
|
||||
<pre class="code">
|
||||
(1) "begin" token
|
||||
=> < a parser that parses the token "begin" >
|
||||
(2) dup "this should fail" swap call lnil? .
|
||||
=> t
|
||||
(3) "begin a successfull parse" swap call
|
||||
=> < lazy list >
|
||||
(4) [ . ] leach
|
||||
=> [[ " a successfull parse" "begin" ]]
|
||||
</pre>
|
||||
<h2>Predicate matching</h2>
|
||||
<p>The word 'satisfy' takes a quotation from the top of the stack and
|
||||
returns a parser than when called will call the quotation with the
|
||||
first item in the input string on the stack. If the quotation returns
|
||||
true then the parse is successful, otherwise it fails:</p>
|
||||
<pre class="code">
|
||||
(1) : digit-parser ( -- parser )
|
||||
[ digit? ] satisfy ;
|
||||
(2) "5" digit-parser call [ . ] leach
|
||||
=> [[ "" 53 ]]
|
||||
(3) "a" digit-parser call lnil? .
|
||||
=> t
|
||||
</pre>
|
||||
<p>Note that 'digit-parser' returns a parser, it is not the parser
|
||||
itself. It is really a parser generating word like 'token'. Whereas
|
||||
our 'char-a' word defined originally was a parser itself.</p>
|
||||
<h2>Zero or more matches</h2>
|
||||
<p>Now that we can parse single digits it would be nice to easily
|
||||
parse a string of them. The '<*>' parser combinator word will do
|
||||
this. It accepts a parser on the top of the stack and produces a
|
||||
parser that parses zero or more of the constructs that the original
|
||||
parser parsed. The result of the '<*>' generated parser will be a list
|
||||
of the successful results returned by the original parser.</p>
|
||||
<pre class="code">
|
||||
(1) digit-parser <*>
|
||||
=> < parser >
|
||||
(2) "123" swap call
|
||||
=> < lazy list >
|
||||
(3) [ . ] leach
|
||||
=> [ "" [ 49 50 51 ] ]
|
||||
[ "3" [ 49 50 ] ]
|
||||
[ "23" [ 49 ] ]
|
||||
[ "123" ]
|
||||
</pre>
|
||||
<p>In this case there are multiple successful parses. This is because
|
||||
the occurrence of zero or more digits happens more than once. There is
|
||||
also the 'f' case where zero digits is parsed. If only the 'longest
|
||||
match' is required then the lcar of the lazy list can be used and the
|
||||
remaining parse results are never produced.</p>
|
||||
<h2>Manipulating parse trees</h2>
|
||||
<p>The result of the previous parse was the list of characters
|
||||
parsed. Sometimes you want this to be something else, like an abstract
|
||||
syntax tree, or some calculation. For the digit case we may want the
|
||||
actual integer number.</p>
|
||||
<p>For this we can use the '<@' parser
|
||||
combinator. This combinator takes a parser and a quotation on the
|
||||
stack and returns a new parser. When the new parser is called it will
|
||||
call the original parser to produce the results, then it will call the
|
||||
quotation on each successfull result, and the result of that quotation
|
||||
will be the result of the parse:</p>
|
||||
<pre class="code">
|
||||
(1) : digit-parser2 ( -- parser )
|
||||
[ digit? ] satisfy [ digit> ] <@ ;
|
||||
(2) "5" digit-parser2 call [ . ] leach
|
||||
=> [[ "" 5 ]]
|
||||
</pre>
|
||||
<p>Notice that now the result is the actual integer '5' rather than
|
||||
character code '53'.</p>
|
||||
<pre class="code">
|
||||
(1) : digit-list>number ( list -- number )
|
||||
#! Converts a list of digits to a number
|
||||
[ >digit ] map >string dup empty? [
|
||||
drop 0
|
||||
] [
|
||||
str>number
|
||||
] ifte ;
|
||||
(2) : natural-parser ( -- parser )
|
||||
digit-parser2 <*> [ car digit-list>number unit ] <@ ;
|
||||
(3) "123" natural-parser call
|
||||
=> < lazy list >
|
||||
(4) [ . ] leach
|
||||
=> [ "" 123 ]
|
||||
[ "3" 12 ]
|
||||
[ "23" 1 ]
|
||||
[ "123" 0 ]
|
||||
[ [ 123 ] | "" ]
|
||||
</pre>
|
||||
<p>The number parsed is the actual integer number due to the operation
|
||||
of the '<@' word. This allows parsers to not only parse the input
|
||||
string but perform operations and transformations on the syntax tree
|
||||
returned.</p>
|
||||
<p>A useful debugging method to work out what to use in the quotation
|
||||
passed to <@ is to write an initial version of the parser that just
|
||||
displays the topmost item on the stack:</p>
|
||||
<pre class="code">
|
||||
(1) : natural-parser-debug ( -- parser )
|
||||
digit-parser2 <*> [ "debug: " write dup . ] <@ ;
|
||||
(3) "123" natural-parser-debug call lcar .
|
||||
=> debug: [ [ 1 2 3 ] ]
|
||||
[ "" [ 1 2 3 ] ]
|
||||
</pre>
|
||||
<p>From the debug output we can see how to manipulate the result to
|
||||
get what we want. In this case it's the quotation in the previous example.</p>
|
||||
|
||||
<h2>Sequential combinator</h2>
|
||||
<p>To create a full grammar we need a parser combinator that does
|
||||
sequential compositions. That is, given two parsers, the sequential
|
||||
combinator will first run the first parser, and then run the second on
|
||||
the remaining text to be parsed. As the first parser returns a lazy
|
||||
list, the second parser will be run on each item of the lazy list. Of
|
||||
course this is done lazily so it only ends up being done when those
|
||||
list items are requested. The sequential combinator word is <&>.</p>
|
||||
<pre class="code">
|
||||
( 1 ) "number:" token
|
||||
=> < parser that parses the text 'number:' >
|
||||
( 2 ) natural-parser
|
||||
=> < parser that parses natural numbers >
|
||||
( 3 ) <&>
|
||||
=> < parser that parses 'number:' followed by a natural >
|
||||
( 4 ) "number:100" swap call
|
||||
=> < list of successes >
|
||||
( 5 ) [ . ] leach
|
||||
=> [ "" "number:" 100 ]
|
||||
[ "0" "number:" 10 ]
|
||||
[ "00" "number:" 1 ]
|
||||
[ "100" "number:" 0 ]
|
||||
</pre>
|
||||
<p>In this example we might prefer not to have the parse result
|
||||
contain the token, we want just the number. Two alternatives to <&>
|
||||
provide the ability to select which result to use from the two
|
||||
parsers. These operators are <& and &>. The < or > points
|
||||
in the direction of which parser to retain the results from. So our
|
||||
example above could be:</p>
|
||||
<pre class="code">
|
||||
( 1 ) "number:" token
|
||||
=> < parser that parses the text 'number:' >
|
||||
( 2 ) natural-parser
|
||||
=> < parser that parses natural numbers >
|
||||
( 3 ) &>
|
||||
=> < parser that parses 'number:' followed by a natural >
|
||||
( 4 ) "number:100" swap call
|
||||
=> < list of successes >
|
||||
( 5 ) [ . ] leach
|
||||
=> [ "" 100 ]
|
||||
[ "0" 10 ]
|
||||
[ "00" 1 ]
|
||||
[ "100" 0 ]
|
||||
</pre>
|
||||
<p>Notice how the parse result only contains the number due to &>
|
||||
being used to retain the result of the second parser.</p>
|
||||
|
||||
<h2>Choice combinator</h2>
|
||||
<p>As well as a sequential combinator we need an alternative
|
||||
combinator. The word for this is <|>. It takes two parsers from the
|
||||
stack and returns a parser that will first try the first parser. If it
|
||||
succeeds then the result for that is returned. If it fails then the
|
||||
second parser is tried and its result returned.</p>
|
||||
<pre class="code">
|
||||
( 1 ) "one" token
|
||||
=> < parser that parses the text 'one' >
|
||||
( 2 ) "two" token
|
||||
=> < parser that parses the text 'two' >
|
||||
( 3 ) <|>
|
||||
=> < parser that parses 'one' or 'two' >
|
||||
( 4 ) "one" over call [ . ] leach
|
||||
=> [[ "" "one" ]]
|
||||
( 5 ) "two" swap call [ . ] leach
|
||||
=> [[ "" "two" ]]
|
||||
</pre>
|
||||
|
||||
<h2>Option combinator</h2>
|
||||
<p>The option combinator, <?> allows adding optional elements to
|
||||
a parser. It takes one parser off the stack and if the parse succeeds
|
||||
add it to the result tree, otherwise it will ignore it and
|
||||
continue. The example below extends our natural-parser to parse
|
||||
integers with an optional leading minus sign.</p>
|
||||
<pre class="code">
|
||||
( 1 ) : integer-parser
|
||||
"-" token <?> natural-parser <&> ;
|
||||
( 2 ) "200" integer-parser call [ . ] leach
|
||||
=> [ "" [ ] 200 ]
|
||||
[ "0" [ ] 20 ]
|
||||
[ "00" [ ] 2 ]
|
||||
[ "200" [ ] 0 ]
|
||||
( 3 ) "-200" integer-parser call [ . ] leach
|
||||
=> [ "" [ "-" ] 200 ]
|
||||
[ "0" [ "-" ] 20 ]
|
||||
[ "00" [ "-" ] 2 ]
|
||||
[ "200" [ "-" ] 0 ]
|
||||
[ "-200" [ ] 0 ]
|
||||
( 4 ) : integer-parser2
|
||||
integer-parser [ uncons swap [ car -1 * ] when ] <@ ;
|
||||
( 5 ) "200" integer-parser2 call [ . ] leach
|
||||
=> [ "" 200 ]
|
||||
[ "0" 20 ]
|
||||
[ "00" 2 ]
|
||||
[ "200" 0 ]
|
||||
( 6 ) "-200" integer-parser2 call [ . ] leach
|
||||
=> [ "" -200 ]
|
||||
[ "0" -20 ]
|
||||
[ "00" -2 ]
|
||||
[ "200" 0 ]
|
||||
[ "-200" 0 ]
|
||||
|
||||
</pre>
|
||||
|
||||
<h2>Skipping Whitespace</h2>
|
||||
<p>A parser transformer exists, the word 'sp', that takes an existing
|
||||
parser and returns a new one that will first skip any whitespace
|
||||
before calling the original parser. This makes it easy to write
|
||||
grammers that avoid whitespace without having to explicitly code it
|
||||
into the grammar.</p>
|
||||
<pre class="code">
|
||||
( 1 ) " 123" natural-parser call [ . ] leach
|
||||
=> [ " 123" 0 ]
|
||||
( 2 ) " 123" natural-parser sp call [ . ] leach
|
||||
=> [ "" 123 ]
|
||||
[ "3" 12 ]
|
||||
[ "23" 1 ]
|
||||
[ "123" 0 ]
|
||||
</pre>
|
||||
<h2>Eval grammar example</h2>
|
||||
<p>This example presents a simple grammar that will parse a number
|
||||
followed by an operator and another number. A factor expression that
|
||||
computes the entered value will be executed.</p>
|
||||
<pre class="code">
|
||||
( 1 ) natural-parser
|
||||
=> < a parser for natural numbers >
|
||||
( 2 ) "/" token "*" token "+" token "-" token <|> <|> <|>
|
||||
=> < a parser for the operator >
|
||||
( 3 ) sp [ "\\ " swap cat2 eval unit ] <@
|
||||
=> < operator parser that skips whitespace and converts to a
|
||||
factor expression >
|
||||
( 4 ) natural-parser sp
|
||||
=> < a whitespace skipping natural parser >
|
||||
( 5 ) <&> <&> [ uncons uncons swap append append call ] <@
|
||||
=> < a parser that parsers the expression, converts it to
|
||||
factor, calls it and puts the result in the parse tree >
|
||||
( 6 ) "123 + 456" over call lcar .
|
||||
=> [[ "" 579 ]]
|
||||
( 7 ) "300-100" over call lcar .
|
||||
=> [[ "" 200 ]]
|
||||
( 8 ) "200/2" over call lcar .
|
||||
=> [[ "" 100 ]]
|
||||
</pre>
|
||||
<p>It looks complicated when expanded as above but the entire parser,
|
||||
factored a little, looks quite readable:</p>
|
||||
<pre class="code">
|
||||
( 1 ) : operator ( -- parser )
|
||||
"/" token
|
||||
"*" token <|>
|
||||
"+" token <|>
|
||||
"-" token <|>
|
||||
[ "\\ " swap cat2 eval unit ] <@ ;
|
||||
( 2 ) : expression ( -- parser )
|
||||
natural-parser
|
||||
operator sp <&>
|
||||
natural-parser sp <&>
|
||||
[ uncons swap uncons -rot append append reverse call ] <@ ;
|
||||
( 3 ) "40+2" expression call lcar .
|
||||
=> [[ "" 42 ]]
|
||||
</pre>
|
||||
<p class="footer">
|
||||
News and updates to this software can be obtained from the authors
|
||||
weblog: <a href="http://radio.weblogs.com/0102385">Chris Double</a>.</p>
|
||||
<p id="copyright">Copyright (c) 2004, Chris Double. All Rights Reserved.</p>
|
||||
</body> </html>
|
|
@ -1,28 +0,0 @@
|
|||
body { background: white; color: black; }
|
||||
p { margin-left: 10%; margin-right: 10%;
|
||||
font: normal 100% Verdana, Arial, Helvetica; }
|
||||
td { margin-left: 10%; margin-right: 10%;
|
||||
font: normal 100% Verdana, Arial, Helvetica; }
|
||||
table { margin-left: 10%; margin-right: 10%; }
|
||||
ul { margin-left: 10%; margin-right: 10%;
|
||||
font: normal 100% Verdana, Arial, Helvetica; }
|
||||
ol { margin-left: 10%; margin-right: 10%;
|
||||
font: normal 100% Verdana, Arial, Helvetica; }
|
||||
h1 { text-align: center; margin-bottom: 0; margin-top: 1em; }
|
||||
h2 { margin: 0 5% 0 7.5%; font-size: 120%; font-style: italic; }
|
||||
h3 { border: 2px solid blue; border-width: 2px 0.5em 2px 0.5em;
|
||||
padding: 0.2em 0.2em 0.2em 0.5em; background: #fafafa;
|
||||
margin-left: 10%; margin-right: 10%; margin-top: 2em;
|
||||
font-size: 100%; }
|
||||
.note { border: 2px solid blue; border-width: 2px 2px 2px 2em;
|
||||
padding: 0.5em 0.5em 0.5em 1em; background: #ffe; }
|
||||
.code { border: 1px solid black; border-width: 1px;
|
||||
padding: 0.5em; background: #ffe;
|
||||
margin-left: 10%; margin-right: 10%; }
|
||||
blockquote { margin-left: 25%; margin-right: 25%;
|
||||
font-style: italic; }
|
||||
.highlite { color: red; }
|
||||
.footer { margin-top: 2.5em; border-top: 1px solid gray; color:
|
||||
#AAA; font-size: 85%; padding-top: 0.33em; }
|
||||
#copyright { text-align: center; color: #AAA;
|
||||
font-size: 65%; }
|
|
@ -1,229 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Tuple Database Library</title>
|
||||
<style>
|
||||
body { background: white; color: black; }
|
||||
p { margin-left: 10%; margin-right: 10%;
|
||||
font: normal 100% Verdana, Arial, Helvetica; }
|
||||
td { margin-left: 10%; margin-right: 10%;
|
||||
font: normal 100% Verdana, Arial, Helvetica; }
|
||||
table { margin-left: 10%; margin-right: 10%; }
|
||||
ul { margin-left: 10%; margin-right: 10%;
|
||||
font: normal 100% Verdana, Arial, Helvetica; }
|
||||
ol { margin-left: 10%; margin-right: 10%;
|
||||
font: normal 100% Verdana, Arial, Helvetica; }
|
||||
h1 { text-align: center; margin-bottom: 0; margin-top: 1em; }
|
||||
h2 { margin: 0 5% 0 7.5%; font-size: 120%; font-style: italic; }
|
||||
h3 { border: 2px solid blue; border-width: 2px 0.5em 2px 0.5em;
|
||||
padding: 0.2em 0.2em 0.2em 0.5em; background: #fafafa;
|
||||
margin-left: 10%; margin-right: 10%; margin-top: 2em;
|
||||
font-size: 100%; }
|
||||
.note { border: 2px solid blue; border-width: 2px 2px 2px 2em;
|
||||
padding: 0.5em 0.5em 0.5em 1em; background: #ffe; }
|
||||
.code { border: 1px solid black; border-width: 1px;
|
||||
padding: 0.5em; background: #ffe;
|
||||
margin-left: 10%; margin-right: 10%; }
|
||||
blockquote { margin-left: 25%; margin-right: 25%;
|
||||
font-style: italic; }
|
||||
.highlite { color: red; }
|
||||
.footer { margin-top: 2.5em; border-top: 1px solid gray; color:
|
||||
#AAA; font-size: 85%; padding-top: 0.33em; }
|
||||
#copyright { text-align: center; color: #AAA;
|
||||
font-size: 65%; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Tuple Database Library</h1>
|
||||
<h1>Overview</h1>
|
||||
<p class="note">The version of sqlite supported by this library is
|
||||
version 3 or greater.</p>
|
||||
<p>This library allows storing Factor tuples in a sqlite database. It
|
||||
provides words to create, read update and delete these entries as well
|
||||
as simple searching.</p>
|
||||
<p>The library is in a very early state and is likely to change quite
|
||||
a bit in the near future. Its most notable omission is it cannot currently
|
||||
handle relationships between tuples. This feature is currently being
|
||||
worked on.</p>
|
||||
<h1>Loading</h1>
|
||||
<p>The Factor image must have been bootstrapped with the
|
||||
sqlite shared library name provided. This can be done with the
|
||||
following command:</p>
|
||||
<pre class="code">
|
||||
./f boot.image.le32 -libraries:sqlite:name=libsqlite3.so
|
||||
</pre>
|
||||
<p>The quickest way to get up and running with this library is to type the following into the listener:</p>
|
||||
<pre class="code">
|
||||
"/contrib/sqlite/load.factor" run-resource
|
||||
USE: sqlite
|
||||
USE: tuple-db
|
||||
</pre>
|
||||
<p>Some simple tests can be run to check that everything is working
|
||||
ok:</p>
|
||||
<pre class="code">
|
||||
"/contrib/sqlite/tuple-db-tests.factor" run-resource
|
||||
</pre>
|
||||
<h1>Basic Usage</h1>
|
||||
<p>This library can be used for storing simple Factor tuples in a
|
||||
sqlite database. In its current form the tuples must not contain
|
||||
references to other tuples and should not have a delegate set.</p>
|
||||
<p>This document will use the following tuple for demonstration
|
||||
purposes:</p>
|
||||
<pre class="code">
|
||||
TUPLE: person name surname phone ;
|
||||
</pre>
|
||||
<p>The sqlite database to store tuples must be created, or an existing
|
||||
one opened. This
|
||||
is done using the 'sqlite-open word. If the database does not exist
|
||||
then it is created. The examples in this document
|
||||
store the database pointer in a variable called 'db':</p>
|
||||
<pre class="code">
|
||||
SYMBOL: db
|
||||
"example.db" sqlite-open db set
|
||||
</pre>
|
||||
<h2>Tuple Mappings</h2>
|
||||
<p>Each tuple has a 'mapping' tuple associated with it. The 'mapping'
|
||||
stores information about what table the tuple will be stored in, the
|
||||
datatypes of the tuple slots, etc. A mapping must be created before a
|
||||
tuple can be stored in a database. A default mapping is easily created
|
||||
using the 'default-mapping' word. Given the tuple class, this will use
|
||||
reflection to get the slots of it, assume that all slots are of
|
||||
database type 'text', and store the tuple objects in a table with the
|
||||
same name as the tuple.</p>
|
||||
<p>The following shows how to create the default mapping for the
|
||||
'person' tuple, and how to register that mapping so the 'tuple-db'
|
||||
system can know how to handle 'person' instances:</p>
|
||||
<pre class="code">
|
||||
person default-mapping set-mapping
|
||||
</pre>
|
||||
<h2>Creating the table</h2>
|
||||
<p>The table used to store tuple instances may need to be
|
||||
created. This can be done manually using 'sqlite' or via the
|
||||
'create-tuple-table' word:</p>
|
||||
<pre class="code">
|
||||
<span class="highlite">! create-tuple-table ( db class -- )</span>
|
||||
db get person create-tuple-table
|
||||
</pre>
|
||||
<p>The SQL used to create the table is produced by the 'create-sql'
|
||||
word. This is a generic word dispatched on the mapping object, and
|
||||
could be specialised if needed. If you wish to see the SQL used to
|
||||
create the table, use the following code:</p>
|
||||
<pre class="code">
|
||||
<span class="highlite">! M: mapping create-sql ( mapping -- string )</span>
|
||||
person get-mapping create-sql .
|
||||
=> "create table person (name text,surname text,phone text);"
|
||||
</pre>
|
||||
<h2>Inserting instances</h2>
|
||||
<p>The 'insert-tuple' word will store instances of a tuple
|
||||
into the database table defined by its mapping object. It's as
|
||||
simple as:</p>
|
||||
<pre class="code">
|
||||
<span class="highlite">! insert-tuple ( db tuple -- )</span>
|
||||
db get "John" "Smith" "123-456-789" <person> insert-tuple
|
||||
</pre>
|
||||
<p>'insert-tuple' internally uses the 'insert-sql' word to produce
|
||||
the SQL used to store the tuple. Like 'create-sql', 'insert-sql' is
|
||||
a generic word specialized on the mapping object. You can call it
|
||||
directly to see what SQL is generated:</p>
|
||||
<pre class="code">
|
||||
<span class="highlite">! M: mapping insert-sql ( mapping -- string )</span>
|
||||
person get-mapping insert-sql .
|
||||
=> "insert into person values(:name,:surname,:phone);"
|
||||
</pre>
|
||||
<p>Notice that the SQL uses named parameters. This parameters are bound to the values stored in the tuple object when the SQL is compiled. This helps prevent SQL injection techniques.</p>
|
||||
<p>When the 'insert-sql' word is run, it adds a delegate to the tuple being stored. The delegate is of type 'persistent' and holds the row id of the tuple in its 'key' slot. This way the exact record can be updated or retrieved later. The following demonstates this fact:</p>
|
||||
<pre class="code">
|
||||
"Mandy" "Jones" "987-654-321" <person> dup .
|
||||
=> << person f "Mandy" "Jones" "987-654-321" >>
|
||||
db get over insert-tuple .
|
||||
=> << person
|
||||
<< persistent ... <span class="highlite">"2"</span> >>
|
||||
"Mandy" "Jones" "987-654-321"
|
||||
>>
|
||||
</pre>
|
||||
<p>The '2' highlited in the above example is the row id of the record inserted. We can go into the 'sqlite' command and view this record:</p>
|
||||
<pre class="code">
|
||||
$ sqlite3 example.db
|
||||
SQLite version 3.0.8
|
||||
Enter ".help" for instructions
|
||||
sqlite> select ROWID,* from person;
|
||||
1|John|Smith|123-456-789
|
||||
<span class="highlite">2|Mandy|Jones|987-654-321</span>
|
||||
sqlite>
|
||||
</pre>
|
||||
<h2>Finding Instances</h2>
|
||||
<p>The 'find-tuples' word is used to return tuples populated with data already
|
||||
existing in the database. As well as the database pointer, it takes a tuple that should be populated only with the fields that should be matched in the database. All fields you do not wish to match against should be set to 'f':</p>
|
||||
<pre class="code">
|
||||
<span class="highlite">! find-tuples ( db tuple -- seq )</span>
|
||||
db get f "Smith" f <person> find-tuples short.
|
||||
=> [ << person # "John" "Smith" "123-456-789" >> ]
|
||||
db get "Mandy" f f <person> find-tuples short.
|
||||
=> [ << person # "Mandy" "Jones" "987-654-321" >> ]
|
||||
db get "Joe" f f <person> find-tuples short.
|
||||
=> f
|
||||
</pre>
|
||||
<p>Notice that if no matching tuples are found then 'f' is returned. The returned tuples also have their delegate set to 'persistent' with the correct row id set as the key. This can be used to later update the tuples with new information and store them in the database.</p>
|
||||
<h2>Updating Instances</h2>
|
||||
<p>Given a tuple that has the 'persistent' delegate with the row id
|
||||
set as the key, you can update this specific record using the
|
||||
'update-tuple' word:</p>
|
||||
<pre class="code">
|
||||
<span class="highlite">! update-tuple ( db tuple -- )</span>
|
||||
db get f "Smith" f <person> find-tuples dup short.
|
||||
=> [ << person # "John" "Smith" "123-456-789" >> ]
|
||||
first [ "999-999-999" swap set-person-phone ] keep dup short.
|
||||
=> << person << persistent f # "1" >> "John" "Smith" "999-999-999" ...
|
||||
db get swap update-tuple
|
||||
</pre>
|
||||
<p>Using the 'sqlite' command from the system shell you can see the
|
||||
record was updated:</p>
|
||||
<pre class="code">
|
||||
$ sqlite3 example.db
|
||||
SQLite version 3.0.8
|
||||
Enter ".help" for instructions
|
||||
sqlite> select ROWID,* from person;
|
||||
1|John|Smith|999-999-999
|
||||
<span class="highlite">2|Mandy|Jones|987-654-321</span>
|
||||
sqlite>
|
||||
</pre>
|
||||
<h2>Inserting or Updating</h2>
|
||||
<p>The 'save-tuple' word can be used to insert a tuple if it has not
|
||||
already been stored in the database, or update it if it already
|
||||
exists. Whether to insert or update is decided by the existance of the
|
||||
'persistent' delegate:</p>
|
||||
<pre class="code">
|
||||
<span class="highlite">! save-tuple ( db tuple -- )</span>
|
||||
"Mary" "Smith" "111-111-111" <person> dup short.
|
||||
=> << person f "Mary" "Smith" "111-111-111" >>
|
||||
! This will insert the tuple
|
||||
db get over save-tuple dup short.
|
||||
=> << person << persistent f # "3" >> "Mary" "Smith" "111-111-111" ...
|
||||
[ "222-222-222" swap set-person-phone ] keep dup short.
|
||||
=> << person << persistent f # "3" >> "Mary" "Smith" "222-222-222" ...
|
||||
! This will update the tuple
|
||||
db get over save-tuple short.
|
||||
=> << person << persistent f # "3" >> "Mary" "Smith" "222-222-222" ...
|
||||
</pre>
|
||||
<h2>Deleting</h2>
|
||||
<p>Given a tuple with the delegate set to 'persistent' (ie. One
|
||||
already stored in the database) you can delete it from the database
|
||||
with the 'delete-tuple' word:</p>
|
||||
<pre class="code">
|
||||
<span class="highlite">! delete-tuple ( db tuple -- )</span>
|
||||
db get f "Smith" f <person> find-tuples [
|
||||
db get swap delete-tuple
|
||||
] each
|
||||
</pre>
|
||||
<h2>Closing the database</h2>
|
||||
<p>It's important to close the sqlite database when you've finished
|
||||
using it. The word for this is 'sqlite-close':</p>
|
||||
<pre class="code">
|
||||
<span class="highlite">! sqlite-close ( db -- )</span>
|
||||
db get sqlite-close
|
||||
</pre>
|
||||
|
||||
<p class="footer">
|
||||
News and updates to this software can be obtained from the authors
|
||||
weblog: <a href="http://radio.weblogs.com/0102385">Chris Double</a>.</p>
|
||||
<p id="copyright">Copyright (c) 2004, Chris Double. All Rights Reserved.</p>
|
||||
</body> </html>
|
293
doc/assoc.eps
293
doc/assoc.eps
|
@ -1,293 +0,0 @@
|
|||
%!PS-Adobe-2.0 EPSF-2.0
|
||||
%%Title: assoc.fig
|
||||
%%Creator: fig2dev Version 3.2 Patchlevel 4
|
||||
%%CreationDate: Wed Apr 27 23:52:59 2005
|
||||
%%For: slava@emu.localdomain (Slava)
|
||||
%%BoundingBox: 0 0 389 141
|
||||
%%Magnification: 1.0000
|
||||
%%EndComments
|
||||
/$F2psDict 200 dict def
|
||||
$F2psDict begin
|
||||
$F2psDict /mtrx matrix put
|
||||
/col-1 {0 setgray} bind def
|
||||
/col0 {0.000 0.000 0.000 srgb} bind def
|
||||
/col1 {0.000 0.000 1.000 srgb} bind def
|
||||
/col2 {0.000 1.000 0.000 srgb} bind def
|
||||
/col3 {0.000 1.000 1.000 srgb} bind def
|
||||
/col4 {1.000 0.000 0.000 srgb} bind def
|
||||
/col5 {1.000 0.000 1.000 srgb} bind def
|
||||
/col6 {1.000 1.000 0.000 srgb} bind def
|
||||
/col7 {1.000 1.000 1.000 srgb} bind def
|
||||
/col8 {0.000 0.000 0.560 srgb} bind def
|
||||
/col9 {0.000 0.000 0.690 srgb} bind def
|
||||
/col10 {0.000 0.000 0.820 srgb} bind def
|
||||
/col11 {0.530 0.810 1.000 srgb} bind def
|
||||
/col12 {0.000 0.560 0.000 srgb} bind def
|
||||
/col13 {0.000 0.690 0.000 srgb} bind def
|
||||
/col14 {0.000 0.820 0.000 srgb} bind def
|
||||
/col15 {0.000 0.560 0.560 srgb} bind def
|
||||
/col16 {0.000 0.690 0.690 srgb} bind def
|
||||
/col17 {0.000 0.820 0.820 srgb} bind def
|
||||
/col18 {0.560 0.000 0.000 srgb} bind def
|
||||
/col19 {0.690 0.000 0.000 srgb} bind def
|
||||
/col20 {0.820 0.000 0.000 srgb} bind def
|
||||
/col21 {0.560 0.000 0.560 srgb} bind def
|
||||
/col22 {0.690 0.000 0.690 srgb} bind def
|
||||
/col23 {0.820 0.000 0.820 srgb} bind def
|
||||
/col24 {0.500 0.190 0.000 srgb} bind def
|
||||
/col25 {0.630 0.250 0.000 srgb} bind def
|
||||
/col26 {0.750 0.380 0.000 srgb} bind def
|
||||
/col27 {1.000 0.500 0.500 srgb} bind def
|
||||
/col28 {1.000 0.630 0.630 srgb} bind def
|
||||
/col29 {1.000 0.750 0.750 srgb} bind def
|
||||
/col30 {1.000 0.880 0.880 srgb} bind def
|
||||
/col31 {1.000 0.840 0.000 srgb} bind def
|
||||
|
||||
end
|
||||
save
|
||||
newpath 0 141 moveto 0 0 lineto 389 0 lineto 389 141 lineto closepath clip newpath
|
||||
-0.4 139.5 translate
|
||||
1 -1 scale
|
||||
|
||||
/cp {closepath} bind def
|
||||
/ef {eofill} bind def
|
||||
/gr {grestore} bind def
|
||||
/gs {gsave} bind def
|
||||
/sa {save} bind def
|
||||
/rs {restore} bind def
|
||||
/l {lineto} bind def
|
||||
/m {moveto} bind def
|
||||
/rm {rmoveto} bind def
|
||||
/n {newpath} bind def
|
||||
/s {stroke} bind def
|
||||
/sh {show} bind def
|
||||
/slc {setlinecap} bind def
|
||||
/slj {setlinejoin} bind def
|
||||
/slw {setlinewidth} bind def
|
||||
/srgb {setrgbcolor} bind def
|
||||
/rot {rotate} bind def
|
||||
/sc {scale} bind def
|
||||
/sd {setdash} bind def
|
||||
/ff {findfont} bind def
|
||||
/sf {setfont} bind def
|
||||
/scf {scalefont} bind def
|
||||
/sw {stringwidth} bind def
|
||||
/tr {translate} bind def
|
||||
/tnt {dup dup currentrgbcolor
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
|
||||
bind def
|
||||
/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
|
||||
4 -2 roll mul srgb} bind def
|
||||
/reencdict 12 dict def /ReEncode { reencdict begin
|
||||
/newcodesandnames exch def /newfontname exch def /basefontname exch def
|
||||
/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def
|
||||
basefontdict { exch dup /FID ne { dup /Encoding eq
|
||||
{ exch dup length array copy newfont 3 1 roll put }
|
||||
{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall
|
||||
newfont /FontName newfontname put newcodesandnames aload pop
|
||||
128 1 255 { newfont /Encoding get exch /.notdef put } for
|
||||
newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat
|
||||
newfontname newfont definefont pop end } def
|
||||
/isovec [
|
||||
8#055 /minus 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde
|
||||
8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis
|
||||
8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron
|
||||
8#220 /dotlessi 8#230 /oe 8#231 /OE
|
||||
8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling
|
||||
8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis
|
||||
8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot
|
||||
8#255 /hyphen 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus
|
||||
8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph
|
||||
8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine
|
||||
8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf
|
||||
8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute
|
||||
8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring
|
||||
8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute
|
||||
8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute
|
||||
8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve
|
||||
8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply
|
||||
8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex
|
||||
8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave
|
||||
8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring
|
||||
8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute
|
||||
8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute
|
||||
8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve
|
||||
8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide
|
||||
8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex
|
||||
8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def
|
||||
/Courier /Courier-iso isovec ReEncode
|
||||
/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
|
||||
/$F2psEnd {$F2psEnteredState restore end} def
|
||||
|
||||
$F2psBegin
|
||||
10 setmiterlimit
|
||||
0 slj 0 slc
|
||||
0.06000 0.06000 sc
|
||||
%
|
||||
% Fig objects follow
|
||||
%
|
||||
%
|
||||
% here starts figure with depth 50
|
||||
/Courier-iso ff 270.00 scf sf
|
||||
5550 2325 m
|
||||
gs 1 -1 sc ("Extra Hot") dup sw pop 2 div neg 0 rm col0 sh gr
|
||||
% Polyline
|
||||
7.500 slw
|
||||
n 1350 0 m 2100 0 l 2100 450 l 1350 450 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 2700 0 m 3450 0 l 3450 450 l 2700 450 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 3450 0 m 4200 0 l 4200 450 l 3450 450 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 4800 0 m 5550 0 l 5550 450 l 4800 450 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 5550 0 m 6300 0 l 6300 450 l 5550 450 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 225 975 m 975 975 l 975 1425 l 225 1425 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 975 975 m 1725 975 l 1725 1425 l 975 1425 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 2325 975 m 3075 975 l 3075 1425 l 2325 1425 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 3075 975 m 3825 975 l 3825 1425 l 3075 1425 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 4425 975 m 5175 975 l 5175 1425 l 4425 1425 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 5175 975 m 5925 975 l 5925 1425 l 5175 1425 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
gs clippath
|
||||
945 990 m 1005 990 l 1005 838 l 975 958 l 945 838 l cp
|
||||
eoclip
|
||||
n 975 225 m
|
||||
975 975 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 945 838 m 975 958 l 1005 838 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
3045 990 m 3105 990 l 3105 838 l 3075 958 l 3045 838 l cp
|
||||
eoclip
|
||||
n 3075 225 m
|
||||
3075 975 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 3045 838 m 3075 958 l 3105 838 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
5145 990 m 5205 990 l 5205 838 l 5175 958 l 5145 838 l cp
|
||||
eoclip
|
||||
n 5175 225 m
|
||||
5175 975 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 5145 838 m 5175 958 l 5205 838 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
2715 255 m 2715 195 l 2563 195 l 2683 225 l 2563 255 l cp
|
||||
eoclip
|
||||
n 1725 225 m
|
||||
2700 225 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 2563 255 m 2683 225 l 2563 195 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
4815 255 m 4815 195 l 4663 195 l 4783 225 l 4663 255 l cp
|
||||
eoclip
|
||||
n 3825 225 m
|
||||
4800 225 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 4663 255 m 4783 225 l 4663 195 l col0 s
|
||||
% Polyline
|
||||
n 5550 450 m
|
||||
6300 0 l gs col0 s gr
|
||||
% Polyline
|
||||
gs clippath
|
||||
570 1740 m 630 1740 l 630 1588 l 600 1708 l 570 1588 l cp
|
||||
eoclip
|
||||
n 600 1200 m
|
||||
600 1725 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 570 1588 m 600 1708 l 630 1588 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
1320 2115 m 1380 2115 l 1380 1963 l 1350 2083 l 1320 1963 l cp
|
||||
eoclip
|
||||
n 1350 1200 m
|
||||
1350 2100 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 1320 1963 m 1350 2083 l 1380 1963 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
2670 1740 m 2730 1740 l 2730 1588 l 2700 1708 l 2670 1588 l cp
|
||||
eoclip
|
||||
n 2700 1200 m
|
||||
2700 1725 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 2670 1588 m 2700 1708 l 2730 1588 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
3420 2115 m 3480 2115 l 3480 1963 l 3450 2083 l 3420 1963 l cp
|
||||
eoclip
|
||||
n 3450 1200 m
|
||||
3450 2100 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 3420 1963 m 3450 2083 l 3480 1963 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
4770 1740 m 4830 1740 l 4830 1588 l 4800 1708 l 4770 1588 l cp
|
||||
eoclip
|
||||
n 4800 1200 m
|
||||
4800 1725 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 4770 1588 m 4800 1708 l 4830 1588 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
5520 2115 m 5580 2115 l 5580 1963 l 5550 2083 l 5520 1963 l cp
|
||||
eoclip
|
||||
n 5550 1200 m
|
||||
5550 2100 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 5520 1963 m 5550 2083 l 5580 1963 l col0 s
|
||||
/Courier-iso ff 270.00 scf sf
|
||||
600 1950 m
|
||||
gs 1 -1 sc ("Salsa") dup sw pop 2 div neg 0 rm col0 sh gr
|
||||
/Courier-iso ff 270.00 scf sf
|
||||
2550 1950 m
|
||||
gs 1 -1 sc ("Stir-Fry") dup sw pop 2 div neg 0 rm col0 sh gr
|
||||
/Courier-iso ff 270.00 scf sf
|
||||
4725 1950 m
|
||||
gs 1 -1 sc ("Peppers") dup sw pop 2 div neg 0 rm col0 sh gr
|
||||
/Courier-iso ff 270.00 scf sf
|
||||
1350 2325 m
|
||||
gs 1 -1 sc ("Hot") dup sw pop 2 div neg 0 rm col0 sh gr
|
||||
/Courier-iso ff 270.00 scf sf
|
||||
3450 2325 m
|
||||
gs 1 -1 sc ("Medium") dup sw pop 2 div neg 0 rm col0 sh gr
|
||||
% Polyline
|
||||
n 600 0 m 1350 0 l 1350 450 l 600 450 l
|
||||
cp gs col0 s gr
|
||||
% here ends figure;
|
||||
$F2psEnd
|
||||
rs
|
||||
showpage
|
|
@ -1,88 +0,0 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 0 0 6525 2325
|
||||
6 600 0 2100 450
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
600 0 1350 0 1350 450 600 450 600 0
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 0 2100 0 2100 450 1350 450 1350 0
|
||||
-6
|
||||
6 2700 0 4200 450
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2700 0 3450 0 3450 450 2700 450 2700 0
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3450 0 4200 0 4200 450 3450 450 3450 0
|
||||
-6
|
||||
6 4800 0 6300 450
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4800 0 5550 0 5550 450 4800 450 4800 0
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5550 0 6300 0 6300 450 5550 450 5550 0
|
||||
-6
|
||||
6 225 975 1725 1425
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
225 975 975 975 975 1425 225 1425 225 975
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
975 975 1725 975 1725 1425 975 1425 975 975
|
||||
-6
|
||||
6 2325 975 3825 1425
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2325 975 3075 975 3075 1425 2325 1425 2325 975
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3075 975 3825 975 3825 1425 3075 1425 3075 975
|
||||
-6
|
||||
6 4425 975 5925 1425
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4425 975 5175 975 5175 1425 4425 1425 4425 975
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5175 975 5925 975 5925 1425 5175 1425 5175 975
|
||||
-6
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
975 225 975 975
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
3075 225 3075 975
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
5175 225 5175 975
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
1725 225 2700 225
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
3825 225 4800 225
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5550 450 6300 0
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
600 1200 600 1725
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
1350 1200 1350 2100
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
2700 1200 2700 1725
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
3450 1200 3450 2100
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
4800 1200 4800 1725
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
5550 1200 5550 2100
|
||||
4 1 0 50 -1 12 18 0.0000 4 165 1155 600 1950 "Salsa"\001
|
||||
4 1 0 50 -1 12 18 0.0000 4 225 1650 2550 1950 "Stir-Fry"\001
|
||||
4 1 0 50 -1 12 18 0.0000 4 195 1485 4725 1950 "Peppers"\001
|
||||
4 1 0 50 -1 12 18 0.0000 4 150 825 1350 2325 "Hot"\001
|
||||
4 1 0 50 -1 12 18 0.0000 4 180 1320 3450 2325 "Medium"\001
|
||||
4 1 0 50 -1 12 18 0.0000 4 150 1815 5550 2325 "Extra Hot"\001
|
||||
-6
|
|
@ -1,274 +0,0 @@
|
|||
%!PS-Adobe-2.0 EPSF-2.0
|
||||
%%Title: catchstack.fig
|
||||
%%Creator: fig2dev Version 3.2 Patchlevel 4
|
||||
%%CreationDate: Thu Apr 28 21:42:33 2005
|
||||
%%For: slava@emu.localdomain (Slava)
|
||||
%%BoundingBox: 0 0 591 297
|
||||
%%Magnification: 1.0000
|
||||
%%EndComments
|
||||
/$F2psDict 200 dict def
|
||||
$F2psDict begin
|
||||
$F2psDict /mtrx matrix put
|
||||
/col-1 {0 setgray} bind def
|
||||
/col0 {0.000 0.000 0.000 srgb} bind def
|
||||
/col1 {0.000 0.000 1.000 srgb} bind def
|
||||
/col2 {0.000 1.000 0.000 srgb} bind def
|
||||
/col3 {0.000 1.000 1.000 srgb} bind def
|
||||
/col4 {1.000 0.000 0.000 srgb} bind def
|
||||
/col5 {1.000 0.000 1.000 srgb} bind def
|
||||
/col6 {1.000 1.000 0.000 srgb} bind def
|
||||
/col7 {1.000 1.000 1.000 srgb} bind def
|
||||
/col8 {0.000 0.000 0.560 srgb} bind def
|
||||
/col9 {0.000 0.000 0.690 srgb} bind def
|
||||
/col10 {0.000 0.000 0.820 srgb} bind def
|
||||
/col11 {0.530 0.810 1.000 srgb} bind def
|
||||
/col12 {0.000 0.560 0.000 srgb} bind def
|
||||
/col13 {0.000 0.690 0.000 srgb} bind def
|
||||
/col14 {0.000 0.820 0.000 srgb} bind def
|
||||
/col15 {0.000 0.560 0.560 srgb} bind def
|
||||
/col16 {0.000 0.690 0.690 srgb} bind def
|
||||
/col17 {0.000 0.820 0.820 srgb} bind def
|
||||
/col18 {0.560 0.000 0.000 srgb} bind def
|
||||
/col19 {0.690 0.000 0.000 srgb} bind def
|
||||
/col20 {0.820 0.000 0.000 srgb} bind def
|
||||
/col21 {0.560 0.000 0.560 srgb} bind def
|
||||
/col22 {0.690 0.000 0.690 srgb} bind def
|
||||
/col23 {0.820 0.000 0.820 srgb} bind def
|
||||
/col24 {0.500 0.190 0.000 srgb} bind def
|
||||
/col25 {0.630 0.250 0.000 srgb} bind def
|
||||
/col26 {0.750 0.380 0.000 srgb} bind def
|
||||
/col27 {1.000 0.500 0.500 srgb} bind def
|
||||
/col28 {1.000 0.630 0.630 srgb} bind def
|
||||
/col29 {1.000 0.750 0.750 srgb} bind def
|
||||
/col30 {1.000 0.880 0.880 srgb} bind def
|
||||
/col31 {1.000 0.840 0.000 srgb} bind def
|
||||
/col32 {0.773 0.715 0.590 srgb} bind def
|
||||
/col33 {0.934 0.969 0.996 srgb} bind def
|
||||
/col34 {0.859 0.793 0.648 srgb} bind def
|
||||
/col35 {0.250 0.250 0.250 srgb} bind def
|
||||
/col36 {0.500 0.500 0.500 srgb} bind def
|
||||
/col37 {0.750 0.750 0.750 srgb} bind def
|
||||
/col38 {0.875 0.875 0.875 srgb} bind def
|
||||
/col39 {0.555 0.559 0.555 srgb} bind def
|
||||
/col40 {0.664 0.664 0.664 srgb} bind def
|
||||
/col41 {0.332 0.332 0.332 srgb} bind def
|
||||
/col42 {0.555 0.555 0.555 srgb} bind def
|
||||
/col43 {0.840 0.840 0.840 srgb} bind def
|
||||
/col44 {0.680 0.680 0.680 srgb} bind def
|
||||
/col45 {0.742 0.742 0.742 srgb} bind def
|
||||
/col46 {0.316 0.316 0.316 srgb} bind def
|
||||
/col47 {0.902 0.887 0.902 srgb} bind def
|
||||
/col48 {0.000 0.000 0.285 srgb} bind def
|
||||
/col49 {0.473 0.473 0.473 srgb} bind def
|
||||
/col50 {0.188 0.203 0.188 srgb} bind def
|
||||
/col51 {0.254 0.254 0.254 srgb} bind def
|
||||
/col52 {0.777 0.711 0.586 srgb} bind def
|
||||
/col53 {0.254 0.270 0.254 srgb} bind def
|
||||
/col54 {0.387 0.387 0.387 srgb} bind def
|
||||
/col55 {0.801 0.801 0.801 srgb} bind def
|
||||
/col56 {0.422 0.422 0.422 srgb} bind def
|
||||
|
||||
end
|
||||
save
|
||||
newpath 0 297 moveto 0 0 lineto 591 0 lineto 591 297 lineto closepath clip newpath
|
||||
0.7 295.9 translate
|
||||
1 -1 scale
|
||||
|
||||
/cp {closepath} bind def
|
||||
/ef {eofill} bind def
|
||||
/gr {grestore} bind def
|
||||
/gs {gsave} bind def
|
||||
/sa {save} bind def
|
||||
/rs {restore} bind def
|
||||
/l {lineto} bind def
|
||||
/m {moveto} bind def
|
||||
/rm {rmoveto} bind def
|
||||
/n {newpath} bind def
|
||||
/s {stroke} bind def
|
||||
/sh {show} bind def
|
||||
/slc {setlinecap} bind def
|
||||
/slj {setlinejoin} bind def
|
||||
/slw {setlinewidth} bind def
|
||||
/srgb {setrgbcolor} bind def
|
||||
/rot {rotate} bind def
|
||||
/sc {scale} bind def
|
||||
/sd {setdash} bind def
|
||||
/ff {findfont} bind def
|
||||
/sf {setfont} bind def
|
||||
/scf {scalefont} bind def
|
||||
/sw {stringwidth} bind def
|
||||
/tr {translate} bind def
|
||||
/tnt {dup dup currentrgbcolor
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
|
||||
bind def
|
||||
/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
|
||||
4 -2 roll mul srgb} bind def
|
||||
/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
|
||||
/$F2psEnd {$F2psEnteredState restore end} def
|
||||
|
||||
$F2psBegin
|
||||
10 setmiterlimit
|
||||
0 slj 0 slc
|
||||
0.06000 0.06000 sc
|
||||
%
|
||||
% Fig objects follow
|
||||
%
|
||||
%
|
||||
% here starts figure with depth 50
|
||||
/Courier ff 270.00 scf sf
|
||||
0 4125 m
|
||||
gs 1 -1 sc ([ "foe's catch block" print rethrow ]) col0 sh gr
|
||||
% Polyline
|
||||
7.500 slw
|
||||
n 1650 600 m 2400 600 l 2400 1050 l 1650 1050 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 3075 600 m 3825 600 l 3825 1050 l 3075 1050 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 3825 600 m 4575 600 l 4575 1050 l 3825 1050 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 5250 600 m 6000 600 l 6000 1050 l 5250 1050 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 6000 600 m 6750 600 l 6750 1050 l 6000 1050 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
2 slj
|
||||
gs clippath
|
||||
1396 617 m 1456 612 l 1444 461 l 1424 583 l 1384 465 l cp
|
||||
eoclip
|
||||
n 0 0 m 1 0 l 4 0 l 9 0 l 18 0 l 29 0 l
|
||||
44 0 l 63 1 l 86 1 l 112 1 l 142 2 l
|
||||
174 3 l 209 4 l 246 6 l 285 7 l 326 9 l
|
||||
367 12 l 410 15 l 452 18 l 496 22 l 540 27 l
|
||||
584 32 l 629 39 l 674 46 l 720 54 l 767 64 l
|
||||
814 74 l 861 86 l 909 100 l 957 115 l 1004 132 l
|
||||
1050 150 l 1103 174 l 1150 199 l 1192 224 l 1229 249 l
|
||||
1261 273 l 1289 298 l 1312 322 l 1332 345 l 1349 369 l
|
||||
1364 392 l 1376 415 l 1386 437 l 1395 459 l 1402 481 l
|
||||
1407 501 l 1412 520 l 1416 538 l 1419 553 l 1421 567 l
|
||||
1423 578 l 1424 587 l
|
||||
1425 600 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
0 slj
|
||||
n 1384 465 m 1424 583 l 1444 461 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
3090 855 m 3090 795 l 2938 795 l 3058 825 l 2938 855 l cp
|
||||
eoclip
|
||||
n 2025 825 m
|
||||
3075 825 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 2938 855 m 3058 825 l 2938 795 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
5595 2040 m 5655 2040 l 5655 1888 l 5625 2008 l 5595 1888 l cp
|
||||
eoclip
|
||||
n 5625 825 m
|
||||
5625 2025 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 5595 1888 m 5625 2008 l 5655 1888 l col0 s
|
||||
% Polyline
|
||||
n 6000 1050 m
|
||||
6750 600 l gs col0 s gr
|
||||
% Polyline
|
||||
gs clippath
|
||||
5265 855 m 5265 795 l 5113 795 l 5233 825 l 5113 855 l cp
|
||||
eoclip
|
||||
n 4200 825 m
|
||||
5250 825 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 5113 855 m 5233 825 l 5113 795 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
3420 3015 m 3480 3015 l 3480 2863 l 3450 2983 l 3420 2863 l cp
|
||||
eoclip
|
||||
n 3450 825 m
|
||||
3450 3000 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 3420 2863 m 3450 2983 l 3480 2863 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
1245 3990 m 1305 3990 l 1305 3838 l 1275 3958 l 1245 3838 l cp
|
||||
eoclip
|
||||
n 1275 825 m
|
||||
1275 3975 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 1245 3838 m 1275 3958 l 1305 3838 l col0 s
|
||||
% Polyline
|
||||
2 slj
|
||||
gs clippath
|
||||
7734 2442 m 7693 2486 l 7804 2589 l 7737 2486 l 7845 2545 l cp
|
||||
eoclip
|
||||
n 6900 3300 m 6901 3301 l 6904 3302 l 6909 3304 l 6917 3308 l 6928 3314 l
|
||||
6944 3321 l 6964 3330 l 6988 3342 l 7016 3355 l 7049 3371 l
|
||||
7087 3389 l 7129 3408 l 7175 3430 l 7225 3453 l 7278 3477 l
|
||||
7334 3503 l 7393 3529 l 7453 3556 l 7515 3584 l 7579 3612 l
|
||||
7643 3640 l 7708 3667 l 7772 3695 l 7837 3721 l 7901 3747 l
|
||||
7965 3772 l 8028 3796 l 8089 3819 l 8150 3840 l 8209 3860 l
|
||||
8267 3878 l 8323 3894 l 8378 3908 l 8431 3921 l 8481 3931 l
|
||||
8530 3938 l 8576 3943 l 8619 3944 l 8658 3943 l 8694 3938 l
|
||||
8726 3929 l 8753 3917 l 8775 3900 l 8791 3878 l 8801 3852 l
|
||||
8805 3823 l 8804 3791 l 8797 3756 l 8786 3719 l 8770 3680 l
|
||||
8750 3639 l 8727 3597 l 8700 3554 l 8671 3509 l 8638 3463 l
|
||||
8604 3417 l 8566 3369 l 8527 3321 l 8486 3272 l 8443 3222 l
|
||||
8399 3172 l 8354 3122 l 8308 3071 l 8262 3021 l 8215 2971 l
|
||||
8168 2922 l 8122 2875 l 8077 2828 l 8034 2783 l 7992 2741 l
|
||||
7952 2701 l 7915 2663 l 7881 2629 l 7850 2598 l 7823 2571 l
|
||||
7799 2548 l 7779 2528 l 7762 2512 l 7749 2499 l 7740 2489 l
|
||||
|
||||
7725 2475 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
0 slj
|
||||
n 7845 2545 m 7737 2486 l 7804 2589 l col0 s
|
||||
% Polyline
|
||||
2 slj
|
||||
gs clippath
|
||||
6234 3417 m 6193 3461 l 6304 3564 l 6237 3461 l 6345 3520 l cp
|
||||
eoclip
|
||||
n 5400 4275 m 5401 4276 l 5404 4277 l 5409 4279 l 5417 4283 l 5428 4289 l
|
||||
5444 4296 l 5464 4305 l 5488 4317 l 5516 4330 l 5549 4346 l
|
||||
5587 4364 l 5629 4383 l 5675 4405 l 5725 4428 l 5778 4452 l
|
||||
5834 4478 l 5893 4504 l 5953 4531 l 6015 4559 l 6079 4587 l
|
||||
6143 4615 l 6208 4642 l 6272 4670 l 6337 4696 l 6401 4722 l
|
||||
6465 4747 l 6528 4771 l 6589 4794 l 6650 4815 l 6709 4835 l
|
||||
6767 4853 l 6823 4869 l 6878 4883 l 6931 4896 l 6981 4906 l
|
||||
7030 4913 l 7076 4918 l 7119 4919 l 7158 4918 l 7194 4913 l
|
||||
7226 4904 l 7253 4892 l 7275 4875 l 7291 4853 l 7301 4827 l
|
||||
7305 4798 l 7304 4766 l 7297 4731 l 7286 4694 l 7270 4655 l
|
||||
7250 4614 l 7227 4572 l 7200 4529 l 7171 4484 l 7138 4438 l
|
||||
7104 4392 l 7066 4344 l 7027 4296 l 6986 4247 l 6943 4197 l
|
||||
6899 4147 l 6854 4097 l 6808 4046 l 6762 3996 l 6715 3946 l
|
||||
6668 3897 l 6622 3850 l 6577 3803 l 6534 3758 l 6492 3716 l
|
||||
6452 3676 l 6415 3638 l 6381 3604 l 6350 3573 l 6323 3546 l
|
||||
6299 3523 l 6279 3503 l 6262 3487 l 6249 3474 l 6240 3464 l
|
||||
|
||||
6225 3450 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
0 slj
|
||||
n 6345 3520 m 6237 3461 l 6304 3564 l col0 s
|
||||
/Courier ff 270.00 scf sf
|
||||
3900 2325 m
|
||||
gs 1 -1 sc ([ [ "Exception: " write . ] when* ]) col0 sh gr
|
||||
/Courier ff 270.00 scf sf
|
||||
1650 3225 m
|
||||
gs 1 -1 sc ([ "fie's catch block" print rethrow ]) col0 sh gr
|
||||
% Polyline
|
||||
n 900 600 m 1650 600 l 1650 1050 l 900 1050 l
|
||||
cp gs col0 s gr
|
||||
% here ends figure;
|
||||
$F2psEnd
|
||||
rs
|
||||
showpage
|
|
@ -1,88 +0,0 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
0 32 #c6b797
|
||||
0 33 #eff8ff
|
||||
0 34 #dccba6
|
||||
0 35 #404040
|
||||
0 36 #808080
|
||||
0 37 #c0c0c0
|
||||
0 38 #e0e0e0
|
||||
0 39 #8e8f8e
|
||||
0 40 #aaaaaa
|
||||
0 41 #555555
|
||||
0 42 #8e8e8e
|
||||
0 43 #d7d7d7
|
||||
0 44 #aeaeae
|
||||
0 45 #bebebe
|
||||
0 46 #515151
|
||||
0 47 #e7e3e7
|
||||
0 48 #000049
|
||||
0 49 #797979
|
||||
0 50 #303430
|
||||
0 51 #414141
|
||||
0 52 #c7b696
|
||||
0 53 #414541
|
||||
0 54 #636363
|
||||
0 55 #cdcdcd
|
||||
0 56 #6c6c6c
|
||||
6 0 0 9675 5100
|
||||
6 900 600 2400 1050
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
900 600 1650 600 1650 1050 900 1050 900 600
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1650 600 2400 600 2400 1050 1650 1050 1650 600
|
||||
-6
|
||||
6 3075 600 4575 1050
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3075 600 3825 600 3825 1050 3075 1050 3075 600
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3825 600 4575 600 4575 1050 3825 1050 3825 600
|
||||
-6
|
||||
6 5250 600 6750 1050
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5250 600 6000 600 6000 1050 5250 1050 5250 600
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6000 600 6750 600 6750 1050 6000 1050 6000 600
|
||||
-6
|
||||
6 0 0 1425 600
|
||||
3 2 0 1 0 7 50 -1 -1 0.000 0 1 0 3
|
||||
0 0 1.00 60.00 120.00
|
||||
0 0 1050 150 1425 600
|
||||
0.000 -1.000 0.000
|
||||
-6
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
2025 825 3075 825
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
5625 825 5625 2025
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6000 1050 6750 600
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
4200 825 5250 825
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
3450 825 3450 3000
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
1275 825 1275 3975
|
||||
3 2 0 1 0 7 50 -1 -1 0.000 0 1 0 3
|
||||
0 0 1.00 60.00 120.00
|
||||
6900 3300 8775 3900 7725 2475
|
||||
0.000 -1.000 0.000
|
||||
3 2 0 1 0 7 50 -1 -1 0.000 0 1 0 3
|
||||
0 0 1.00 60.00 120.00
|
||||
5400 4275 7275 4875 6225 3450
|
||||
0.000 -1.000 0.000
|
||||
4 0 0 50 -1 12 18 0.0000 4 225 5775 3900 2325 [ [ "Exception: " write . ] when* ]\001
|
||||
4 0 0 50 -1 12 18 0.0000 4 225 6105 1650 3225 [ "fie's catch block" print rethrow ]\001
|
||||
4 0 0 50 -1 12 18 0.0000 4 225 6105 0 4125 [ "foe's catch block" print rethrow ]\001
|
||||
-6
|
147
doc/cons.eps
147
doc/cons.eps
|
@ -1,147 +0,0 @@
|
|||
%!PS-Adobe-2.0 EPSF-2.0
|
||||
%%Title: cons.fig
|
||||
%%Creator: fig2dev Version 3.2 Patchlevel 4
|
||||
%%CreationDate: Wed Apr 27 21:12:41 2005
|
||||
%%For: slava@emu.localdomain (Slava)
|
||||
%%BoundingBox: 0 0 182 137
|
||||
%%Magnification: 1.0000
|
||||
%%EndComments
|
||||
/$F2psDict 200 dict def
|
||||
$F2psDict begin
|
||||
$F2psDict /mtrx matrix put
|
||||
/col-1 {0 setgray} bind def
|
||||
/col0 {0.000 0.000 0.000 srgb} bind def
|
||||
/col1 {0.000 0.000 1.000 srgb} bind def
|
||||
/col2 {0.000 1.000 0.000 srgb} bind def
|
||||
/col3 {0.000 1.000 1.000 srgb} bind def
|
||||
/col4 {1.000 0.000 0.000 srgb} bind def
|
||||
/col5 {1.000 0.000 1.000 srgb} bind def
|
||||
/col6 {1.000 1.000 0.000 srgb} bind def
|
||||
/col7 {1.000 1.000 1.000 srgb} bind def
|
||||
/col8 {0.000 0.000 0.560 srgb} bind def
|
||||
/col9 {0.000 0.000 0.690 srgb} bind def
|
||||
/col10 {0.000 0.000 0.820 srgb} bind def
|
||||
/col11 {0.530 0.810 1.000 srgb} bind def
|
||||
/col12 {0.000 0.560 0.000 srgb} bind def
|
||||
/col13 {0.000 0.690 0.000 srgb} bind def
|
||||
/col14 {0.000 0.820 0.000 srgb} bind def
|
||||
/col15 {0.000 0.560 0.560 srgb} bind def
|
||||
/col16 {0.000 0.690 0.690 srgb} bind def
|
||||
/col17 {0.000 0.820 0.820 srgb} bind def
|
||||
/col18 {0.560 0.000 0.000 srgb} bind def
|
||||
/col19 {0.690 0.000 0.000 srgb} bind def
|
||||
/col20 {0.820 0.000 0.000 srgb} bind def
|
||||
/col21 {0.560 0.000 0.560 srgb} bind def
|
||||
/col22 {0.690 0.000 0.690 srgb} bind def
|
||||
/col23 {0.820 0.000 0.820 srgb} bind def
|
||||
/col24 {0.500 0.190 0.000 srgb} bind def
|
||||
/col25 {0.630 0.250 0.000 srgb} bind def
|
||||
/col26 {0.750 0.380 0.000 srgb} bind def
|
||||
/col27 {1.000 0.500 0.500 srgb} bind def
|
||||
/col28 {1.000 0.630 0.630 srgb} bind def
|
||||
/col29 {1.000 0.750 0.750 srgb} bind def
|
||||
/col30 {1.000 0.880 0.880 srgb} bind def
|
||||
/col31 {1.000 0.840 0.000 srgb} bind def
|
||||
|
||||
end
|
||||
save
|
||||
newpath 0 137 moveto 0 0 lineto 182 0 lineto 182 137 lineto closepath clip newpath
|
||||
0.7 135.7 translate
|
||||
1 -1 scale
|
||||
|
||||
/cp {closepath} bind def
|
||||
/ef {eofill} bind def
|
||||
/gr {grestore} bind def
|
||||
/gs {gsave} bind def
|
||||
/sa {save} bind def
|
||||
/rs {restore} bind def
|
||||
/l {lineto} bind def
|
||||
/m {moveto} bind def
|
||||
/rm {rmoveto} bind def
|
||||
/n {newpath} bind def
|
||||
/s {stroke} bind def
|
||||
/sh {show} bind def
|
||||
/slc {setlinecap} bind def
|
||||
/slj {setlinejoin} bind def
|
||||
/slw {setlinewidth} bind def
|
||||
/srgb {setrgbcolor} bind def
|
||||
/rot {rotate} bind def
|
||||
/sc {scale} bind def
|
||||
/sd {setdash} bind def
|
||||
/ff {findfont} bind def
|
||||
/sf {setfont} bind def
|
||||
/scf {scalefont} bind def
|
||||
/sw {stringwidth} bind def
|
||||
/tr {translate} bind def
|
||||
/tnt {dup dup currentrgbcolor
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
|
||||
bind def
|
||||
/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
|
||||
4 -2 roll mul srgb} bind def
|
||||
/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
|
||||
/$F2psEnd {$F2psEnteredState restore end} def
|
||||
|
||||
$F2psBegin
|
||||
10 setmiterlimit
|
||||
0 slj 0 slc
|
||||
0.06000 0.06000 sc
|
||||
%
|
||||
% Fig objects follow
|
||||
%
|
||||
%
|
||||
% here starts figure with depth 50
|
||||
/Courier ff 540.00 scf sf
|
||||
225 375 m
|
||||
gs 1 -1 sc (1) col0 sh gr
|
||||
% Polyline
|
||||
7.500 slw
|
||||
gs clippath
|
||||
1095 915 m 1155 915 l 1155 763 l 1125 883 l 1095 763 l cp
|
||||
eoclip
|
||||
n 1125 225 m
|
||||
1125 900 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 1095 763 m 1125 883 l 1155 763 l col0 s
|
||||
% Polyline
|
||||
n 0 0 m 750 0 l 750 450 l 0 450 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 1500 900 m 2250 900 l 2250 1350 l 1500 1350 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
gs clippath
|
||||
1845 1815 m 1905 1815 l 1905 1663 l 1875 1783 l 1845 1663 l cp
|
||||
eoclip
|
||||
n 1875 1125 m
|
||||
1875 1800 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 1845 1663 m 1875 1783 l 1905 1663 l col0 s
|
||||
% Polyline
|
||||
n 750 900 m 1500 900 l 1500 1350 l 750 1350 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 1500 1800 m 2250 1800 l 2250 2250 l 1500 2250 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 2250 1800 m 3000 1800 l 3000 2250 l 2250 2250 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 2250 2250 m
|
||||
3000 1800 l gs col0 s gr
|
||||
/Courier ff 540.00 scf sf
|
||||
975 1275 m
|
||||
gs 1 -1 sc (2) col0 sh gr
|
||||
/Courier ff 540.00 scf sf
|
||||
1725 2175 m
|
||||
gs 1 -1 sc (3) col0 sh gr
|
||||
% Polyline
|
||||
n 750 0 m 1500 0 l 1500 450 l 750 450 l
|
||||
cp gs col0 s gr
|
||||
% here ends figure;
|
||||
$F2psEnd
|
||||
rs
|
||||
showpage
|
40
doc/cons.fig
40
doc/cons.fig
|
@ -1,40 +0,0 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 0 0 1500 900
|
||||
6 750 0 1500 900
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
750 0 1500 0 1500 450 750 450 750 0
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
1125 225 1125 900
|
||||
-6
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
0 0 750 0 750 450 0 450 0 0
|
||||
-6
|
||||
6 750 900 2250 1800
|
||||
6 1500 900 2250 1800
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1500 900 2250 900 2250 1350 1500 1350 1500 900
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
1875 1125 1875 1800
|
||||
-6
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
750 900 1500 900 1500 1350 750 1350 750 900
|
||||
-6
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1500 1800 2250 1800 2250 2250 1500 2250 1500 1800
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2250 1800 3000 1800 3000 2250 2250 2250 2250 1800
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
2250 2250 3000 1800
|
||||
4 0 0 50 -1 12 36 0.0000 4 330 330 975 1275 2\001
|
||||
4 0 0 50 -1 12 36 0.0000 4 330 330 1725 2175 3\001
|
||||
4 0 0 50 -1 12 36 0.0000 4 330 330 225 375 1\001
|
396
doc/glossary.sty
396
doc/glossary.sty
|
@ -1,396 +0,0 @@
|
|||
%%
|
||||
%% This is file `glossary.sty',
|
||||
%% generated with the docstrip utility.
|
||||
%%
|
||||
%% The original source files were:
|
||||
%%
|
||||
%% glossary.dtx (with options: `package')
|
||||
%% Copyright (C) 2000 Nicola Talbot, all rights reserved.
|
||||
%% If you modify this file, you must change its name first.
|
||||
%% You are NOT ALLOWED to distribute this file alone. You are NOT
|
||||
%% ALLOWED to take money for the distribution or use of either this
|
||||
%% file or a changed version, except for a nominal charge for copying
|
||||
%% etc.
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{glossary}
|
||||
\RequirePackage{ifthen}
|
||||
\RequirePackage{keyval}
|
||||
\define@key{gloss}
|
||||
{style}
|
||||
{\ifthenelse{\equal{#1}{list} \or \equal{#1}{altlist} \or \equal{#1}{super} \or \equal{#1}{long}}
|
||||
{\def\gls@style{#1}}
|
||||
{\PackageError{glossary}
|
||||
{Unknown glossary style '#1'}
|
||||
{Available styles are: list, altlist, super and long}}}
|
||||
|
||||
\define@key{gloss}
|
||||
{header}[plain]{\ifthenelse{\equal{#1}{none} \or \equal{#1}{plain}}
|
||||
{\def\gls@header{#1}}
|
||||
{\PackageError{glossary}
|
||||
{Unknown glossary style '#1'}
|
||||
{Available styles are: none and plain}}}
|
||||
|
||||
\define@key{gloss}
|
||||
{border}[plain]{\ifthenelse{\equal{#1}{none} \or \equal{#1}{plain}}
|
||||
{\def\gls@border{#1}}
|
||||
{\PackageError{glossary}
|
||||
{Unknown glossary border '#1'}
|
||||
{Available styles are: none and plain}}}
|
||||
\newcount\gls@cols
|
||||
\define@key{gloss}{cols}{\gls@cols=#1\relax
|
||||
\ifthenelse{\gls@cols<2 \or \gls@cols>3}
|
||||
{\PackageError{glossary}
|
||||
{invalid number of columns}
|
||||
{The cols option can only be 2 or 3}}
|
||||
{}}
|
||||
|
||||
\define@key{gloss}
|
||||
{number}
|
||||
{\ifthenelse{\equal{#1}{none}\or\equal{#1}{page}\or\equal{#1}{section}}
|
||||
{\def\gls@number{#1}}
|
||||
{\PackageError{glossary}
|
||||
{Unknown glossary number style '#1'}
|
||||
{Available styles are: none, page and section}}}
|
||||
|
||||
\newif\ifgls@toc
|
||||
\define@key{gloss}{toc}[true]{\ifthenelse{\equal{#1}{true} \or \equal{#1}{false}}
|
||||
{\csname gls@toc#1\endcsname}
|
||||
{\PackageError{glossary}{Glossary option 'toc' is boolean}
|
||||
{The value of 'toc' can only be set to 'true' or 'false'}}}
|
||||
|
||||
\newif\ifglshyper
|
||||
\define@key{gloss}{hyper}[true]{\ifthenelse{\equal{#1}{true} \or \equal{#1}{false}}
|
||||
{\csname glshyper#1\endcsname}
|
||||
{\PackageError{glossary}{Glossary option 'hyper' is boolean}
|
||||
{The value of 'hyper' can only be set to 'true' or 'false'}}}
|
||||
\def\gls@style{long}
|
||||
\def\gls@header{none}
|
||||
\def\gls@border{none}
|
||||
\def\gls@number{page}
|
||||
\gls@cols=2\relax
|
||||
\gls@tocfalse
|
||||
\@ifundefined{hyperpage}{\glshyperfalse}{\glshypertrue}
|
||||
|
||||
\DeclareOption*{\edef\@pkg@ptions{\noexpand\setkeys{gloss}{\CurrentOption}}
|
||||
\ifthenelse{\equal{\CurrentOption}{}}{}{\@pkg@ptions}}
|
||||
|
||||
\ProcessOptions
|
||||
\ifthenelse{\(\equal{\gls@style}{list} \or \equal{\gls@style}{altlist}\) \and \(\not\equal{\gls@header}{none} \or \not\equal{\gls@border}{none} \or \gls@cols=3\)}
|
||||
{\PackageError{glossary}{You can't have option 'style=list' or 'style=altlist' in combination with any of the other options}
|
||||
{The 'list' and 'altlist' options don't have a header, border or number of columns option.}}
|
||||
{}
|
||||
\define@key{wrgloss}{name}{\def\@n@me{#1}}
|
||||
\define@key{wrgloss}{description}{\def\@descr{#1}}
|
||||
\define@key{wrgloss}{sort}{\def\@s@rt{#1}}
|
||||
\define@key{wrgloss}{format}{\def\@f@rm@t{#1}}
|
||||
\renewcommand{\@wrglossary}[1]{\relax
|
||||
\def\@n@me{}\def\@descr{}\def\@s@rt{}\def\@f@rm@t{}\relax
|
||||
\setkeys{wrgloss}{#1}\relax
|
||||
\ifthenelse{\equal{\@s@rt}{}}
|
||||
{\relax
|
||||
\ifthenelse{\equal{\@f@rm@t}{}}
|
||||
{\protected@write\@glossaryfile{}{\string\glossaryentry{\@n@me @{\@n@me}\@descr\string\relax|glsnumformat}{\theglossarynum}}}
|
||||
{\protected@write\@glossaryfile{}{\string\glossaryentry{\@n@me @{\@n@me}\@descr\string\relax|\@f@rm@t}{\theglossarynum}}}\relax
|
||||
}{\relax
|
||||
\ifthenelse{\equal{\@f@rm@t}{}}
|
||||
{\protected@write\@glossaryfile{}{\string\glossaryentry{\@s@rt @{\@n@me}\@descr\string\relax|glsnumformat}{\theglossarynum}}}
|
||||
{\protected@write\@glossaryfile{}{\string\glossaryentry{\@s@rt @{\@n@me}\@descr\string\relax|\@f@rm@t}{\theglossarynum}}}\relax
|
||||
}\relax
|
||||
\endgroup\@esphack
|
||||
}
|
||||
\ifthenelse{\equal{\gls@number}{page}}{
|
||||
\newcommand{\theglossarynum}{\thepage}
|
||||
\newcommand{\pagecompositor}{-}
|
||||
\newcommand{\delimN}{, }
|
||||
\newcommand{\delimR}{--}
|
||||
\ifglshyper\newcommand{\glsnumformat}[1]{\hyperpage{#1}}\else\newcommand{\glsnumformat}[1]{#1}\fi}
|
||||
{\ifthenelse{\equal{\gls@number}{section}}
|
||||
{\newcommand{\theglossarynum}{\thesection}
|
||||
\newcommand{\pagecompositor}{.}
|
||||
\newcommand{\delimN}{, }
|
||||
\newcommand{\delimR}{--}
|
||||
\ifglshyper\newcommand{\glsnumformat}[1]{\hypersection{#1}}\else\newcommand{\glsnumformat}[1]{#1}\fi}
|
||||
{\newcommand{\theglossarynum}{\thepage}
|
||||
\newcommand{\pagecompositor}{-}
|
||||
\newcommand{\delimN}{}
|
||||
\newcommand{\delimR}{}
|
||||
\newcommand{\glsnumformat}[1]{}}}
|
||||
\newcommand\printglossary{\@input@{\jobname.gls}}
|
||||
\newcommand{\glossaryname}{Glossary}
|
||||
\newcommand{\entryname}{Notation}
|
||||
\newcommand{\descriptionname}{Description}
|
||||
\newcommand{\istfilename}{\jobname.ist}
|
||||
\newenvironment{theglossary}
|
||||
{\@ifundefined{chapter}
|
||||
{\section*{\glossaryname}\ifgls@toc\addcontentsline{toc}{section}{\glossaryname}\fi}
|
||||
{\chapter*{\glossaryname}\ifgls@toc\addcontentsline{toc}{chapter}{\glossaryname}\fi}
|
||||
\glossarypreamble\@bef@reglos}
|
||||
{\@ftergl@s\glossarypostamble}
|
||||
|
||||
\newcommand{\glossarypreamble}{}
|
||||
\newcommand{\glossarypostamble}{}
|
||||
|
||||
\newif\ifgloitemfirst
|
||||
\newcommand{\@bef@reglos}{\global\gloitemfirsttrue\beforeglossary}
|
||||
\newcommand{\@ftergl@s}{\afterglossary\global\gloitemfirstfalse}
|
||||
|
||||
\ifthenelse{\equal{\gls@style}{list} \or \equal{\gls@style}{altlist}}
|
||||
{
|
||||
\newcommand{\beforeglossary}{\begin{description}}
|
||||
\newcommand{\afterglossary}{\end{description}}
|
||||
\newcommand{\gloskip}{\indexspace}
|
||||
\ifthenelse{\equal{\gls@style}{list}}
|
||||
{\newcommand{\gloitem}[1]{\item[#1]}
|
||||
\newcommand{\glodelim}{, }}
|
||||
{\newcommand{\gloitem}[1]{\item[#1]\mbox{}\par}
|
||||
\newcommand{\glodelim}{ }}
|
||||
}{
|
||||
\ifthenelse{\equal{\gls@style}{super}}{
|
||||
\IfFileExists{supertab.sty}{\RequirePackage{supertab}}
|
||||
{\IfFileExists{supertabular.sty}{\RequirePackage{supertabular}}
|
||||
{\PackageError{glossary}{Option "super" chosen, but can't find "supertab" package}
|
||||
{If you want the "super" option, you have to have the "supertab" package installed.}}}
|
||||
}
|
||||
{\RequirePackage{longtable}}
|
||||
|
||||
\newlength{\descriptionwidth}
|
||||
\setlength{\descriptionwidth}{0.6\textwidth}
|
||||
|
||||
\ifthenelse{\equal{\gls@header}{none}}
|
||||
{
|
||||
\ifthenelse{\equal{\gls@border}{none}}
|
||||
{\newcommand{\glossaryheader}{}}
|
||||
{\newcommand{\glossaryheader}{\hline }}
|
||||
}
|
||||
{
|
||||
\ifnum\gls@cols=2\relax
|
||||
\ifthenelse{\equal{\gls@border}{none}}
|
||||
{\newcommand{\glossaryheader}
|
||||
{\bfseries\entryname & \bfseries \descriptionname\\}}
|
||||
{\newcommand{\glossaryheader}
|
||||
{\hline\bfseries\entryname & \bfseries\descriptionname
|
||||
\\\hline\hline}}
|
||||
\else
|
||||
\ifthenelse{\equal{\gls@border}{none}}
|
||||
{\newcommand{\glossaryheader}
|
||||
{\bfseries\entryname & \bfseries \descriptionname & \\}}
|
||||
{\newcommand{\glossaryheader}
|
||||
{\hline\bfseries\entryname &\bfseries\descriptionname &
|
||||
\\\hline\hline}}
|
||||
\fi
|
||||
}
|
||||
|
||||
\ifthenelse{\equal{\gls@border}{none}}
|
||||
{
|
||||
\ifnum\gls@cols=2\relax
|
||||
\@ifundefined{newcolumntype}{\newcommand{\glossaryalignment}{@{\hspace{\tabcolsep}\bfseries}lp{\descriptionwidth}}}{
|
||||
\newcolumntype{G}{@{\hspace{\tabcolsep}\bfseries}lp{\descriptionwidth}}}
|
||||
\else
|
||||
\@ifundefined{newcolumntype}{\newcommand{\glossaryalignment}{@{\hspace{\tabcolsep}\bfseries}lp{\descriptionwidth}l}}{
|
||||
\newcolumntype{G}{@{\hspace{\tabcolsep}\bfseries}lp{\descriptionwidth}l}}
|
||||
\fi
|
||||
|
||||
\ifthenelse{\equal{\gls@style}{super}}{
|
||||
\newcommand{\afterglossary}{ \\\end{supertabular}}
|
||||
}
|
||||
{
|
||||
\newcommand{\afterglossary}{ \\\end{longtable}}
|
||||
}
|
||||
|
||||
\newcommand{\glosstail}{}
|
||||
}
|
||||
{
|
||||
\ifnum\gls@cols=2\relax
|
||||
\@ifundefined{newcolumntype}{\newcommand{\glossaryalignment}{|@{\hspace{\tabcolsep}\bfseries}lp{\descriptionwidth}|}}{
|
||||
\newcolumntype{G}{|@{\hspace{\tabcolsep}\bfseries}lp{\descriptionwidth}|}}
|
||||
\else
|
||||
\@ifundefined{newcolumntype}{\newcommand{\glossaryalignment}{|@{\hspace{\tabcolsep}\bfseries}lp{\descriptionwidth}l|}}{
|
||||
\newcolumntype{G}{|@{\hspace{\tabcolsep}\bfseries}lp{\descriptionwidth}l|}}
|
||||
\fi
|
||||
|
||||
\ifthenelse{\equal{\gls@style}{super}}{
|
||||
\newcommand{\afterglossary}{ \\\hline\end{supertabular}}
|
||||
}
|
||||
{
|
||||
\newcommand{\afterglossary}{ \\\hline\end{longtable}}
|
||||
}
|
||||
|
||||
\newcommand{\glosstail}{\hline}
|
||||
}
|
||||
|
||||
\ifthenelse{\equal{\gls@style}{super}}
|
||||
{
|
||||
\@ifundefined{newcolumntype}{
|
||||
\newcommand{\beforeglossary}
|
||||
{\tablehead{\glossaryheader}\tabletail{\glosstail}
|
||||
\begin{supertabular}{\glossaryalignment}}}
|
||||
{\newcommand{\beforeglossary}
|
||||
{\tablehead{\glossaryheader}\tabletail{\glosstail}
|
||||
\begin{supertabular}{G}}}
|
||||
}
|
||||
{
|
||||
\@ifundefined{newcolumntype}{\newcommand{\beforeglossary}
|
||||
{\begin{longtable}{\glossaryalignment}
|
||||
\glossaryheader\endhead\glosstail\endfoot}}
|
||||
{\newcommand{\beforeglossary}
|
||||
{\begin{longtable}{G}
|
||||
\glossaryheader\endhead\glosstail\endfoot}}
|
||||
}
|
||||
|
||||
\ifnum\gls@cols=2\relax
|
||||
\newcommand{\gloskip}{\ifgloitemfirst\global\gloitemfirstfalse \else\\ \fi &}
|
||||
\newcommand{\glodelim}{, }
|
||||
\else
|
||||
\newcommand{\gloskip}{\ifgloitemfirst\global\gloitemfirstfalse \else\\ \fi & &}
|
||||
\newcommand{\glodelim}{& }
|
||||
\fi
|
||||
\newcommand{\gloitem}[1]{\ifgloitemfirst\global\gloitemfirstfalse #1 \else \\#1 \fi &}
|
||||
}
|
||||
|
||||
\ifthenelse{\equal{\gls@number}{none} \and \gls@cols<3}{\renewcommand{\glodelim}{}}{}
|
||||
\newif\ifist
|
||||
\let\noist=\istfalse
|
||||
\if@filesw\isttrue\else\istfalse\fi
|
||||
|
||||
\newwrite\istfile
|
||||
\catcode`\%11\relax
|
||||
\newcommand{\writeist}{
|
||||
\openout\istfile=\istfilename
|
||||
\write\istfile{% makeindex style file created by LaTeX for document "\jobname" on \the\year-\the\month-\the\day}
|
||||
\write\istfile{keyword "\string\\glossaryentry"}
|
||||
\write\istfile{preamble "\string\\begin{theglossary}"}
|
||||
\write\istfile{postamble "\string\n\string\\end{theglossary}\string\n"}
|
||||
\write\istfile{group_skip "\string\\gloskip "}
|
||||
\write\istfile{item_0 "\string\n\string\\gloitem "}
|
||||
\write\istfile{delim_0 "\string\n\string\\glodelim "}
|
||||
\write\istfile{page_compositor "\pagecompositor"}
|
||||
\write\istfile{delim_n "\string\\delimN"}
|
||||
\write\istfile{delim_r "\string\\delimR"}
|
||||
\closeout\istfile
|
||||
}
|
||||
\catcode`\%14\relax
|
||||
\renewcommand{\makeglossary}{
|
||||
\newwrite\@glossaryfile
|
||||
\immediate\openout\@glossaryfile=\jobname.glo
|
||||
\def\glossary{\@bsphack \begingroup \@sanitize \@wrglossary }
|
||||
\typeout {Writing glossary file \jobname .glo }
|
||||
\let \makeglossary \@empty
|
||||
\ifist\writeist\fi
|
||||
\noist}
|
||||
\newcommand{\newglossarytype}[3]{
|
||||
\@ifundefined{#1}{%
|
||||
\def\@glstype{#1}\def\@glsout{#2}\def\@glsin{#3}%
|
||||
\expandafter\edef\csname make\@glstype\endcsname{\noexpand\@m@kegl@ss{\@glstype}{\@glsout}}
|
||||
\expandafter\edef\csname \@glstype\endcsname{\noexpand\@gl@ss@ary{\@glstype}}
|
||||
\expandafter\edef\csname print\@glstype\endcsname{\noexpand\@prntgl@ss@ry{\@glsin}}
|
||||
}{\PackageError{glossary}{Command \expandafter\string\csname #1\endcsname \space already defined}{%
|
||||
You can't call your new glossary type '#1' because there already exists a command with this name}}
|
||||
}
|
||||
\newcommand\@m@kegl@ss[2]{
|
||||
\expandafter\newwrite\csname @#1file\endcsname
|
||||
\expandafter\immediate\expandafter\openout\csname @#1file\endcsname=\jobname.#2
|
||||
\typeout {Writing #1 file \jobname .#2 }
|
||||
\expandafter\let \csname make#1\endcsname \@empty
|
||||
\ifist\writeist\fi
|
||||
\expandafter\def\csname the#1num\endcsname{\thepage}
|
||||
\noist
|
||||
}
|
||||
\newcommand{\@wrgl@ss@ry}[2]{\relax
|
||||
\def\@n@me{}\def\@descr{}\def\@s@rt{}\def\@f@rm@t{}\relax
|
||||
\setkeys{wrgloss}{#2}\relax
|
||||
\ifthenelse{\equal{\@s@rt}{}}
|
||||
{\relax
|
||||
\ifthenelse{\equal{\@f@rm@t}{}}
|
||||
{\expandafter\protected@write\csname @#1file\endcsname{}{\string\glossaryentry{\@n@me @{\@n@me}\@descr\string\relax|glsnumformat}{\csname the#1num\endcsname}}}
|
||||
{\expandafter\protected@write\csname @#1file\endcsname{}{\string\glossaryentry{\@n@me @{\@n@me}\@descr\string\relax|\@f@rm@t}{\csname the#1num\endcsname}}}\relax
|
||||
}{\relax
|
||||
\ifthenelse{\equal{\@f@rm@t}{}}
|
||||
{\expandafter\protected@write\csname @#1file\endcsname{}{\string\glossaryentry{\@s@rt @{\@n@me}\@descr\string\relax|glsnumformat}{\csname the#1num\endcsname}}}
|
||||
{\expandafter\protected@write\csname @#1file\endcsname{}{\string\glossaryentry{\@s@rt @{\@n@me}\@descr\string\relax|\@f@rm@t}{\csname the#1num\endcsname}}}\relax
|
||||
}\relax
|
||||
\endgroup\@esphack
|
||||
}
|
||||
\newcommand\@gl@ss@ary[1]{\@ifundefined{@#1file}{\@bsphack\begingroup \@sanitize \@index}{\@bsphack \begingroup \@sanitize \@wrgl@ss@ry{#1}}}
|
||||
\newcommand\@prntgl@ss@ry[1]{\@input@{\jobname.#1}}
|
||||
\@onlypreamble{\newglossarytype}
|
||||
\newcommand\@acrnmsh{}
|
||||
\newcommand\@acrnmln{}
|
||||
\newcommand\@acrnmcmd{}
|
||||
\newcommand\@acrnmgls{}
|
||||
\newcommand\@acrnmins{}
|
||||
|
||||
\newcommand{\glsprimaryfmt}[1]{\textbf{\glsnumformat{#1}}}
|
||||
|
||||
\newcommand{\newacronym}[4][]{%
|
||||
\ifthenelse{\equal{#1}{}}{\renewcommand\@acrnmcmd{#2}}{\renewcommand\@acrnmcmd{#1}}
|
||||
\@ifundefined{\@acrnmcmd}{%
|
||||
\renewcommand\@acrnmsh{#2}
|
||||
\renewcommand\@acrnmln{#3}
|
||||
\expandafter\gdef\csname @\@acrnmcmd @glsentryi\endcsname{{name={#3 (#2)},format=glsprimaryfmt,#4}}%
|
||||
\expandafter\gdef\csname @\@acrnmcmd @glsentry\endcsname{{name={#3 (#2)},format=glsnumformat,#4}}%
|
||||
\newboolean{\@acrnmcmd first}\setboolean{\@acrnmcmd first}{true}%
|
||||
\expandafter\edef\csname @\@acrnmcmd\endcsname{\noexpand\ifthenelse{\noexpand\boolean{\@acrnmcmd first}}%
|
||||
{\@acrnmln\noexpand\@acrnmins\ (\@acrnmsh)\noexpand\expandafter\noexpand\glossary\expandafter\noexpand\csname @\@acrnmcmd @glsentryi\endcsname%
|
||||
\noexpand\global\noexpand\let\expandafter\noexpand\csname if\@acrnmcmd first\endcsname=\noexpand\iffalse
|
||||
}%
|
||||
{\@acrnmsh\noexpand\@acrnmins\noexpand\expandafter\noexpand\glossary\expandafter\noexpand\csname @\@acrnmcmd @glsentry\endcsname}}
|
||||
\expandafter\edef\csname @s@\@acrnmcmd\endcsname{\noexpand\ifthenelse{\noexpand\boolean{\@acrnmcmd first}}%
|
||||
{\noexpand\MakeUppercase\@acrnmln\noexpand\@acrnmins\ (\@acrnmsh)\noexpand\expandafter\noexpand\glossary\expandafter\noexpand\csname @\@acrnmcmd @glsentryi\endcsname%
|
||||
\noexpand\global\noexpand\let\expandafter\noexpand\csname if\@acrnmcmd first\endcsname=\noexpand\iffalse
|
||||
}%
|
||||
{\noexpand\MakeUppercase\@acrnmsh\noexpand\@acrnmins\noexpand\expandafter\noexpand\glossary\expandafter\noexpand\csname @\@acrnmcmd @glsentry\endcsname}}
|
||||
\expandafter\edef\csname\@acrnmcmd\endcsname{\noexpand\@ifstar\expandafter\noexpand\csname @s@\@acrnmcmd\endcsname
|
||||
\expandafter\noexpand\csname @\@acrnmcmd\endcsname}%
|
||||
}
|
||||
{\PackageError{glossary}{Command '\expandafter\string\csname\@acrnmcmd\endcsname' already defined}{
|
||||
The command name specified by \string\newacronym already exists.}}}
|
||||
|
||||
\newcommand{\useacronym}{\@ifstar\@suseacronym\@useacronym}
|
||||
\newcommand{\@suseacronym}[2][]{{\def\@acrnmins{#1}\csname @s@#2\endcsname}}
|
||||
\newcommand{\@useacronym}[2][]{{\def\@acrnmins{#1}\csname @#2\endcsname}}
|
||||
\ifglshyper
|
||||
\def\hypersection#1{\@hypersection#1----\\}
|
||||
\def\@hypersection#1--#2--#3\\{%
|
||||
\ifx\\#2\\%
|
||||
\@commahypersection{#1}%
|
||||
\else
|
||||
\@ifundefined{hyperlink}{#1--#2}{\hyperlink{section.#1}{#1}--\hyperlink{section.#2}{#2}}%
|
||||
\fi
|
||||
}
|
||||
\def\@commahypersection#1{\@@commahypersection#1, ,\\}
|
||||
\def\@@commahypersection#1, #2,#3\\{%
|
||||
\ifx\\#2\\%
|
||||
\@ifundefined{hyperlink}{#1}{\hyperlink{section.#1}{#1}}%
|
||||
\else
|
||||
\@ifundefined{hyperlink}{#1, #2}{\hyperlink{section.#1}{#1}, \hyperlink{section.#2}{#2}}%
|
||||
\fi
|
||||
}
|
||||
|
||||
\ifthenelse{\equal{\gls@number}{section}}{
|
||||
\ifglshyper
|
||||
\@ifundefined{chapter}
|
||||
{}
|
||||
{\let\@gls@old@chapter\@chapter
|
||||
\def\@chapter[#1]#2{\@gls@old@chapter[{#1}]{#2}\@ifundefined{hyperdef}{}{\hyperdef{section}{\thechapter.0}{}}}}
|
||||
\fi
|
||||
|
||||
\providecommand\hypersf[1]{\textsf{\hypersection{#1}}}
|
||||
\providecommand\hypertt[1]{\texttt{\hypersection{#1}}}
|
||||
\providecommand\hyperbf[1]{\textbf{\hypersection{#1}}}
|
||||
\providecommand\hyperit[1]{\textit{\hypersection{#1}}}
|
||||
}
|
||||
{
|
||||
\providecommand\hypersf[1]{\textsf{\hyperpage{#1}}}
|
||||
\providecommand\hypertt[1]{\texttt{\hyperpage{#1}}}
|
||||
\providecommand\hyperbf[1]{\textbf{\hyperpage{#1}}}
|
||||
\providecommand\hyperit[1]{\textit{\hyperpage{#1}}}
|
||||
}
|
||||
\else
|
||||
\providecommand\hypersf[1]{\textsf{#1}}
|
||||
\providecommand\hypertt[1]{\texttt{#1}}
|
||||
\providecommand\hyperbf[1]{\textbf{#1}}
|
||||
\providecommand\hyperit[1]{\textit{#1}}
|
||||
\fi
|
||||
\endinput
|
||||
%%
|
||||
%% End of file `glossary.sty'.
|
6578
doc/handbook.tex
6578
doc/handbook.tex
File diff suppressed because it is too large
Load Diff
Binary file not shown.
5460
doc/interpreter.eps
5460
doc/interpreter.eps
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +0,0 @@
|
|||
#!/bin/sh
|
||||
echo X | pdflatex handbook
|
||||
makeindex handbook
|
||||
sh makeglos handbook
|
||||
pdflatex handbook
|
||||
pdflatex handbook
|
||||
pdflatex handbook
|
|
@ -1,2 +0,0 @@
|
|||
#!/bin/sh
|
||||
makeindex -s $1.ist -t $1.glg -o $1.gls $1.glo
|
|
@ -1,390 +0,0 @@
|
|||
% Mathpartir --- Math Paragraph for Typesetting Inference Rules
|
||||
%
|
||||
% Copyright (C) 2001, 2002, 2003 Didier Rémy
|
||||
%
|
||||
% Author : Didier Remy
|
||||
% Version : 1.1.1
|
||||
% Bug Reports : to author
|
||||
% Web Site : http://pauillac.inria.fr/~remy/latex/
|
||||
%
|
||||
% WhizzyTeX is free software; you can redistribute it and/or modify
|
||||
% it under the terms of the GNU General Public License as published by
|
||||
% the Free Software Foundation; either version 2, or (at your option)
|
||||
% any later version.
|
||||
%
|
||||
% Mathpartir is distributed in the hope that it will be useful,
|
||||
% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
% GNU General Public License for more details
|
||||
% (http://pauillac.inria.fr/~remy/license/GPL).
|
||||
%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% File mathpartir.sty (LaTeX macros)
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{mathpartir}
|
||||
[2003/07/10 version 1.1.1 Math Paragraph for Typesetting Inference Rules]
|
||||
|
||||
%%
|
||||
|
||||
%% Identification
|
||||
%% Preliminary declarations
|
||||
|
||||
\RequirePackage {keyval}
|
||||
|
||||
%% Options
|
||||
%% More declarations
|
||||
|
||||
%% PART I: Typesetting maths in paragraphe mode
|
||||
|
||||
\newdimen \mpr@tmpdim
|
||||
|
||||
% To ensure hevea \hva compatibility, \hva should expands to nothing
|
||||
% in mathpar or in inferrule
|
||||
\let \mpr@hva \empty
|
||||
|
||||
%% normal paragraph parametters, should rather be taken dynamically
|
||||
\def \mpr@savepar {%
|
||||
\edef \MathparNormalpar
|
||||
{\noexpand \lineskiplimit \the\lineskiplimit
|
||||
\noexpand \lineskip \the\lineskip}%
|
||||
}
|
||||
|
||||
\def \mpr@rulelineskip {\lineskiplimit=0.3em\lineskip=0.2em plus 0.1em}
|
||||
\def \mpr@lesslineskip {\lineskiplimit=0.6em\lineskip=0.5em plus 0.2em}
|
||||
\def \mpr@lineskip {\lineskiplimit=1.2em\lineskip=1.2em plus 0.2em}
|
||||
\let \MathparLineskip \mpr@lineskip
|
||||
\def \mpr@paroptions {\MathparLineskip}
|
||||
\let \mpr@prebindings \relax
|
||||
|
||||
\newskip \mpr@andskip \mpr@andskip 2em plus 0.5fil minus 0.5em
|
||||
|
||||
\def \mpr@goodbreakand
|
||||
{\hskip -\mpr@andskip \penalty -1000\hskip \mpr@andskip}
|
||||
\def \mpr@and {\hskip \mpr@andskip}
|
||||
\def \mpr@andcr {\penalty 50\mpr@and}
|
||||
\def \mpr@cr {\penalty -10000\mpr@and}
|
||||
\def \mpr@eqno #1{\mpr@andcr #1\hskip 0em plus -1fil \penalty 10}
|
||||
|
||||
\def \mpr@bindings {%
|
||||
\let \and \mpr@andcr
|
||||
\let \par \mpr@andcr
|
||||
\let \\\mpr@cr
|
||||
\let \eqno \mpr@eqno
|
||||
\let \hva \mpr@hva
|
||||
}
|
||||
\let \MathparBindings \mpr@bindings
|
||||
|
||||
% \@ifundefined {ignorespacesafterend}
|
||||
% {\def \ignorespacesafterend {\aftergroup \ignorespaces}
|
||||
|
||||
\newenvironment{mathpar}[1][]
|
||||
{$$\mpr@savepar \parskip 0em \hsize \linewidth \centering
|
||||
\vbox \bgroup \mpr@prebindings \mpr@paroptions #1\ifmmode $\else
|
||||
\noindent $\displaystyle\fi
|
||||
\MathparBindings}
|
||||
{\unskip \ifmmode $\fi\egroup $$\ignorespacesafterend}
|
||||
|
||||
% \def \math@mathpar #1{\setbox0 \hbox {$\displaystyle #1$}\ifnum
|
||||
% \wd0 < \hsize $$\box0$$\else \bmathpar #1\emathpar \fi}
|
||||
|
||||
%%% HOV BOXES
|
||||
|
||||
\def \mathvbox@ #1{\hbox \bgroup \mpr@normallineskip
|
||||
\vbox \bgroup \tabskip 0em \let \\ \cr
|
||||
\halign \bgroup \hfil $##$\hfil\cr #1\crcr \egroup \egroup
|
||||
\egroup}
|
||||
|
||||
\def \mathhvbox@ #1{\setbox0 \hbox {\let \\\qquad $#1$}\ifnum \wd0 < \hsize
|
||||
\box0\else \mathvbox {#1}\fi}
|
||||
|
||||
|
||||
%% Part II -- operations on lists
|
||||
|
||||
\newtoks \mpr@lista
|
||||
\newtoks \mpr@listb
|
||||
|
||||
\long \def\mpr@cons #1\mpr@to#2{\mpr@lista {\\{#1}}\mpr@listb \expandafter
|
||||
{#2}\edef #2{\the \mpr@lista \the \mpr@listb}}
|
||||
|
||||
\long \def\mpr@snoc #1\mpr@to#2{\mpr@lista {\\{#1}}\mpr@listb \expandafter
|
||||
{#2}\edef #2{\the \mpr@listb\the\mpr@lista}}
|
||||
|
||||
\long \def \mpr@concat#1=#2\mpr@to#3{\mpr@lista \expandafter {#2}\mpr@listb
|
||||
\expandafter {#3}\edef #1{\the \mpr@listb\the\mpr@lista}}
|
||||
|
||||
\def \mpr@head #1\mpr@to #2{\expandafter \mpr@head@ #1\mpr@head@ #1#2}
|
||||
\long \def \mpr@head@ #1#2\mpr@head@ #3#4{\def #4{#1}\def#3{#2}}
|
||||
|
||||
\def \mpr@flatten #1\mpr@to #2{\expandafter \mpr@flatten@ #1\mpr@flatten@ #1#2}
|
||||
\long \def \mpr@flatten@ \\#1\\#2\mpr@flatten@ #3#4{\def #4{#1}\def #3{\\#2}}
|
||||
|
||||
\def \mpr@makelist #1\mpr@to #2{\def \mpr@all {#1}%
|
||||
\mpr@lista {\\}\mpr@listb \expandafter {\mpr@all}\edef \mpr@all {\the
|
||||
\mpr@lista \the \mpr@listb \the \mpr@lista}\let #2\empty
|
||||
\def \mpr@stripof ##1##2\mpr@stripend{\def \mpr@stripped{##2}}\loop
|
||||
\mpr@flatten \mpr@all \mpr@to \mpr@one
|
||||
\expandafter \mpr@snoc \mpr@one \mpr@to #2\expandafter \mpr@stripof
|
||||
\mpr@all \mpr@stripend
|
||||
\ifx \mpr@stripped \empty \let \mpr@isempty 0\else \let \mpr@isempty 1\fi
|
||||
\ifx 1\mpr@isempty
|
||||
\repeat
|
||||
}
|
||||
|
||||
%% Part III -- Type inference rules
|
||||
|
||||
\def \mpr@rev #1\mpr@to #2{\let \mpr@tmp \empty
|
||||
\def \\##1{\mpr@cons ##1\mpr@to \mpr@tmp}#1\let #2\mpr@tmp}
|
||||
|
||||
\newif \if@premisse
|
||||
\newbox \mpr@hlist
|
||||
\newbox \mpr@vlist
|
||||
\newif \ifmpr@center \mpr@centertrue
|
||||
\def \mpr@htovlist {%
|
||||
\setbox \mpr@hlist
|
||||
\hbox {\strut
|
||||
\ifmpr@center \hskip -0.5\wd\mpr@hlist\fi
|
||||
\unhbox \mpr@hlist}%
|
||||
\setbox \mpr@vlist
|
||||
\vbox {\if@premisse \box \mpr@hlist \unvbox \mpr@vlist
|
||||
\else \unvbox \mpr@vlist \box \mpr@hlist
|
||||
\fi}%
|
||||
}
|
||||
% OLD version
|
||||
% \def \mpr@htovlist {%
|
||||
% \setbox \mpr@hlist
|
||||
% \hbox {\strut \hskip -0.5\wd\mpr@hlist \unhbox \mpr@hlist}%
|
||||
% \setbox \mpr@vlist
|
||||
% \vbox {\if@premisse \box \mpr@hlist \unvbox \mpr@vlist
|
||||
% \else \unvbox \mpr@vlist \box \mpr@hlist
|
||||
% \fi}%
|
||||
% }
|
||||
|
||||
\def \mpr@sep{2em}
|
||||
\def \mpr@blank { }
|
||||
\def \mpr@hovbox #1#2{\hbox
|
||||
\bgroup
|
||||
\ifx #1T\@premissetrue
|
||||
\else \ifx #1B\@premissefalse
|
||||
\else
|
||||
\PackageError{mathpartir}
|
||||
{Premisse orientation should either be P or B}
|
||||
{Fatal error in Package}%
|
||||
\fi \fi
|
||||
\def \@test {#2}\ifx \@test \mpr@blank\else
|
||||
\setbox \mpr@hlist \hbox {}%
|
||||
\setbox \mpr@vlist \vbox {}%
|
||||
\if@premisse \let \snoc \mpr@cons \else \let \snoc \mpr@snoc \fi
|
||||
\let \@hvlist \empty \let \@rev \empty
|
||||
\mpr@tmpdim 0em
|
||||
\expandafter \mpr@makelist #2\mpr@to \mpr@flat
|
||||
\if@premisse \mpr@rev \mpr@flat \mpr@to \@rev \else \let \@rev \mpr@flat \fi
|
||||
\def \\##1{%
|
||||
\def \@test {##1}\ifx \@test \empty
|
||||
\mpr@htovlist
|
||||
\mpr@tmpdim 0em %%% last bug fix not extensively checked
|
||||
\else
|
||||
\setbox0 \hbox{$\displaystyle {##1}$}\relax
|
||||
\advance \mpr@tmpdim by \wd0
|
||||
%\mpr@tmpdim 1.02\mpr@tmpdim
|
||||
\ifnum \mpr@tmpdim < \hsize
|
||||
\ifnum \wd\mpr@hlist > 0
|
||||
\if@premisse
|
||||
\setbox \mpr@hlist
|
||||
\hbox {\unhbox0 \hskip \mpr@sep \unhbox \mpr@hlist}%
|
||||
\else
|
||||
\setbox \mpr@hlist
|
||||
\hbox {\unhbox \mpr@hlist \hskip \mpr@sep \unhbox0}%
|
||||
\fi
|
||||
\else
|
||||
\setbox \mpr@hlist \hbox {\unhbox0}%
|
||||
\fi
|
||||
\else
|
||||
\ifnum \wd \mpr@hlist > 0
|
||||
\mpr@htovlist
|
||||
\mpr@tmpdim \wd0
|
||||
\fi
|
||||
\setbox \mpr@hlist \hbox {\unhbox0}%
|
||||
\fi
|
||||
\advance \mpr@tmpdim by \mpr@sep
|
||||
\fi
|
||||
}%
|
||||
\@rev
|
||||
\mpr@htovlist
|
||||
\ifmpr@center \hskip \wd\mpr@vlist\fi \box \mpr@vlist
|
||||
\fi
|
||||
\egroup
|
||||
}
|
||||
|
||||
%%% INFERENCE RULES
|
||||
|
||||
\@ifundefined{@@over}{%
|
||||
\let\@@over\over % fallback if amsmath is not loaded
|
||||
\let\@@overwithdelims\overwithdelims
|
||||
\let\@@atop\atop \let\@@atopwithdelims\atopwithdelims
|
||||
\let\@@above\above \let\@@abovewithdelims\abovewithdelims
|
||||
}{}
|
||||
|
||||
|
||||
\def \mpr@@fraction #1#2{\hbox {\advance \hsize by -0.5em
|
||||
$\displaystyle {#1\@@over #2}$}}
|
||||
\let \mpr@fraction \mpr@@fraction
|
||||
\def \mpr@@reduce #1#2{\hbox
|
||||
{$\lower 0.01pt \mpr@@fraction {#1}{#2}\mkern -15mu\rightarrow$}}
|
||||
\def \mpr@@rewrite #1#2#3{\hbox
|
||||
{$\lower 0.01pt \mpr@@fraction {#2}{#3}\mkern -8mu#1$}}
|
||||
\def \mpr@infercenter #1{\vcenter {\mpr@hovbox{T}{#1}}}
|
||||
|
||||
\def \mpr@empty {}
|
||||
\def \mpr@inferrule
|
||||
{\bgroup
|
||||
\ifnum \linewidth<\hsize \hsize \linewidth\fi
|
||||
\mpr@rulelineskip
|
||||
\let \and \qquad
|
||||
\let \hva \mpr@hva
|
||||
\let \@rulename \mpr@empty
|
||||
\let \@rule@options \mpr@empty
|
||||
\mpr@inferrule@}
|
||||
\newcommand {\mpr@inferrule@}[3][]
|
||||
{\everymath={\displaystyle}%
|
||||
\def \@test {#2}\ifx \empty \@test
|
||||
\setbox0 \hbox {$\vcenter {\mpr@hovbox{B}{#3}}$}%
|
||||
\else
|
||||
\def \@test {#3}\ifx \empty \@test
|
||||
\setbox0 \hbox {$\vcenter {\mpr@hovbox{T}{#2}}$}%
|
||||
\else
|
||||
\setbox0 \mpr@fraction {\mpr@hovbox{T}{#2}}{\mpr@hovbox{B}{#3}}%
|
||||
\fi \fi
|
||||
\def \@test {#1}\ifx \@test\empty \box0
|
||||
\else \vbox
|
||||
%%% Suggestion de Francois pour les etiquettes longues
|
||||
%%% {\hbox to \wd0 {\RefTirName {#1}\hfil}\box0}\fi
|
||||
{\hbox {\RefTirName {#1}}\box0}\fi
|
||||
\egroup}
|
||||
|
||||
\def \mpr@vdotfil #1{\vbox to #1{\leaders \hbox{$\cdot$} \vfil}}
|
||||
|
||||
% They are two forms
|
||||
% \inferrule [label]{[premisses}{conclusions}
|
||||
% or
|
||||
% \inferrule* [options]{[premisses}{conclusions}
|
||||
%
|
||||
% Premisses and conclusions are lists of elements separated by \\
|
||||
% Each \\ produces a break, attempting horizontal breaks if possible,
|
||||
% and vertical breaks if needed.
|
||||
%
|
||||
% An empty element obtained by \\\\ produces a vertical break in all cases.
|
||||
%
|
||||
% The former rule is aligned on the fraction bar.
|
||||
% The optional label appears on top of the rule
|
||||
% The second form to be used in a derivation tree is aligned on the last
|
||||
% line of its conclusion
|
||||
%
|
||||
% The second form can be parameterized, using the key=val interface. The
|
||||
% folloiwng keys are recognized:
|
||||
%
|
||||
% width set the width of the rule to val
|
||||
% narrower set the width of the rule to val\hsize
|
||||
% before execute val at the beginning/left
|
||||
% lab put a label [Val] on top of the rule
|
||||
% lskip add negative skip on the right
|
||||
% left put a left label [Val]
|
||||
% Left put a left label [Val], ignoring its width
|
||||
% right put a right label [Val]
|
||||
% Right put a right label [Val], ignoring its width
|
||||
% leftskip skip negative space on the left-hand side
|
||||
% rightskip skip negative space on the right-hand side
|
||||
% vdots lift the rule by val and fill vertical space with dots
|
||||
% after execute val at the end/right
|
||||
%
|
||||
% Note that most options must come in this order to avoid strange
|
||||
% typesetting (in particular leftskip must preceed left and Left and
|
||||
% rightskip must follow Right or right; vdots must come last
|
||||
% or be only followed by rightskip.
|
||||
%
|
||||
|
||||
\define@key {mprset}{flushleft}[]{\mpr@centerfalse}
|
||||
\define@key {mprset}{center}[]{\mpr@centertrue}
|
||||
\def \mprset #1{\setkeys{mprset}{#1}}
|
||||
|
||||
\newbox \mpr@right
|
||||
\define@key {mpr}{flushleft}[]{\mpr@centerfalse}
|
||||
\define@key {mpr}{center}[]{\mpr@centertrue}
|
||||
\define@key {mpr}{left}{\setbox0 \hbox {$\TirName {#1}\;$}\relax
|
||||
\advance \hsize by -\wd0\box0}
|
||||
\define@key {mpr}{width}{\hsize #1}
|
||||
\define@key {mpr}{sep}{\def\mpr@sep{#1}}
|
||||
\define@key {mpr}{before}{#1}
|
||||
\define@key {mpr}{lab}{\let \RefTirName \TirName \def \mpr@rulename {#1}}
|
||||
\define@key {mpr}{Lab}{\let \RefTirName \TirName \def \mpr@rulename {#1}}
|
||||
\define@key {mpr}{narrower}{\hsize #1\hsize}
|
||||
\define@key {mpr}{leftskip}{\hskip -#1}
|
||||
\define@key {mpr}{reduce}[]{\let \mpr@fraction \mpr@@reduce}
|
||||
\define@key {mpr}{rightskip}
|
||||
{\setbox \mpr@right \hbox {\unhbox \mpr@right \hskip -#1}}
|
||||
\define@key {mpr}{LEFT}{\setbox0 \hbox {$#1$}\relax
|
||||
\advance \hsize by -\wd0\box0}
|
||||
\define@key {mpr}{left}{\setbox0 \hbox {$\TirName {#1}\;$}\relax
|
||||
\advance \hsize by -\wd0\box0}
|
||||
\define@key {mpr}{Left}{\llap{$\TirName {#1}\;$}}
|
||||
\define@key {mpr}{right}
|
||||
{\setbox0 \hbox {$\;\TirName {#1}$}\relax \advance \hsize by -\wd0
|
||||
\setbox \mpr@right \hbox {\unhbox \mpr@right \unhbox0}}
|
||||
\define@key {mpr}{RIGHT}
|
||||
{\setbox0 \hbox {$#1$}\relax \advance \hsize by -\wd0
|
||||
\setbox \mpr@right \hbox {\unhbox \mpr@right \unhbox0}}
|
||||
\define@key {mpr}{Right}
|
||||
{\setbox \mpr@right \hbox {\unhbox \mpr@right \rlap {$\;\TirName {#1}$}}}
|
||||
\define@key {mpr}{vdots}{\def \mpr@vdots {\@@atop \mpr@vdotfil{#1}}}
|
||||
\define@key {mpr}{after}{\edef \mpr@after {\mpr@after #1}}
|
||||
|
||||
\newdimen \rule@dimen
|
||||
\newcommand \mpr@inferstar@ [3][]{\setbox0
|
||||
\hbox {\let \mpr@rulename \mpr@empty \let \mpr@vdots \relax
|
||||
\setbox \mpr@right \hbox{}%
|
||||
$\setkeys{mpr}{#1}%
|
||||
\ifx \mpr@rulename \mpr@empty \mpr@inferrule {#2}{#3}\else
|
||||
\mpr@inferrule [{\mpr@rulename}]{#2}{#3}\fi
|
||||
\box \mpr@right \mpr@vdots$}
|
||||
\setbox1 \hbox {\strut}
|
||||
\rule@dimen \dp0 \advance \rule@dimen by -\dp1
|
||||
\raise \rule@dimen \box0}
|
||||
|
||||
\def \mpr@infer {\@ifnextchar *{\mpr@inferstar}{\mpr@inferrule}}
|
||||
\newcommand \mpr@err@skipargs[3][]{}
|
||||
\def \mpr@inferstar*{\ifmmode
|
||||
\let \@do \mpr@inferstar@
|
||||
\else
|
||||
\let \@do \mpr@err@skipargs
|
||||
\PackageError {mathpartir}
|
||||
{\string\inferrule* can only be used in math mode}{}%
|
||||
\fi \@do}
|
||||
|
||||
|
||||
%%% Exports
|
||||
|
||||
% Envirnonment mathpar
|
||||
|
||||
\let \inferrule \mpr@infer
|
||||
|
||||
% make a short name \infer is not already defined
|
||||
\@ifundefined {infer}{\let \infer \mpr@infer}{}
|
||||
|
||||
\def \TirNameStyle #1{\small \textsc{#1}}
|
||||
\def \tir@name #1{\hbox {\small \TirNameStyle{#1}}}
|
||||
\let \TirName \tir@name
|
||||
\let \DefTirName \TirName
|
||||
\let \RefTirName \TirName
|
||||
|
||||
%%% Other Exports
|
||||
|
||||
% \let \listcons \mpr@cons
|
||||
% \let \listsnoc \mpr@snoc
|
||||
% \let \listhead \mpr@head
|
||||
% \let \listmake \mpr@makelist
|
||||
|
||||
|
||||
|
||||
|
||||
\endinput
|
|
@ -1,271 +0,0 @@
|
|||
%!PS-Adobe-2.0 EPSF-2.0
|
||||
%%Title: /usr/home/slava/work/Factor/doc/namestack.fig
|
||||
%%Creator: fig2dev Version 3.2 Patchlevel 4
|
||||
%%CreationDate: Thu Apr 28 02:45:07 2005
|
||||
%%For: slava@emu.localdomain (Slava)
|
||||
%%BoundingBox: 0 0 447 162
|
||||
%%Magnification: 1.0000
|
||||
%%EndComments
|
||||
/$F2psDict 200 dict def
|
||||
$F2psDict begin
|
||||
$F2psDict /mtrx matrix put
|
||||
/col-1 {0 setgray} bind def
|
||||
/col0 {0.000 0.000 0.000 srgb} bind def
|
||||
/col1 {0.000 0.000 1.000 srgb} bind def
|
||||
/col2 {0.000 1.000 0.000 srgb} bind def
|
||||
/col3 {0.000 1.000 1.000 srgb} bind def
|
||||
/col4 {1.000 0.000 0.000 srgb} bind def
|
||||
/col5 {1.000 0.000 1.000 srgb} bind def
|
||||
/col6 {1.000 1.000 0.000 srgb} bind def
|
||||
/col7 {1.000 1.000 1.000 srgb} bind def
|
||||
/col8 {0.000 0.000 0.560 srgb} bind def
|
||||
/col9 {0.000 0.000 0.690 srgb} bind def
|
||||
/col10 {0.000 0.000 0.820 srgb} bind def
|
||||
/col11 {0.530 0.810 1.000 srgb} bind def
|
||||
/col12 {0.000 0.560 0.000 srgb} bind def
|
||||
/col13 {0.000 0.690 0.000 srgb} bind def
|
||||
/col14 {0.000 0.820 0.000 srgb} bind def
|
||||
/col15 {0.000 0.560 0.560 srgb} bind def
|
||||
/col16 {0.000 0.690 0.690 srgb} bind def
|
||||
/col17 {0.000 0.820 0.820 srgb} bind def
|
||||
/col18 {0.560 0.000 0.000 srgb} bind def
|
||||
/col19 {0.690 0.000 0.000 srgb} bind def
|
||||
/col20 {0.820 0.000 0.000 srgb} bind def
|
||||
/col21 {0.560 0.000 0.560 srgb} bind def
|
||||
/col22 {0.690 0.000 0.690 srgb} bind def
|
||||
/col23 {0.820 0.000 0.820 srgb} bind def
|
||||
/col24 {0.500 0.190 0.000 srgb} bind def
|
||||
/col25 {0.630 0.250 0.000 srgb} bind def
|
||||
/col26 {0.750 0.380 0.000 srgb} bind def
|
||||
/col27 {1.000 0.500 0.500 srgb} bind def
|
||||
/col28 {1.000 0.630 0.630 srgb} bind def
|
||||
/col29 {1.000 0.750 0.750 srgb} bind def
|
||||
/col30 {1.000 0.880 0.880 srgb} bind def
|
||||
/col31 {1.000 0.840 0.000 srgb} bind def
|
||||
/col32 {0.773 0.715 0.590 srgb} bind def
|
||||
/col33 {0.934 0.969 0.996 srgb} bind def
|
||||
/col34 {0.859 0.793 0.648 srgb} bind def
|
||||
/col35 {0.250 0.250 0.250 srgb} bind def
|
||||
/col36 {0.500 0.500 0.500 srgb} bind def
|
||||
/col37 {0.750 0.750 0.750 srgb} bind def
|
||||
/col38 {0.875 0.875 0.875 srgb} bind def
|
||||
/col39 {0.555 0.559 0.555 srgb} bind def
|
||||
/col40 {0.664 0.664 0.664 srgb} bind def
|
||||
/col41 {0.332 0.332 0.332 srgb} bind def
|
||||
/col42 {0.555 0.555 0.555 srgb} bind def
|
||||
/col43 {0.840 0.840 0.840 srgb} bind def
|
||||
/col44 {0.680 0.680 0.680 srgb} bind def
|
||||
/col45 {0.742 0.742 0.742 srgb} bind def
|
||||
/col46 {0.316 0.316 0.316 srgb} bind def
|
||||
/col47 {0.902 0.887 0.902 srgb} bind def
|
||||
/col48 {0.000 0.000 0.285 srgb} bind def
|
||||
/col49 {0.473 0.473 0.473 srgb} bind def
|
||||
/col50 {0.188 0.203 0.188 srgb} bind def
|
||||
/col51 {0.254 0.254 0.254 srgb} bind def
|
||||
/col52 {0.777 0.711 0.586 srgb} bind def
|
||||
/col53 {0.254 0.270 0.254 srgb} bind def
|
||||
/col54 {0.387 0.387 0.387 srgb} bind def
|
||||
/col55 {0.801 0.801 0.801 srgb} bind def
|
||||
/col56 {0.422 0.422 0.422 srgb} bind def
|
||||
|
||||
end
|
||||
save
|
||||
newpath 0 162 moveto 0 0 lineto 447 0 lineto 447 162 lineto closepath clip newpath
|
||||
-0.0 161.0 translate
|
||||
1 -1 scale
|
||||
|
||||
/cp {closepath} bind def
|
||||
/ef {eofill} bind def
|
||||
/gr {grestore} bind def
|
||||
/gs {gsave} bind def
|
||||
/sa {save} bind def
|
||||
/rs {restore} bind def
|
||||
/l {lineto} bind def
|
||||
/m {moveto} bind def
|
||||
/rm {rmoveto} bind def
|
||||
/n {newpath} bind def
|
||||
/s {stroke} bind def
|
||||
/sh {show} bind def
|
||||
/slc {setlinecap} bind def
|
||||
/slj {setlinejoin} bind def
|
||||
/slw {setlinewidth} bind def
|
||||
/srgb {setrgbcolor} bind def
|
||||
/rot {rotate} bind def
|
||||
/sc {scale} bind def
|
||||
/sd {setdash} bind def
|
||||
/ff {findfont} bind def
|
||||
/sf {setfont} bind def
|
||||
/scf {scalefont} bind def
|
||||
/sw {stringwidth} bind def
|
||||
/tr {translate} bind def
|
||||
/tnt {dup dup currentrgbcolor
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
|
||||
bind def
|
||||
/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
|
||||
4 -2 roll mul srgb} bind def
|
||||
/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
|
||||
/$F2psEnd {$F2psEnteredState restore end} def
|
||||
|
||||
$F2psBegin
|
||||
10 setmiterlimit
|
||||
0 slj 0 slc
|
||||
0.06000 0.06000 sc
|
||||
%
|
||||
% Fig objects follow
|
||||
%
|
||||
%
|
||||
% here starts figure with depth 50
|
||||
/Courier ff 270.00 scf sf
|
||||
0 2250 m
|
||||
gs 1 -1 sc (rand) col0 sh gr
|
||||
% Polyline
|
||||
7.500 slw
|
||||
n 2325 600 m 3075 600 l 3075 1050 l 2325 1050 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 5925 600 m 6675 600 l 6675 1050 l 5925 1050 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 6675 600 m 7425 600 l 7425 1050 l 6675 1050 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 3750 600 m 4500 600 l 4500 1050 l 3750 1050 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 4500 600 m 5250 600 l 5250 1050 l 4500 1050 l
|
||||
cp gs col0 s gr
|
||||
% Polyline
|
||||
n 3525 1650 m 4800 1650 l 4800 2250 l 3525 2250 l
|
||||
cp gs col0 s gr
|
||||
/Courier ff 270.00 scf sf
|
||||
3600 1875 m
|
||||
gs 1 -1 sc (rand 4) col0 sh gr
|
||||
/Courier ff 270.00 scf sf
|
||||
3600 2175 m
|
||||
gs 1 -1 sc (rator 5) col0 sh gr
|
||||
% Polyline
|
||||
n 5700 1650 m 6975 1650 l 6975 2250 l 5700 2250 l
|
||||
cp gs col0 s gr
|
||||
/Courier ff 270.00 scf sf
|
||||
5775 1875 m
|
||||
gs 1 -1 sc (gator 2) col0 sh gr
|
||||
/Courier ff 270.00 scf sf
|
||||
5775 2175 m
|
||||
gs 1 -1 sc (rand 3) col0 sh gr
|
||||
% Polyline
|
||||
n 1350 1650 m 2625 1650 l 2625 1950 l 1350 1950 l
|
||||
cp gs col0 s gr
|
||||
/Courier ff 270.00 scf sf
|
||||
1425 1875 m
|
||||
gs 1 -1 sc (rator 8) col0 sh gr
|
||||
% Polyline
|
||||
n 6675 1050 m
|
||||
7425 600 l gs col0 s gr
|
||||
% Polyline
|
||||
gs clippath
|
||||
1920 1665 m 1980 1665 l 1980 1513 l 1950 1633 l 1920 1513 l cp
|
||||
eoclip
|
||||
n 1950 825 m
|
||||
1950 1650 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 1920 1513 m 1950 1633 l 1980 1513 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
4095 1665 m 4155 1665 l 4155 1513 l 4125 1633 l 4095 1513 l cp
|
||||
eoclip
|
||||
n 4125 825 m
|
||||
4125 1650 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 4095 1513 m 4125 1633 l 4155 1513 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
6270 1665 m 6330 1665 l 6330 1513 l 6300 1633 l 6270 1513 l cp
|
||||
eoclip
|
||||
n 6300 825 m
|
||||
6300 1650 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 6270 1513 m 6300 1633 l 6330 1513 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
3765 855 m 3765 795 l 3613 795 l 3733 825 l 3613 855 l cp
|
||||
eoclip
|
||||
n 2700 825 m
|
||||
3750 825 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 3613 855 m 3733 825 l 3613 795 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
5940 855 m 5940 795 l 5788 795 l 5908 825 l 5788 855 l cp
|
||||
eoclip
|
||||
n 4875 825 m
|
||||
5925 825 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 5788 855 m 5908 825 l 5788 795 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
1365 1830 m 1365 1770 l 1213 1770 l 1333 1800 l 1213 1830 l cp
|
||||
eoclip
|
||||
n 900 1800 m
|
||||
1350 1800 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 1213 1830 m 1333 1800 l 1213 1770 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
3540 1830 m 3540 1770 l 3388 1770 l 3508 1800 l 3388 1830 l cp
|
||||
eoclip
|
||||
n 900 2175 m 3000 2175 l 3000 1800 l
|
||||
3525 1800 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 3388 1830 m 3508 1800 l 3388 1770 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
5715 1830 m 5715 1770 l 5563 1770 l 5683 1800 l 5563 1830 l cp
|
||||
eoclip
|
||||
n 900 2550 m 5175 2550 l 5175 1800 l
|
||||
5700 1800 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 5563 1830 m 5683 1800 l 5563 1770 l col0 s
|
||||
% Polyline
|
||||
2 slj
|
||||
gs clippath
|
||||
2071 617 m 2131 612 l 2119 461 l 2099 583 l 2059 465 l cp
|
||||
eoclip
|
||||
n 675 0 m 676 0 l 679 0 l 684 0 l 693 0 l 704 0 l
|
||||
719 0 l 738 1 l 761 1 l 787 1 l 817 2 l
|
||||
849 3 l 884 4 l 921 6 l 960 7 l 1001 9 l
|
||||
1042 12 l 1085 15 l 1127 18 l 1171 22 l 1215 27 l
|
||||
1259 32 l 1304 39 l 1349 46 l 1395 54 l 1442 64 l
|
||||
1489 74 l 1536 86 l 1584 100 l 1632 115 l 1679 132 l
|
||||
1725 150 l 1778 174 l 1825 199 l 1867 224 l 1904 249 l
|
||||
1936 273 l 1964 298 l 1987 322 l 2007 345 l 2024 369 l
|
||||
2039 392 l 2051 415 l 2061 437 l 2070 459 l 2077 481 l
|
||||
2082 501 l 2087 520 l 2091 538 l 2094 553 l 2096 567 l
|
||||
2098 578 l 2099 587 l
|
||||
2100 600 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
0 slj
|
||||
n 2059 465 m 2099 583 l 2119 461 l col0 s
|
||||
/Courier ff 270.00 scf sf
|
||||
0 2625 m
|
||||
gs 1 -1 sc (gator) col0 sh gr
|
||||
/Courier ff 270.00 scf sf
|
||||
0 1875 m
|
||||
gs 1 -1 sc (rator) col0 sh gr
|
||||
% Polyline
|
||||
n 1575 600 m 2325 600 l 2325 1050 l 1575 1050 l
|
||||
cp gs col0 s gr
|
||||
% here ends figure;
|
||||
$F2psEnd
|
||||
rs
|
||||
showpage
|
|
@ -1,114 +0,0 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
0 32 #c6b797
|
||||
0 33 #eff8ff
|
||||
0 34 #dccba6
|
||||
0 35 #404040
|
||||
0 36 #808080
|
||||
0 37 #c0c0c0
|
||||
0 38 #e0e0e0
|
||||
0 39 #8e8f8e
|
||||
0 40 #aaaaaa
|
||||
0 41 #555555
|
||||
0 42 #8e8e8e
|
||||
0 43 #d7d7d7
|
||||
0 44 #aeaeae
|
||||
0 45 #bebebe
|
||||
0 46 #515151
|
||||
0 47 #e7e3e7
|
||||
0 48 #000049
|
||||
0 49 #797979
|
||||
0 50 #303430
|
||||
0 51 #414141
|
||||
0 52 #c7b696
|
||||
0 53 #414541
|
||||
0 54 #636363
|
||||
0 55 #cdcdcd
|
||||
0 56 #6c6c6c
|
||||
6 1575 600 3075 1050
|
||||
6 1575 600 3075 1050
|
||||
6 1575 600 3075 1050
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1575 600 2325 600 2325 1050 1575 1050 1575 600
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2325 600 3075 600 3075 1050 2325 1050 2325 600
|
||||
-6
|
||||
-6
|
||||
-6
|
||||
6 5925 600 7425 1050
|
||||
6 5925 600 7425 1050
|
||||
6 5925 600 7425 1050
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5925 600 6675 600 6675 1050 5925 1050 5925 600
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6675 600 7425 600 7425 1050 6675 1050 6675 600
|
||||
-6
|
||||
-6
|
||||
-6
|
||||
6 3750 600 5250 1050
|
||||
6 3750 600 5250 1050
|
||||
6 3750 600 5250 1050
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3750 600 4500 600 4500 1050 3750 1050 3750 600
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4500 600 5250 600 5250 1050 4500 1050 4500 600
|
||||
-6
|
||||
-6
|
||||
-6
|
||||
6 3525 1650 4800 2250
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3525 1650 4800 1650 4800 2250 3525 2250 3525 1650
|
||||
4 0 0 50 -1 12 18 0.0000 4 165 1155 3600 1875 rand 4\001
|
||||
4 0 0 50 -1 12 18 0.0000 4 165 1155 3600 2175 rator 5\001
|
||||
-6
|
||||
6 5700 1650 6975 2250
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5700 1650 6975 1650 6975 2250 5700 2250 5700 1650
|
||||
4 0 0 50 -1 12 18 0.0000 4 210 1155 5775 1875 gator 2\001
|
||||
4 0 0 50 -1 12 18 0.0000 4 165 1155 5775 2175 rand 3\001
|
||||
-6
|
||||
6 1350 1650 2625 1950
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1350 1650 2625 1650 2625 1950 1350 1950 1350 1650
|
||||
4 0 0 50 -1 12 18 0.0000 4 165 1155 1425 1875 rator 8\001
|
||||
-6
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6675 1050 7425 600
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
1950 825 1950 1650
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
4125 825 4125 1650
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
6300 825 6300 1650
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
2700 825 3750 825
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
4875 825 5925 825
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
900 1800 1350 1800
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 4
|
||||
0 0 1.00 60.00 120.00
|
||||
900 2175 3000 2175 3000 1800 3525 1800
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 4
|
||||
0 0 1.00 60.00 120.00
|
||||
900 2550 5175 2550 5175 1800 5700 1800
|
||||
3 2 0 1 0 7 50 -1 -1 0.000 0 1 0 3
|
||||
0 0 1.00 60.00 120.00
|
||||
675 0 1725 150 2100 600
|
||||
0.000 -1.000 0.000
|
||||
4 0 0 50 -1 12 18 0.0000 4 195 825 0 2625 gator\001
|
||||
4 0 0 50 -1 12 18 0.0000 4 150 825 0 1875 rator\001
|
||||
4 0 0 50 -1 12 18 0.0000 4 165 660 0 2250 rand\001
|
198
doc/number.eps
198
doc/number.eps
|
@ -1,198 +0,0 @@
|
|||
%!PS-Adobe-2.0 EPSF-2.0
|
||||
%%Title: number.fig
|
||||
%%Creator: fig2dev Version 3.2 Patchlevel 4
|
||||
%%CreationDate: Wed Apr 27 22:37:31 2005
|
||||
%%For: slava@emu.localdomain (Slava)
|
||||
%%BoundingBox: 0 0 336 302
|
||||
%%Magnification: 1.0000
|
||||
%%EndComments
|
||||
/$F2psDict 200 dict def
|
||||
$F2psDict begin
|
||||
$F2psDict /mtrx matrix put
|
||||
/col-1 {0 setgray} bind def
|
||||
/col0 {0.000 0.000 0.000 srgb} bind def
|
||||
/col1 {0.000 0.000 1.000 srgb} bind def
|
||||
/col2 {0.000 1.000 0.000 srgb} bind def
|
||||
/col3 {0.000 1.000 1.000 srgb} bind def
|
||||
/col4 {1.000 0.000 0.000 srgb} bind def
|
||||
/col5 {1.000 0.000 1.000 srgb} bind def
|
||||
/col6 {1.000 1.000 0.000 srgb} bind def
|
||||
/col7 {1.000 1.000 1.000 srgb} bind def
|
||||
/col8 {0.000 0.000 0.560 srgb} bind def
|
||||
/col9 {0.000 0.000 0.690 srgb} bind def
|
||||
/col10 {0.000 0.000 0.820 srgb} bind def
|
||||
/col11 {0.530 0.810 1.000 srgb} bind def
|
||||
/col12 {0.000 0.560 0.000 srgb} bind def
|
||||
/col13 {0.000 0.690 0.000 srgb} bind def
|
||||
/col14 {0.000 0.820 0.000 srgb} bind def
|
||||
/col15 {0.000 0.560 0.560 srgb} bind def
|
||||
/col16 {0.000 0.690 0.690 srgb} bind def
|
||||
/col17 {0.000 0.820 0.820 srgb} bind def
|
||||
/col18 {0.560 0.000 0.000 srgb} bind def
|
||||
/col19 {0.690 0.000 0.000 srgb} bind def
|
||||
/col20 {0.820 0.000 0.000 srgb} bind def
|
||||
/col21 {0.560 0.000 0.560 srgb} bind def
|
||||
/col22 {0.690 0.000 0.690 srgb} bind def
|
||||
/col23 {0.820 0.000 0.820 srgb} bind def
|
||||
/col24 {0.500 0.190 0.000 srgb} bind def
|
||||
/col25 {0.630 0.250 0.000 srgb} bind def
|
||||
/col26 {0.750 0.380 0.000 srgb} bind def
|
||||
/col27 {1.000 0.500 0.500 srgb} bind def
|
||||
/col28 {1.000 0.630 0.630 srgb} bind def
|
||||
/col29 {1.000 0.750 0.750 srgb} bind def
|
||||
/col30 {1.000 0.880 0.880 srgb} bind def
|
||||
/col31 {1.000 0.840 0.000 srgb} bind def
|
||||
|
||||
end
|
||||
save
|
||||
newpath 0 302 moveto 0 0 lineto 336 0 lineto 336 302 lineto closepath clip newpath
|
||||
-1.0 305.5 translate
|
||||
1 -1 scale
|
||||
|
||||
/cp {closepath} bind def
|
||||
/ef {eofill} bind def
|
||||
/gr {grestore} bind def
|
||||
/gs {gsave} bind def
|
||||
/sa {save} bind def
|
||||
/rs {restore} bind def
|
||||
/l {lineto} bind def
|
||||
/m {moveto} bind def
|
||||
/rm {rmoveto} bind def
|
||||
/n {newpath} bind def
|
||||
/s {stroke} bind def
|
||||
/sh {show} bind def
|
||||
/slc {setlinecap} bind def
|
||||
/slj {setlinejoin} bind def
|
||||
/slw {setlinewidth} bind def
|
||||
/srgb {setrgbcolor} bind def
|
||||
/rot {rotate} bind def
|
||||
/sc {scale} bind def
|
||||
/sd {setdash} bind def
|
||||
/ff {findfont} bind def
|
||||
/sf {setfont} bind def
|
||||
/scf {scalefont} bind def
|
||||
/sw {stringwidth} bind def
|
||||
/tr {translate} bind def
|
||||
/tnt {dup dup currentrgbcolor
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
|
||||
bind def
|
||||
/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
|
||||
4 -2 roll mul srgb} bind def
|
||||
/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
|
||||
/$F2psEnd {$F2psEnteredState restore end} def
|
||||
|
||||
$F2psBegin
|
||||
10 setmiterlimit
|
||||
0 slj 0 slc
|
||||
0.06000 0.06000 sc
|
||||
%
|
||||
% Fig objects follow
|
||||
%
|
||||
%
|
||||
% here starts figure with depth 50
|
||||
/Courier ff 270.00 scf sf
|
||||
3225 1425 m
|
||||
gs 1 -1 sc (real) dup sw pop 2 div neg 0 rm col0 sh gr
|
||||
% Polyline
|
||||
7.500 slw
|
||||
gs clippath
|
||||
3214 3631 m 3256 3589 l 3149 3481 l 3213 3588 l 3106 3524 l cp
|
||||
eoclip
|
||||
n 2325 2700 m
|
||||
3225 3600 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 3106 3524 m 3213 3588 l 3149 3481 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
493 4789 m 535 4831 l 643 4724 l 537 4788 l 600 4681 l cp
|
||||
eoclip
|
||||
n 1425 3900 m
|
||||
525 4800 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 600 4681 m 537 4788 l 643 4724 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
2314 4831 m 2356 4789 l 2249 4681 l 2313 4788 l 2206 4724 l cp
|
||||
eoclip
|
||||
n 1425 3900 m
|
||||
2325 4800 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 2206 4724 m 2313 4788 l 2249 4681 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
4114 2431 m 4156 2389 l 4049 2281 l 4113 2388 l 4006 2324 l cp
|
||||
eoclip
|
||||
n 3225 1500 m
|
||||
4125 2400 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 4006 2324 m 4113 2388 l 4049 2281 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
2293 2389 m 2335 2431 l 2443 2324 l 2337 2388 l 2400 2281 l cp
|
||||
eoclip
|
||||
n 3225 1500 m
|
||||
2325 2400 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 2400 2281 m 2337 2388 l 2443 2324 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
3193 1189 m 3235 1231 l 3343 1124 l 3237 1188 l 3300 1081 l cp
|
||||
eoclip
|
||||
n 4125 300 m
|
||||
3225 1200 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 3300 1081 m 3237 1188 l 3343 1124 l col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
5014 1231 m 5056 1189 l 4949 1081 l 5013 1188 l 4906 1124 l cp
|
||||
eoclip
|
||||
n 4125 300 m
|
||||
5025 1200 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 4906 1124 m 5013 1188 l 4949 1081 l col0 s
|
||||
/Courier ff 270.00 scf sf
|
||||
1425 3825 m
|
||||
gs 1 -1 sc (integer) dup sw pop 2 div neg 0 rm col0 sh gr
|
||||
/Courier ff 270.00 scf sf
|
||||
2325 5025 m
|
||||
gs 1 -1 sc (bignum) dup sw pop 2 div neg 0 rm col0 sh gr
|
||||
/Courier ff 270.00 scf sf
|
||||
525 5025 m
|
||||
gs 1 -1 sc (fixnum) dup sw pop 2 div neg 0 rm col0 sh gr
|
||||
/Courier ff 270.00 scf sf
|
||||
3225 3825 m
|
||||
gs 1 -1 sc (ratio) dup sw pop 2 div neg 0 rm col0 sh gr
|
||||
/Courier ff 270.00 scf sf
|
||||
2325 2625 m
|
||||
gs 1 -1 sc (rational) dup sw pop 2 div neg 0 rm col0 sh gr
|
||||
/Courier ff 270.00 scf sf
|
||||
4125 2625 m
|
||||
gs 1 -1 sc (float) dup sw pop 2 div neg 0 rm col0 sh gr
|
||||
/Courier ff 270.00 scf sf
|
||||
4125 225 m
|
||||
gs 1 -1 sc (number) dup sw pop 2 div neg 0 rm col0 sh gr
|
||||
/Courier ff 270.00 scf sf
|
||||
5025 1425 m
|
||||
gs 1 -1 sc (complex) dup sw pop 2 div neg 0 rm col0 sh gr
|
||||
% Polyline
|
||||
gs clippath
|
||||
1393 3589 m 1435 3631 l 1543 3524 l 1437 3588 l 1500 3481 l cp
|
||||
eoclip
|
||||
n 2325 2700 m
|
||||
1425 3600 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 1500 3481 m 1437 3588 l 1543 3524 l col0 s
|
||||
% here ends figure;
|
||||
$F2psEnd
|
||||
rs
|
||||
showpage
|
|
@ -1,44 +0,0 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 0 0 5625 5100
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
2325 2700 1425 3600
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
2325 2700 3225 3600
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
1425 3900 525 4800
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
1425 3900 2325 4800
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
3225 1500 4125 2400
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
3225 1500 2325 2400
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
4125 300 3225 1200
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 60.00 120.00
|
||||
4125 300 5025 1200
|
||||
4 1 0 50 -1 12 18 0.0000 4 225 1155 1425 3825 integer\001
|
||||
4 1 0 50 -1 12 18 0.0000 4 225 990 2325 5025 bignum\001
|
||||
4 1 0 50 -1 12 18 0.0000 4 180 990 525 5025 fixnum\001
|
||||
4 1 0 50 -1 12 18 0.0000 4 180 825 3225 3825 ratio\001
|
||||
4 1 0 50 -1 12 18 0.0000 4 180 1320 2325 2625 rational\001
|
||||
4 1 0 50 -1 12 18 0.0000 4 165 825 4125 2625 float\001
|
||||
4 1 0 50 -1 12 18 0.0000 4 165 990 4125 225 number\001
|
||||
4 1 0 50 -1 12 18 0.0000 4 210 1155 5025 1425 complex\001
|
||||
4 1 0 50 -1 12 18 0.0000 4 165 660 3225 1425 real\001
|
||||
-6
|
BIN
doc/parser.dia
BIN
doc/parser.dia
Binary file not shown.
647
doc/parser.eps
647
doc/parser.eps
|
@ -1,647 +0,0 @@
|
|||
%!PS-Adobe-2.0 EPSF-2.0
|
||||
%%Title: /usr/home/slava/Factor/doc/parser.dia
|
||||
%%Creator: Dia v0.94
|
||||
%%CreationDate: Wed Apr 27 23:20:53 2005
|
||||
%%For: slava
|
||||
%%Orientation: Portrait
|
||||
%%Magnification: 1.0000
|
||||
%%BoundingBox: 0 0 764 1201
|
||||
%%BeginSetup
|
||||
%%EndSetup
|
||||
%%EndComments
|
||||
%%BeginProlog
|
||||
[ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
|
||||
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
|
||||
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
|
||||
/.notdef /.notdef /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright
|
||||
/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash /zero /one
|
||||
/two /three /four /five /six /seven /eight /nine /colon /semicolon
|
||||
/less /equal /greater /question /at /A /B /C /D /E
|
||||
/F /G /H /I /J /K /L /M /N /O
|
||||
/P /Q /R /S /T /U /V /W /X /Y
|
||||
/Z /bracketleft /backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c
|
||||
/d /e /f /g /h /i /j /k /l /m
|
||||
/n /o /p /q /r /s /t /u /v /w
|
||||
/x /y /z /braceleft /bar /braceright /asciitilde /.notdef /.notdef /.notdef
|
||||
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
|
||||
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
|
||||
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
|
||||
/space /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright
|
||||
/ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron /degree /plusminus /twosuperior /threesuperior
|
||||
/acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf
|
||||
/threequarters /questiondown /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
|
||||
/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde
|
||||
/Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex
|
||||
/Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring
|
||||
/ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis
|
||||
/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave
|
||||
/uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] /isolatin1encoding exch def
|
||||
/cp {closepath} bind def
|
||||
/c {curveto} bind def
|
||||
/f {fill} bind def
|
||||
/a {arc} bind def
|
||||
/ef {eofill} bind def
|
||||
/ex {exch} bind def
|
||||
/gr {grestore} bind def
|
||||
/gs {gsave} bind def
|
||||
/sa {save} bind def
|
||||
/rs {restore} bind def
|
||||
/l {lineto} bind def
|
||||
/m {moveto} bind def
|
||||
/rm {rmoveto} bind def
|
||||
/n {newpath} bind def
|
||||
/s {stroke} bind def
|
||||
/sh {show} bind def
|
||||
/slc {setlinecap} bind def
|
||||
/slj {setlinejoin} bind def
|
||||
/slw {setlinewidth} bind def
|
||||
/srgb {setrgbcolor} bind def
|
||||
/rot {rotate} bind def
|
||||
/sc {scale} bind def
|
||||
/sd {setdash} bind def
|
||||
/ff {findfont} bind def
|
||||
/sf {setfont} bind def
|
||||
/scf {scalefont} bind def
|
||||
/sw {stringwidth pop} bind def
|
||||
/tr {translate} bind def
|
||||
|
||||
/ellipsedict 8 dict def
|
||||
ellipsedict /mtrx matrix put
|
||||
/ellipse
|
||||
{ ellipsedict begin
|
||||
/endangle exch def
|
||||
/startangle exch def
|
||||
/yrad exch def
|
||||
/xrad exch def
|
||||
/y exch def
|
||||
/x exch def /savematrix mtrx currentmatrix def
|
||||
x y tr xrad yrad sc
|
||||
0 0 1 startangle endangle arc
|
||||
savematrix setmatrix
|
||||
end
|
||||
} def
|
||||
|
||||
/mergeprocs {
|
||||
dup length
|
||||
3 -1 roll
|
||||
dup
|
||||
length
|
||||
dup
|
||||
5 1 roll
|
||||
3 -1 roll
|
||||
add
|
||||
array cvx
|
||||
dup
|
||||
3 -1 roll
|
||||
0 exch
|
||||
putinterval
|
||||
dup
|
||||
4 2 roll
|
||||
putinterval
|
||||
} bind def
|
||||
/Times-Roman-latin1
|
||||
/Times-Roman findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Times-Italic-latin1
|
||||
/Times-Italic findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Times-Bold-latin1
|
||||
/Times-Bold findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Times-BoldItalic-latin1
|
||||
/Times-BoldItalic findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/AvantGarde-Book-latin1
|
||||
/AvantGarde-Book findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/AvantGarde-BookOblique-latin1
|
||||
/AvantGarde-BookOblique findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/AvantGarde-Demi-latin1
|
||||
/AvantGarde-Demi findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/AvantGarde-DemiOblique-latin1
|
||||
/AvantGarde-DemiOblique findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Bookman-Light-latin1
|
||||
/Bookman-Light findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Bookman-LightItalic-latin1
|
||||
/Bookman-LightItalic findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Bookman-Demi-latin1
|
||||
/Bookman-Demi findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Bookman-DemiItalic-latin1
|
||||
/Bookman-DemiItalic findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Courier-latin1
|
||||
/Courier findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Courier-Oblique-latin1
|
||||
/Courier-Oblique findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Courier-Bold-latin1
|
||||
/Courier-Bold findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Courier-BoldOblique-latin1
|
||||
/Courier-BoldOblique findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Helvetica-latin1
|
||||
/Helvetica findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Helvetica-Oblique-latin1
|
||||
/Helvetica-Oblique findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Helvetica-Bold-latin1
|
||||
/Helvetica-Bold findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Helvetica-BoldOblique-latin1
|
||||
/Helvetica-BoldOblique findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Helvetica-Narrow-latin1
|
||||
/Helvetica-Narrow findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Helvetica-Narrow-Oblique-latin1
|
||||
/Helvetica-Narrow-Oblique findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Helvetica-Narrow-Bold-latin1
|
||||
/Helvetica-Narrow-Bold findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Helvetica-Narrow-BoldOblique-latin1
|
||||
/Helvetica-Narrow-BoldOblique findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/NewCenturySchoolbook-Roman-latin1
|
||||
/NewCenturySchoolbook-Roman findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/NewCenturySchoolbook-Italic-latin1
|
||||
/NewCenturySchoolbook-Italic findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/NewCenturySchoolbook-Bold-latin1
|
||||
/NewCenturySchoolbook-Bold findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/NewCenturySchoolbook-BoldItalic-latin1
|
||||
/NewCenturySchoolbook-BoldItalic findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Palatino-Roman-latin1
|
||||
/Palatino-Roman findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Palatino-Italic-latin1
|
||||
/Palatino-Italic findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Palatino-Bold-latin1
|
||||
/Palatino-Bold findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Palatino-BoldItalic-latin1
|
||||
/Palatino-BoldItalic findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/Symbol-latin1
|
||||
/Symbol findfont
|
||||
definefont pop
|
||||
/ZapfChancery-MediumItalic-latin1
|
||||
/ZapfChancery-MediumItalic findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
/ZapfDingbats-latin1
|
||||
/ZapfDingbats findfont
|
||||
dup length dict begin
|
||||
{1 index /FID ne {def} {pop pop} ifelse} forall
|
||||
/Encoding isolatin1encoding def
|
||||
currentdict end
|
||||
definefont pop
|
||||
28.346000 -28.346000 scale
|
||||
-2.000000 -31.626100 translate
|
||||
%%EndProlog
|
||||
|
||||
|
||||
1.000000 1.000000 1.000000 srgb
|
||||
n 15.386947 -0.282107 m 22.303000 2.772277 l 15.386947 5.826661 l 8.470894 2.772277 l ef
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0.000000 0.000000 0.000000 srgb
|
||||
n 15.386947 -0.282107 m 22.303000 2.772277 l 15.386947 5.826661 l 8.470894 2.772277 l cp s
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Is the current character) dup sw 2 div 15.386947 ex sub 2.572277 m gs 1 -1 sc sh gr
|
||||
(a quotation mark \("\)?) dup sw 2 div 15.386947 ex sub 3.372277 m gs 1 -1 sc sh gr
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slc
|
||||
n 18.844974 4.299469 m 22.977248 8.320714 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 22.524686 8.229148 m 23.057374 8.398687 l 22.873393 7.870813 l s
|
||||
1.000000 1.000000 1.000000 srgb
|
||||
n 19.725000 8.476660 m 19.725000 10.376660 l 26.550000 10.376660 l 26.550000 8.476660 l f
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0.000000 0.000000 0.000000 srgb
|
||||
n 19.725000 8.476660 m 19.725000 10.376660 l 26.550000 10.376660 l 26.550000 8.476660 l cp s
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Parse string literal) dup sw 2 div 23.137500 ex sub 9.626660 m gs 1 -1 sc sh gr
|
||||
1.000000 1.000000 1.000000 srgb
|
||||
n 12.310336 -4.485840 m 12.310336 -2.585840 l 18.460336 -2.585840 l 18.460336 -4.485840 l f
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0.000000 0.000000 0.000000 srgb
|
||||
n 12.310336 -4.485840 m 12.310336 -2.585840 l 18.460336 -2.585840 l 18.460336 -4.485840 l cp s
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Skip whitespace) dup sw 2 div 15.385336 ex sub -3.335840 m gs 1 -1 sc sh gr
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slc
|
||||
n 15.385336 -2.585840 m 15.386791 -0.505714 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 15.136519 -0.893735 m 15.386869 -0.393910 l 15.636519 -0.894085 l s
|
||||
1.000000 1.000000 1.000000 srgb
|
||||
n 11.775000 8.064170 m 11.775000 10.764170 l 18.975000 10.764170 l 18.975000 8.064170 l f
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0.000000 0.000000 0.000000 srgb
|
||||
n 11.775000 8.064170 m 11.775000 10.764170 l 18.975000 10.764170 l 18.975000 8.064170 l cp s
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Read next token,) dup sw 2 div 15.375000 ex sub 9.214170 m gs 1 -1 sc sh gr
|
||||
(lookup in dictionary) dup sw 2 div 15.375000 ex sub 10.014170 m gs 1 -1 sc sh gr
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slc
|
||||
n 15.386947 5.826661 m 15.376194 7.840566 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 15.128270 7.451040 m 15.375597 7.952368 l 15.628263 7.453710 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 23.137500 10.376700 m 23.137500 11.013600 l 27.300000 11.013600 l 27.300000 -6.048330 l 16.922836 -6.048330 l 16.922836 -4.709447 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 16.672836 -5.097643 m 16.922836 -4.597643 l 17.172836 -5.097643 l s
|
||||
1.000000 1.000000 1.000000 srgb
|
||||
n 15.376148 12.901700 m 19.927296 14.547115 l 15.376148 16.192530 l 10.825000 14.547115 l ef
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0.000000 0.000000 0.000000 srgb
|
||||
n 15.376148 12.901700 m 19.927296 14.547115 l 15.376148 16.192530 l 10.825000 14.547115 l cp s
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Word found?) dup sw 2 div 15.376148 ex sub 14.747115 m gs 1 -1 sc sh gr
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slc
|
||||
n 15.375000 10.764170 m 15.375985 12.678093 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 15.125785 12.290025 m 15.376042 12.789897 l 15.625785 12.289768 l s
|
||||
1.000000 1.000000 1.000000 srgb
|
||||
n 21.318809 17.001700 m 26.137617 18.711075 l 21.318809 20.420449 l 16.500000 18.711075 l ef
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0.000000 0.000000 0.000000 srgb
|
||||
n 21.318809 17.001700 m 26.137617 18.711075 l 21.318809 20.420449 l 16.500000 18.711075 l cp s
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Parsing word?) dup sw 2 div 21.318809 ex sub 18.911075 m gs 1 -1 sc sh gr
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slc
|
||||
n 17.651700 15.369800 m 18.808477 17.656864 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 18.410179 17.423293 m 18.858938 17.756632 l 18.856355 17.197621 l s
|
||||
1.000000 1.000000 1.000000 srgb
|
||||
n 6.150000 17.376700 m 6.150000 19.276700 l 14.750000 19.276700 l 14.750000 17.376700 l f
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0.000000 0.000000 0.000000 srgb
|
||||
n 6.150000 17.376700 m 6.150000 19.276700 l 14.750000 19.276700 l 14.750000 17.376700 l cp s
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Try parsing as a number) dup sw 2 div 10.450000 ex sub 18.526700 m gs 1 -1 sc sh gr
|
||||
1.000000 1.000000 1.000000 srgb
|
||||
n 10.445199 21.426700 m 15.525733 23.861123 l 10.445199 26.295545 l 5.364664 23.861123 l ef
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0.000000 0.000000 0.000000 srgb
|
||||
n 10.445199 21.426700 m 15.525733 23.861123 l 10.445199 26.295545 l 5.364664 23.861123 l cp s
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Token is a number?) dup sw 2 div 10.445199 ex sub 24.061123 m gs 1 -1 sc sh gr
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slc
|
||||
n 13.100600 15.369800 m 10.628272 17.241722 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 10.786853 16.808076 m 10.539136 17.309211 l 11.088674 17.206704 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slc
|
||||
n 10.450000 19.276700 m 10.445698 21.203094 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 10.196566 20.814340 m 10.445448 21.314897 l 10.696564 20.815456 l s
|
||||
1.000000 1.000000 1.000000 srgb
|
||||
n 11.452940 28.789200 m 19.594117 28.789200 l 18.866176 30.789200 l 10.725000 30.789200 l ef
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0.000000 0.000000 0.000000 srgb
|
||||
n 11.452940 28.789200 m 19.594117 28.789200 l 18.866176 30.789200 l 10.725000 30.789200 l cp s
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Append to parse tree) dup sw 2 div 15.159558 ex sub 29.989200 m gs 1 -1 sc sh gr
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slc
|
||||
n 12.985466 25.078334 m 13.458181 28.567617 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 13.158329 28.216497 m 13.473190 28.678409 l 13.653802 28.149372 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slc
|
||||
0 slj
|
||||
0 slc
|
||||
0 slj
|
||||
[] 0 sd
|
||||
1.000000 1.000000 1.000000 srgb
|
||||
n 6.271450 28.739200 m 8.628557 28.739200 l 8.628557 30.667728 l 8.157135 30.346307 7.921425 30.346307 7.450003 30.667728 c 6.978582 30.989149 6.742871 30.989149 6.271450 30.667728 c 6.271450 28.739200 l ef
|
||||
0.000000 0.000000 0.000000 srgb
|
||||
n 6.271450 28.739200 m 8.628557 28.739200 l 8.628557 30.667728 l 8.157135 30.346307 7.921425 30.346307 7.450003 30.667728 c 6.978582 30.989149 6.742871 30.989149 6.271450 30.667728 c 6.271450 28.739200 l s
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Error) dup sw 2 div 7.450003 ex sub 29.742753 m gs 1 -1 sc sh gr
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slc
|
||||
n 7.904931 25.078334 m 7.477575 28.517300 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 7.277356 28.101236 m 7.463788 28.628250 l 7.773539 28.162897 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slc
|
||||
n 18.909400 19.565700 m 17.591197 28.567953 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 17.400079 28.147631 m 17.574999 28.678576 l 17.894803 28.220073 l s
|
||||
1.000000 1.000000 1.000000 srgb
|
||||
n 21.827940 22.189200 m 27.419117 22.189200 l 26.691176 24.189200 l 21.100000 24.189200 l ef
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0.000000 0.000000 0.000000 srgb
|
||||
n 21.827940 22.189200 m 27.419117 22.189200 l 26.691176 24.189200 l 21.100000 24.189200 l cp s
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Execute word) dup sw 2 div 24.259558 ex sub 23.389200 m gs 1 -1 sc sh gr
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slc
|
||||
n 23.728200 19.565700 m 24.205977 21.944970 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 23.884442 21.613590 m 24.227988 22.054585 l 24.374656 21.515151 l s
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Yes) 24.550000 20.839200 m gs 1 -1 sc sh gr
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(No) 17.400000 22.789200 m gs 1 -1 sc sh gr
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Yes) 13.450000 26.589200 m gs 1 -1 sc sh gr
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(No) 6.400000 26.589200 m gs 1 -1 sc sh gr
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(No) 10.850000 16.239200 m gs 1 -1 sc sh gr
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Yes) 18.300000 16.239200 m gs 1 -1 sc sh gr
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(No) 14.150000 7.126860 m gs 1 -1 sc sh gr
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Yes) 21.100000 6.264170 m gs 1 -1 sc sh gr
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 14.795588 30.789200 m 14.795588 31.576100 l 2.050000 31.576100 l 2.050000 -5.998330 l 13.847836 -5.998330 l 13.847836 -4.709447 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 13.597836 -5.097643 m 13.847836 -4.597643 l 14.097836 -5.097643 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 23.895600 24.189200 m 23.895600 24.964200 l 28.900000 24.964200 l 28.900000 -6.885830 l 15.385336 -6.885830 l 15.385336 -4.709447 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 15.135336 -5.097643 m 15.385336 -4.597643 l 15.635336 -5.097643 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slc
|
||||
0 slj
|
||||
0 slc
|
||||
0 slj
|
||||
[] 0 sd
|
||||
1.000000 1.000000 1.000000 srgb
|
||||
n 14.204089 -10.686400 m 16.561196 -10.686400 l 16.914762 -10.364979 17.032617 -10.204268 17.032617 -9.882847 c 17.032617 -9.561425 16.914762 -9.400715 16.561196 -9.079293 c 14.204089 -9.079293 l 13.732668 -9.882847 l 14.204089 -10.686400 l ef
|
||||
0.000000 0.000000 0.000000 srgb
|
||||
n 14.204089 -10.686400 m 16.561196 -10.686400 l 16.914762 -10.364979 17.032617 -10.204268 17.032617 -9.882847 c 17.032617 -9.561425 16.914762 -9.400715 16.561196 -9.079293 c 14.204089 -9.079293 l 13.732668 -9.882847 l 14.204089 -10.686400 l s
|
||||
/Helvetica-latin1 ff 0.560000 scf sf
|
||||
(Start) dup sw 2 div 15.382643 ex sub -9.682847 m gs 1 -1 sc sh gr
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
[] 0 sd
|
||||
0 slc
|
||||
n 15.382643 -9.079293 m 15.385205 -4.709447 l s
|
||||
0.100000 slw
|
||||
[] 0 sd
|
||||
0 slj
|
||||
0 slc
|
||||
n 15.134977 -5.097497 m 15.385270 -4.597643 l 15.634977 -5.097790 l s
|
||||
showpage
|
388
doc/theory.tex
388
doc/theory.tex
|
@ -1,388 +0,0 @@
|
|||
\documentclass{amsart}
|
||||
\usepackage{times}
|
||||
\usepackage{tabularx}
|
||||
\usepackage{mathpartir}
|
||||
|
||||
\theoremstyle{plain}
|
||||
\newtheorem{theorem}{Theorem}[section]
|
||||
\newtheorem{lemma}[theorem]{Lemma}
|
||||
\newtheorem{proposition}[theorem]{Proposition}
|
||||
\newtheorem{conjecture}[theorem]{Conjecture}
|
||||
\newtheorem{corollary}[theorem]{Corollary}
|
||||
|
||||
\theoremstyle{definition}
|
||||
\newtheorem{algorithm}[theorem]{Algorithm}
|
||||
\newtheorem{definition}[theorem]{Definition}
|
||||
\newtheorem{remark}[theorem]{Remark}
|
||||
\newtheorem{example}[theorem]{Example}
|
||||
|
||||
\newcommand{\pcall }{\mbox{\texttt{call}}}
|
||||
\newcommand{\pchoose}{\mbox{\texttt{?}} }
|
||||
\newcommand{\pdrop }{\mbox{\texttt{drop}}}
|
||||
\newcommand{\pdup }{\mbox{\texttt{dup}}}
|
||||
\newcommand{\pswap }{\mbox{\texttt{swap}}}
|
||||
\newcommand{\ptor }{\mbox{\texttt{>r}}}
|
||||
\newcommand{\pfromr }{\mbox{\texttt{r>}}}
|
||||
\newcommand{\pcar }{\mbox{\texttt{car}}}
|
||||
\newcommand{\pcdr }{\mbox{\texttt{cdr}}}
|
||||
\newcommand{\pcons }{\mbox{\texttt{cdr}}}
|
||||
\newcommand{\peq }{\mbox{\texttt{=}}}
|
||||
|
||||
\def\leng{\mathop{\rm length}}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\title{Factor Theory}
|
||||
\author{Slava Pestov}
|
||||
|
||||
\begin{abstract}
|
||||
|
||||
In this article, I will attempt to give formal semantics to several aspects of
|
||||
the Factor programming language. This is neither a reference or an introduction; for such
|
||||
information, consult \texttt{http://factor.sf.net}.
|
||||
|
||||
\end{abstract}
|
||||
|
||||
\maketitle
|
||||
|
||||
\tableofcontents{}
|
||||
|
||||
\section{Transition semantics}
|
||||
|
||||
First, I present formal semantics for a subset of the Factor language.
|
||||
|
||||
\begin{definition}
|
||||
The set of objects, denoted $OBJ$, is the smallest set satisfying:
|
||||
|
||||
\begin{enumerate}
|
||||
|
||||
\item The empty list $\bot \in OBJ$.
|
||||
\item If $P$ is a primitive word, then $P \in OBJ$, where the primitive words are
|
||||
\texttt{call}, \texttt{?},
|
||||
\texttt{car}, \texttt{cdr}, \texttt{cons},
|
||||
\texttt{drop}, \texttt{dup}, \texttt{swap}, \texttt{>r}, \texttt{r>}, and
|
||||
\texttt{=}.
|
||||
\item If $a, b \in OBJ$, the cons cell $(a::b) \in OBJ$.
|
||||
\end{enumerate}
|
||||
|
||||
Note that Factor source code syntax for cons cells is \texttt{[[ a b ]]}, and the
|
||||
empty list is denoted \texttt{f}. However, I will use the above notation since it
|
||||
looks better in typeset output.
|
||||
|
||||
\end{definition}
|
||||
|
||||
In practice, Factor also allows a number of other data types, such as
|
||||
numbers, strings, vectors, and so on. They will not be needed for now. We are
|
||||
interested in a number of subsets of $OBJ$, the first being literal values.
|
||||
|
||||
\begin{definition}
|
||||
The set $LIT\subset OBJ$ consists of $OBJ-PRIM$, where $PRIM$ is the set of primitive words:
|
||||
\texttt{call}, \texttt{?},
|
||||
\texttt{car}, \texttt{cdr}, \texttt{cons},
|
||||
\texttt{drop}, \texttt{dup}, \texttt{swap}, \texttt{>r}, \texttt{r>}, and
|
||||
\texttt{=}.
|
||||
\end{definition}
|
||||
|
||||
\begin{definition}
|
||||
The set of program quotations, $QUOT \subset OBJ$, is the smallest set satisfying:
|
||||
|
||||
\begin{enumerate}
|
||||
|
||||
\item The empty list $\bot \in QUOT$.
|
||||
\item If $a \in OBJ$, $b \in QUOT$, $(a::b) \in QUOT$.
|
||||
|
||||
\end{enumerate}
|
||||
|
||||
I will write $(a,b,c)$ in place of $(a::(b::(c::\bot)))$. Note the Factor source code
|
||||
syntax is \texttt{[ a b c ]}.
|
||||
|
||||
It is convenient to define $\leng(\bot) := 0$, and $\leng(a::d):=1+\leng(d)$. Also, I will write $a\circ b$ for the concatenation of $a,b \in QUOT$.
|
||||
|
||||
\end{definition}
|
||||
|
||||
\begin{definition}
|
||||
The set of stacks, $STACK \subset QUOT$, is the smallest set satisfying:
|
||||
|
||||
\begin{enumerate}
|
||||
|
||||
\item The empty list $\bot \in STACK$.
|
||||
\item If $a \in QUOT$, $b \in STACK$, $(a::b) \in STACK$.
|
||||
|
||||
\end{enumerate}
|
||||
|
||||
\end{definition}
|
||||
|
||||
\begin{definition}
|
||||
|
||||
An \emph{interpreter} is a 3-tuple $(\delta, \rho, \chi)$, where $\delta, \rho \in STACK$,
|
||||
and $\chi \in QUOT$. The set of interpreters is denoted $INT$, and can be regarded as
|
||||
a subset of $OBJ$.
|
||||
|
||||
I call $\delta$ the \emph{data stack}; it holds values currently
|
||||
being operated on by the running program. The stack $\rho$ is called the \emph{return stack} and retains interpreter state
|
||||
between recursive calls. The quotation $\chi$ is called \emph{call frame}, and stores the
|
||||
currently executing program fragment. Basically, the transition relation looks at the
|
||||
call frame; if the first element is a literal, it is pushed on the stack, if the first
|
||||
element is a primitive word, it is executed, and if the call frame is the empty list,
|
||||
a new call frame is popped from the return stack.
|
||||
|
||||
\begin{figure}
|
||||
\caption{\label{trans}Transition semantics for the Factor interpreter.}
|
||||
|
||||
\begin{tabularx}{12cm}{lc}
|
||||
\hline
|
||||
|
||||
\{Reload\}&
|
||||
$$
|
||||
\inferrule
|
||||
{\chi = \bot \\ \rho = (\chi\prime::\rho\prime)}
|
||||
{(\delta,\rho,\chi)\rhd(\delta,\rho\prime,\chi\prime)}
|
||||
$$
|
||||
\\[4mm]
|
||||
|
||||
\{Literal\}&
|
||||
$$
|
||||
\inferrule
|
||||
{\chi = (\lambda :: \chi\prime) \\ \lambda \in LIT}
|
||||
{(\delta,\rho,\chi)\rhd((\lambda :: \delta),\rho,\chi\prime)}
|
||||
$$
|
||||
\\[4mm]
|
||||
|
||||
\{\pcall\}&
|
||||
$$
|
||||
\inferrule
|
||||
{\delta = (q :: \delta\prime) \\ \chi = (\pcall :: \chi\prime)}
|
||||
{(\delta,\rho,\chi)\rhd(\delta\prime,(\chi::\rho),\chi\prime)}
|
||||
$$
|
||||
\\[4mm]
|
||||
|
||||
\{\pchoose{}a\}&
|
||||
$$
|
||||
\inferrule
|
||||
{\delta = (\tau,\phi,\beta :: \delta\prime) \\ \beta = \bot \\ \chi = (\pchoose :: \chi\prime)}
|
||||
{(\delta,\rho,\chi)\rhd((\phi :: \delta\prime),\rho,\chi\prime)}
|
||||
$$
|
||||
\\[4mm]
|
||||
|
||||
\{\pchoose{}b\}&
|
||||
$$
|
||||
\inferrule
|
||||
{\delta = (\tau,\phi,\beta :: \delta\prime) \\ \beta \ne \bot \\ \chi = (\pchoose :: \chi\prime)}
|
||||
{(\delta,\rho,\chi)\rhd((\tau :: \delta\prime),\rho,\chi\prime)}
|
||||
$$
|
||||
\\[4mm]
|
||||
|
||||
\{\pdrop\}&
|
||||
$$
|
||||
\inferrule
|
||||
{\delta = (o :: \delta\prime) \\ \chi = (\pdrop :: \chi\prime)}
|
||||
{(\delta,\rho,\chi)\rhd(\delta\prime,\rho,\chi\prime)}
|
||||
$$
|
||||
\\[4mm]
|
||||
|
||||
\{\pdup\}&
|
||||
$$
|
||||
\inferrule
|
||||
{\delta = (o :: \delta\prime) \\ \chi = (\pdup :: \chi\prime)}
|
||||
{(\delta,\rho,\chi)\rhd((o o :: \delta\prime),\rho,\chi\prime)}
|
||||
$$
|
||||
\\[4mm]
|
||||
|
||||
\{\ptor\}&
|
||||
$$
|
||||
\inferrule
|
||||
{\delta = (o :: \delta\prime) \\ \chi = (\ptor :: \chi\prime)}
|
||||
{(\delta,\rho,\chi)\rhd(\delta\prime,(o :: \rho),\chi\prime)}
|
||||
$$
|
||||
\\[4mm]
|
||||
|
||||
\{\pfromr\}&
|
||||
$$
|
||||
\inferrule
|
||||
{\rho = (o :: \rho\prime) \\ \chi = (\pfromr :: \chi\prime)}
|
||||
{(\delta,\rho,\chi)\rhd((o :: \delta),\rho,\chi\prime)}
|
||||
$$
|
||||
\\[4mm]
|
||||
|
||||
\{\pcar\}&
|
||||
$$
|
||||
\inferrule
|
||||
{\rho = ((a :: d) :: \rho\prime) \\ \chi = (\pcar :: \chi\prime)}
|
||||
{(\delta,\rho,\chi)\rhd((a :: \delta),\rho,\chi\prime)}
|
||||
$$
|
||||
\\[4mm]
|
||||
|
||||
\{\pcdr\}&
|
||||
$$
|
||||
\inferrule
|
||||
{\rho = ((a :: d) :: \rho\prime) \\ \chi = (\pcdr :: \chi\prime)}
|
||||
{(\delta,\rho,\chi)\rhd((d :: \delta),\rho,\chi\prime)}
|
||||
$$
|
||||
\\[4mm]
|
||||
|
||||
\{\pcons\}&
|
||||
$$
|
||||
\inferrule
|
||||
{\rho = (a,d :: \rho\prime) \\ \chi = (\pcons :: \chi\prime)}
|
||||
{(\delta,\rho,\chi)\rhd(((a :: d) :: \delta),\rho,\chi\prime)}
|
||||
$$
|
||||
\\[4mm]
|
||||
|
||||
\{\peq{}a\}&
|
||||
$$
|
||||
\inferrule
|
||||
{\rho = (x,y :: \rho\prime) \\ x = y \\ \chi = (\peq :: \chi\prime)}
|
||||
{(\delta,\rho,\chi)\rhd((\bot :: \delta),\rho,\chi\prime)}
|
||||
$$
|
||||
\\[4mm]
|
||||
|
||||
\{\peq{}b\}&
|
||||
$$
|
||||
\inferrule
|
||||
{\rho = (x,y :: \rho\prime) \\ x \ne y \\ \chi = (\peq :: \chi\prime)}
|
||||
{(\delta,\rho,\chi)\rhd(((\bot) :: \delta),\rho,\chi\prime)}
|
||||
$$
|
||||
\\
|
||||
|
||||
\hline
|
||||
\end{tabularx}
|
||||
|
||||
\end{figure}
|
||||
|
||||
Now, I am ready to present transition semantics.
|
||||
Define a relation $\rhd$ by the deduction rules of figure \ref{trans}. By inspection, it is obvious that $(x\rhd y \wedge x \rhd z) \Rightarrow y=z$, so we are able to make the following definition.
|
||||
|
||||
\begin{definition}
|
||||
Define a functional $\mathcal{F}: (INT \rightarrow INT) \rightarrow (INT \rightarrow INT)$:
|
||||
|
||||
$$
|
||||
\mathcal{F}(f)(i) =
|
||||
\begin{cases}
|
||||
f(j)&\text{if $\exists j / i\rhd j$}\\
|
||||
i&\text{else}
|
||||
\end{cases}
|
||||
$$
|
||||
|
||||
\end{definition}
|
||||
|
||||
Now, let $F: INT \rightarrow INT$ be the least fixed point of $\mathcal{F}$. $F$ is the \emph{Factor evaluator function}. It takes an interpreter and maps it to another
|
||||
interpreter. If the resulting interpreter's call frame is $\bot$, evaluation completed
|
||||
successfully; otherwise, at some stage of the computation, there was no applicable
|
||||
inference rule (for example, a \texttt{drop} was attempted with an empty stack), in which case it is an error condition. In the case that the final call frame is non-empty, we abuse notation and say that $F(\delta,\rho,\chi)=\bot$.
|
||||
|
||||
Note that $F$ is a partial function, and it might not terminate; in this case, lets say $F(i) = \bot$.
|
||||
|
||||
\end{definition}
|
||||
|
||||
Now, I will give the first lemma. Intuitively, it states that if a quotation consumes $n$ elements from the stack, it does not ``see'' anything below. This forms the basis for the work in the next section.
|
||||
|
||||
\begin{lemma}\label{dipping}
|
||||
Let $q\in QUOT$ be such that there exists $\delta\in STACK$ with $F(\delta,\bot,q)=(\delta\prime,\bot,\bot)$. Then for any $\delta_0\in STACK$,
|
||||
$F(\delta\circ\delta_0,\bot,q)=(\delta\prime\circ\delta_0,\bot,\bot)$
|
||||
\end{lemma}
|
||||
|
||||
\begin{proof}
|
||||
Since $F(\delta,\bot,q)\ne\bot$ by assumption, each step of its transition chain has the
|
||||
property that the data stack is either $\bot$ and no attempt is made to access its top
|
||||
element, or the data stack is not $\bot$. Now notice that the same transition chain will
|
||||
occur with $F(\delta\circ \delta_0,\bot,q)$; the only difference being that when the data stack would become $\bot$ in the former, it would become $\delta_0$ in the latter. But since no attempt is made to access the top stack element, both transition chains are equivalent up to the appending of $\delta_0$. Therefore $F(\delta\circ \delta_0,\bot,q)=(\delta\prime\circ \delta_0,\bot,\bot)$.
|
||||
|
||||
\end{proof}
|
||||
|
||||
\section{Stack effects}
|
||||
|
||||
Now, I will study the effect of evaluation on the data stack in detail. The primary motivation, and
|
||||
eventual goal, is to be able to statically deduce the number of input and output parameters
|
||||
of a quotation on the stack.
|
||||
|
||||
\begin{definition} Let $q \in QUOT$ be a program fragment. The \emph{stack effect} of $q$, denoted $[q]$, is $(m,n)\in \mathbb{Z}^+\times\mathbb{Z}^+$ iff the following conditions hold:
|
||||
|
||||
\begin{enumerate}
|
||||
|
||||
\item If $\leng(\delta)=m$, $(F(\delta,\bot,q)=(\delta\prime,\bot,\bot)) \Rightarrow (\leng(\delta\prime)=n)$.
|
||||
|
||||
\item If $l<m$, there exists a data stack $\delta$ with $\leng(\delta)=l$ such that $F(\delta,\bot,q)=\bot$.
|
||||
|
||||
\end{enumerate}
|
||||
|
||||
Note that if for all data stacks $\delta$, we have $F(\delta,\bot,q)=\bot$, the stack effect can be stated to be any pair $(m,n)$. This does not cause a problem in practice.
|
||||
|
||||
\end{definition}
|
||||
|
||||
The following result is intuitively obvious; the stack effect of a literal object is to increase the number of elements on the stack by one.
|
||||
|
||||
\begin{lemma}
|
||||
For $o \in LIT$, $[o]=(0,1)$.
|
||||
\end{lemma}
|
||||
|
||||
\begin{proof}
|
||||
By the transition rule \{Literal\}, we have:
|
||||
|
||||
$$F(\bot,\bot,(o))=((o),\bot,\bot)$$
|
||||
|
||||
By definition if the length function, it follows that:
|
||||
|
||||
$$\leng((o))=1+\leng(\bot)=1$$
|
||||
|
||||
Since 0 is the smallest possible choice of $n$, the second condition on the definition of a
|
||||
stack effect is automatically satisfied.
|
||||
\end{proof}
|
||||
|
||||
\begin{definition} The \emph{composition of stack effects} $(a,b), (c,d) \in \mathbb{Z}^+\times\mathbb{Z}^+$ is defined and denoted as follows:
|
||||
|
||||
$$(a,b) \otimes (c,d) = (a + \max(0,c-b),d + \max(0,b-c))$$
|
||||
|
||||
\end{definition}
|
||||
|
||||
The reason we define the above operation becomes clear with the following theorem.
|
||||
It actually does represent composition of stack effects.
|
||||
|
||||
\begin{theorem}\label{iso}
|
||||
For $p,q \in QUOT$, $[p\circ q]=[p]\otimes [q]$.
|
||||
\end{theorem}
|
||||
|
||||
\begin{proof}
|
||||
Let $[p]=(a,b)$, $[q]=(c,d)$.
|
||||
If for all $\delta$, $F(\delta,\bot,p\circ q)=\bot$, then the stack effect of $p\circ q$ is vacuously $(a,b)\otimes(c,d)$. So assume that there exists a stack $\delta$ such that $F(\delta,\bot,p\circ q)=(\delta\prime,\bot,\bot)$ for some $\delta\prime$.
|
||||
|
||||
Now, consider two cases.
|
||||
|
||||
\begin{enumerate}
|
||||
\item $c<b$. Let $\delta$ be such that $\leng(\delta)=a$ and $F(\delta,\bot,p)=(\delta\prime,\bot,\bot)$. Then $\leng(\delta\prime)=b$.
|
||||
By assumption, $F(\delta\prime,\bot,q)\ne\bot$. So by \ref{dipping},
|
||||
$F(\delta\prime,\bot,q)=(\delta\prime\prime,\bot,\bot)$ where $\leng(\delta\prime\prime)=\leng(\delta\prime)+b-c$.
|
||||
|
||||
\item $c\geq b$. p takes a, leaves b, q takes c-b more then and leaves c-b+d by \ref{dipping}.
|
||||
\end{enumerate}
|
||||
|
||||
In both cases, we have that $[p\circ q]=(a + \max(0,c-b),d + \max(0,b-c))$.
|
||||
\end{proof}
|
||||
|
||||
\begin{lemma}
|
||||
Stack effect composition has an equal left and right identity, and is associative:
|
||||
|
||||
\begin{enumerate}
|
||||
\item For all $(a,b) \in \mathbb{Z}^+\times\mathbb{Z}^+$, $(a,b) \otimes (0,0) = (0,0) \otimes (a,b) = (a,b)$.
|
||||
\item For all $x,y,z \in \mathbb{Z}^+\times\mathbb{Z}^+$, $x\otimes (y\otimes z) = (x\otimes y) \otimes z$.
|
||||
\end{enumerate}
|
||||
|
||||
\end{lemma}
|
||||
|
||||
\begin{proof}
|
||||
The first part follows by routine calculation.
|
||||
|
||||
$$(a,b) \otimes (0,0) = (a+\max(0,0-b),0+\max(0,b-0)) = (a,b)$$
|
||||
$$(0,0) \otimes (a,b) = (0+\max(0,a-0),b+\max(0,0-a)) = (a,b)$$
|
||||
|
||||
The second follows from the associativity of the concatenation operator $\circ$. Given stack effects $x,y,z$, let $X,Y,Z \in QUOT$ be quotations whose stack effects are $x,y,z$, respectively. Then by the previous theorem we have:
|
||||
|
||||
$$[X\circ Y\circ Z] = [X] \otimes [Y\circ Z] = [X] \otimes ([Y] \otimes [Z])$$
|
||||
$$[X\circ Y\circ Z] = [X\circ Y] \otimes [Z] = ([X] \otimes [Y]) \otimes [Z]$$
|
||||
|
||||
Or indeed,
|
||||
|
||||
$$x\otimes(y\otimes z) = (x\otimes y)\otimes z$$
|
||||
|
||||
\end{proof}
|
||||
|
||||
\end{document}
|
|
@ -70,7 +70,7 @@ M: canvas draw-gadget* ( gadget -- )
|
|||
: turtle-test
|
||||
{ 400 400 0 } [
|
||||
36 [
|
||||
! random-color
|
||||
random-color
|
||||
10 line-to
|
||||
10 turn-by [ 60 10 regular-polygon ] new-pen
|
||||
] times
|
||||
|
|
|
@ -16,9 +16,6 @@ IN: ray
|
|||
|
||||
: size 200 ; inline
|
||||
|
||||
! kludge
|
||||
: INF inf swons ; parsing
|
||||
|
||||
: delta 1.4901161193847656E-8 ; inline
|
||||
|
||||
TUPLE: ray orig dir ;
|
||||
|
@ -40,11 +37,11 @@ TUPLE: sphere center radius ;
|
|||
: -+ ( x y -- x-y x+y ) [ - ] 2keep + ;
|
||||
|
||||
: sphere-b/d ( b d -- t )
|
||||
-+ dup 0.0 < [ 2drop inf ] [ >r [ 0.0 > ] keep r> ? ] if ;
|
||||
-+ dup 0.0 < [ 2drop 1.0/0.0 ] [ >r [ 0.0 > ] keep r> ? ] if ;
|
||||
|
||||
: ray-sphere ( sphere ray -- t )
|
||||
2dup sphere-v tuck sphere-b [ sphere-disc ] keep
|
||||
over 0.0 < [ 2drop inf ] [ swap sqrt sphere-b/d ] if ;
|
||||
over 0.0 < [ 2drop 1.0/0.0 ] [ swap sqrt sphere-b/d ] if ;
|
||||
|
||||
: sphere-n ( ray sphere l -- n )
|
||||
pick ray-dir n*v swap sphere-center v- swap ray-orig v+ ;
|
||||
|
@ -72,7 +69,7 @@ M: group intersect-scene ( hit ray group -- hit )
|
|||
drop
|
||||
] if-ray-sphere ;
|
||||
|
||||
: initial-hit T{ hit f { 0.0 0.0 0.0 } INF } ;
|
||||
: initial-hit T{ hit f { 0.0 0.0 0.0 } 1.0/0.0 } ;
|
||||
|
||||
: initial-intersect ( ray scene -- hit )
|
||||
initial-hit -rot intersect-scene ;
|
||||
|
@ -88,10 +85,10 @@ M: group intersect-scene ( hit ray group -- hit )
|
|||
: ray-g ( hit -- g ) hit-normal light v. ;
|
||||
|
||||
: cast-ray ( ray scene -- g )
|
||||
2dup initial-intersect dup hit-lambda inf = [
|
||||
2dup initial-intersect dup hit-lambda 1.0/0.0 = [
|
||||
3drop 0.0
|
||||
] [
|
||||
dup ray-g >r sray-intersect hit-lambda inf =
|
||||
dup ray-g >r sray-intersect hit-lambda 1.0/0.0 =
|
||||
[ r> neg ] [ r> drop 0.0 ] if
|
||||
] if ;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
! :folding=indent:collapseFolds=1:
|
||||
|
||||
! $Id$
|
||||
! $Id: win32-io.factor,v 1.10 2005/09/29 19:26:32 eiz Exp $
|
||||
!
|
||||
! Copyright (C) 2003, 2004 Mackenzie Straight.
|
||||
!
|
||||
|
|
|
@ -72,6 +72,4 @@ M: %alien-invoke generate-node
|
|||
: card-bits 7 ;
|
||||
: card-mark HEX: 80 ;
|
||||
|
||||
: shift-add ( by -- n )
|
||||
#! Used in fixnum-shift overflow check.
|
||||
>r 1 cell-bits r> 1- - shift ;
|
||||
: string-offset 3 cells object-tag - ;
|
||||
|
|
|
@ -59,20 +59,20 @@ namespaces sequences words ;
|
|||
1 %write-barrier ,
|
||||
] "intrinsic" set-word-prop
|
||||
|
||||
! \ char-slot [
|
||||
! drop
|
||||
! in-2
|
||||
! -1 %inc-d ,
|
||||
! 0 1 %char-slot ,
|
||||
! 1 <vreg> 0 %replace-d ,
|
||||
! ] "intrinsic" set-word-prop
|
||||
!
|
||||
! \ set-char-slot [
|
||||
! drop
|
||||
! in-3
|
||||
! -3 %inc-d ,
|
||||
! 0 2 1 %set-char-slot ,
|
||||
! ] "intrinsic" set-word-prop
|
||||
\ char-slot [
|
||||
drop
|
||||
in-2
|
||||
-1 %inc-d ,
|
||||
0 1 %char-slot ,
|
||||
1 <vreg> 0 %replace-d ,
|
||||
] "intrinsic" set-word-prop
|
||||
|
||||
\ set-char-slot [
|
||||
drop
|
||||
in-3
|
||||
-3 %inc-d ,
|
||||
0 2 1 %set-char-slot ,
|
||||
] "intrinsic" set-word-prop
|
||||
|
||||
\ type [
|
||||
drop
|
||||
|
|
|
@ -43,8 +43,6 @@ M: %write-barrier generate-node ( vop -- )
|
|||
0 scratch dup card-mark ORI
|
||||
0 scratch 0 input-operand 0 STB ;
|
||||
|
||||
: string-offset 3 cells object-tag - ;
|
||||
|
||||
M: %char-slot generate-node ( vop -- )
|
||||
drop 1 [ string-offset LHZ ] generate-slot
|
||||
0 output-operand dup tag-fixnum ;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
IN: compiler-backend
|
||||
USING: alien arrays assembler compiler compiler-backend kernel
|
||||
kernel-internals sequences ;
|
||||
USING: alien arrays assembler compiler compiler-backend generic
|
||||
kernel kernel-internals sequences words ;
|
||||
|
||||
! x86 register assignments
|
||||
! EAX, ECX, EDX vregs
|
||||
|
|
|
@ -19,12 +19,9 @@ GENERIC: canonicalize ( op -- op )
|
|||
|
||||
#! Extended AMD64 registers return true.
|
||||
GENERIC: extended? ( op -- ? )
|
||||
#! 64-bit registers return true.
|
||||
GENERIC: operand-64? ( op -- ? )
|
||||
|
||||
M: object canonicalize ;
|
||||
M: object extended? drop f ;
|
||||
M: object operand-64? drop cell 8 = ;
|
||||
|
||||
( Register operands -- eg, ECX )
|
||||
: define-register ( symbol num size -- )
|
||||
|
@ -61,6 +58,7 @@ SYMBOL: XMM7 \ XMM7 7 128 define-register
|
|||
|
||||
PREDICATE: word register "register" word-prop ;
|
||||
|
||||
PREDICATE: register register-16 "register-size" word-prop 16 = ;
|
||||
PREDICATE: register register-32 "register-size" word-prop 32 = ;
|
||||
PREDICATE: register register-64 "register-size" word-prop 64 = ;
|
||||
PREDICATE: register register-128 "register-size" word-prop 128 = ;
|
||||
|
@ -69,7 +67,6 @@ M: register modifier drop BIN: 11 ;
|
|||
M: register register "register" word-prop 7 bitand ;
|
||||
M: register displacement drop ;
|
||||
M: register extended? "register" word-prop 7 > ;
|
||||
M: register operand-64? register-64? ;
|
||||
|
||||
( Indirect register operands -- eg, { ECX } )
|
||||
PREDICATE: array indirect
|
||||
|
@ -80,7 +77,6 @@ M: indirect register first register ;
|
|||
M: indirect displacement drop ;
|
||||
M: indirect canonicalize dup first EBP = [ drop { EBP 0 } ] when ;
|
||||
M: indirect extended? first extended? ;
|
||||
M: indirect operand-64? first register-64? ;
|
||||
|
||||
( Displaced indirect register operands -- eg, { EAX 4 } )
|
||||
PREDICATE: array displaced
|
||||
|
@ -95,7 +91,6 @@ M: displaced canonicalize
|
|||
dup first EBP = not over second zero? and
|
||||
[ first 1array ] when ;
|
||||
M: displaced extended? first extended? ;
|
||||
M: displaced operand-64? first register-64? ;
|
||||
|
||||
( Displacement-only operands -- eg, { 1234 } )
|
||||
PREDICATE: array disp-only
|
||||
|
@ -121,19 +116,24 @@ UNION: operand register indirect displaced disp-only ;
|
|||
swap extended? [ BIN: 00000001 bitor ] when
|
||||
dup BIN: 01000000 = [ drop ] [ assemble-1 ] if ;
|
||||
|
||||
: rex-prefix-1 ( reg rex.w -- ) f swap rex-prefix ;
|
||||
: 16-prefix ( reg r/m -- )
|
||||
[ register-16? ] 2apply or [ HEX: 66 assemble-1 ] when ;
|
||||
|
||||
: prefix ( reg r/m rex.w -- ) pick pick 16-prefix rex-prefix ;
|
||||
|
||||
: prefix-1 ( reg rex.w -- ) f swap prefix ;
|
||||
|
||||
: short-operand ( reg rex.w n -- )
|
||||
#! Some instructions encode their single operand as part of
|
||||
#! the opcode.
|
||||
>r dupd rex-prefix-1 register r> + assemble-1 ;
|
||||
>r dupd prefix-1 register r> + assemble-1 ;
|
||||
|
||||
: mod-r/m ( op reg -- )
|
||||
>r canonicalize dup modifier 6 shift over register bitor r>
|
||||
3 shift bitor assemble-1 displacement ;
|
||||
|
||||
: 1-operand ( op reg rex.w opcode -- )
|
||||
>r >r over r> rex-prefix-1 r> assemble-1 mod-r/m ;
|
||||
>r >r over r> prefix-1 r> assemble-1 mod-r/m ;
|
||||
|
||||
: immediate-1 ( imm dst reg rex.w opcode -- )
|
||||
#! The 'reg' is not really a register, but a value for the
|
||||
|
@ -155,7 +155,7 @@ UNION: operand register indirect displaced disp-only ;
|
|||
#! Sets the opcode's direction bit. It is set if the
|
||||
#! destination is a direct register operand.
|
||||
pick register? [ BIN: 10 bitor swapd ] when
|
||||
>r 2dup t rex-prefix r> assemble-1 register mod-r/m ;
|
||||
>r 2dup t prefix r> assemble-1 register mod-r/m ;
|
||||
|
||||
: from ( addr -- addr )
|
||||
#! Relative to after next 32-bit immediate.
|
||||
|
@ -282,7 +282,7 @@ M: operand CMP OCT: 071 2-operand ;
|
|||
|
||||
: 2-operand-sse ( dst src op1 op2 -- )
|
||||
pick register-128? [ nip ] [ drop swapd ] if
|
||||
>r 2dup t rex-prefix HEX: 0f assemble-1 r>
|
||||
>r 2dup t prefix HEX: 0f assemble-1 r>
|
||||
assemble-1 register mod-r/m ;
|
||||
|
||||
: MOVLPD ( dest src -- )
|
||||
|
|
|
@ -42,6 +42,28 @@ M: %set-slot generate-node ( vop -- )
|
|||
M: %fast-set-slot generate-node ( vop -- )
|
||||
drop 1 input-operand 2 input 2array 0 input-operand MOV ;
|
||||
|
||||
: >register-16 ( reg -- reg )
|
||||
"register" word-prop { AX CX DX } nth ;
|
||||
|
||||
: scratch-16 ( n -- reg ) scratch >register-16 ;
|
||||
|
||||
M: %char-slot generate-node ( vop -- )
|
||||
drop
|
||||
0 input-operand 2 SHR
|
||||
0 scratch dup XOR
|
||||
dest/src ADD
|
||||
0 scratch-16 0 output-operand string-offset 2array MOV
|
||||
0 scratch tag-bits SHL
|
||||
0 output-operand 0 scratch MOV ;
|
||||
|
||||
M: %set-char-slot generate-node ( vop -- )
|
||||
drop
|
||||
0 input-operand tag-bits SHR
|
||||
2 input-operand 2 SHR
|
||||
2 input-operand 1 input-operand ADD
|
||||
2 input-operand string-offset
|
||||
2array 0 input-operand >register-16 MOV ;
|
||||
|
||||
: userenv@ ( n -- addr ) cells "userenv" f dlsym + ;
|
||||
|
||||
M: %getenv generate-node ( vop -- )
|
||||
|
|
|
@ -26,7 +26,7 @@ UNION: integer fixnum bignum ;
|
|||
>r 1 shift r> (next-power-of-2)
|
||||
] if ;
|
||||
|
||||
: next-power-of-2 ( n -- n ) 1 swap (next-power-of-2) ;
|
||||
: next-power-of-2 ( n -- n ) 2 swap (next-power-of-2) ;
|
||||
|
||||
IN: math-internals
|
||||
|
||||
|
|
|
@ -83,8 +83,8 @@ unit-test
|
|||
[ 0 ] [ -7/8 ceiling ] unit-test
|
||||
[ -1 ] [ -3/2 ceiling ] unit-test
|
||||
|
||||
[ 1 ] [ 0 next-power-of-2 ] unit-test
|
||||
[ 1 ] [ 1 next-power-of-2 ] unit-test
|
||||
[ 2 ] [ 0 next-power-of-2 ] unit-test
|
||||
[ 2 ] [ 1 next-power-of-2 ] unit-test
|
||||
[ 2 ] [ 2 next-power-of-2 ] unit-test
|
||||
[ 4 ] [ 3 next-power-of-2 ] unit-test
|
||||
[ 16 ] [ 13 next-power-of-2 ] unit-test
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
! :folding=indent:collapseFolds=1:
|
||||
|
||||
! $Id$
|
||||
! $Id: win32-errors.factor,v 1.11 2005/12/22 02:30:00 erg Exp $
|
||||
!
|
||||
! Copyright (C) 2004 Mackenzie Straight.
|
||||
!
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
! $Id$
|
||||
! $Id: win32-io-internals.factor,v 1.15 2006/01/28 20:49:31 spestov Exp $
|
||||
!
|
||||
! Copyright (C) 2004, 2005 Mackenzie Straight.
|
||||
!
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
! :folding=indent:collapseFolds=1:
|
||||
|
||||
! $Id$
|
||||
! $Id: win32-io.factor,v 1.4 2005/07/23 06:11:07 eiz Exp $
|
||||
!
|
||||
! Copyright (C) 2004 Mackenzie Straight.
|
||||
!
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
! $Id$
|
||||
! $Id: win32-server.factor,v 1.13 2006/01/28 20:49:31 spestov Exp $
|
||||
!
|
||||
! Copyright (C) 2004, 2005 Mackenzie Straight.
|
||||
!
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
! $Id$
|
||||
! $Id: win32-stream.factor,v 1.16 2006/01/28 20:49:31 spestov Exp $
|
||||
!
|
||||
! Copyright (C) 2004, 2005 Mackenzie Straight.
|
||||
!
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
! :folding=indent:collapseFolds=1:
|
||||
|
||||
! $Id$
|
||||
! $Id: winsock.factor,v 1.8 2005/09/12 15:10:33 erg Exp $
|
||||
!
|
||||
! Copyright (C) 2004 Mackenzie Straight.
|
||||
!
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2003, 2004 Slava Pestov.
|
||||
* Copyright (C) 2003, 2006 Slava Pestov.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* :tabSize=2:indentSize=2:noTabs=true:
|
||||
|
||||
$Id$
|
||||
$Id: s48_bignum.c,v 1.12 2005/12/21 02:36:52 spestov Exp $
|
||||
|
||||
Copyright (c) 1989-94 Massachusetts Institute of Technology
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*-C-*-
|
||||
|
||||
$Id$
|
||||
$Id: s48_bignum.h,v 1.13 2005/12/21 02:36:52 spestov Exp $
|
||||
|
||||
Copyright (c) 1989-1992 Massachusetts Institute of Technology
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*-C-*-
|
||||
|
||||
$Id$
|
||||
$Id: s48_bignumint.h,v 1.14 2005/12/21 02:36:52 spestov Exp $
|
||||
|
||||
Copyright (c) 1989-1992 Massachusetts Institute of Technology
|
||||
|
||||
|
|
Loading…
Reference in New Issue