Mercurial > lasercutter
diff src/clojure/contrib/trace.clj @ 10:ef7dbbd6452c
added clojure source goodness
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 06:25:44 -0400 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/clojure/contrib/trace.clj Sat Aug 21 06:25:44 2010 -0400 1.3 @@ -0,0 +1,97 @@ 1.4 +;;; trace.clj -- simple call-tracing macros for Clojure 1.5 + 1.6 +;; by Stuart Sierra, http://stuartsierra.com/ 1.7 +;; December 3, 2008 1.8 + 1.9 +;; Copyright (c) Stuart Sierra, 2008. All rights reserved. The use 1.10 +;; and distribution terms for this software are covered by the Eclipse 1.11 +;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) 1.12 +;; which can be found in the file epl-v10.html at the root of this 1.13 +;; distribution. By using this software in any fashion, you are 1.14 +;; agreeing to be bound by the terms of this license. You must not 1.15 +;; remove this notice, or any other, from this software. 1.16 + 1.17 + 1.18 +;; This file defines simple "tracing" macros to help you see what your 1.19 +;; code is doing. 1.20 + 1.21 + 1.22 +;; CHANGE LOG 1.23 +;; 1.24 +;; December 3, 2008: 1.25 +;; 1.26 +;; * replaced *trace-out* with tracer 1.27 +;; 1.28 +;; * made trace a function instead of a macro 1.29 +;; (suggestion from Stuart Halloway) 1.30 +;; 1.31 +;; * added trace-fn-call 1.32 +;; 1.33 +;; June 9, 2008: first version 1.34 + 1.35 + 1.36 + 1.37 +(ns 1.38 + ^{:author "Stuart Sierra, Michel Salim", 1.39 + :doc "This file defines simple \"tracing\" macros to help you see what your 1.40 +code is doing."} 1.41 + clojure.contrib.trace) 1.42 + 1.43 +(def 1.44 + ^{:doc "Current stack depth of traced function calls."} 1.45 + *trace-depth* 0) 1.46 + 1.47 +(defn tracer 1.48 + "This function is called by trace. Prints to standard output, but 1.49 + may be rebound to do anything you like. 'name' is optional." 1.50 + [name value] 1.51 + (println (str "TRACE" (when name (str " " name)) ": " value))) 1.52 + 1.53 +(defn trace 1.54 + "Sends name (optional) and value to the tracer function, then 1.55 + returns value. May be wrapped around any expression without 1.56 + affecting the result." 1.57 + ([value] (trace nil value)) 1.58 + ([name value] 1.59 + (tracer name (pr-str value)) 1.60 + value)) 1.61 + 1.62 +(defn trace-indent 1.63 + "Returns an indentation string based on *trace-depth*" 1.64 + [] 1.65 + (apply str (take *trace-depth* (repeat "| ")))) 1.66 + 1.67 +(defn trace-fn-call 1.68 + "Traces a single call to a function f with args. 'name' is the 1.69 + symbol name of the function." 1.70 + [name f args] 1.71 + (let [id (gensym "t")] 1.72 + (tracer id (str (trace-indent) (pr-str (cons name args)))) 1.73 + (let [value (binding [*trace-depth* (inc *trace-depth*)] 1.74 + (apply f args))] 1.75 + (tracer id (str (trace-indent) "=> " (pr-str value))) 1.76 + value))) 1.77 + 1.78 +(defmacro deftrace 1.79 + "Use in place of defn; traces each call/return of this fn, including 1.80 + arguments. Nested calls to deftrace'd functions will print a 1.81 + tree-like structure." 1.82 + [name & definition] 1.83 + `(do 1.84 + (def ~name) 1.85 + (let [f# (fn ~@definition)] 1.86 + (defn ~name [& args#] 1.87 + (trace-fn-call '~name f# args#))))) 1.88 + 1.89 +(defmacro dotrace 1.90 + "Given a sequence of function identifiers, evaluate the body 1.91 + expressions in an environment in which the identifiers are bound to 1.92 + the traced functions. Does not work on inlined functions, 1.93 + such as clojure.core/+" 1.94 + [fnames & exprs] 1.95 + `(binding [~@(interleave fnames 1.96 + (for [fname fnames] 1.97 + `(let [f# @(var ~fname)] 1.98 + (fn [& args#] 1.99 + (trace-fn-call '~fname f# args#)))))] 1.100 + ~@exprs))