-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrace.mal
42 lines (36 loc) · 1.12 KB
/
trace.mal
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
(def! *trace* (atom {}))
(def! *trace-level* (atom 0))
(def! trace:get get)
(def! trace:cons cons)
(def! make-list (fn* [n val]
(if (<= n 0) ()
(trace:cons val (make-list (dec n) val)))))
(def! trace-level (fn* [prompt fun]
(str (apply str ";; trace: " (make-list @*trace-level* " "))
prompt
" "
fun
":")))
(defmacro! trace (fn* [f]
(cond (trace:get @*trace* f)
true
(fn? (eval f))
(let* [val (gensym)
fun (gensym)]
(swap! *trace* assoc f (eval f))
`(do (def! ~f (fn* [& args]
(let* [~fun (trace:get @*trace* '~f)]
(println (trace-level "-->" '~f) (apply pr-str args))
(swap! *trace-level* + 1)
(let* [~val (apply ~fun args)]
(swap! *trace-level* - 1)
(println (trace-level "<--" '~f) (pr-str ~val))
~val))))
'~f))
:else false)))
(defmacro! untrace (fn* [f]
(let* [fun (trace:get @*trace* f)]
(when fun
(swap! *trace* dissoc f)
`(do (def! ~f ~fun)
`~f)))))