Skip to content

Commit

Permalink
core vars
Browse files Browse the repository at this point in the history
  • Loading branch information
borkdude committed Jul 20, 2022
1 parent c0b74b4 commit 9e31490
Show file tree
Hide file tree
Showing 10 changed files with 108 additions and 14 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@
package-lock.json
target
node_modules
.shadow-cljs
lib
report.html
test/scratch.js
1 change: 1 addition & 0 deletions cljs.core.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './lib/cljs_core.js';
9 changes: 9 additions & 0 deletions corpus/core_vars.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(ns core-vars)

(def js-map (clj->js (assoc nil :foo :bar)))

(js/console.log js-map)

(def clj-map (assoc nil :foo (+ 1 2 3)))

(js/console.log (get clj-map :foo)) ;; => 6
6 changes: 6 additions & 0 deletions corpus/core_vars.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { toJs, get, keyword, assoc } from 'cherry-cljs/cljs.core.js'

const js_map = toJs(assoc(null, keyword("foo"), keyword("bar")));
console.log(js_map);
const clj_map = assoc(null, keyword("foo"), (1 + 2 + 3));
console.log(get(clj_map, keyword("foo")));
16 changes: 16 additions & 0 deletions corpus/destructuring.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
(ns destructuring)

;; TODO:
(let [{:keys [a]} x]

)

;; This currently transpiles as:

;; const {keys: [a]} = {a: 1};

;; What we probably want:

;; const _temp_object = x // the enti
;; const a = ...

6 changes: 6 additions & 0 deletions corpus/destructuring.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(function () {
const {keys: [a]} = {a: 1};
return (function () {
return null;
})();
})();
3 changes: 1 addition & 2 deletions deps.edn
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{:deps {borkdude/edamame {:mvn/version "1.0.0"}}

:aliases
{:cljs {:extra-deps {org.clojure/clojurescript {:mvn/version "1.11.60"}}}
{:cljs {:extra-deps {thheller/shadow-cljs {:mvn/version "2.19.6"}}}
:test ;; added by neil
{:extra-paths ["test"]
:extra-deps {io.github.cognitect-labs/test-runner
Expand Down
10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"dependencies": {
"mori": "^0.3.2"
}
"type": "module",
"name": "cherry-cljs",
"sideEffects": false,
"version": "0.0.0-alpha.4",
"files": ["cljs.core.js",
"lib/cljs_core.js"],
"devDependencies": {"cherry-cljs": "."}
}
24 changes: 24 additions & 0 deletions shadow-cljs.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{:deps {:aliases [:cljs]}
:builds
{:cherry
{:js-options {;; don't bundle any npm libs
:js-provider :import}
:compiler-options {:infer-externs :auto}
:target :esm
:runtime :node
:output-dir "lib"
:modules
{:cljs_core {:exports {assoc cljs.core/assoc
map cljs.core/map
str cljs.core/str
keyword cljs.core/keyword
symbol cljs.core/symbol
vector cljs.core/vector
toJs cljs.core/clj->js
toCljs cljs.core/js->clj
dissoc cljs.core/dissoc
conj cljs.core/conj
get cljs.core/get}}
#_#_:transpiler {}}
:build-hooks [(shadow.cljs.build-report/hook
{:output-to "report.html"})]}}}
43 changes: 34 additions & 9 deletions src/cherry/transpiler.clj
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,21 @@
;;; This is incomplete, it disallows unicode
(boolean (re-matches #"[_$\p{Alpha}][.\w]*" (str sym))))

;; TODO: move to context argument
(def ^:dynamic *imported-core-vars* (atom #{}))

(defmethod emit clojure.lang.Keyword [expr]
(when-not (valid-symbol? (name expr))
(#'throwf "%s is not a valid javascript symbol" expr))
(str (name expr)))
(swap! *imported-core-vars* conj 'keyword)
(str (format "keyword(%s)" (pr-str (subs (str expr) 1)))))

(defmethod emit clojure.lang.Symbol [expr]
(let [expr (if (and (qualified-symbol? expr)
(= "js" (namespace expr)))
(name expr)
expr)]
expr)
expr (symbol (munge expr))]
(when-not (valid-symbol? (str expr))
(#' throwf "%s is not a valid javascript symbol" expr))
(str expr)))
Expand All @@ -89,10 +94,16 @@

(def special-forms (set ['var '. '.. 'if 'funcall 'fn 'quote 'set!
'return 'delete 'new 'do 'aget 'while 'doseq
'str 'inc! 'dec! 'dec 'inc 'defined? 'and 'or
'inc! 'dec! 'dec 'inc 'defined? 'and 'or
'? 'try 'break
'await 'const 'defn 'let 'ns 'def]))

(def core-vars (set '[map assoc str keyword symbol
dissoc conj vector clj->js js->clj get]))

(def core->js '{clj->js toJs
js->cljs toCljs})

(def prefix-unary-operators (set ['!]))

(def suffix-unary-operators (set ['++ '--]))
Expand Down Expand Up @@ -183,10 +194,16 @@
;; TODO
)

(defmethod emit-special 'funcall [type [name & args]]
(defmethod emit-special 'funcall [_type [name & args]]
(str (if (and (list? name) (= 'fn (first name))) ; function literal call
(str "(" (emit name) ")")
(emit name))
(let [name
(if (contains? core-vars name)
(let [name (get core->js name name)]
(swap! *imported-core-vars* conj name)
name)
name)]
(emit name)))
(comma-list (map emit args))))

(defmethod emit-special 'str [type [str & args]]
Expand Down Expand Up @@ -484,7 +501,15 @@
(recur (str transpiled next-js))))))))

(defn transpile-file [{:keys [in-file out-file]}]
(let [out-file (or out-file
(str/replace in-file #".cljs$" ".mjs"))]
(spit out-file (transpile-string (slurp in-file)))
{:out-file out-file}))
(let [core-vars (atom #{})]
(binding [*imported-core-vars* core-vars]
(let [out-file (or out-file
(str/replace in-file #".cljs$" ".mjs"))
transpiled (transpile-string (slurp in-file))
transpiled (if-let [core-vars (seq @core-vars)]
(str (format "import { %s } from 'cherry-cljs/cljs.core.js'\n\n"
(str/join ", " core-vars))
transpiled)
transpiled)]
(spit out-file transpiled)
{:out-file out-file}))))

0 comments on commit 9e31490

Please sign in to comment.