Skip to content
This repository was archived by the owner on Jan 2, 2023. It is now read-only.

Commit 1c0ab95

Browse files
committed
core vars
1 parent ba6e288 commit 1c0ab95

File tree

10 files changed

+108
-14
lines changed

10 files changed

+108
-14
lines changed

cherry/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33
package-lock.json
44
target
55
node_modules
6+
.shadow-cljs
7+
lib
8+
report.html
9+
test/scratch.js

cherry/cljs.core.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './lib/cljs_core.js';

cherry/corpus/core_vars.cljs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
(ns core-vars)
2+
3+
(def js-map (clj->js (assoc nil :foo :bar)))
4+
5+
(js/console.log js-map)
6+
7+
(def clj-map (assoc nil :foo (+ 1 2 3)))
8+
9+
(js/console.log (get clj-map :foo)) ;; => 6

cherry/corpus/core_vars.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { toJs, get, keyword, assoc } from 'cherry-cljs/cljs.core.js'
2+
3+
const js_map = toJs(assoc(null, keyword("foo"), keyword("bar")));
4+
console.log(js_map);
5+
const clj_map = assoc(null, keyword("foo"), (1 + 2 + 3));
6+
console.log(get(clj_map, keyword("foo")));

cherry/corpus/destructuring.cljs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
(ns destructuring)
2+
3+
;; TODO:
4+
(let [{:keys [a]} x]
5+
6+
)
7+
8+
;; This currently transpiles as:
9+
10+
;; const {keys: [a]} = {a: 1};
11+
12+
;; What we probably want:
13+
14+
;; const _temp_object = x // the enti
15+
;; const a = ...
16+

cherry/corpus/destructuring.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
(function () {
2+
const {keys: [a]} = {a: 1};
3+
return (function () {
4+
return null;
5+
})();
6+
})();

cherry/deps.edn

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
{:deps {borkdude/edamame {:mvn/version "1.0.0"}}
2-
32
:aliases
4-
{:cljs {:extra-deps {org.clojure/clojurescript {:mvn/version "1.11.60"}}}
3+
{:cljs {:extra-deps {thheller/shadow-cljs {:mvn/version "2.19.6"}}}
54
:test ;; added by neil
65
{:extra-paths ["test"]
76
:extra-deps {io.github.cognitect-labs/test-runner

cherry/package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
{
2-
"dependencies": {
3-
"mori": "^0.3.2"
4-
}
2+
"type": "module",
3+
"name": "cherry-cljs",
4+
"sideEffects": false,
5+
"version": "0.0.0-alpha.4",
6+
"files": ["cljs.core.js",
7+
"lib/cljs_core.js"],
8+
"devDependencies": {"cherry-cljs": "."}
59
}

cherry/shadow-cljs.edn

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{:deps {:aliases [:cljs]}
2+
:builds
3+
{:cherry
4+
{:js-options {;; don't bundle any npm libs
5+
:js-provider :import}
6+
:compiler-options {:infer-externs :auto}
7+
:target :esm
8+
:runtime :node
9+
:output-dir "lib"
10+
:modules
11+
{:cljs_core {:exports {assoc cljs.core/assoc
12+
map cljs.core/map
13+
str cljs.core/str
14+
keyword cljs.core/keyword
15+
symbol cljs.core/symbol
16+
vector cljs.core/vector
17+
toJs cljs.core/clj->js
18+
toCljs cljs.core/js->clj
19+
dissoc cljs.core/dissoc
20+
conj cljs.core/conj
21+
get cljs.core/get}}
22+
#_#_:transpiler {}}
23+
:build-hooks [(shadow.cljs.build-report/hook
24+
{:output-to "report.html"})]}}}

cherry/src/cherry/transpiler.clj

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,21 @@
6767
;;; This is incomplete, it disallows unicode
6868
(boolean (re-matches #"[_$\p{Alpha}][.\w]*" (str sym))))
6969

70+
;; TODO: move to context argument
71+
(def ^:dynamic *imported-core-vars* (atom #{}))
72+
7073
(defmethod emit clojure.lang.Keyword [expr]
7174
(when-not (valid-symbol? (name expr))
7275
(#'throwf "%s is not a valid javascript symbol" expr))
73-
(str (name expr)))
76+
(swap! *imported-core-vars* conj 'keyword)
77+
(str (format "keyword(%s)" (pr-str (subs (str expr) 1)))))
7478

7579
(defmethod emit clojure.lang.Symbol [expr]
7680
(let [expr (if (and (qualified-symbol? expr)
7781
(= "js" (namespace expr)))
7882
(name expr)
79-
expr)]
83+
expr)
84+
expr (symbol (munge expr))]
8085
(when-not (valid-symbol? (str expr))
8186
(#' throwf "%s is not a valid javascript symbol" expr))
8287
(str expr)))
@@ -89,10 +94,16 @@
8994

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

101+
(def core-vars (set '[map assoc str keyword symbol
102+
dissoc conj vector clj->js js->clj get]))
103+
104+
(def core->js '{clj->js toJs
105+
js->cljs toCljs})
106+
96107
(def prefix-unary-operators (set ['!]))
97108

98109
(def suffix-unary-operators (set ['++ '--]))
@@ -183,10 +194,16 @@
183194
;; TODO
184195
)
185196

186-
(defmethod emit-special 'funcall [type [name & args]]
197+
(defmethod emit-special 'funcall [_type [name & args]]
187198
(str (if (and (list? name) (= 'fn (first name))) ; function literal call
188199
(str "(" (emit name) ")")
189-
(emit name))
200+
(let [name
201+
(if (contains? core-vars name)
202+
(let [name (get core->js name name)]
203+
(swap! *imported-core-vars* conj name)
204+
name)
205+
name)]
206+
(emit name)))
190207
(comma-list (map emit args))))
191208

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

486503
(defn transpile-file [{:keys [in-file out-file]}]
487-
(let [out-file (or out-file
488-
(str/replace in-file #".cljs$" ".mjs"))]
489-
(spit out-file (transpile-string (slurp in-file)))
490-
{:out-file out-file}))
504+
(let [core-vars (atom #{})]
505+
(binding [*imported-core-vars* core-vars]
506+
(let [out-file (or out-file
507+
(str/replace in-file #".cljs$" ".mjs"))
508+
transpiled (transpile-string (slurp in-file))
509+
transpiled (if-let [core-vars (seq @core-vars)]
510+
(str (format "import { %s } from 'cherry-cljs/cljs.core.js'\n\n"
511+
(str/join ", " core-vars))
512+
transpiled)
513+
transpiled)]
514+
(spit out-file transpiled)
515+
{:out-file out-file}))))

0 commit comments

Comments
 (0)