-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.lisp
48 lines (44 loc) · 1.49 KB
/
main.lisp
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
(in-package #:explicit-bind)
(defun %trace ()
(trace eb-expander:expand eb-merger:merge eb-merger:merge1))
(defun %untrace ()
(untrace eb-expander:expand eb-merger:merge eb-merger:merge1))
(defun %merge (binding body)
(etypecase (first binding)
((or symbol cons)
(flet ((process (var-spec form)
(list
(destructuring-bind (kind name declarations) var-spec
(when declarations
(setf body (cons `(declare ,@declarations)
body)))
(ecase kind
(variable
`(let ((,name ,form))
,@body))
(function
`(flet* ((,name ,form))
,@body)))))))
(destructuring-bind (vars form) binding
(when (typep form '(cons (eql declare)))
(error "Misplaced DECLARE expression ~S ~
as form for ~S." form vars))
(let ((analyzed (%analyze-binding vars)))
(case (length analyzed)
(0 (list form))
(1 (process (first analyzed) form))
(t (let* ((names (mapcar #'second analyzed))
(gensymed (mapcar #'%gensymed-function-name names)))
(list `(multiple-value-bind ,gensymed ,form
,@(mapcan #'process analyzed names))))))))))))
(defmacro bind (bindings &body body)
(let* ((expanded (mapcan
(lambda (binding)
(copy-seq (eb-expander:expand binding)))
bindings))
(body (eb-merger:merge expanded body)))
(cond ((not body)
nil)
((not (rest body))
(first body))
(t `(progn ,@body)))))