-
Notifications
You must be signed in to change notification settings - Fork 0
/
feature-test.scm
102 lines (95 loc) · 3.88 KB
/
feature-test.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
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
90
91
92
93
94
95
96
97
98
99
100
101
102
(module feature-test
((register-foreign-features R! U!)
declare-foreign-features define-foreign-features
declaration-prefix registration-prefix)
(import scheme)
(cond-expand
(chicken-4
(import chicken))
(else
(import (chicken format))
(import (chicken syntax))
(begin-for-syntax
(import (chicken string))
(import (chicken format)))))
(define-syntax register-foreign-feature
(er-macro-transformer
(lambda (e r c)
(let ((F (->string (cadr e))))
(let ((%begin (r 'begin))
(%define-foreign-variable (r 'define-foreign-variable))
(%bool (r 'bool)) (%quote (r 'quote))
(%if (r 'if)) (%R! (r 'R!)) (%U! (r 'U!)))
(let* ((cvar (string-append *ft:declaration-prefix* F))
(var (string->symbol cvar))
(ft (string->symbol (string-append *ft:registration-prefix* F))))
`(,%begin (,%define-foreign-variable ,var ,%bool ,cvar)
((,%if ,var ,%R! ,%U!)
(,%quote ,ft)))))))))
(define-syntax declare-foreign-feature
(er-macro-transformer
(lambda (e r c)
(let ((d (->string (cadr e)))
(dp *ft:declaration-prefix*))
`(,(r 'foreign-declare)
,(sprintf "#ifdef ~A\n#define ~A~A 1\n#else \n#define ~A~A 0\n#endif\n"
d dp d dp d))))))
(define-syntax declare-foreign-features
(er-macro-transformer
(lambda (e r c)
`(,(r 'begin)
. ,(map (lambda (x) `(,(r 'declare-foreign-feature) ,x))
(cdr e))))))
(define-syntax register-foreign-features
(er-macro-transformer
(lambda (e r c)
`(,(r 'begin)
. ,(map (lambda (x) `(,(r 'register-foreign-feature) ,x))
(cdr e))))))
(define-syntax define-foreign-features
(syntax-rules () ((DR args ...)
(begin (declare-foreign-features args ...)
(register-foreign-features args ...)))))
(define-syntax declaration-prefix
(er-macro-transformer
(lambda (e r c)
(set! *ft:declaration-prefix* (->string (cadr e)))
`(,(r 'begin)))))
(define-syntax registration-prefix
(er-macro-transformer
(lambda (e r c)
(set! *ft:registration-prefix* (->string (cadr e)))
`(,(r 'begin)))))
(define *declaration-prefix* "HAVE_")
(define *registration-prefix* "")
(define R! (lambda (f) (printf "(register-feature! '~S)\n" f)))
(define U! (lambda (f) (printf "(unregister-feature! '~S)\n" f)))
(define write-feature-syntax
(lambda ()
(for-each (lambda (x) (write x) (newline))
`(
(set-sharp-read-syntax!
#\+ (lambda (p) (let ((ft (read p))
(body (read p)))
(eval
`(cond-expand (,ft ',body)
(else '(##core#undefined)))) ;; should be (values) if reader patched
)))
(set-sharp-read-syntax!
#\- (lambda (p) (let ((ft (read p))
(body (read p)))
(eval
`(cond-expand (,ft '(##core#undefined)) ;; should be (values) if reader patched
(else ',body))))))
(set-sharp-read-syntax!
#\? (lambda (p) (let* ((test (read p))
(ft (car test))
(con (cadr test))
(alt (cddr test))) ;; alt optional; maybe should not be
(eval
`(cond-expand (,ft ',con)
(else
,(if (null? alt)
'(##core#undefined)
(list 'quote (car alt)))))))))))))
)