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.
37 !!! Other languages have classes, objects, variables, etc.
38 !!! Factor has similar concepts.
47 !!! get ( name -- value ) and set ( value name -- ) search in
48 !!! the namespaces on the namespace stack, in top-down order.
50 !!! At the bottom of the namespace stack, is the global
51 !!! namespace; it is always present.
53 !!! bind ( namespace quot -- ) executes a quotation with a
54 !!! namespace pushed on the namespace stack.
56 : namestack ( -- stack )
57 #! Push a copy of the namespace stack; same naming
58 #! convention as the primitives datastack and callstack.
59 namestack* clone ; inline
61 : set-namestack ( stack -- )
62 #! Set the namespace stack to a copy of another stack; same
63 #! naming convention as the primitives datastack and
65 clone set-namestack* ; inline
67 : >n ( namespace -- n:namespace )
68 #! Push a namespace on the namespace stack.
69 namestack* vector-push ; inline
71 : n> ( n:namespace -- namespace )
72 #! Pop the top of the namespace stack.
73 namestack* vector-pop ; inline
75 : namespace ( -- namespace )
76 #! Push the current namespace.
77 namestack* vector-peek ; inline
79 : bind ( namespace quot -- )
80 #! Execute a quotation with a new namespace on the namespace
81 #! stack. Compiles if the quotation compiles.
82 swap namespace-of >n call n> drop ; inline
84 : extend ( object code -- object )
85 #! Used in code like this:
90 over >r bind r> ; inline
92 : lazy ( var [ a ] -- value )
93 #! If the value of the variable is f, set the value to the
94 #! result of evaluating [ a ].
95 over get [ drop get ] [ dip dupd set ] ifte ;
97 : alist> ( alist namespace -- )
98 #! Set each key in the alist to its value in the
100 [ [ unswons set ] each ] bind ;
102 : alist>namespace ( alist -- namespace )
103 <namespace> tuck alist> ;
105 : object-path-traverse ( name object -- object )
106 dup has-namespace? [ get* ] [ 2drop f ] ifte ;
108 : object-path-iter ( object list -- object )
110 uncons [ swap object-path-traverse ] dip
114 : object-path ( list -- object )
115 #! An object path is a list of strings. Each string is a
116 #! variable name in the object namespace at that level.
117 #! Returns f if any of the objects are not set.
118 this swap object-path-iter ;
120 : global-object-path ( string -- object )
121 #! An object path based from the global namespace.
122 "'" split global [ object-path ] bind ;
124 : on ( var -- ) t put ;
125 : off ( var -- ) f put ;
126 : toggle ( var -- ) dup get not put ;