175 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Factor
		
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Factor
		
	
	
| ! Copyright (C) 2007 Doug Coleman.
 | |
| ! See http://factorcode.org/license.txt for BSD license.
 | |
| USING: accessors alien alien.accessors arrays assocs
 | |
| combinators.lib io kernel macros math namespaces prettyprint
 | |
| quotations sequences vectors vocabs words html.elements sets
 | |
| slots.private combinators.short-circuit ;
 | |
| IN: lint
 | |
| 
 | |
| SYMBOL: def-hash
 | |
| SYMBOL: def-hash-keys
 | |
| 
 | |
| : set-hash-vector ( val key hash -- )
 | |
|     2dup at -rot >r >r ?push r> r> set-at ;
 | |
| 
 | |
| : add-word-def ( word quot -- )
 | |
|     dup callable? [
 | |
|         def-hash get-global set-hash-vector
 | |
|     ] [
 | |
|         2drop
 | |
|     ] if ;
 | |
| 
 | |
| : more-defs ( -- )
 | |
|     {
 | |
|         { [ swap >r swap r> ] -rot }
 | |
|         { [ swap swapd ] -rot }
 | |
|         { [ >r swap r> swap ] rot }
 | |
|         { [ swapd swap ] rot }
 | |
|         { [ dup swap ] over }
 | |
|         { [ dup -rot ] tuck }
 | |
|         { [ >r swap r> ] swapd }
 | |
|         { [ nip nip ] 2nip }
 | |
|         { [ drop drop ] 2drop }
 | |
|         { [ drop drop drop ] 3drop }
 | |
|         { [ 0 = ] zero? }
 | |
|         { [ pop drop ] pop* }
 | |
|         { [ [ ] if ] when }
 | |
|         { [ f = not ] >boolean }
 | |
|     } [ first2 swap add-word-def ] each ;
 | |
| 
 | |
| : accessor-words ( -- seq )
 | |
| {
 | |
|     alien-signed-1 alien-signed-2 alien-signed-4 alien-signed-8
 | |
|     alien-unsigned-1 alien-unsigned-2 alien-unsigned-4 alien-unsigned-8
 | |
|     <displaced-alien> alien-unsigned-cell set-alien-signed-cell
 | |
|     set-alien-unsigned-1 set-alien-signed-1 set-alien-unsigned-2
 | |
|     set-alien-signed-2 set-alien-unsigned-4 set-alien-signed-4
 | |
|     set-alien-unsigned-8 set-alien-signed-8
 | |
|     alien-cell alien-signed-cell set-alien-cell set-alien-unsigned-cell
 | |
|     set-alien-float alien-float
 | |
| } ;
 | |
| 
 | |
| : trivial-defs
 | |
|     {
 | |
|         [ get ] [ t ] [ { } ] [ . ] [ drop f ]
 | |
|         [ drop ] [ f ] [ first ] [ second ] [ third ] [ fourth ]
 | |
|         [ ">" write-html ] [ "/>" write-html ]
 | |
|     } ;
 | |
| 
 | |
| H{ } clone def-hash set-global
 | |
| all-words [ dup def>> add-word-def ] each
 | |
| more-defs
 | |
| 
 | |
| ! Remove empty word defs
 | |
| def-hash get-global [
 | |
|     drop empty? not
 | |
| ] assoc-filter
 | |
| 
 | |
| ! Remove constants [ 1 ]
 | |
| [
 | |
|     drop dup length 1 = swap first number? and not
 | |
| ] assoc-filter
 | |
| 
 | |
| ! Remove set-alien-cell, etc.
 | |
| [
 | |
|     drop [ accessor-words diff ] keep [ length ] bi@ =
 | |
| ] assoc-filter
 | |
| 
 | |
| ! Remove trivial defs
 | |
| [
 | |
|     drop trivial-defs member? not
 | |
| ] assoc-filter
 | |
| 
 | |
| ! Remove n m shift defs
 | |
| [
 | |
|     drop dup length 3 = [
 | |
|         dup first2 [ number? ] both?
 | |
|         swap third \ shift = and not
 | |
|     ] [ drop t ] if
 | |
| ] assoc-filter 
 | |
| 
 | |
| ! Remove [ n slot ]
 | |
| [
 | |
|     drop dup length 2 = [
 | |
|         first2 \ slot = swap number? and not
 | |
|     ] [ drop t ] if
 | |
| ] assoc-filter def-hash set-global
 | |
| 
 | |
| : find-duplicates ( -- seq )
 | |
|     def-hash get-global [
 | |
|         nip length 1 >
 | |
|     ] assoc-filter ;
 | |
| 
 | |
| def-hash get-global keys def-hash-keys set-global
 | |
| 
 | |
| GENERIC: lint ( obj -- seq )
 | |
| 
 | |
| M: object lint ( obj -- seq )
 | |
|     drop f ;
 | |
| 
 | |
| : subseq/member? ( subseq/member seq -- ? )
 | |
|     { [ start ] [ member? ] } 2|| ;
 | |
| 
 | |
| M: callable lint ( quot -- seq )
 | |
|     def-hash-keys get [
 | |
|         swap subseq/member?
 | |
|     ] with filter ;
 | |
| 
 | |
| M: word lint ( word -- seq )
 | |
|     def>> dup callable? [ lint ] [ drop f ] if ;
 | |
| 
 | |
| : word-path. ( word -- )
 | |
|     [ vocabulary>> ":" ] keep unparse 3append write nl ;
 | |
| 
 | |
| : (lint.) ( pair -- )
 | |
|     first2 >r word-path. r> [
 | |
|         bl bl bl bl
 | |
|         dup .
 | |
|         "-----------------------------------" print
 | |
|         def-hash get at [ bl bl bl bl word-path. ] each
 | |
|         nl
 | |
|     ] each nl nl ;
 | |
| 
 | |
| : lint. ( alist -- )
 | |
|     [ (lint.) ] each ;
 | |
|     
 | |
| 
 | |
| GENERIC: run-lint ( obj -- obj )
 | |
| 
 | |
| : (trim-self) ( val key -- obj ? )
 | |
|     def-hash get-global at* [
 | |
|         dupd remove empty? not
 | |
|     ] [
 | |
|         drop f
 | |
|     ] if ;
 | |
| 
 | |
| : trim-self ( seq -- newseq )
 | |
|     [ [ (trim-self) ] filter ] assoc-map ;
 | |
| 
 | |
| : filter-symbols ( alist -- alist )
 | |
|     [
 | |
|         nip first dup def-hash get at
 | |
|         [ first ] bi@ literalize = not
 | |
|     ] assoc-filter ;
 | |
| 
 | |
| M: sequence run-lint ( seq -- seq )
 | |
|     [
 | |
|         global [ dup . flush ] bind
 | |
|         dup lint
 | |
|     ] { } map>assoc
 | |
|     trim-self
 | |
|     [ second empty? not ] filter
 | |
|     filter-symbols ;
 | |
| 
 | |
| M: word run-lint ( word -- seq )
 | |
|     1array run-lint ;
 | |
| 
 | |
| : lint-all ( -- seq )
 | |
|     all-words run-lint dup lint. ;
 | |
| 
 | |
| : lint-vocab ( vocab -- seq )
 | |
|     words run-lint dup lint. ;
 | |
| 
 | |
| : lint-word ( word -- seq )
 | |
|     1array run-lint dup lint. ;
 |