Skip to content

Commit

Permalink
* src/clj/cljs/compiler.clj: add no-op to the compiler. allow (set! *…
Browse files Browse the repository at this point in the history
…unchecked-math* true/false) just like Clojure.
  • Loading branch information
swannodette committed Jan 29, 2012
1 parent 4257e06 commit 9da2402
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 21 deletions.
41 changes: 27 additions & 14 deletions src/clj/cljs/compiler.clj
Expand Up @@ -9,11 +9,12 @@
(set! *warn-on-reflection* true)

(ns cljs.compiler
(:refer-clojure :exclude [munge macroexpand-1])
(:refer-clojure :exclude [munge macroexpand-1 *unchecked-math*])
(:require [clojure.java.io :as io]
[clojure.string :as string]))

(declare resolve-var)
(def ^:dynamic *unchecked-math* (atom false))
(require 'cljs.core)

(def js-reserved
Expand Down Expand Up @@ -237,6 +238,9 @@
~@body
(when-not (= :expr (:context env#)) (print ";\n"))))

(defmethod emit :no-op [m]
(println "null;"))

(defmethod emit :var
[{:keys [info env] :as arg}]
(emit-wrap env (print (munge (:name info)))))
Expand Down Expand Up @@ -788,21 +792,30 @@
[_ env [_ target val] _]
(disallowing-recur
(let [enve (assoc env :context :expr)
targetexpr (if (symbol? target)
(do
(let [local (-> env :locals target)]
(assert (or (nil? local)
(and (:field local)
(:mutable local)))
"Can't set! local var or non-mutable field"))
(analyze-symbol enve target))
(when (seq? target)
(let [targetexpr (analyze-seq enve target nil)]
(when (:field targetexpr)
targetexpr))))
targetexpr (cond
(= target '*unchecked-math*)
(do
(reset! *unchecked-math* val)
::set-unchecked-math)

(symbol? target)
(do
(let [local (-> env :locals target)]
(assert (or (nil? local)
(and (:field local)
(:mutable local)))
"Can't set! local var or non-mutable field"))
(analyze-symbol enve target))

:else (when (seq? target)
(let [targetexpr (analyze-seq enve target nil)]
(when (:field targetexpr)
targetexpr))))
valexpr (analyze enve val)]
(assert targetexpr "set! target must be a field or a symbol naming a var")
{:env env :op :set! :target targetexpr :val valexpr :children [targetexpr valexpr]})))
(if (= targetexpr ::set-unchecked-math)
{:env env :op :no-op}
{:env env :op :set! :target targetexpr :val valexpr :children [targetexpr valexpr]}))))

(defmethod parse 'ns
[_ env [_ name & args] _]
Expand Down
9 changes: 2 additions & 7 deletions src/clj/cljs/core.clj
Expand Up @@ -61,11 +61,6 @@
(defmacro aset [a i v]
(list 'js* "(~{}[~{}] = ~{})" a i v))

(def ^:dynamic *js-unchecked-arithmetic* (atom false))

(defmacro set-unchecked-arithmetic! [v]
(reset! *js-unchecked-arithmetic* v))

;; arith-ops and def-arith-op-errors are helpers to help
;; prevent code bloat from checked math ops

Expand All @@ -85,7 +80,7 @@
(let [return-expr (if (seq args)
`(~'js* ~expr ~@args)
`(~'js* ~expr))]
(if @*js-unchecked-arithmetic*
(if @cljs.compiler/*unchecked-math*
return-expr
`(if (~'js* ~(s/join " && " (repeat (count args) "typeof ~{} == 'number'")) ~@args)
~return-expr
Expand All @@ -111,7 +106,7 @@
(defmacro /
([x] `(/ 1 ~x))
([x y] (let [expr (check-numbers "(~{} / ~{})" '/ x y)]
(if @*js-unchecked-arithmetic*
(if @cljs.compiler/*unchecked-math*
expr
`(if (zero? ~y)
(throw (js/Error. "Arithmetic exception: divide by zero"))
Expand Down

0 comments on commit 9da2402

Please sign in to comment.