diff --git a/src/hopen/syntax/silly_j.cljc b/src/hopen/syntax/silly_j.cljc new file mode 100644 index 0000000..e788de5 --- /dev/null +++ b/src/hopen/syntax/silly_j.cljc @@ -0,0 +1,51 @@ +(ns hopen.syntax.silly-j + (:require [hopen.renderer.xf :as rxf] + [instaparse.core :as insta])) + +(declare parse) + +;; TODO test case +(defn render + ([template data] + (render template data '())) + ([template data other-env] + (let [new-env (update rxf/default-env :bindings assoc other-env) + renderer (rxf/renderer (parse template) new-env)] + (transduce renderer str data)))) + +(def ebnf + (insta/parser " + S = [STR | SILLYSTR]+ + STR = #'[^{}]+' + SILLYSTR = OBK SILLY CBK + OBK = '{' + CBK = '}' + SILLY = [FCTX | FN] + FCTX = '@' ':' ATTR + ATTR = #'[^}]'+ + FN = FNNAME APPLIES* + APPLIES = SPC | FCTX | APPLY + FNNAME = #'[a-zA-Z0-9\\-]+' + SPC = #'\\ '+ + APPLY = #'^[^@\\ ][^}\\ ]+' + " + )) + +(defn parse [msg] + (->> (ebnf msg) + (insta/transform + {:STR str + :APPLY str + :FNNAME str + :ATTR str + :FCTX (fn [at comma attr] + (list 'hopen/ctx (keyword attr))) + :SPC identity + :FN (fn [first-elm & applies] + (cons (symbol first-elm) + (remove #{" "} applies))) + :APPLIES identity + :SILLY identity + :SILLYSTR (fn [obrk silly cbrk] silly) + :S list + }))) diff --git a/test/hopen/runner.cljs b/test/hopen/runner.cljs index 625ad81..5ce7cf9 100644 --- a/test/hopen/runner.cljs +++ b/test/hopen/runner.cljs @@ -5,6 +5,7 @@ [hopen.renderer.xf-test] [hopen.syntax.handlebars-test] [hopen.syntax.partition-test] + [hopen.syntax.silly-j-test] [hopen.syntax.util-test] [hopen.util-test])) @@ -12,5 +13,6 @@ 'hopen.renderer.xf-test 'hopen.syntax.handlebars-test 'hopen.syntax.partition-test + 'hopen.syntax.silly-j-test 'hopen.syntax.util-test 'hopen.util-test) diff --git a/test/hopen/syntax/silly_j_test.cljc b/test/hopen/syntax/silly_j_test.cljc new file mode 100644 index 0000000..a1031e0 --- /dev/null +++ b/test/hopen/syntax/silly_j_test.cljc @@ -0,0 +1,21 @@ +(ns hopen.syntax.silly-j-test + (:require #?(:clj [clojure.test :refer [deftest testing is are]] + :cljs [cljs.test :refer [deftest testing is are] + :include-macros true]) + [hopen.syntax.silly-j :refer [parse]])) + +(deftest parse-test + (testing "basic syntax test" + (are [template parsed] + (= (parse template) + parsed) + ;; Split string and context + "Hello {@:name}, {@:n} * {@:n} = {square @:n}" ["Hello " + '(hopen/ctx :name) + ", " + '(hopen/ctx :n) + " * " + '(hopen/ctx :n) + " = " + '(square (hopen/ctx :n))] + )))