Here is the match-forms function:
(defn match-forms [p s]
(if (= '_ p) []
(loop [p p s s vars []]
(cond (and (= 0 (count p)) (= 0 (count s))) vars
(= 0 (count s)) false
true
(let [fp (first p) rp (rest p)
fs (first s) rs (rest s)]
(cond
;; wildcard pattern
(= '_ fp) (recur rp rs vars)
;; rest
(and (symbol? fp) (= '& fp))
(conj (conj vars (first rp)) `'~(conj rs fs))
;; add variable to bindings
(symbol? fp) (recur rp rs (conj (conj vars fp)
`'~fs))
;; match a symbol
(and (seq? fp) (= 'quote (first fp)))
(if (= fs (second fp)) (recur rp rs vars) false)
;; not matching
true false))))))
It basically only add a wildcard token to the pattern matching
algorithm, but it is less general too because it only support simple
list.
Here's how I intend to use it:
(defn- expand-parser-body [body s]
(let [r (gensym 'r)]
(match body
(_ '<- _) (parser-error)
(p) (list p s)
(v '<- p & xs)
`(let [~r (~p ~s)]
(if (= 0 (count ~r)) ~r
~(expand-parser-body xs)))
(p & xs)
`(let [~r (~p ~s)]
(if (= 0 (count ~r)) ~r
~(expand-parser-body xs))))))
(defmacro parser [& body]
(let [s (gensym 's)]
`(fn [~s] ~(expand-parser-body body s))))
It's for a small parser combinator library I'm writing.
On Aug 24, 1:26 pm, Chouser <[EMAIL PROTECTED]> wrote:
> On Sun, Aug 24, 2008 at 12:46 PM, budu <[EMAIL PROTECTED]> wrote:
>
> > Hi, I've been having a great time using Clojure in the last few month.
> > But this week I've come accross something that is blocking me. I'm
> > trying to write a very simple pattern matching macro to use in other
> > macros for matching forms. I've based my macro on one posted in this
> > group by James Reeves a few months ago. It's working great but, as it
> > uses eval, it does not evaluate in the lexical scope.
>
> > (defmacro match [value & clauses]
> > (when (and clauses (= 0 (rem (count clauses) 2)))
> > (let [m (gensym 'm)]
> > `(if-let ~m (match-forms '~(first clauses) ~value)
> > (eval (list 'let ~m '~(second clauses)))
> > (match ~value ~@(rrest clauses))))))
>
> > user=> (match '(1 2 3) (a b c) (list c b a))
> > (3 2 1)
>
> I believe you're referring to
> this:http://groups.google.com/group/clojure/browse_thread/thread/c6db91161...
>
> However, you've made some changes -- your match macro above is
> different from James Reeves', and simply renaming "matches?" to
> "match-forms" still doesn't allow your example to work. This makes it
> difficult to help you! Would you mind posting a working example?
>
> So it's hard to be sure, but I suspect we'll be able to find a
> solution. I think this because the eval in match is executed at
> runtime, not when the macro is evaluated. This means I think we ought
> to be able to make the match macro emit the appropriate code to have
> the same behavior as the eval, but without any eval at all.
>
> --Chouser
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---