1 ! Copyright (C) 2005, 2010 Slava Pestov.
2 ! See https://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays assocs combinators.short-circuit compiler.units effects
4 generalizations generic inspector io kernel math namespaces prettyprint
5 quotations sequences sequences.deep sequences.generalizations sorting summary
6 tools.time vocabs words ;
9 SYMBOL: override-annotations?
13 GENERIC: (reset) ( word -- )
16 subwords [ (reset) ] each ;
19 dup "unannotated-def" word-prop [
20 dupd define "unannotated-def" remove-word-prop
26 [ (reset) ] with-compilation-unit ;
28 ERROR: cannot-annotate-twice word ;
30 M: cannot-annotate-twice summary drop "Cannot annotate a word twice" ;
32 PREDICATE: annotated < word "unannotated-def" word-prop >boolean ;
36 : check-annotate-twice ( word -- word )
38 [ override-annotations? get
40 [ cannot-annotate-twice ] if
43 : annotate-generic ( word quot -- )
44 [ "methods" word-prop values ] dip each ; inline
46 : prepare-annotate ( word quot -- word quot quot )
47 [ check-annotate-twice ] dip
48 [ dup def>> 2dup "unannotated-def" set-word-prop ] dip ;
50 GENERIC#: (annotate) 1 ( word quot -- )
53 '[ _ (annotate) ] annotate-generic ;
57 call( old -- new ) define ;
59 GENERIC#: (deep-annotate) 1 ( word quot -- )
61 M: generic (deep-annotate)
62 '[ _ (deep-annotate) ] annotate-generic ;
64 M: word (deep-annotate)
66 '[ dup callable? [ _ call( old -- new ) ] when ] deep-map define ;
70 : annotate ( word quot -- )
71 [ (annotate) ] with-compilation-unit ;
73 : deep-annotate ( word quot -- )
74 [ (deep-annotate) ] with-compilation-unit ;
78 dup { [ annotated? ] [ subwords [ annotated? ] any? ] } 1||
84 :: trace-quot ( word effect quot str -- quot' )
85 effect quot call :> values
89 "--- " write str write bl word .
90 n ndup n narray values swap zip simple-table.
95 MACRO: entering ( word -- quot )
96 dup stack-effect [ in>> ] "Entering" trace-quot ;
98 MACRO: leaving ( word -- quot )
99 dup stack-effect [ out>> ] "Leaving" trace-quot ;
101 : (watch) ( word def -- def )
102 over '[ _ entering @ _ leaving ] ;
107 dup '[ [ _ ] dip (watch) ] annotate ;
111 : (watch-vars) ( word vars quot -- newquot )
114 "--- Entering: " write _ .
115 "--- Variable values:" print _ [ dup get ] H{ } map>assoc describe
122 : watch-vars ( word vars -- )
123 dupd '[ [ _ _ ] dip (watch-vars) ] annotate ;
127 word-timing [ H{ } clone ] initialize
129 : reset-word-timing ( -- )
130 word-timing get clear-assoc ;
134 : (add-timing) ( def word -- def' )
136 _ benchmark _ word-timing get [
138 [ 0 swap [ + ] change-nth ] keep
139 [ 1 swap [ 1 + ] change-nth ] keep
146 : add-timing ( word -- )
147 dup '[ _ (add-timing) ] annotate ;
149 : word-timing. ( -- )
150 word-timing get >alist
151 [ second first ] sort-with
152 [ first2 first2 [ 1,000,000,000 /f ] dip 3array ] map