]> gitweb.factorcode.org Git - factor.git/commitdiff
working on the compiler
authorSlava Pestov <slava@factorcode.org>
Mon, 16 May 2005 01:17:56 +0000 (01:17 +0000)
committerSlava Pestov <slava@factorcode.org>
Mon, 16 May 2005 01:17:56 +0000 (01:17 +0000)
34 files changed:
library/bootstrap/boot-stage2.factor
library/bootstrap/boot-stage3.factor
library/collections/sequences-epilogue.factor
library/compiler/intrinsics.factor
library/compiler/linearizer.factor
library/compiler/optimizer.factor
library/compiler/simplifier.factor
library/compiler/vops.factor
library/compiler/x86/fixnum.factor
library/compiler/x86/stack.factor
library/generic/builtin.factor
library/generic/generic.factor
library/generic/tuple.factor
library/inference/branches.factor
library/inference/dataflow.factor
library/inference/inference.factor
library/inference/partial-eval.factor [new file with mode: 0644]
library/inference/stack.factor
library/inference/values.factor [new file with mode: 0644]
library/inference/words.factor
library/math/math.factor
library/test/benchmark/prettyprint.factor [new file with mode: 0644]
library/test/compiler/optimizer.factor
library/test/dataflow.factor
library/test/gadgets.factor
library/test/math/bitops.factor
library/test/memory.factor
library/test/prettyprint.factor [deleted file]
library/test/sequences.factor
library/test/test.factor
library/test/tuple.factor
library/test/words.factor
library/tools/memory.factor
library/vocabularies.factor

index df66df31b644da2a27700a0ec341ebf98c344ef9..8b7a1945ef1c0abdfa5ac5d9463a4152ed574fe9 100644 (file)
@@ -28,12 +28,14 @@ recrossref
 t [\r
     "/library/inference/conditions.factor"\r
     "/library/inference/dataflow.factor"\r
+    "/library/inference/values.factor"\r
     "/library/inference/inference.factor"\r
     "/library/inference/ties.factor"\r
     "/library/inference/branches.factor"\r
     "/library/inference/words.factor"\r
     "/library/inference/stack.factor"\r
     "/library/inference/types.factor"\r
+    "/library/inference/partial-eval.factor"\r
 \r
     "/library/compiler/assembler.factor"\r
     "/library/compiler/relocate.factor"\r
index 5b769397341ba32783753735786c36ec654c3103..89a5939392d2425ee949f80104ca033c15beb7b6 100644 (file)
@@ -1,7 +1,8 @@
 ! Copyright (C) 2004, 2005 Slava Pestov.
 ! See http://factor.sf.net/license.txt for BSD license.
-USING: alien assembler command-line compiler io-internals kernel
-lists math namespaces parser sequences stdio unparser words ;
+USING: alien assembler command-line compiler compiler-backend
+io-internals kernel lists math namespaces parser sequences stdio
+unparser words ;
 
 "Compiling base..." print
 
@@ -36,6 +37,7 @@ compile? [
     \ = compile
     \ unparse compile
     \ scan compile
+    \ (generate) compile
 ] when
 
 "Loading more library code..." print
index b8620f84198938461dabc3fb57eef3f09bd47359..3b95f914ad5754dcf4cbd68c74bf48b41233a188 100644 (file)
@@ -182,7 +182,7 @@ C: range ( from to -- range )
     [ set-range-from ] keep ;
 
 M: range length ( range -- n )
-    dup range-to swap range-from - abs 1 + ;
+    dup range-to swap range-from - abs ;
 
 M: range nth ( n range -- n )
     [ range-step * ] keep range-from + ;
@@ -200,6 +200,9 @@ M: slice nth ( n slice -- obj )
 M: slice set-nth ( obj n slice -- )
     [ delegate nth ] keep slice-seq set-nth ;
 
+: tail-slice ( n seq -- slice )
+    [ length [ swap - ] keep ] keep <slice> ;
+
 IN: kernel
 
 : depth ( -- n )
index 8bb1478e4cc4d40ccb10f2438a9194a6bc93b197..63c8c93a814bf01da51f4e474d5e3f19e1b457e9 100644 (file)
@@ -11,18 +11,20 @@ sequences words ;
     #! by GC, and is indexed through a table.
     dup fixnum? swap f eq? or ;
 
+: push-1 ( obj -- )
+    0 swap literal-value dup
+    immediate? [ %immediate ] [ %indirect ] ifte , ;
+
 #push [
-    1 %inc-d ,
-    [ node-param get ] bind dup immediate? [
-        %immediate-d ,
-    ] [
-        0 swap %indirect ,  out-1
-    ] ifte
+    [ node-produce-d get ] bind
+    dup length dup %inc-d ,
+    1 - swap [
+        push-1 0 over %replace-d ,
+    ] each drop
 ] "linearizer" set-word-prop
 
-\ drop [
-    drop
-    1 %dec-d ,
+#drop [
+    [ node-consume-d get length ] bind %dec-d ,
 ] "linearizer" set-word-prop
 
 \ dup [
@@ -171,9 +173,12 @@ sequences words ;
     1 <vreg> 0 <vreg> rot execute ,
     r> 0 %replace-d , ;
 
+: literal-fixnum? ( value -- ? )
+    dup literal? [ literal-value fixnum? ] [ drop f ] ifte ;
+
 : binary-op ( node op out -- )
     #! out is a vreg where the vop stores the result.
-    >r >r node-peek dup literal? [
+    >r >r node-peek dup literal-fixnum? [
         1 %dec-d ,
         in-1
         literal-value 0 <vreg> r> execute ,
@@ -206,7 +211,7 @@ sequences words ;
 
 \ fixnum* [
     ! Turn multiplication by a power of two into a left shift.
-    node-peek dup literal? [
+    node-peek dup literal-fixnum? [
         literal-value dup power-of-2? [
             1 %dec-d ,
             in-1
index c58a5015c7280a321a85af11ec8705afbd36ddf8..97853d2fa95c81645f85a044602c4f0bdde9f3ef 100644 (file)
@@ -21,16 +21,6 @@ math namespaces words strings errors prettyprint sequences ;
     #! rest is arguments.
     [ %prologue , (linearize) ] make-list ;
 
-: linearize-simple-label ( node -- )
-    #! Some labels become simple labels after the optimization
-    #! stage.
-    dup [ node-label get ] bind %label ,
-    [ node-param get ] bind (linearize) ;
-
-#simple-label [
-    linearize-simple-label
-] "linearizer" set-word-prop
-
 : linearize-label ( node -- )
     #! Labels are tricky, because they might contain non-tail
     #! calls. So we push the address of the location right after
@@ -39,7 +29,8 @@ math namespaces words strings errors prettyprint sequences ;
     #! this in the common case where the labelled block does
     #! not contain non-tail recursive calls to itself.
     <label> dup %return-to , >r
-    linearize-simple-label
+    dup [ node-label get ] bind %label ,
+    [ node-param get ] bind (linearize)
     f %return ,
     r> %label , ;
 
index a2cc4f50aa76b0447fc4139ba4cb657adb45150a..3a5c98ce57cd6e62dd85df9fcf47def5e2e28479 100644 (file)
@@ -100,9 +100,26 @@ SYMBOL: branch-returns
         node-param [ [ dupd kill-nodes ] map nip ] change
     ] extend , ;
 
-#push [ [ node-param get ] bind , ] "scan-literal" set-word-prop
-#push [ consumes-literal? not ] "can-kill" set-word-prop
-#push [ kill-node ] "kill-node" set-word-prop
+: kill-literal ( literals values -- values )
+    [
+        swap [ swap value= ] some-with? not
+    ] subset-with ;
+
+#push [
+    [ node-produce-d get ] bind [ literal-value ] map %
+] "scan-literal" set-word-prop
+
+#push [ 2drop t ] "can-kill" set-word-prop
+
+#push [
+    [ node-produce-d [ kill-literal ] change ] extend ,
+] "kill-node" set-word-prop
+
+#drop [ 2drop t ] "can-kill" set-word-prop
+
+#drop [
+    [ node-consume-d [ kill-literal ] change ] extend ,
+] "kill-node" set-word-prop
 
 #label [
     [ node-param get ] bind (scan-literals)
@@ -123,10 +140,6 @@ SYMBOL: branch-returns
     [ node-param get ] bind calls-label?
 ] "calls-label" set-word-prop
 
-#simple-label [
-    [ node-param get ] bind calls-label?
-] "calls-label" set-word-prop
-
 : branches-call-label? ( label list -- ? )
     [ calls-label? ] some-with? ;
 
@@ -138,16 +151,8 @@ SYMBOL: branch-returns
     [ node-param get ] bind branches-call-label?
 ] "calls-label" set-word-prop
 
-: optimize-label ( -- op )
-    #! Does the label node contain calls to itself?
-    node-label get node-param get calls-label?
-    #label #simple-label ? ;
-
 #label [ ( literals node -- )
-    [
-        optimize-label node-op set
-        node-param [ kill-nodes ] change
-    ] extend ,
+    [ node-param [ kill-nodes ] change ] extend ,
 ] "kill-node" set-word-prop
 
 #values [
index d71a70c16d121f2f68a19265a00c134b3fc357e8..4897b978784410b25a209510f488b611cfb381b5 100644 (file)
@@ -51,14 +51,15 @@ M: %label simplify-node ( linear vop -- linear ? )
 
 M: %inc-d simplify-node ( linear vop -- linear ? )
     #! %inc-d cancels a following %inc-d.
-    >r dup \ %inc-d next-physical? [
-        vop-literal r> vop-literal + dup 0 = [
-            drop cdr cdr f
-        ] [
+    dup vop-literal 0 = [
+        drop cdr t
+    ] [
+        >r dup \ %inc-d next-physical? [
+            vop-literal r> vop-literal + 
             %inc-d >r cdr cdr r> swons t
+        ] [
+            r> 2drop f
         ] ifte
-    ] [
-        r> 2drop f
     ] ifte ;
 
 : dead-load? ( linear vop -- ? )
@@ -91,8 +92,8 @@ M: %replace-d simplify-node ( linear vop -- linear ? )
         ] ifte
     ] ifte ;
 
-M: %immediate-d simplify-node ( linear vop -- linear ? )
-    over 0 dead-store? [ drop cdr t ] [ drop f ] ifte ;
+M: %immediate-d simplify-node ( linear vop -- linear ? )
+    over 0 dead-store? [ drop cdr t ] [ drop f ] ifte ;
 
 : pop? ( vop -- ? ) dup %inc-d? swap vop-literal -1 = and ;
 
index fb26e2f0b497bce416a0d0fad0cd10b0cd67947d..145cc0584f54acc7a82a1193f394997b171f97f1 100644 (file)
@@ -93,8 +93,8 @@ VOP: %inc-d
 : %inc-d ( n -- ) literal-vop <%inc-d> ;
 : %dec-d ( n -- ) neg %inc-d ;
 VOP: %immediate
-VOP: %immediate-d
-: %immediate-d ( obj -- ) literal-vop <%immediate-d> ;
+: %immediate ( vreg obj -- )
+    >r <vreg> r> dest/literal-vop <%immediate> ;
 VOP: %peek-r
 : %peek-r ( vreg n -- ) >r >r f r> <vreg> r> f <%peek-r> ;
 VOP: %replace-r
index ad588a56072624cd147913de042548484da523d2..214bb4ff7e2341cbcca21389810fb9b2fc4c40a3 100644 (file)
@@ -36,7 +36,7 @@ memory namespaces words ;
     ! An untagged pointer to the bignum is now in EAX; tag it
     EAX bignum-tag OR
     ESP 4 ADD
-    "end" get save-xt ;
+    "end" get save-xt ; inline
 
 M: %fixnum+ generate-node ( vop -- )
     dest/src 2dup ADD  \ SUB \ ADD simple-overflow ;
index 6ff96ed7836c641391e0b183b6c8f094b7cd5317..7cf9ca41baa78051a2c53d97fa4e315edd1965f6 100644 (file)
@@ -30,9 +30,6 @@ M: %inc-d generate-node ( vop -- )
 M: %immediate generate-node ( vop -- )
     dup vop-dest v>operand swap vop-literal address MOV ;
 
-M: %immediate-d generate-node ( vop -- )
-    vop-literal [ ESI ] swap address MOV ;
-
 : load-indirect ( dest literal -- )
     intern-literal unit MOV 0 0 rel-address ;
 
index 97d1ddd5d681c7689abaafb1e5fbfb8afdcfda41..e073bab42512d9366d0d9c6430cadf4a25b95483 100644 (file)
@@ -39,7 +39,7 @@ builtin [ 2drop t ] "class<" set-word-prop
     dup intern-symbol
     dup r> "builtin-type" set-word-prop
     dup builtin define-class
-    dup r> unit "predicate" set-word-prop
+    dup r> set-predicate
     dup builtin-predicate
     dup r> define-slots
     register-builtin ;
index b850d7f88e2bca8c2532d7bcc9869a73e3ff148a..0e1fe78603de86e56b6355e259099885949f5e5e 100644 (file)
@@ -174,4 +174,8 @@ SYMBOL: object
     dup builtin-supertypes [ > ] sort
     typemap get set-hash ;
 
+: set-predicate ( class word -- )
+    dup t "inline" set-word-prop
+    unit "predicate" set-word-prop ;
+
 typemap get [ <namespace> typemap set ] unless
index 6714434e3d767d790c2b1ee854a419e32aa91c45..a6643d2d42f1ff3c98e398b97682b759b777b585 100644 (file)
@@ -69,8 +69,7 @@ UNION: arrayed array tuple ;
 : tuple-predicate ( word -- )
     #! Make a foo? word for testing the tuple class at the top
     #! of the stack.
-    dup predicate-word
-    2dup unit "predicate" set-word-prop
+    dup predicate-word 2dup set-predicate
     swap [
         [ dup tuple? ] %
         [ \ class-tuple , literal, \ eq? , ] make-list ,
@@ -78,12 +77,15 @@ UNION: arrayed array tuple ;
         \ ifte ,
     ] make-list define-compound ;
 
+: forget-tuple ( class -- )
+    dup forget "predicate" word-prop car forget ;
+
 : check-shape ( word slots -- )
     #! If the new list of slots is different from the previous,
     #! forget the old definition.
     >r "use" get search dup [
         dup "tuple-size" word-prop r> length 2 + =
-        [ drop ] [ forget ] ifte
+        [ drop ] [ forget-tuple ] ifte
     ] [
         r> 2drop
     ] ifte ;
index d8cfae230c115adb70c12aa2d70cabe9b7d6dd25..16c3f0c2312ecab671c02956f4b43f9fc6de3de1 100644 (file)
@@ -4,7 +4,7 @@ IN: inference
 USING: errors generic interpreter kernel lists math namespaces
 sequences strings vectors words hashtables prettyprint ;
 
-: longest-vector ( list -- length )
+: longest ( list -- length )
     0 swap [ length max ] each ;
 
 : computed-value-vector ( n -- vector )
@@ -17,7 +17,7 @@ sequences strings vectors words hashtables prettyprint ;
 : unify-lengths ( list -- list )
     #! Pad all vectors to the same length. If one vector is
     #! shorter, pad it with unknown results at the bottom.
-    dup longest-vector swap [ add-inputs ] map-with ;
+    dup longest swap [ add-inputs ] map-with ;
 
 : unify-results ( list -- value )
     #! If all values in list are equal, return the value.
@@ -137,49 +137,20 @@ SYMBOL: cloned
     #! base case to this stack effect and try again.
     (infer-branches) dup unify-effects unify-dataflow ;
 
-: (with-block) ( [[ label quot ]] quot -- node )
-    #! Call a quotation in a new namespace, and transfer
-    #! inference state from the outer scope.
-    swap car >r [
-        dataflow-graph off
-        call
-        d-in get meta-d get meta-r get get-dataflow
-    ] with-scope
-    r> swap #label dataflow, [ node-label set ] extend >r
-    meta-r set meta-d set d-in set r> ;
-
-: with-block ( word [[ label quot ]] quot -- node )
-    #! Execute a quotation with the word on the stack, and add
-    #! its dataflow contribution to a new block node in the IR.
-    over [
-        >r
-        dupd cons
-        recursive-state [ cons ] change
-        r> call
-    ] (with-block) ;
-
-: dynamic-ifte ( true false -- )
+: infer-ifte ( true false -- )
     #! If branch taken is computed, infer along both paths and
     #! unify.
-    2list >r peek-d \ ifte r>
-    pop-d [
-        dup \ general-t <class-tie> ,
-        \ f <class-tie> ,
-    ] make-list zip ( condition )
+    2list >r pop-d \ ifte r>
+    pick [ general-t POSTPONE: f ] [ <class-tie> ] map-with
+    zip ( condition )
     infer-branches ;
 
-: infer-ifte ( -- )
-    #! Infer effects for both branches, unify.
-    [ object general-list general-list ] ensure-d
-    dataflow-drop, pop-d
-    dataflow-drop, pop-d swap
-    dynamic-ifte ;
+\ ifte [
+    2 dataflow-drop, pop-d pop-d swap infer-ifte
+] "infer" set-word-prop
 
-\ ifte [ infer-ifte ] "infer" set-word-prop
-
-: vtable>list ( value -- list )
-    dup value-recursion swap literal-value >list
-    [ over <literal> ] map nip ;
+: vtable>list ( rstate vtable -- list  )
+    [ swap <literal> ] map-with >list ;
 
 : <dispatch-index> ( value -- value )
     value-literal-ties
@@ -188,17 +159,12 @@ SYMBOL: cloned
 
 USE: kernel-internals
 
-: dynamic-dispatch ( vtable -- )
-    >r peek-d \ dispatch r>
+: infer-dispatch ( rstate vtable -- )
+    >r >r peek-d \ dispatch r> r>
     vtable>list
     pop-d <dispatch-index>
     over length [ <literal-tie> ] project-with
     zip infer-branches ;
 
-: infer-dispatch ( -- )
-    #! Infer effects for all branches, unify.
-    [ object vector ] ensure-d
-    dataflow-drop, pop-d dynamic-dispatch ;
-
-\ dispatch [ infer-dispatch ] "infer" set-word-prop
+\ dispatch [ pop-literal infer-dispatch ] "infer" set-word-prop
 \ dispatch [ [ fixnum vector ] [ ] ] "infer-effect" set-word-prop
index 101efdf33a92863385e3afca8994efe36696af66..c309d610ec6e885999bbc5244448a55a66a5c939 100644 (file)
@@ -1,39 +1,11 @@
-! :folding=indent:collapseFolds=1:
-
-! $Id$
-!
-! Copyright (C) 2004 Slava Pestov.
-! 
-! Redistribution and use in source and binary forms, with or without
-! modification, are permitted provided that the following conditions are met:
-! 
-! 1. Redistributions of source code must retain the above copyright notice,
-!    this list of conditions and the following disclaimer.
-! 
-! 2. Redistributions in binary form must reproduce the above copyright notice,
-!    this list of conditions and the following disclaimer in the documentation
-!    and/or other materials provided with the distribution.
-! 
-! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
-! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+! Copyright (C) 2004, 2005 Slava Pestov.
+! See http://factor.sf.net/license.txt for BSD license.
 IN: inference
-USE: interpreter
-USE: kernel
-USE: lists
-USE: math
-USE: namespaces
-USE: words
-USE: vectors
-USE: sequences
+USING: interpreter kernel lists namespaces sequences vectors
+words ;
+
+! Recursive state. An alist, mapping words to labels.
+SYMBOL: recursive-state
 
 ! We build a dataflow graph for the compiler.
 SYMBOL: dataflow-graph
@@ -41,14 +13,10 @@ SYMBOL: dataflow-graph
 ! Label nodes have the node-label variable set.
 SYMBOL: #label
 
-! A label that is not called recursively at all, or only tail
-! recursively. The optimizer changes some #labels to
-! #simple-labels.
-SYMBOL: #simple-label
-
 SYMBOL: #call ( non-tail call )
 SYMBOL: #call-label
 SYMBOL: #push ( literal )
+SYMBOL: #drop
 
 ! This is purely a marker for values we retain after a
 ! conditional. It does not generate code, but merely alerts the
@@ -101,10 +69,11 @@ SYMBOL: node-param
     #! Add a node to the dataflow IR.
     <dataflow-node> dup dataflow-graph [ cons ] change ;
 
-: dataflow-drop, ( -- )
-    #! Remove the top stack element and add a dataflow node
-    #! noting this.
-    f \ drop dataflow, [ 1 0 node-inputs ] bind ;
+: dataflow-drop, ( n -- )
+    f #drop dataflow, [ 0 node-inputs ] bind ;
+
+: dataflow-push, ( n -- )
+    f #push dataflow, [ 0 node-outputs ] bind ;
 
 : apply-dataflow ( dataflow name default -- )
     #! For the dataflow node, look up named word property,
index e3533ca165bae2124e2a1988cade781e760f1e06..7fc164a6e6bea9034ba6b82e61dd04805c401b9f 100644 (file)
@@ -17,68 +17,9 @@ SYMBOL: inferring-base-case
 ! inputs.
 SYMBOL: d-in
 
-! Recursive state. An alist, mapping words to labels.
-SYMBOL: recursive-state
-
-GENERIC: value= ( literal value -- ? )
-GENERIC: value-class-and ( class value -- )
-
-TUPLE: value class recursion class-ties literal-ties ;
-
-C: value ( recursion -- value )
-    [ set-value-recursion ] keep ;
-
-TUPLE: computed ;
-
-C: computed ( class -- value )
-    swap recursive-state get <value> [ set-value-class ] keep
-    over set-delegate ;
-
-M: computed value= ( literal value -- ? )
-    2drop f ;
-
-: failing-class-and ( class class -- class )
-    2dup class-and dup null = [
-        -rot [
-            word-name , " and " , word-name ,
-            " do not intersect" ,
-        ] make-string inference-warning
-    ] [
-        2nip
-    ] ifte ;
-
-M: computed value-class-and ( class value -- )
-    [
-        value-class  failing-class-and
-    ] keep set-value-class ;
-
-TUPLE: literal value ;
-
-C: literal ( obj rstate -- value )
-    [
-        >r <value> [ >r dup class r> set-value-class ] keep
-        r> set-delegate
-    ] keep
-    [ set-literal-value ] keep ;
-
-M: literal value= ( literal value -- ? )
-    literal-value = ;
-
-M: literal value-class-and ( class value -- )
-    value-class class-and drop ;
-
-M: literal set-value-class ( class value -- )
-    2drop ;
-
-M: computed literal-value ( value -- )
-    "A literal value was expected where a computed value was"
-    " found: " rot unparse cat3 inference-error ;
-
-: value-types ( value -- list )
-    value-class builtin-supertypes ;
-
 : pop-literal ( -- rstate obj )
-    dataflow-drop, pop-d dup value-recursion swap literal-value ;
+    1 dataflow-drop, pop-d
+    dup value-recursion swap literal-value ;
 
 : (ensure-types) ( typelist n stack -- )
     pick [
@@ -131,8 +72,7 @@ GENERIC: apply-object
 : apply-literal ( obj -- )
     #! Literals are annotated with the current recursive
     #! state.
-    dup recursive-state get <literal> push-d
-    #push dataflow, [ 1 0 node-outputs ] bind ;
+    recursive-state get <literal> push-d  1 dataflow-push, ;
 
 M: object apply-object apply-literal ;
 
@@ -140,11 +80,6 @@ M: object apply-object apply-literal ;
     #! Is this branch not terminated?
     d-in get meta-d get and ;
 
-: check-active ( -- )
-    active? [
-         "Provable runtime error" inference-error
-    ] unless ;
-
 : effect ( -- [[ d-in meta-d ]] )
     d-in get meta-d get cons ;
 
@@ -170,9 +105,12 @@ M: object apply-object apply-literal ;
         drop
     ] ifte ;
 
+: check-active ( -- )
+    active? [ "Provable runtime error" inference-error ] unless ;
+
 : check-return ( -- )
     #! Raise an error if word leaves values on return stack.
-    meta-r get length 0 = [
+    meta-r get empty? [
         "Word leaves elements on return stack" inference-error
     ] unless ;
 
@@ -182,16 +120,18 @@ M: object apply-object apply-literal ;
         meta-d get >list node-consume-d set
     ] bind ;
 
-: (infer) ( quot -- )
-    f init-inference
-    infer-quot
-    check-active
-    #return values-node check-return ;
+: with-infer ( quot -- )
+    [
+        f init-inference
+        call
+        check-active
+        check-return
+    ] with-scope ;
 
 : infer ( quot -- [[ in out ]] )
     #! Stack effect of a quotation.
-    [ (infer) effect present-effect ] with-scope ;
+    [ infer-quot effect present-effect ] with-infer ;
 
 : dataflow ( quot -- dataflow )
     #! Data flow of a quotation.
-    [ (infer) get-dataflow ] with-scope ;
+    [ infer-quot #return values-node get-dataflow ] with-infer ;
diff --git a/library/inference/partial-eval.factor b/library/inference/partial-eval.factor
new file mode 100644 (file)
index 0000000..9a77787
--- /dev/null
@@ -0,0 +1,96 @@
+! Copyright (C) 2005 Slava Pestov.
+! See http://factor.sf.net/license.txt for BSD license.
+IN: inference
+USING: generic interpreter kernel lists math namespaces
+sequences words ;
+
+: literal-inputs? ( in stack -- )
+    tail-slice dup >list [ literal-safe? ] all? [
+        length dataflow-drop, t
+    ] [
+        drop f
+    ] ifte ;
+
+: literal-inputs ( out stack -- )
+    tail-slice [ literal-value ] nmap ;
+
+: literal-outputs ( out stack -- )
+    tail-slice dup [ recursive-state get <literal> ] nmap
+    length dataflow-push, ;
+
+: partial-eval? ( word -- ? )
+    "infer-effect" word-prop car length
+    meta-d get literal-inputs? ;
+
+: infer-eval ( word -- )
+    dup partial-eval? [
+        dup "infer-effect" word-prop 2unlist
+        >r length meta-d get
+        literal-inputs
+        host-word
+        r> length meta-d get literal-outputs
+    ] [
+        dup "infer-effect" word-prop consume/produce
+    ] ifte ;
+
+: stateless ( word -- )
+    #! A stateless word can be evaluated at compile-time.
+    dup unit [ car infer-eval ] cons "infer" set-word-prop ;
+
+! Could probably add more words here
+[
+    car
+    cdr
+    cons
+    <
+    <=
+    >
+    >=
+    number=
+    +
+    -
+    *
+    /
+    /i
+    /f
+    mod
+    /mod
+    bitand
+    bitor
+    bitxor
+    shift
+    bitnot
+    >fixnum
+    >bignum
+    >float
+    real
+    imaginary
+] [
+    stateless
+] each
+
+! Partially-evaluated words need their stack effects to be
+! entered by hand.
+\ car [ [ general-list ] [ object ] ] "infer-effect" set-word-prop
+\ cdr [ [ general-list ] [ object ] ] "infer-effect" set-word-prop
+\ < [ [ real real ] [ boolean ] ] "infer-effect" set-word-prop
+\ <= [ [ real real ] [ boolean ] ] "infer-effect" set-word-prop
+\ > [ [ real real ] [ boolean ] ] "infer-effect" set-word-prop
+\ >= [ [ real real ] [ boolean ] ] "infer-effect" set-word-prop
+\ number= [ [ real real ] [ boolean ] ] "infer-effect" set-word-prop
+\ + [ [ number number ] [ number ] ] "infer-effect" set-word-prop
+\ - [ [ number number ] [ number ] ] "infer-effect" set-word-prop
+\ * [ [ number number ] [ number ] ] "infer-effect" set-word-prop
+\ / [ [ number number ] [ number ] ] "infer-effect" set-word-prop
+\ /i [ [ number number ] [ number ] ] "infer-effect" set-word-prop
+\ /f [ [ number number ] [ number ] ] "infer-effect" set-word-prop
+\ mod [ [ integer integer ] [ integer ] ] "infer-effect" set-word-prop
+\ /mod [ [ integer integer ] [ integer integer ] ] "infer-effect" set-word-prop
+\ bitand [ [ integer integer ] [ integer ] ] "infer-effect" set-word-prop
+\ bitor [ [ integer integer ] [ integer ] ] "infer-effect" set-word-prop
+\ bitxor [ [ integer integer ] [ integer ] ] "infer-effect" set-word-prop
+\ shift [ [ integer integer ] [ integer ] ] "infer-effect" set-word-prop
+\ bitnot [ [ integer ] [ integer ] ] "infer-effect" set-word-prop
+\ gcd [ [ integer integer ] [ integer integer ] ] "infer-effect" set-word-prop
+\ real [ [ number ] [ real ] ] "infer-effect" set-word-prop
+\ imaginary [ [ number ] [ real ] ] "infer-effect" set-word-prop
index 0c177c5f17ca342337eea7fc911e5922f7959d0a..6726b37bdbd919cf03c821c55d35e1eac6b378ff 100644 (file)
@@ -15,12 +15,13 @@ USING: interpreter kernel namespaces words ;
     [ 1 0 node-outputs ] bind
 ] "infer" set-word-prop
 
+: partial-eval ( word quot -- | quot: word -- )
+    >r f over dup "infer-effect" word-prop r> with-dataflow ;
+
 : infer-shuffle ( word -- )
-    f over dup
-    "infer-effect" word-prop
-    [ host-word ] with-dataflow ;
+    [ host-word ] partial-eval ;
 
-\ drop [ \ drop infer-shuffle ] "infer" set-word-prop
+\ drop [ 1 dataflow-drop, pop-d drop ] "infer" set-word-prop
 \ dup  [ \ dup  infer-shuffle ] "infer" set-word-prop
 \ swap [ \ swap infer-shuffle ] "infer" set-word-prop
 \ over [ \ over infer-shuffle ] "infer" set-word-prop
diff --git a/library/inference/values.factor b/library/inference/values.factor
new file mode 100644 (file)
index 0000000..59a685c
--- /dev/null
@@ -0,0 +1,66 @@
+! Copyright (C) 2004, 2005 Slava Pestov.
+! See http://factor.sf.net/license.txt for BSD license.
+IN: inference
+USING: generic kernel namespaces sequences unparser words ;
+
+GENERIC: value= ( literal value -- ? )
+GENERIC: value-class-and ( class value -- )
+
+TUPLE: value class recursion class-ties literal-ties ;
+
+C: value ( recursion -- value )
+    [ set-value-recursion ] keep ;
+
+TUPLE: computed ;
+
+C: computed ( class -- value )
+    swap recursive-state get <value> [ set-value-class ] keep
+    over set-delegate ;
+
+M: computed value= ( literal value -- ? )
+    2drop f ;
+
+: failing-class-and ( class class -- class )
+    2dup class-and dup null = [
+        -rot [
+            word-name , " and " , word-name ,
+            " do not intersect" ,
+        ] make-string inference-warning
+    ] [
+        2nip
+    ] ifte ;
+
+M: computed value-class-and ( class value -- )
+    [
+        value-class  failing-class-and
+    ] keep set-value-class ;
+
+TUPLE: literal value safe? ;
+
+C: literal ( obj rstate -- value )
+    [ t swap set-literal-safe? ] keep
+    [
+        >r <value> [ >r dup class r> set-value-class ] keep
+        r> set-delegate
+    ] keep
+    [ set-literal-value ] keep ;
+
+M: literal value= ( literal value -- ? )
+    literal-value = ;
+
+M: literal value-class-and ( class value -- )
+    value-class class-and drop ;
+
+M: literal set-value-class ( class value -- )
+    2drop ;
+
+M: computed literal-safe? drop f ;
+
+M: computed set-literal-safe? 2drop ;
+
+M: computed literal-value ( value -- )
+    "A literal value was expected where a computed value was"
+    " found: " rot unparse append3 inference-error ;
+
+: value-types ( value -- list )
+    value-class builtin-supertypes ;
index 831151c887af308132bd046780367648f7f9f1bb..121c1822a99e4233128b489c6d1c7c6301fe0835 100644 (file)
@@ -33,21 +33,56 @@ hashtables parser prettyprint ;
 : no-effect ( word -- )
     "Unknown stack effect: " swap word-name cat2 inference-error ;
 
-: inline-compound ( word -- effect node )
-    #! Infer the stack effect of a compound word in the current
-    #! inferencer instance. If the word in question is recursive
-    #! we infer its stack effect inside a new block.
+: inhibit-parital ( -- )
+    meta-d get [ f swap set-literal-safe? ] each ;
+
+: recursive? ( word -- ? )
+    f swap dup word-def [ = or ] tree-each-with ;
+
+: (with-block) ( [[ label quot ]] quot -- node )
+    #! Call a quotation in a new namespace, and transfer
+    #! inference state from the outer scope.
+    swap car >r [
+        dataflow-graph off
+        call
+        d-in get meta-d get meta-r get get-dataflow
+    ] with-scope
+    r> swap #label dataflow, [ node-label set ] extend >r
+    meta-r set meta-d set d-in set r> ;
+
+: with-block ( word [[ label quot ]] quot -- node )
+    #! Execute a quotation with the word on the stack, and add
+    #! its dataflow contribution to a new block node in the IR.
+    over [
+        >r
+        dupd cons
+        recursive-state [ cons ] change
+        r> call
+    ] (with-block) ;
+
+: inline-block ( word -- effect node )
     gensym over word-def cons [
+        inhibit-parital
         word-def infer-quot effect
     ] with-block ;
 
+: inline-compound ( word -- )
+    #! Infer the stack effect of a compound word in the current
+    #! inferencer instance. If the word in question is recursive
+    #! we infer its stack effect inside a new block.
+    dup recursive? [
+        inline-block 2drop
+    ] [
+        word-def infer-quot
+    ] ifte ;
+
 : infer-compound ( word -- )
     #! Infer a word's stack effect in a separate inferencer
     #! instance.
     [
         [
             recursive-state get init-inference
-            dup dup inline-compound drop present-effect
+            dup dup inline-block drop present-effect
             [ "infer-effect" set-word-prop ] keep
         ] with-scope consume/produce
     ] [
@@ -66,6 +101,9 @@ M: object (apply-word) ( word -- )
     #! A primitive with an unknown stack effect.
     no-effect ;
 
+M: primitive (apply-word) ( word -- )
+    dup "infer-effect" word-prop consume/produce ;
+
 M: compound (apply-word) ( word -- )
     #! Infer a compound word's stack effect.
     dup "no-effect" word-prop [
@@ -95,7 +133,7 @@ M: word apply-word ( word -- )
 
 M: compound apply-word ( word -- )
     dup "inline" word-prop [
-        inline-compound 2drop
+        inline-compound
     ] [
         apply-default
     ] ifte ;
@@ -111,7 +149,7 @@ M: compound apply-word ( word -- )
 
 : base-case ( word [ label quot ] -- )
     [
-        car over inline-compound [
+        car over inline-block [
             drop
             [ #call-label ] [ #call ] ?ifte
             node-op set
@@ -126,11 +164,15 @@ M: compound apply-word ( word -- )
     #! Handle a recursive call, by either applying a previously
     #! inferred base case, or raising an error. If the recursive
     #! call is to a local block, emit a label call node.
-    inferring-base-case get [
-        drop no-base-case
+    over "infer-effect" word-prop [
+        nip consume/produce
     ] [
-        base-case
-    ] ifte ;
+        inferring-base-case get [
+            drop no-base-case
+        ] [
+            base-case
+        ] ifte
+    ] ifte* ;
 
 M: word apply-object ( word -- )
     #! Apply the word's stack effect to the inferencer state.
@@ -141,41 +183,28 @@ M: word apply-object ( word -- )
     ] ifte* ;
 
 : infer-quot-value ( rstate quot -- )
-    gensym dup pick cons [
-        drop
-        swap recursive-state set
-        dup infer-quot
-    ] with-block drop handle-terminator ;
+    recursive-state get >r
+    swap recursive-state set
+    dup infer-quot handle-terminator
+    r> recursive-state set ;
 
 \ call [
-    [ general-list ] ensure-d pop-literal infer-quot-value
+    pop-literal infer-quot-value
 ] "infer" set-word-prop
 
 \ execute [
-    [ word ] ensure-d pop-literal unit infer-quot-value
+    pop-literal unit infer-quot-value
 ] "infer" set-word-prop
 
 ! These hacks will go away soon
-\ * [ [ number number ] [ number ] ] "infer-effect" set-word-prop
-\ - [ [ number number ] [ number ] ] "infer-effect" set-word-prop
-\ + [ [ number number ] [ number ] ] "infer-effect" set-word-prop
-\ integer/ [ [ integer integer ] [ rational ] ] "infer-effect" set-word-prop
-\ gcd [ [ integer integer ] [ integer integer ] ] "infer-effect" set-word-prop
-\ = [ [ object object ] [ boolean ] ] "infer-effect" set-word-prop
-\ <= [ [ number number ] [ boolean ] ] "infer-effect" set-word-prop
-\ < [ [ number number ] [ boolean ] ] "infer-effect" set-word-prop
-\ >= [ [ number number ] [ boolean ] ] "infer-effect" set-word-prop
-\ > [ [ number number ] [ boolean ] ] "infer-effect" set-word-prop
-\ <no-method> [ [ object object ] [ tuple ] ] "infer-effect" set-word-prop
-\ set-no-method-generic [ [ object tuple ] [ ] ] "infer-effect" set-word-prop
-\ set-no-method-object [ [ object tuple ] [ ] ] "infer-effect" set-word-prop
-\ car [ [ general-list ] [ object ] ] "infer-effect" set-word-prop
-\ real [ [ number ] [ real ] ] "infer-effect" set-word-prop
-\ imaginary [ [ number ] [ real ] ] "infer-effect" set-word-prop
 \ delegate [ [ object ] [ object ] ] "infer-effect" set-word-prop
-
 \ no-method t "terminator" set-word-prop
 \ no-method [ [ object word ] [ ] ] "infer-effect" set-word-prop
-\ <no-method> [ [ object word ] [ tuple ] ] "infer-effect" set-word-prop
+\ <no-method> [ [ object object ] [ tuple ] ] "infer-effect" set-word-prop
+\ set-no-method-generic [ [ object tuple ] [ ] ] "infer-effect" set-word-prop
+\ set-no-method-object [ [ object tuple ] [ ] ] "infer-effect" set-word-prop
 \ not-a-number t "terminator" set-word-prop
 \ throw t "terminator" set-word-prop
+\ = [ [ object object ] [ boolean ] ] "infer-effect" set-word-prop
+\ integer/ [ [ integer integer ] [ rational ] ] "infer-effect" set-word-prop
+\ gcd [ [ integer integer ] [ integer integer ] ] "infer-effect" set-word-prop
index 94ff6437645cbc073d78e1d7d814436331e73092..6824ba0cdcc72d246d807ce6c2888be6ef1b434a 100644 (file)
@@ -33,19 +33,18 @@ GENERIC: truncate ( n -- n )
 GENERIC: floor    ( n -- n )
 GENERIC: ceiling  ( n -- n )
 
-: max ( x y -- z ) [ > ] 2keep ? ;
-
-: min ( x y -- z ) [ < ] 2keep ? ;
+: max ( x y -- z ) [ > ] 2keep ? ; inline
+: min ( x y -- z ) [ < ] 2keep ? ; inline
 
 : between? ( x min max -- ? )
     #! Push if min <= x <= max. Handles case where min > max
     #! by swapping them.
     2dup > [ swap ] when  >r dupd max r> min = ;
 
-: sq dup * ;
+: sq dup * ; inline
 
-: neg 0 swap - ;
-: recip 1 swap / ;
+: neg 0 swap - ; inline
+: recip 1 swap / ; inline
 
 : rem ( x y -- x%y )
     #! Like modulus, but always gives a positive result.
diff --git a/library/test/benchmark/prettyprint.factor b/library/test/benchmark/prettyprint.factor
new file mode 100644 (file)
index 0000000..58f5a0b
--- /dev/null
@@ -0,0 +1,11 @@
+IN: temporary
+USE: lists
+USE: prettyprint
+USE: test
+USE: words
+USE: kernel
+USE: sequences
+
+[ ] [ gensym dup [ ] define-compound . ] unit-test
+[ ] [ vocabs [ words [ see ] each ] each ] unit-test
+[ ] [ classes [ methods. ] each ] unit-test
index 95090e650d53efb11334ccc85ff6ec1b92a8e0c7..e54d04e1b4b58cc954ea2c8b0040c36f880b88a8 100644 (file)
@@ -1,5 +1,6 @@
 IN: temporary
 USE: test
+USE: assembler
 USE: compiler
 USE: compiler-frontend
 USE: inference
@@ -13,8 +14,6 @@ USE: sequences
 
 [ [ ] ] [ \ foo word-def dataflow kill-set ] unit-test
 
-[ [ [ + ] [ - ] ] ] [ [ 3 4 1 2 > [ + ] [ - ] ifte ] dataflow kill-set ] unit-test
-
 [ [ [ 1 ] [ 2 ] ] ] [ [ [ 1 ] [ 2 ] ifte ] dataflow kill-set ] unit-test
 
 [ [ [ 1 ] [ 2 ] ] ] [ [ [ 1 ] [ 2 ] ifte ] dataflow kill-set ] unit-test
@@ -22,3 +21,15 @@ USE: sequences
 [ [ t t f ] ] [ [ 1 2 ] [ 1 2 3 ] [ f <literal> ] map kill-mask ] unit-test
 
 [ t ] [ 3 [ 3 over [ ] [ ] ifte drop ] dataflow kill-set contains? ] unit-test
+
+: literal-kill-test-1 4 compiled-offset cell 2 * - ; compiled
+
+[ 4 ] [ literal-kill-test-1 drop ] unit-test
+
+: literal-kill-test-2 3 compiled-offset cell 2 * - ; compiled
+
+[ 3 ] [ literal-kill-test-2 drop ] unit-test
+
+: literal-kill-test-3 10 3 /mod drop ; compiled
+
+[ 3 ] [ literal-kill-test-3 ] unit-test
index a6f4b64f47bd3e3b94d0f02807c0ccf75c1ed198..0a2db059c81685cd3cae6cd0be514996b1c82147 100644 (file)
@@ -19,7 +19,7 @@ sequences test words ;
     ] some-with? ;
 
 [ t ] [
-    \ + [ 2 + ] dataflow dataflow-contains-param? >boolean
+    \ + [ 2 + ] dataflow dataflow-contains-param? >boolean
 ] unit-test
 
 : inline-test
@@ -79,10 +79,3 @@ SYMBOL: #test
         [[ node-param 5 ]]
     }} "foobar" [ [ node-param get ] bind 1 + ] apply-dataflow
 ] unit-test
-
-! Somebody (cough) got the order of ifte nodes wrong.
-
-[ t ] [
-    \ ifte [ [ 1 ] [ 2 ] ifte ] dataflow dataflow-contains-op? car
-    [ node-param get ] bind car car [ node-param get ] bind 1 =
-] unit-test
index 38ff3b8ddc40703d0a1d7abc226ae0d02b519167..5cb9df1a130e07ed57cd2b01dcfdd41e4dabb78e 100644 (file)
@@ -1,5 +1,5 @@
 IN: temporary
-USING: gadgets kernel lists math namespaces test ;
+USING: gadgets kernel lists math namespaces test sequences ;
 
 [ t ] [
     [
index 131053bb24127a7bb5a1e53560a524e79ffac6c1..40ff7a8aa2bacaf46180fdbefe6b8e6a376c1ce2 100644 (file)
@@ -3,6 +3,7 @@ USE: kernel
 USE: math
 USE: test
 USE: lists
+USE: sequences
 
 [ -2 ] [ 1 bitnot ] unit-test
 [ -2 ] [ 1 >bignum bitnot ] unit-test
index 08505efc8e39f3d22641c9fbc30b6ce59e78ec27..4ea4baedf374083f28d5b2c5fa53990d64bcb966 100644 (file)
@@ -1,5 +1,6 @@
 IN: temporary
-USING: generic kernel lists math memory words prettyprint test ;
+USING: generic kernel lists math memory words prettyprint 
+sequences test ;
 
 [ ] [
     num-types [
diff --git a/library/test/prettyprint.factor b/library/test/prettyprint.factor
deleted file mode 100644 (file)
index d484efd..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-IN: temporary
-USE: lists
-USE: prettyprint
-USE: test
-USE: words
-USE: kernel
-
-[ ] [ gensym dup [ ] define-compound . ] unit-test
-[ ] [ vocabs [ words [ see ] each ] each ] unit-test
-[ ] [ classes [ methods. ] each ] unit-test
index bbe93f44b656a7a1410c062df6141a62d4875b6e..ca00bb2538b9bec38f1b0c14f12c6dc7f64505ca 100644 (file)
@@ -1,8 +1,9 @@
 IN: temporary
-USING: lists test sequences ;
+USING: lists sequences test vectors ;
 
-[ [ 1 2 3 4 ] ] [ 1 4 <range> >list ] unit-test
-[ 4 ] [ 1 4 <range> length ] unit-test
-[ [ 4 3 2 1 ] ] [ 4 1 <range> >list ] unit-test
-[ 2 ] [ 1 2 { 1 2 3 4 } <slice> length ] unit-test
-[ [ 2 3 ] ] [ 1 2 { 1 2 3 4 } <slice> >list ] unit-test
+[ [ 1 2 3 4 ] ] [ 1 5 <range> >list ] unit-test
+[ 3 ] [ 1 4 <range> length ] unit-test
+[ [ 4 3 2 1 ] ] [ 4 0 <range> >list ] unit-test
+[ 2 ] [ 1 3 { 1 2 3 4 } <slice> length ] unit-test
+[ [ 2 3 ] ] [ 1 3 { 1 2 3 4 } <slice> >list ] unit-test
+[ { 4 5 } ] [ 2 { 1 2 3 4 5 } tail-slice >vector ] unit-test
index 63533dce9cec6be9d76fba3fcadaad9b518a6d78..ee0d9df2610940535147039812082f93fd3d974c 100644 (file)
@@ -69,7 +69,7 @@ SYMBOL: failures
             "lists/namespaces" "lists/combinators" "combinators"
             "continuations" "errors" "hashtables" "strings"
             "namespaces" "generic" "tuple" "files" "parser"
-            "parse-number" "prettyprint" "image" "init" "io/io"
+            "parse-number" "image" "init" "io/io"
             "listener" "vectors" "words" "unparser" "random"
             "stream" "math/bitops"
             "math/math-combinators" "math/rational" "math/float"
@@ -102,7 +102,7 @@ SYMBOL: failures
             "benchmark/fib" "benchmark/sort"
             "benchmark/continuations" "benchmark/ack"
             "benchmark/hashtables" "benchmark/strings"
-            "benchmark/vectors"
+            "benchmark/vectors" "benchmark/prettyprint"
         ] %
     ] make-list ;
 
index 7f158d1288e5ac951a1071510b7b87ca88aa5e29..96796b1421aa898c5fa7eee787203cd6e8b87e15 100644 (file)
@@ -41,13 +41,16 @@ C: quuux-tuple-2
 [
     100
 ] [
+    FORGET: point
+    FORGET: point?
+    FORGET: point-x
     TUPLE: point x y ;
     C: point [ set-point-y ] keep [ set-point-x ] keep ;
     
     100 200 <point>
     
     ! Use eval to sequence parsing explicitly
-    "TUPLE: point x y z ;" eval
+    "IN: temporary TUPLE: point x y z ;" eval
     
     point-x
 ] unit-test
index 1723d10fb08feafcd15b83bf7afc3bc6d67596ec..d6c5082e543c1a5c51b476b7f76998c8e3429ce1 100644 (file)
@@ -1,5 +1,5 @@
 IN: temporary
-USING: generic kernel lists math namespaces test words ;
+USING: generic kernel lists math namespaces test words sequences ;
 
 [ 4 ] [
     "poo" "scratchpad" create [ 2 2 + ] define-compound
index 13307e6307b5c455c587fe974717782c049ad29d..5a1d426eabe46ca3450da3034aeef31aa9a6774c 100644 (file)
@@ -109,7 +109,7 @@ M: object (each-slot) ( quot obj -- )
 : orphan? ( word -- ? )
     #! Test if the word is not a member of its vocabulary.
     dup dup word-name swap word-vocabulary dup [
-        vocab hash eq? not
+        vocab dup [ hash eq? not ] [ 3drop t ] ifte
     ] [
         3drop t
     ] ifte ;
index 4aa66170c9291a9d0e87fa2c32bdd8c279d55ed6..f8303d5e21fccc97ac43e3aa6503c5be9485f683 100644 (file)
@@ -37,7 +37,7 @@ SYMBOL: vocabularies
 
 : recrossref ( -- )
     #! Update word cross referencing information.
-    [ f "usages" set-word-prop ] each-word
+    global [ <namespace> crossref set ] bind
     [ add-crossref ] each-word ;
 
 : (search) ( name vocab -- word )