diff options
author | Rich Hickey <richhickey@gmail.com> | 2006-04-30 18:58:58 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2006-04-30 18:58:58 +0000 |
commit | e7f3719fcbe74e0f923243f9628f7450ebed2e4f (patch) | |
tree | db6b2d5daa706ba366ec56816dbd81139a7c16bf /src | |
parent | 96db6cebb28b28f30fdc9b7232a8172a18f52ace (diff) |
added if
Diffstat (limited to 'src')
-rw-r--r-- | src/lisp/clojure.lisp | 58 | ||||
-rw-r--r-- | src/lisp/test.lisp | 8 |
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 |