1 ! :folding=indent:collapseFolds=1:
5 ! Copyright (C) 2003, 2004 Slava Pestov.
7 ! Redistribution and use in source and binary forms, with or without
8 ! modification, are permitted provided that the following conditions are met:
10 ! 1. Redistributions of source code must retain the above copyright notice,
11 ! this list of conditions and the following disclaimer.
13 ! 2. Redistributions in binary form must reproduce the above copyright notice,
14 ! this list of conditions and the following disclaimer in the documentation
15 ! and/or other materials provided with the distribution.
17 ! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 ! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19 ! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 ! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 ! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 ! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 ! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 ! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 : slip ( quot x -- x )
34 >r call r> ; inline interpret-only
36 : 2slip ( quot x y -- x y )
37 >r >r call r> r> ; inline interpret-only
39 : 3slip ( quot x y z -- x y z )
40 >r >r >r call r> r> r> ; inline interpret-only
42 : keep ( a quot -- a )
43 #! Execute the quotation with a on the stack, and restore a
44 #! after the quotation returns.
47 : apply ( code input -- code output )
48 #! Apply code to input.
49 swap dup >r call r> swap ;
52 #! The list is of this form:
54 #! [ [ condition 1 ] [ code 1 ]
55 #! [ condition 2 ] [ code 2 ]
58 #! Each condition is evaluated in turn. If it returns true,
59 #! the code is evaluated. If it returns false, the next
60 #! condition is checked.
62 #! Before evaluating each condition, the top of the stack is
63 #! duplicated. After the last condition is evaluated, the
64 #! top of the stack is popped.
66 #! So each condition and code block must have stack effect:
69 #! This combinator will not compile.
71 uncons >r over >r call r> r> rot [
78 ] ifte ; interpret-only
80 : ifte* ( cond true false -- )
81 #! If the condition is not f, execute the 'true' quotation,
82 #! with the condition on the stack. Otherwise, pop the
83 #! condition and execute the 'false' quotation.
84 pick [ drop call ] [ nip nip call ] ifte ;
87 : unless ( cond quot -- )
88 #! Execute a quotation only when the condition is f. The
89 #! condition is popped off the stack.
91 #! In order to compile, the quotation must consume as many
92 #! values as it produces.
93 [ ] swap ifte ; inline interpret-only
95 : unless* ( cond quot -- )
96 #! If cond is f, pop it off the stack and evaluate the
97 #! quotation. Otherwise, leave cond on the stack.
99 #! In order to compile, the quotation must consume one less
100 #! value than it produces.
101 over [ drop ] [ nip call ] ifte ; inline interpret-only
103 : when ( cond quot -- )
104 #! Execute a quotation only when the condition is not f. The
105 #! condition is popped off the stack.
107 #! In order to compile, the quotation must consume as many
108 #! values as it produces.
109 [ ] ifte ; inline interpret-only
111 : when* ( cond quot -- )
112 #! If the condition is true, it is left on the stack, and
113 #! the quotation is evaluated. Otherwise, the condition is
114 #! popped off the stack.
116 #! In order to compile, the quotation must consume one more
117 #! value than it produces.
118 over [ call ] [ 2drop ] ifte ; inline interpret-only
120 : forever ( quot -- )
121 #! The code is evaluated in an infinite loop. Typically, a
122 #! continuation is used to escape the infinite loop.
124 #! This combinator will not compile.
125 dup slip forever ; interpret-only
129 : 2apply ( x y quot -- )
130 #! First applies the code to x, then to y.
132 #! If the quotation compiles, this combinator compiles.
133 2dup >r >r nip call r> r> call ; inline interpret-only
135 : cleave ( x quot quot -- )
136 #! Executes each quotation, with x on top of the stack.
138 #! If the quotation compiles, this combinator compiles.
139 >r over >r call r> r> call ; inline interpret-only
141 : dip ( a [ b ] -- b a )
142 #! Call b as if b was not present on the stack.
144 #! If the quotation compiles, this combinator compiles.
145 swap >r call r> ; inline interpret-only
147 : 2dip ( a b [ c ] -- c a b )
148 #! Call c as if a and b were not present on the stack.
150 #! If the quotation compiles, this combinator compiles.
151 -rot >r >r call r> r> ; inline interpret-only
153 : interleave ( X quot -- )
154 #! Evaluate each element of the list with X on top of the
155 #! stack. When done, X is popped off the stack.
157 #! To avoid unexpected results, each element of the list
158 #! must have stack effect ( X -- ).
160 #! This combinator will not compile.
162 over [ unswons dip ] dip swap interleave
165 ] ifte ; interpret-only
167 : while ( cond body -- )
168 #! Evaluate cond. If it leaves t on the stack, evaluate
169 #! body, and recurse.
171 #! In order to compile, the stack effect of
172 #! cond * ( X -- ) * body must consume as many values as
177 r> drop r> drop r> drop
178 ] ifte ; inline interpret-only