summaryrefslogtreecommitdiff
path: root/src/lisp
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2006-05-03 20:43:36 +0000
committerRich Hickey <richhickey@gmail.com>2006-05-03 20:43:36 +0000
commit0f37571e76e21f39e3c3696a5d591004dd572085 (patch)
treea2dff9d3af328fab7989e0ad8523dd7007079c5f /src/lisp
parent66a1be8e45bb2aac3efdefa50a028d0851b6c9e8 (diff)
added try
Diffstat (limited to 'src/lisp')
-rw-r--r--src/lisp/clojure.lisp54
-rw-r--r--src/lisp/test.lisp19
2 files changed, 71 insertions, 2 deletions
diff --git a/src/lisp/clojure.lisp b/src/lisp/clojure.lisp
index 73b295f2..c39bffde 100644
--- a/src/lisp/clojure.lisp
+++ b/src/lisp/clojure.lisp
@@ -15,7 +15,8 @@
"defn*" "def" "defn" "fn"
"if" "and" "or" "not" "when" "unless"
"block" "let" "let*" "letfn"
- "set" "pset" "set*" "do"))
+ "set" "pset" "set*" "do"
+ "try" "ex"))
(in-package "clojure")
@@ -415,7 +416,8 @@
(:and (emit-and context expr))
(:set (emit-set context expr))
(:loop (emit-loop context expr))
- (:break (emit-break context expr))))))
+ (:break (emit-break context expr))
+ (:try (emit-try context expr))))))
(defun emit-return (expr)
(format t "return ")
@@ -881,6 +883,53 @@
(:return
(emit :return (@ :result expr)))))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; try ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+#|
+(try
+ (body 1 2 3)
+ (some-catch-code-presuming-ex-bound-to-exception ...)
+ (do-something-finally))
+|#
+
+(defun analyze-try (context form)
+ (ccase context
+ ((:expression :fn)
+ (analyze :expression `((|fn*| (() ,form)))))
+ ((:statement :return)
+ (let* ((catch-clause (macroexpand (third form)))
+ (ex-binding (when catch-clause
+ (newobj :type :binding
+ :symbol '|ex|
+ :ex-name? t))))
+ (newobj :type :try
+ :body (analyze context (macroexpand (second form)))
+ :catch (when catch-clause
+ (let ((*var-env* *var-env*))
+ (register-local-binding ex-binding)
+ (add-to-var-env ex-binding)
+ (analyze context catch-clause)))
+ :ex ex-binding
+ :finally (analyze :statement (macroexpand (fourth form))))))))
+
+(defun emit-try (context expr)
+ (ccase context
+ ((:statement :return)
+ (let ((body (@ :body expr))
+ (catch-clause (@ :catch expr))
+ (ex (@ :ex expr))
+ (finally-clause (@ :finally expr)))
+ (format t "try{~%")
+ (emit context body)
+ (format t "}~%")
+ (when catch-clause
+ (format t "catch (Exception ~A){~%" (binding-name ex))
+ (emit context catch-clause)
+ (format t "}~%"))
+ (format t "finally{~%")
+ (emit :statement finally-clause)
+ (format t "}~%")))))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; defn ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun analyze-defn* (context form)
@@ -1123,6 +1172,7 @@
(unless (@ :param? b)
(setf (@ :id b) (get-next-id))
(unless (or (@ :anonymous-lambda? b)
+ (@ :ex-name? b)
(will-be-static-method b))
(emit-binding-declaration b))))
diff --git a/src/lisp/test.lisp b/src/lisp/test.lisp
index 128eecda..16c43539 100644
--- a/src/lisp/test.lisp
+++ b/src/lisp/test.lisp
@@ -85,3 +85,22 @@
(defn fg (x)
y)
+
+(defn ftry (x)
+ (try
+ (foo x)
+ nil
+ (bar x))
+ (try
+ (let ((ex x))
+ (try
+ (foo x)
+ (fred ex)
+ (bar x)))
+ (foo x)
+ (fred ex)
+ (bar x))
+ (try
+ (foo x)
+ (fred ex)
+ (bar x))) \ No newline at end of file