/
ocaml.cljs
95 lines (78 loc) · 3.58 KB
/
ocaml.cljs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
(ns klipse.lang.ocaml
(:require-macros
[gadjett.core :refer [dbg my-with-redefs]]
[cljs.core.async.macros :refer [go]])
(:require
[clojure.string :as string]
[cljs.core.async :refer [chan put!]]
[klipse.common.registry :refer [codemirror-mode-src register-mode]]
[applied-science.js-interop :as j]))
(def eval-in-global-scope js/eval); this is the trick to make `eval` work in the global scope: http://perfectionkills.com/global-eval-what-are-the-options/
(defn ocaml-to-js [src]
(let [{:keys [js_error_msg js_code]} (js->clj (-> (js/ocaml.compile src)
js/JSON.parse)
:keywordize-keys true)];TODO - use transit JSON reader
(if js_error_msg [:error js_error_msg]
[:ok js_code])))
(defn eval-with-types [exp]
(try
[:ok (j/call js/evaluator :execute exp)]
(catch :default o
[:error (str o)])))
(defn eval-ocaml [exp _]
(let [c (chan)]
(my-with-redefs [js/console.log (fn[& args]
(put! c (string/join " " args))
(put! c "\n"))]
(try
(set! js/exports #js {})
(let [[status res] (ocaml-to-js exp)]
(if (= :error status) (put! c res)
(put! c (-> res
eval-in-global-scope
str))))
(catch :default o
(str o))))
c))
(defn eval-ocaml-with-types [exp _]
(let [c (chan)]
(my-with-redefs [js/console.error (fn[& args]
(put! c (string/join " " args))
(put! c "\n"))]
(try
(set! js/exports #js {})
(let [[status res] (eval-with-types exp)]
(if (= :error status) (put! c res)
(put! c res)))
(catch :default o
(str o))))
c))
(defn transpile-ocaml [exp _]
(go
(let [[_ res] (ocaml-to-js exp)]
res)))
(defn comment-out [src]
(str "(* " src " *)"))
(def eval-opts {:editor-in-mode "text/x-ocaml"
:editor-out-mode "text/x-ocaml"
:beautify? false
:eval-fn eval-ocaml
:external-scripts [(codemirror-mode-src "mllike") "https://viebel.github.io/klipse/repo/js/bs.js" "https://viebel.github.io/klipse/repo/js/stdlibBundle.js"]
:comment-str comment-out})
(def eval-with-types-opts
{:editor-in-mode "text/x-ocaml"
:editor-out-mode "text/x-ocaml"
:beautify? false
:eval-fn eval-ocaml-with-types
:external-scripts [(codemirror-mode-src "mllike") "https://viebel.github.io/klipse/repo/js/ocaml_evaluate_type.js"]
;; https://github.com/ocsigen/js_of_ocaml/issues/629
:comment-str comment-out})
(def transpile-opts {:editor-in-mode "text/x-ocaml"
:editor-out-mode "javascript"
:beautify? false
:eval-fn transpile-ocaml
:external-scripts [(codemirror-mode-src "mllike") "https://viebel.github.io/klipse/repo/js/bs.js" "https://viebel.github.io/klipse/repo/js/pretty_format.js"]
:comment-str comment-out})
(register-mode "eval-ocaml" "selector_eval_ocaml" eval-opts)
(register-mode "transpile-ocaml" "selector_transpile_ocaml" transpile-opts)
(register-mode "eval-with-types-opts" "selector_eval_ocaml_with_types" eval-with-types-opts)