diff --git a/resources/public/ocaml-dbg.html b/resources/public/ocaml-dbg.html new file mode 100644 index 00000000..0a321b6e --- /dev/null +++ b/resources/public/ocaml-dbg.html @@ -0,0 +1,45 @@ + + + + + KLIPSE: a simple and elegant online cljs compiler and evaluator + + + + +
+            
+let rec fib (n: int): int =
+  match n with
+    | 0 -> 1
+    | 1 -> 1
+    | _ -> (fib (n - 1)) + (fib (n - 2))
+
+let () =
+  Js.log (fib 9)
+            
+        
+

Transpilation

+
+            
+let rec fib (n: int): int =
+  match n with
+    | 0 -> 0
+    | 1 -> 1
+    | _ -> (fib (n - 1)) + (fib (n - 2))
+
+let () =
+  Js.log (fib 6)
+            
+        
+
+ + + + + diff --git a/src/klipse/lang/ocaml.cljs b/src/klipse/lang/ocaml.cljs new file mode 100644 index 00000000..9a760974 --- /dev/null +++ b/src/klipse/lang/ocaml.cljs @@ -0,0 +1,59 @@ +(ns klipse.lang.ocaml + (:require-macros + [gadjett.core :refer [dbg]] + [klipse.macros :refer [my-with-redefs]] + [purnam.core :refer [!>]] + [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]])) + +(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-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 + js/prettyFormat)))) + (catch :default o + (str o)))) + c)) + +(defn transpile-ocaml [exp _] + (go + (let [[_ res] (ocaml-to-js exp)] + res))) + +(def eval-opts {:editor-in-mode "text/x-ocaml" + :editor-out-mode "javascript" + :beautify? false + :eval-fn eval-ocaml + :external-scripts [(codemirror-mode-src "mllike") "https://viebel.github.io/klipse/repo/js/ocaml-compiler.js" "https://viebel.github.io/klipse/repo/js/pretty_format.js"] + ; oCaml does not know a single line comment + }) + +(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/ocaml-compiler.js"] + ; oCaml does not know a single line comment + }) + +(register-mode "eval-ocaml" "selector_eval_ocaml" eval-opts) +(register-mode "transpile-ocaml" "selector_transpile_ocaml" transpile-opts) diff --git a/src/klipse/run/all.cljs b/src/klipse/run/all.cljs index 1f4bb900..9002939f 100644 --- a/src/klipse/run/all.cljs +++ b/src/klipse/run/all.cljs @@ -9,4 +9,5 @@ klipse.lang.cpp klipse.lang.server-eval klipse.lang.php + klipse.lang.ocaml klipse.run.app.app)) diff --git a/src/klipse/run/plugin/plugin.cljs b/src/klipse/run/plugin/plugin.cljs index b1febedb..74154be5 100644 --- a/src/klipse/run/plugin/plugin.cljs +++ b/src/klipse/run/plugin/plugin.cljs @@ -13,6 +13,7 @@ klipse.lang.html klipse.lang.server-eval klipse.lang.clojure + klipse.lang.ocaml [klipse.plugin :as plugin])) (js/console.info "settings: " (aget js/window "klipse_settings")) diff --git a/src/klipse/run/plugin_prod/plugin.cljs b/src/klipse/run/plugin_prod/plugin.cljs index 68edc795..be328344 100644 --- a/src/klipse/run/plugin_prod/plugin.cljs +++ b/src/klipse/run/plugin_prod/plugin.cljs @@ -11,8 +11,9 @@ klipse.lang.server-eval klipse.lang.markdown klipse.lang.lambdaway - ; DO NOT include clojure it inflates the build sive and anyway it doesn't work with advanced compilation klipse.lang.clojure + ; DO NOT include clojure it inflates the build size and anyway it doesn't work with advanced compilation klipse.lang.clojure klipse.lang.html + klipse.lang.ocaml [klipse.plugin :as plugin])) (print "settings: " (aget js/window "klipse_settings"))