summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2006-04-30 18:58:58 +0000
committerRich Hickey <richhickey@gmail.com>2006-04-30 18:58:58 +0000
commite7f3719fcbe74e0f923243f9628f7450ebed2e4f (patch)
treedb6b2d5daa706ba366ec56816dbd81139a7c16bf /src
parent96db6cebb28b28f30fdc9b7232a8172a18f52ace (diff)
added if
Diffstat (limited to 'src')
-rw-r--r--src/lisp/clojure.lisp58
-rw-r--r--src/lisp/test.lisp8
2 files changed, 65 insertions, 1 deletions
diff --git a/src/lisp/clojure.lisp b/src/lisp/clojure.lisp
index a2b0f7ea..9e89ac9a 100644
--- a/src/lisp/clojure.lisp
+++ b/src/lisp/clojure.lisp
@@ -345,6 +345,61 @@
(let ((*standard-output* s))
,@body)))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; if ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun analyze-if (context form)
+ (if (eql (second form) '|t|)
+ ;optimize macro-generated (if t ...) forms
+ (analyze context (macroexpand (third form)))
+ (let* ((test (analyze :expression (macroexpand (second form))))
+ (negate (eql :not (@ :type test))))
+ (newobj :type :if
+ :test (if negate (@ :expr test) test)
+ :comp (if negate "==" "!=")
+ :then (analyze context (macroexpand (third form)))
+ :else (when (fourth form)
+ (analyze context (macroexpand (fourth form))))
+ :else-p (= 4 (length form))))))
+
+(defun emit-if (context expr)
+ (let ((test (@ :test expr))
+ (then (@ :then expr))
+ (else (@ :else expr))
+ (else-p (@ :else-p expr))
+ (comp (@ :comp expr)))
+ (ccase context
+ (:expression
+ (format t "(")
+ (emit :expression test)
+ (format t " ~A null?" comp)
+ (emit :expression then)
+ (format t ":")
+ (emit :expression else)
+ (format t ")"))
+ (:statement
+ (format t "if(")
+ (emit :expression test)
+ (format t " ~A null)~%{~%" comp)
+ (emit context then)
+ (format t "}~%")
+ (when (and else-p else)
+ (format t "else~%{~%")
+ (emit context else)
+ (format t "}~%")))
+ (:return
+ (format t "if(")
+ (emit :expression test)
+ (format t " ~A null)~%{~%" comp)
+ (emit context then)
+ (format t "}~%")
+ (format t "else~%{~%")
+ (if else-p
+ (emit context else)
+ (format t "return null;~%"))
+ (format t "}~%")))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; invoke ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
(defun analyze-invoke (context op form)
(declare (ignore context))
;if we hit this unspecialized method, it is not a special op, presume function invocation
@@ -409,7 +464,8 @@
(:global-binding (emit-global-binding context expr))
(:block (emit-block context expr))
(:invoke (emit-invoke context expr))
- (:let (emit-let context expr))))))
+ (:let (emit-let context expr))
+ (:if (emit-if context expr))))))
(defun emit-return (expr)
(format t "return ")
diff --git a/src/lisp/test.lisp b/src/lisp/test.lisp
index f3427df2..37b550e0 100644
--- a/src/lisp/test.lisp
+++ b/src/lisp/test.lisp
@@ -40,4 +40,12 @@
(d (x) (d a)))
(c x)))
+
+(defn fif (a b x y z)
+ (if a
+ (if (if x y z)
+ y
+ z)
+ b))
+
(defn fr (a b & c) c) \ No newline at end of file