2005-01-29 14:18:28 -05:00
|
|
|
! Copyright (C) 2004, 2005 Slava Pestov.
|
|
|
|
! See http://factor.sf.net/license.txt for BSD license.
|
2004-07-16 02:26:21 -04:00
|
|
|
IN: words
|
2005-01-29 14:18:28 -05:00
|
|
|
USING: generic hashtables kernel kernel-internals lists math
|
2005-04-02 02:39:33 -05:00
|
|
|
namespaces sequences strings vectors ;
|
2005-03-26 20:12:14 -05:00
|
|
|
|
|
|
|
! The basic word type. Words can be named and compared using
|
|
|
|
! identity. They hold a property map.
|
2005-02-20 19:03:37 -05:00
|
|
|
|
2005-03-26 20:12:14 -05:00
|
|
|
: word-prop ( word name -- value ) swap word-props hash ;
|
|
|
|
: set-word-prop ( word value name -- ) rot word-props set-hash ;
|
|
|
|
|
|
|
|
! Pointer to executable native code
|
2005-02-20 19:03:37 -05:00
|
|
|
GENERIC: word-xt
|
2005-08-29 02:34:04 -04:00
|
|
|
M: word word-xt ( w -- xt ) 7 integer-slot ;
|
2005-02-20 19:03:37 -05:00
|
|
|
GENERIC: set-word-xt
|
2005-08-29 02:34:04 -04:00
|
|
|
M: word set-word-xt ( xt w -- ) 7 set-integer-slot ;
|
2005-02-20 19:03:37 -05:00
|
|
|
|
2005-04-10 18:58:30 -04:00
|
|
|
: word-sort ( list -- list )
|
|
|
|
#! Sort a list of words by name.
|
2005-08-13 23:39:46 -04:00
|
|
|
[ swap word-name swap word-name lexi ] sort ;
|
2005-04-10 18:58:30 -04:00
|
|
|
|
2005-03-26 20:12:14 -05:00
|
|
|
! The cross-referencer keeps track of word dependencies, so that
|
|
|
|
! words can be recompiled when redefined.
|
|
|
|
SYMBOL: crossref
|
2004-12-15 16:57:29 -05:00
|
|
|
|
2005-03-26 20:12:14 -05:00
|
|
|
: (add-crossref)
|
|
|
|
dup word? [
|
|
|
|
crossref get [ dupd nest set-hash ] bind
|
|
|
|
] [
|
|
|
|
2drop
|
|
|
|
] ifte ;
|
|
|
|
|
|
|
|
: add-crossref ( word -- )
|
|
|
|
#! Marks each word in the quotation as being a dependency
|
|
|
|
#! of the word.
|
2005-08-15 15:34:00 -04:00
|
|
|
crossref get [
|
|
|
|
dup word-def [ (add-crossref) ] tree-each-with
|
|
|
|
] [
|
|
|
|
drop
|
|
|
|
] ifte ;
|
2005-03-26 20:12:14 -05:00
|
|
|
|
|
|
|
: (remove-crossref)
|
|
|
|
dup word? [
|
|
|
|
crossref get [ nest remove-hash ] bind
|
|
|
|
] [
|
|
|
|
2drop
|
|
|
|
] ifte ;
|
|
|
|
|
|
|
|
: remove-crossref ( word -- )
|
|
|
|
#! Marks each word in the quotation as not being a
|
|
|
|
#! dependency of the word.
|
2005-08-15 15:34:00 -04:00
|
|
|
crossref get [
|
|
|
|
dup word-def [ (remove-crossref) ] tree-each-with
|
|
|
|
] [
|
|
|
|
drop
|
|
|
|
] ifte ;
|
2005-03-26 20:12:14 -05:00
|
|
|
|
|
|
|
: usages ( word -- deps )
|
2005-04-10 18:58:30 -04:00
|
|
|
#! List all usages of a word. This is a transitive closure,
|
|
|
|
#! so indirect usages are reported.
|
2005-08-22 20:54:01 -04:00
|
|
|
crossref get dup [ closure ] [ 2drop { } ] ifte ;
|
2005-04-10 18:58:30 -04:00
|
|
|
|
|
|
|
: usage ( word -- list )
|
|
|
|
#! List all direct usages of a word.
|
2005-08-22 20:54:01 -04:00
|
|
|
crossref get ?hash dup [ hash-keys ] when ;
|
2005-03-26 20:12:14 -05:00
|
|
|
|
2005-04-05 22:18:36 -04:00
|
|
|
GENERIC: (uncrossref) ( word -- )
|
|
|
|
M: word (uncrossref) drop ;
|
2005-03-26 20:12:14 -05:00
|
|
|
|
2005-04-05 22:18:36 -04:00
|
|
|
: uncrossref ( word -- )
|
2005-08-22 20:54:01 -04:00
|
|
|
dup (uncrossref) usages [ (uncrossref) ] each ;
|
2005-03-26 20:12:14 -05:00
|
|
|
|
|
|
|
! The word primitive combined with the word def specify what the
|
|
|
|
! word does when invoked.
|
|
|
|
|
|
|
|
: define ( word primitive parameter -- )
|
2005-08-29 02:34:04 -04:00
|
|
|
pick uncrossref
|
|
|
|
pick set-word-def
|
|
|
|
over set-word-primitive
|
|
|
|
update-xt ;
|
2004-11-25 21:51:47 -05:00
|
|
|
|
2005-03-23 22:49:40 -05:00
|
|
|
GENERIC: definer ( word -- word )
|
|
|
|
#! Return the parsing word that defined this word.
|
|
|
|
|
2005-03-26 20:12:14 -05:00
|
|
|
! Undefined words raise an error when invoked.
|
|
|
|
PREDICATE: word undefined ( obj -- ? ) word-primitive 0 = ;
|
|
|
|
M: undefined definer drop \ DEFER: ;
|
2005-03-23 22:49:40 -05:00
|
|
|
|
2005-03-26 20:12:14 -05:00
|
|
|
! Primitives are defined in the runtime.
|
2004-12-12 23:49:44 -05:00
|
|
|
PREDICATE: word primitive ( obj -- ? ) word-primitive 2 > ;
|
2005-03-23 22:49:40 -05:00
|
|
|
M: primitive definer drop \ PRIMITIVE: ;
|
|
|
|
|
2005-03-26 20:12:14 -05:00
|
|
|
! Symbols push themselves when executed.
|
2004-12-12 23:49:44 -05:00
|
|
|
PREDICATE: word symbol ( obj -- ? ) word-primitive 2 = ;
|
2005-03-23 22:49:40 -05:00
|
|
|
M: symbol definer drop \ SYMBOL: ;
|
|
|
|
|
2005-03-26 20:12:14 -05:00
|
|
|
: define-symbol ( word -- ) 2 over define ;
|
2004-11-25 21:51:47 -05:00
|
|
|
|
2005-03-26 20:12:14 -05:00
|
|
|
: intern-symbol ( word -- )
|
|
|
|
dup undefined? [ define-symbol ] [ drop ] ifte ;
|
2005-03-05 14:45:23 -05:00
|
|
|
|
2005-03-26 20:12:14 -05:00
|
|
|
! Compound words invoke a quotation when executed.
|
|
|
|
PREDICATE: word compound ( obj -- ? ) word-primitive 1 = ;
|
|
|
|
M: compound definer drop \ : ;
|
|
|
|
|
2005-08-23 15:50:32 -04:00
|
|
|
: define-compound ( word def -- )
|
2005-03-26 20:12:14 -05:00
|
|
|
>r dup dup remove-crossref r> 1 swap define add-crossref ;
|
2004-11-25 21:51:47 -05:00
|
|
|
|
2005-08-21 23:35:50 -04:00
|
|
|
: reset-props ( word seq -- )
|
|
|
|
[ f swap set-word-prop ] each-with ;
|
|
|
|
|
2005-08-23 15:50:32 -04:00
|
|
|
: reset-word ( word -- )
|
2005-08-27 15:12:37 -04:00
|
|
|
{
|
|
|
|
"parsing" "inline" "foldable" "flushable" "predicating"
|
|
|
|
"documentation" "stack-effect"
|
|
|
|
} reset-props ;
|
2005-08-21 23:35:50 -04:00
|
|
|
|
2005-08-23 15:50:32 -04:00
|
|
|
: reset-generic ( word -- )
|
|
|
|
dup reset-word { "methods" "combination" } reset-props ;
|
2005-07-13 22:51:43 -04:00
|
|
|
|
2005-08-03 23:56:28 -04:00
|
|
|
GENERIC: literalize ( obj -- obj )
|
|
|
|
|
|
|
|
M: object literalize ;
|
|
|
|
|
|
|
|
M: word literalize <wrapper> ;
|
|
|
|
|
|
|
|
M: wrapper literalize <wrapper> ;
|