PageRenderTime 61ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 0ms

/src/clj/clojure/template.clj

https://gitlab.com/hcaty/clojure
Clojure | 55 lines | 24 code | 10 blank | 21 comment | 0 complexity | 592b2f2137f7d67a2738e57811c2a3b7 MD5 | raw file
  1. ; Copyright (c) Rich Hickey. All rights reserved.
  2. ; The use and distribution terms for this software are covered by the
  3. ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
  4. ; which can be found in the file epl-v10.html at the root of this distribution.
  5. ; By using this software in any fashion, you are agreeing to be bound by
  6. ; the terms of this license.
  7. ; You must not remove this notice, or any other, from this software.
  8. ;;; template.clj - anonymous functions that pre-evaluate sub-expressions
  9. ;; By Stuart Sierra
  10. ;; June 23, 2009
  11. ;; CHANGE LOG
  12. ;;
  13. ;; June 23, 2009: complete rewrite, eliminated _1,_2,... argument
  14. ;; syntax
  15. ;;
  16. ;; January 20, 2009: added "template?" and checks for valid template
  17. ;; expressions.
  18. ;;
  19. ;; December 15, 2008: first version
  20. (ns ^{:doc "Macros that expand to repeated copies of a template expression."
  21. :author "Stuart Sierra"}
  22. clojure.template
  23. (:require [clojure.walk :as walk]))
  24. (defn apply-template
  25. "For use in macros. argv is an argument list, as in defn. expr is
  26. a quoted expression using the symbols in argv. values is a sequence
  27. of values to be used for the arguments.
  28. apply-template will recursively replace argument symbols in expr
  29. with their corresponding values, returning a modified expr.
  30. Example: (apply-template '[x] '(+ x x) '[2])
  31. ;=> (+ 2 2)"
  32. [argv expr values]
  33. (assert (vector? argv))
  34. (assert (every? symbol? argv))
  35. (walk/prewalk-replace (zipmap argv values) expr))
  36. (defmacro do-template
  37. "Repeatedly copies expr (in a do block) for each group of arguments
  38. in values. values are automatically partitioned by the number of
  39. arguments in argv, an argument vector as in defn.
  40. Example: (macroexpand '(do-template [x y] (+ y x) 2 4 3 5))
  41. ;=> (do (+ 4 2) (+ 5 3))"
  42. [argv expr & values]
  43. (let [c (count argv)]
  44. `(do ~@(map (fn [a] (apply-template argv expr a))
  45. (partition c values)))))