-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpox-query.scm
61 lines (53 loc) · 1.83 KB
/
pox-query.scm
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
(module pox-query
(as-grouping as-filter as-list-of-symbols)
(import chicken scheme)
(use extras data-structures ports srfi-1 srfi-13 srfi-14 sexpressive)
(define-syntax define-converter
(syntax-rules ()
((_ name syntax fn default)
(begin
(define name #f)
(let* ((syntax* syntax)
(convert (lambda (str)
(parameterize ((sexpressive syntax*))
(call-with-input-string str
(lambda (in)
(reverse (port-fold fn '() (lambda () (read* in))))))))))
(set! name
(lambda (variable params)
(let ((val (alist-ref variable params)))
(if val (convert val) default)))))))
((_ name syntax fn)
(define-converter name syntax fn '()))
((_ name syntax)
(define-converter name syntax cons))))
(define (read-id port)
(string->number
(list->string
(let loop ()
(let ((char (peek-char port)))
(cond ((eof-object? char)
'())
((char-set-contains? char-set:whitespace char)
'())
((char-set-contains? char-set:digit char)
(cons (read-char port) (loop)))
(else 'read* "invalid char in id" char)))))))
(define-converter as-filter
(append (syntax:whitespace)
(syntax:keywords)
`((#\# . ,(lambda (port)
(read-char port)
(read-id port))))
(syntax:symbols as-string: #t))
(lambda (x filter)
(if (or (not x) (and (string? x) (< (string-length x) 2)))
filter
(cons x filter))))
(define-converter as-grouping
(append (syntax:whitespace)
(syntax:symbols)))
(define-converter as-list-of-symbols
(append (syntax:whitespace)
(syntax:symbols)))
)