I have a CLJC file that produces the following desired output in Clojure:
(ns myproj.macros-ns)
(defmacro inner-macro [s]
`['(my-ns/my-fn) :from ['~s :all]])
(defmacro outer-macro [y xs]
`(into ['~y '~'<-] (eval '~xs)))
(defmacro macro-context [other-macros]
(let [symbols (eval other-macros)
_ (println "Expanded in macro context" symbols)]
{:result `(list '~symbols '~'+ '~'further-rearrangement)}))
(macro-context (outer-macro ?sym-a (inner-macro ?sym-b)))
Expanded in macro context [?sym-a <- (my-ns/my-fn) :from [?sym-b :all]]
=> {:result ([?sym-a <- (my-ns/my-fn) :from [?sym-b :all]] + further-rearrangement)}
My question is: How can I get the same result in Clojurescript?
My CLJS file looks like this:
(ns myproj.app-ns
(:require-macros [myproj.macros-ns :refer [outer-macro
inner-macro
macro-context]]))
(enable-console-print!)
(macro-context (outer-macro ?sym-a (inner-macro ?sym-b)))
Error I'm getting is:
clojure.lang.ExceptionInfo: java.lang.RuntimeException: Unable to
resolve symbol: outer-macro in this context, compiling:
(/private/var/folders/2g/sfp74ftj6_q1vw51ytjbgvph0000gn/T/form-
init4244939051951953637.clj:13:3) at line 12
test/macros/cljs/myproj/app_ns.cljs
What am I ultimately trying to do and why?
I'm writing a framework that wraps https://github.com/cerner/clara-rules. Clara has its own macro, defrule, that uses the following DSL syntax
(defrule my-rule
[?fact <- (my-ns/my-fn) :from [:all (= ?e (:e this))]
...
I have a macro that expands the following to the previous:
(macro-context my-rule
[?fact <- (my-ns/my-fn) :from [?e :all]]
...
The macro that does this is basically the macro-context in the more general example above. When I am only parsing syntax like this, I don't call eval or macroexpand. I'm able to treat everything as a symbol, rewrite it to Clara's DSL, then pass it to defrule.
Here's where I think that breaks down:
(macro-context
[(outer-macro ?fact (inner-macro ?e))]
...
Inside the macro-context macro, outer-macro and inner-macro are unevaluated and at that point I need their expansion. By calling eval, I can get that in Clojure, but for some reason when compiling Clojurescript I receive "unable to resolve symbol outer-macro in this context.