-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsgrep.rkt
More file actions
89 lines (79 loc) · 2.74 KB
/
sgrep.rkt
File metadata and controls
89 lines (79 loc) · 2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#lang at-exp rscript
(require utill/read-module
syntax/parse)
(define (sgrep-file path pattern [recursive? #f])
(define mod-stx (with-handlers ([exn:fail? (const #'())])
(read-module path)))
(define mod-sexp (syntax->datum mod-stx))
(sgrep-sexp mod-sexp pattern recursive?))
(define ns (make-base-namespace))
(eval '(require racket racket/match (for-syntax syntax/parse)) ns)
(require (for-syntax syntax/parse)
racket/match)
#;(define-match-expander list-no-order*
(syntax-parser
[(_ head no-order-pats ...)
#'(cons head (list-no-order no-order-pats ...))]))
(eval (syntax->datum
#'(define-match-expander list-no-order*
(syntax-parser
[(_ head no-order-pats (... ...))
#'(cons head (list-no-order no-order-pats (... ...)))])))
ns)
(eval (syntax->datum
#'(define-match-expander list-containing
(syntax-parser
[(_ pat)
#'(list-no-order pat _ ___)])))
ns)
(module+ test
(require ruinit)
(test-begin
(test-equal? (eval '(match '(head 1 2 3)
[(list-no-order* 'head 2 _ ___) 'yes]
[else 'no])
ns)
'yes)))
(define (sgrep-sexp s pattern [recursive? #f])
(let loop ([s s])
(cond [(try-match s pattern)
(list s)]
[recursive?
(match s
[(list sub-exps ...)
(append* (map loop sub-exps))]
[datum empty])]
[else empty])))
(define (try-match s pattern)
(eval `(match ',s
[,pattern #t]
[else #f])
ns))
(define-logger sgrep)
(main
#:arguments ([(hash-table ['recursive? recursive?]) (list* pattern-str paths)]
#:once-each
[("-r" "--recursive")
'recursive?
("Recursively search module syntax for the pattern."
"The default is to just match the module syntax as a whole against the pattern."
"Warning: this can be slow!")
#:record]
#:args [match-pattern . paths])
(define pattern (call-with-input-string pattern-str read))
(define paths-to-search
(match paths
['() (list (current-directory))]
[specific-files-or-dirs specific-files-or-dirs]))
(define-values {files-to-search dirs-to-search}
(partition path-to-existant-file? paths-to-search))
(for ([f (apply in-sequences
(in-list files-to-search)
(map in-directory dirs-to-search))]
#:when (path-has-extension? f ".rkt"))
(log-sgrep-info (~a @(system/string "date +'%r'") f))
(define results (sgrep-file f pattern recursive?))
(unless (empty? results)
(displayln f)
(pretty-write results)
(newline))))