Mercurial > lasercutter
view 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 source
1 ;;; trace.clj -- simple call-tracing macros for Clojure3 ;; by Stuart Sierra, http://stuartsierra.com/4 ;; December 3, 20086 ;; Copyright (c) Stuart Sierra, 2008. All rights reserved. The use7 ;; and distribution terms for this software are covered by the Eclipse8 ;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)9 ;; which can be found in the file epl-v10.html at the root of this10 ;; distribution. By using this software in any fashion, you are11 ;; agreeing to be bound by the terms of this license. You must not12 ;; remove this notice, or any other, from this software.15 ;; This file defines simple "tracing" macros to help you see what your16 ;; code is doing.19 ;; CHANGE LOG20 ;;21 ;; December 3, 2008:22 ;;23 ;; * replaced *trace-out* with tracer24 ;;25 ;; * made trace a function instead of a macro26 ;; (suggestion from Stuart Halloway)27 ;;28 ;; * added trace-fn-call29 ;;30 ;; June 9, 2008: first version34 (ns35 ^{:author "Stuart Sierra, Michel Salim",36 :doc "This file defines simple \"tracing\" macros to help you see what your37 code is doing."}38 clojure.contrib.trace)40 (def41 ^{:doc "Current stack depth of traced function calls."}42 *trace-depth* 0)44 (defn tracer45 "This function is called by trace. Prints to standard output, but46 may be rebound to do anything you like. 'name' is optional."47 [name value]48 (println (str "TRACE" (when name (str " " name)) ": " value)))50 (defn trace51 "Sends name (optional) and value to the tracer function, then52 returns value. May be wrapped around any expression without53 affecting the result."54 ([value] (trace nil value))55 ([name value]56 (tracer name (pr-str value))57 value))59 (defn trace-indent60 "Returns an indentation string based on *trace-depth*"61 []62 (apply str (take *trace-depth* (repeat "| "))))64 (defn trace-fn-call65 "Traces a single call to a function f with args. 'name' is the66 symbol name of the function."67 [name f args]68 (let [id (gensym "t")]69 (tracer id (str (trace-indent) (pr-str (cons name args))))70 (let [value (binding [*trace-depth* (inc *trace-depth*)]71 (apply f args))]72 (tracer id (str (trace-indent) "=> " (pr-str value)))73 value)))75 (defmacro deftrace76 "Use in place of defn; traces each call/return of this fn, including77 arguments. Nested calls to deftrace'd functions will print a78 tree-like structure."79 [name & definition]80 `(do81 (def ~name)82 (let [f# (fn ~@definition)]83 (defn ~name [& args#]84 (trace-fn-call '~name f# args#)))))86 (defmacro dotrace87 "Given a sequence of function identifiers, evaluate the body88 expressions in an environment in which the identifiers are bound to89 the traced functions. Does not work on inlined functions,90 such as clojure.core/+"91 [fnames & exprs]92 `(binding [~@(interleave fnames93 (for [fname fnames]94 `(let [f# @(var ~fname)]95 (fn [& args#]96 (trace-fn-call '~fname f# args#)))))]97 ~@exprs))