Skip to content

Instantly share code, notes, and snippets.

@MarchLiu
Created April 4, 2016 06:54
Show Gist options
  • Save MarchLiu/f84145d7b44622cdc7f5ce383aa8a5f3 to your computer and use it in GitHub Desktop.
Save MarchLiu/f84145d7b44622cdc7f5ce383aa8a5f3 to your computer and use it in GitHub Desktop.
模拟 haskell do 环境的 clojure 宏
;; parsec.clj
(defmacro =>>
"Threads the state through the parsers. Inserts state as the
parameter in the first parser. If there are more parsers,
inserts the first residue as the second state in second parser, etc.
If a parser throw exception, throw it and exit, else return all bind result
as a dictionay and residue data.
"
[data & forms]
(loop [data (list (list return {}) data), forms forms]
(if forms
(let [form (first forms)
need-bind (and (seq? form) (symbol? (first form)) (keyword? (second form)) (= (name (first form)) "<-"))
func (if need-bind (nth form 2) form)
tail (if need-bind
(let [key (second form)]
`(let [[results# data#] ~data, [result# residue#] (~func data#)]
(list (assoc results# ~key result#) residue#)))
`(let [[results# data#] ~data, [result# residue#] (~func data#)]
(list results# residue#)))]
(recur tail (next forms)))
data)))
;; retrun in atom.clj
(defn return [value]
(fn [data] (list value data)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment