diff --git a/.gitignore b/.gitignore index f244287..dd435ec 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ pom.xml.asc .hgignore .hg/ /.idea/ +/nashorn_code_cache +/.cljs_nashorn_repl \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 4159794..3c80436 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,19 @@ -language: clojure +language: generic jdk: - openjdk8 jobs: include: - - stage: Tests + - stage: JvmTests script: - lein do clean, compile, check, eastwood - lein trampoline test + - stage: JsTests + script: + - nvm install 10.10 && nvm use 10.10 + - lein trampoline cljsbuild test + - stage: Benchmark if: branch = master script: diff --git a/project.clj b/project.clj index f656b4f..d3e0613 100644 --- a/project.clj +++ b/project.clj @@ -7,7 +7,18 @@ [instaparse/instaparse "1.4.10"]] :profiles {:dev {:dependencies [[criterium/criterium "0.4.5"] ;; benchmark [org.clojure/test.check "0.10.0"]] - :plugins [[jonase/eastwood "0.3.5"]]}} + :plugins [[jonase/eastwood "0.3.5"] + [lein-cljsbuild "1.1.7"]] + :cljsbuild {:builds + [{:id "dev" + :source-paths ["src" "test"] + :compiler {:main parcera.test-runner + :output-to "target/out/tests.js" + :target :nodejs + :optimizations :none}}] + :test-commands + {"test" ["node" "target/out/tests.js"]}}} + :provided {:dependencies [[org.clojure/clojurescript "1.10.520"]]}} :test-selectors {:default (fn [m] (not (some #{:benchmark} (keys m)))) :benchmark :benchmark} :deploy-repositories [["clojars" {:url "https://clojars.org/repo" diff --git a/src/parcera/core.clj b/src/parcera/core.cljc similarity index 91% rename from src/parcera/core.clj rename to src/parcera/core.cljc index 04557cb..adb51f3 100644 --- a/src/parcera/core.clj +++ b/src/parcera/core.cljc @@ -1,8 +1,9 @@ (ns parcera.core - (:require [instaparse.core :as instaparse])) + (:require [instaparse.core :as instaparse]) + #?(:cljs (:import goog.string.StringBuffer))) (def grammar - "code: form*; + "code: form*;
: whitespace ( literal | symbol @@ -139,7 +140,9 @@ | 'tab' | 'formfeed' | 'backspace' - | #'\\P{M}\\p{M}*+'; (* https://www.regular-expressions.info/unicode.html *)") + | #'[^\\u0300-\\u036F\\u1DC0-\\u1DFF\\u20D0-\\u20FF][\\u0300-\\u036F\\u1DC0-\\u1DFF\\u20D0-\\u20FF]*'; + (* This is supposed to be the JavaScript friendly version of #'\\P{M}\\p{M}*+' mentioned here: https://www.regular-expressions.info/unicode.html + It's cooked by this generator: http://kourge.net/projects/regexp-unicode-block, ticking all 'Combining Diacritical Marks' boxes *)") (def clojure @@ -160,7 +163,8 @@ (defn- code* "internal function used to imperatively build up the code from the provided AST as Clojure's str would be too slow" - [ast ^StringBuilder string-builder] + [ast #?(:clj ^StringBuilder string-builder + :cljs ^StringBuffer string-builder)] (case (first ast) :code (doseq [child (rest ast)] @@ -280,7 +284,8 @@ In general (= input (parcera/code (parcera/clojure input)))" [ast] - (let [string-builder (new StringBuilder)] + (let [string-builder #?(:clj (new StringBuilder) + :cljs (new StringBuffer))] (code* ast string-builder) (. string-builder (toString)))) diff --git a/src/parcera/slurp.cljc b/src/parcera/slurp.cljc new file mode 100644 index 0000000..b585e26 --- /dev/null +++ b/src/parcera/slurp.cljc @@ -0,0 +1,6 @@ +(ns parcera.slurp + "Some glue to help with CLJC things" + #?(:clj (:refer-clojure :exclude [slurp]))) + +#?(:clj (defmacro slurp [file] + (clojure.core/slurp file))) \ No newline at end of file diff --git a/test/parcera/test/core.clj b/test/parcera/test/core.cljc similarity index 89% rename from test/parcera/test/core.clj rename to test/parcera/test/core.cljc index 8810714..2268f2f 100644 --- a/test/parcera/test/core.clj +++ b/test/parcera/test/core.cljc @@ -5,7 +5,8 @@ [clojure.test.check.properties :as prop] [clojure.test.check :as tc] [parcera.core :as parcera] - [instaparse.core :as instaparse])) + [instaparse.core :as instaparse]) + #?(:cljs (:require-macros [parcera.slurp :refer [slurp]]))) (defn- roundtrip "checks parcera can parse and write back the exact same input code" @@ -41,6 +42,16 @@ (prop/for-all [input (gen/fmap pr-str gen/any)] (= 1 (count (instaparse/parses parcera/clojure input))))) +(deftest simple + (testing "character literals" + (as-> "\\t" input (is (= input (parcera/code (parcera/clojure input))))) + (as-> "\\n" input (is (= input (parcera/code (parcera/clojure input))))) + (as-> "\\r" input (is (= input (parcera/code (parcera/clojure input))))) + (as-> "\\a" input (is (= input (parcera/code (parcera/clojure input))))) + (as-> "\\é" input (is (= input (parcera/code (parcera/clojure input))))) + (as-> "\\ö" input (is (= input (parcera/code (parcera/clojure input))))) + (as-> "\\ï" input (is (= input (parcera/code (parcera/clojure input))))) + (as-> "\\ϕ" input (is (= input (parcera/code (parcera/clojure input))))))) (deftest data-structures (testing "grammar definitions" @@ -149,11 +160,11 @@ (deftest bootstrap (testing "parcera should be able to parse itself" - (let [input (slurp "./src/parcera/core.clj")] + (let [input (slurp "./src/parcera/core.cljc")] (is (and (valid? input) (roundtrip input) (clear input))))) (testing "parcera should be able to parse its own test suite" - (let [input (slurp "./test/parcera/test/core.clj")] + (let [input (slurp "./test/parcera/test/core.cljc")] (is (and (valid? input) (roundtrip input) (clear input)))))) diff --git a/test/parcera/test_runner.cljs b/test/parcera/test_runner.cljs new file mode 100644 index 0000000..958116c --- /dev/null +++ b/test/parcera/test_runner.cljs @@ -0,0 +1,11 @@ +(ns parcera.test-runner + (:require [cljs.nodejs :as nodejs] + [cljs.test :refer-macros [run-tests]] + [parcera.test.core :as ct])) + +(nodejs/enable-util-print!) + +(defn -main [] + (run-tests 'parcera.test.core)) + +(set! *main-cli-fn* -main)