-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgeneric.shen
35 lines (31 loc) · 1.22 KB
/
generic.shen
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
(define generic.dispatch
[(@p Pred Body) | _] Arg -> (Body Arg) where (Pred Arg)
[_ | More] Arg -> (generic.dispatch More Arg)
_ _ -> (error "no matching implementation"))
(define defgeneric
doc "Declares a new generic method with the given type."
Name Type ->
(do
(put Name dispatch-list [])
(eval [define Name ~'Arg -> [generic.dispatch [get Name dispatch-list] ~'Arg]])
(declare Name Type)
Name))
(define defspecific
doc "Declares a case-specific implementation of a generic method. New implementations supercede old ones."
Name Pred Body ->
(do
(put Name dispatch-list [(@p Pred Body) | (get Name dispatch-list)])
Name))
(defmacro defgeneric-macro
[defgeneric Name doc Doc | More] ->
[do
[set-doc Name Doc]
[defgeneric Name | More]]
[defgeneric Name] ->
[defgeneric Name (internal.rcons [[protect (gensym A)] --> [protect (gensym B)]])]
[defgeneric Name { | More] ->
(if (= } (last More))
[defgeneric Name (internal.rcons (but-last More))]
(error "invalid type signature in (defgeneric ~A ...)" Name)))
(declare defgeneric [symbol --> [T --> symbol]])
(declare defspecific [symbol --> [[A --> boolean] --> [[A --> B] --> symbol]]])