-
Notifications
You must be signed in to change notification settings - Fork 115
/
Copy pathstxparam.ss
71 lines (61 loc) · 2.37 KB
/
stxparam.ss
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
;;; -*- Gerbil -*-
;;; © vyzo
;;; syntax parameters
(export #t (for-syntax #t))
(begin-syntax
(defclass syntax-parameter (key default))
(def (syntax-parameter-value id-stx)
(let (param (syntax-local-value id-stx))
(if (syntax-parameter? param)
(using (param :- syntax-parameter)
(let (key-stx (syntax-local-rewrap param.key))
(or (syntax-local-value key-stx false)
param.default)))
(abort!
(raise-syntax-error #f "Bad syntax; not defined as a syntax parameter" id-stx)))))
(def (syntax-parameter-e (param : syntax-parameter))
(let (key-stx (syntax-local-rewrap param.key))
(or (syntax-local-e key-stx false)
param.default)))
(defmethod {apply-macro-expander syntax-parameter}
(lambda (self stx)
(let (e (syntax-parameter-e self))
(core-apply-expander e stx)))))
(defrules defsyntax-parameter ()
((_ id default)
(defsyntax id
(make-syntax-parameter key: (gensym 'id) default: default))))
;; TODO: generalize to accept functions as parameters.
(defsyntax (defsyntax-parameter* stx)
(def (defparam macro param errmsg)
(with-syntax ((macro macro)
(param param)
(errmsg errmsg))
#'(begin
(defsyntax-parameter param #f)
(defsyntax (macro stx)
(if (identifier? stx)
(cond
((syntax-parameter-value (quote-syntax param)))
(else
(raise-syntax-error #f errmsg stx)))
(raise-syntax-error #f "Bad syntax; defsyntax-parameter* expects a macro definition" stx))))))
(syntax-case stx ()
((_ macro param)
(identifier-list? #'(macro param))
(defparam #'macro #'param "Bad syntax; syntax parameter* unbound"))
((_ macro param errmsg)
(identifier-list? #'(macro param))
(defparam #'macro #'param #'errmsg))))
(defsyntax (syntax-parameterize stx)
(def (parameter-key param-id)
(let (param (syntax-local-value param-id))
(unless (syntax-parameter? param)
(raise-syntax-error #f "Bad syntax; not defined as a syntax parameter" stx param-id))
(syntax-local-rewrap
(syntax-parameter-key param))))
(syntax-case stx ()
((_ ((param expr) ...) body rest ...)
(with-syntax (((key ...) (map parameter-key #'(param ...))))
#'(let-syntax ((key expr) ...)
body rest ...)))))