summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/clj/clojure/core.clj28
-rw-r--r--src/clj/clojure/main.clj1
-rw-r--r--src/jvm/clojure/lang/RT.java1
3 files changed, 25 insertions, 5 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index e8068dff..ba674763 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -2607,7 +2607,7 @@
(even? (count bindings)) "an even number of forms in binding vector")
`(let* ~(destructure bindings) ~@body))
-;redefine fn with destructuring
+;redefine fn with destructuring and pre/post conditions
(defmacro fn
"(fn name? [params* ] exprs*)
(fn name? ([params* ] exprs*)+)
@@ -2623,9 +2623,26 @@
sigs (if name (next sigs) sigs)
sigs (if (vector? (first sigs)) (list sigs) sigs)
psig (fn [sig]
- (let [[params & body] sig]
+ (let [[params & body] sig
+ conds (when (and (next body) (map? (first body)))
+ (first body))
+ body (if conds (next body) body)
+ conds (or conds ^params)
+ pre (:pre conds)
+ post (:post conds)
+ body (if post
+ `((let [~'% ~(if (< 1 (count body))
+ `(do ~@body)
+ (first body))]
+ ~@(map (fn [c] `(assert ~c)) post)
+ ~'%))
+ body)
+ body (if pre
+ (concat (map (fn [c] `(assert ~c)) pre)
+ body)
+ body)]
(if (every? symbol? params)
- sig
+ (cons params body)
(loop [params params
new-params []
lets []]
@@ -2794,8 +2811,9 @@
"Evaluates expr and throws an exception if it does not evaluate to
logical true."
[x]
- `(when-not ~x
- (throw (new Exception (str "Assert failed: " (pr-str '~x))))))
+ (when *assert*
+ `(when-not ~x
+ (throw (new Exception (str "Assert failed: " (pr-str '~x)))))))
(defn test
"test [v] finds fn at key :test in var metadata and calls it,
diff --git a/src/clj/clojure/main.clj b/src/clj/clojure/main.clj
index ee185afe..6bd798da 100644
--- a/src/clj/clojure/main.clj
+++ b/src/clj/clojure/main.clj
@@ -27,6 +27,7 @@
*print-level* *print-level*
*compile-path* (System/getProperty "clojure.compile.path" "classes")
*command-line-args* *command-line-args*
+ *assert* *assert*
*1 nil
*2 nil
*3 nil
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index 728a2a76..d0cb01f6 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -179,6 +179,7 @@ final static public Var ERR =
final static Keyword TAG_KEY = Keyword.intern(null, "tag");
final static public Var AGENT = Var.intern(CLOJURE_NS, Symbol.create("*agent*"), null);
final static public Var READEVAL = Var.intern(CLOJURE_NS, Symbol.create("*read-eval*"), T);
+final static public Var ASSERT = Var.intern(CLOJURE_NS, Symbol.create("*assert*"), T);
final static public Var MACRO_META = Var.intern(CLOJURE_NS, Symbol.create("*macro-meta*"), null);
final static public Var MATH_CONTEXT = Var.intern(CLOJURE_NS, Symbol.create("*math-context*"), null);
static Keyword LINE_KEY = Keyword.intern(null, "line");