 : private-vocab-name ( string -- string' )
     ".private" ?tail drop ".private" append ;
 
+: coverage-words ( string -- words )
+    words [ { [ primitive? not ] [ symbol? not ] } 1&& ] filter ;
+
 PRIVATE>
 
 : each-word ( string quot -- )
     over ".private" tail? [
-        [ words ] dip each
+        [ coverage-words ] dip each
     ] [
-        [ [ private-vocab-name words ] dip each ]
-        [ [ words ] dip each ] 2bi
+        [ [ private-vocab-name coverage-words ] dip each ]
+        [ [ coverage-words ] dip each ] 2bi
     ] if ; inline
 
 : map-words ( string quot -- sequence )
     over ".private" tail? [
-        [ words ] dip map
+        [ coverage-words ] dip map
     ] [
-        [ [ private-vocab-name words ] dip map ]
-        [ [ words ] dip map ] 2bi append
+        [ [ private-vocab-name coverage-words ] dip map ]
+        [ [ coverage-words ] dip map ] 2bi append
     ] if ; inline
 
 M: string coverage-on

! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs fry io kernel math prettyprint
quotations sequences sequences.deep splitting strings
tools.annotations vocabs words arrays ;
IN: tools.coverage

TUPLE: coverage < identity-tuple executed? ;

GENERIC: coverage. ( object -- )

M: string coverage.
    [ coverage. ] each-word ;

M: word coverage.
    dup coverage [
