-
Notifications
You must be signed in to change notification settings - Fork 2
/
cl-indeterminism.lisp
78 lines (65 loc) · 2.64 KB
/
cl-indeterminism.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
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
;;; -*- mode: Lisp; Syntax: Common-Lisp; -*-
;;;
;;; cl-indeterminism.lisp
;;;
;;; Copyright (c) 2013 by Alexander Popolitov.
;;;
;;; See COPYING for details.
(in-package #:hu.dwim.walker)
(def (layer e) find-undefined-references ()
())
(def layered-method handle-undefined-reference :in find-undefined-references
:around (type name &key &allow-other-keys)
(declare (special undefs))
(push name (cdr (assoc (ecase type
(:function :functions)
(:variable :variables))
undefs))))
(defmacro find-undefs (form &key (env :current))
;; TODO: variables and functions undefined w.r.t CURRENT lexenv, not NULL lexenv.
`(cl-curlex:with-current-lexenv
(let ((undefs (list (list :functions) (list :variables))))
(declare (special undefs))
(with-active-layers (find-undefined-references)
,(ecase env
(:current `(walk-form ,form :environment (make-walk-environment ,(intern "*LEXENV*"))))
(:null `(walk-form ,form)))
undefs))))
(def (layer e) transform-undefined-references ()
())
(defparameter *variable-transformer* nil)
(defparameter *function-transformer* nil)
(define-condition transform-not-handled (condition) ())
(defmacro fail-transform ()
`(signal 'transform-not-handled))
(def layered-method handle-undefined-reference :in transform-undefined-references
:around (type name &rest args &key &allow-other-keys)
(handler-case (ecase type
(:function (when *function-transformer*
(values (walk-form (funcall *function-transformer* (getf args :form))
:parent (getf args :parent)
:environment (getf args :environment))
t)))
(:variable (when *variable-transformer*
(values (walk-form (funcall *variable-transformer* name)
:parent (getf args :parent)
:environment (getf args :environment))
t))))
(transform-not-handled () nil)))
(defmacro-enhance:defmacro! macroexpand-all-transforming-undefs (form &key (o!-env :current))
`(cl-curlex:with-current-lexenv
(with-active-layers (transform-undefined-references)
(unwalk-form (walk-form ,form
:environment (ecase ,o!-env
(:current (make-walk-environment ,(intern "*LEXENV*")))
(:null nil)))))))
(defun macroexpand-cc-all-transforming-undefs (form &key env)
(with-active-layers (transform-undefined-references)
(unwalk-form (walk-form form
:environment (if env
(make-walk-environment env)
nil)))))
(export '(find-undefs macroexpand-all-transforming-undefs
macroexpand-cc-all-transforming-undefs
*variable-transformer* *function-transformer*
fail-transform))