Here is something I wrote as a Clojure learning exercise.

I have a suspicion that a serious implementation of this may exist,
please let me know if that is so!

Cheers,

Victor Rodriguez.

http://gist.github.com/82727

;;; A toy to experiment with Clojure macros.
;;;
;;; (f "1 + 2 = ~(+ 1 2)") results in "1 + 2 = 3"
;;;
;;; Know of a real implementation of this? Please Let me know at
;;; vict...@gmail.com.


(defn tokenize
  "Split a string into a sequence of plain strings and
''unquoted'' form-strings. For example, it turns

\"~a = ~(- b c)\" into (\"~a\" \" = \"~(- b c)\")"
  [s]
  (let [unquote-re
        (re-pattern
         (str "~\\([^\\)]*\\)" ; a tilde followed by a paren
              "|"
              "~\\w+" ; a tilde not followed by an open paren...
              "|"
              "[^~]+" ; anything that is not a tilde
              "|"
              "~$"))] ; a tilde at the end
    (re-seq unquote-re s)))

(defn to-form
  "Convert a strings to forms. For example, it turns
''~foo'' and ''~(inc a)'' into 'foo' and '(inc a)',
respectively."
  [s]
  (if (= \~ (first s))
    (read-string (.substring s 1))
    s))

(defn f*
  "Convert a string with ''unquoted'' forms into a
list of strings and forms."
  [s]
  (loop [tokens (tokenize s)
         form '(str )]
    (if-let [token (first tokens)]
      (recur (rest tokens)
             (conj form (to-form token)))
      (reverse form))))

(defmacro f
  "Compile time string templates!"
  [s]
  (f* s))

(comment

(let [s "a + b ="
      a 1
      b 2
      m {:title 'chihuahua }]
  (f "let ~s ~(+ a b) and the title be ~(:title m)"))
)

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to