-
Notifications
You must be signed in to change notification settings - Fork 0
/
graph.lisp
81 lines (63 loc) · 2.54 KB
/
graph.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
79
80
81
(defgeneric graph-from-expr (expr))
(defmethod graph-from-expr ((expr var-expr))
(let* ((var-name (expr-symbol expr))
(var-data (cdr (assoc var-name *vars*))))
(if var-data (graph-from-var var-name var-data)
(make-gref
(or (let ((fun (lookup-function var-name)))
(and fun (make-instance 'fun-gnode :fun-name var-name :arity (function-arity fun))))
(make-instance 'param-gnode :var var-name))))))
(defmethod graph-from-expr ((expr cons-expr))
(make-gref (make-instance 'cons-gnode :cons (expr-symbol expr))))
(defmethod graph-from-expr ((expr apply-expr))
(make-gref
(let ((fun (graph-from-expr (expr-fun expr)))
(arg (graph-from-expr (expr-arg expr) )))
(make-instance 'apply-gnode :fun fun :args (list arg)))))
(defmethod graph-from-expr ((expr let-expr))
(let ((*vars* *vars*))
(add-vars (expr-bindings expr))
(fill-var-gref (graph-from-expr (expr-body expr)))))
(defmethod graph-from-expr ((expr lambda-expr))
(error "Not implemented: lambdas"))
(defvar *vars-built*)
(defclass bottom-gnode (gnode)
((var :initarg :var :reader gnode-var)
(ptr :initarg :ptr :reader gnode-var-ptr)))
(defun graph-from-var (var-name var-data)
(or (car (second var-data))
(let* ((gref (make-instance 'gref))
(gref-ptr (list gref)))
(setf (gderef gref) (make-instance 'bottom-gnode :var var-name :ptr gref-ptr))
(setf (second var-data) gref-ptr)
(let ((gref* (graph-from-expr (first var-data))))
(rplaca gref-ptr gref*)
gref*))))
(defvar *filled*)
(defun fill-var-gref (gref)
(let ((*filled* (list)))
(fill-var-gref* gref)))
(defgeneric fill-var-gref** (gref gnode))
(defmethod fill-var-gref** (gref (gnode bottom-gnode))
(let ((gref* (car (gnode-var-ptr gnode))))
(fill-var-gref* gref*)))
(defmethod fill-var-gref** (gref gnode)
(fill-var-gnode (gderef gref))
gref)
(defun fill-var-gref* (gref)
(or (cdr (assoc gref *filled*))
(progn
(push (cons gref gref) *filled*)
(let ((gref* (fill-var-gref** gref (gderef gref))))
(push (cons gref gref*) *filled*)
gref*))))
(defgeneric fill-var-gnode (gnode))
(defmethod fill-var-gnode ((gnode gnode))
(values))
(defmethod fill-var-gnode ((gnode cons-gnode))
(setf (gnode-args gnode) (mapcar #'fill-var-gref* (gnode-args gnode)))
(values))
(defmethod fill-var-gnode ((gnode apply-gnode))
(setf (gnode-fun gnode) (fill-var-gref* (gnode-fun gnode)))
(setf (gnode-args gnode) (mapcar #'fill-var-gref* (gnode-args gnode)))
(values))