Implement CATCH and THROW
[jscl.git] / ecmalisp.lisp
index 2ee17ec..ebfe885 100644 (file)
       (concat "(function(){" *newline*
               (indent "try {" *newline*
                       (indent "return " (ls-compile `(progn ,@body)
-                                                    (extend-lexenv b env 'block))) ";" *newline*
+                                                    (extend-lexenv b env 'block))
+                              ";" *newline*)
                       "}" *newline*
                       "catch (cf){" *newline*
                       "    if (cf.type == 'block' && cf.id == " tr ")" *newline*
                 "})})()")
         (error (concat "Unknown block `" (symbol-name name) "'.")))))
 
+
+(define-compilation catch (id &rest body)
+  (concat "(function(){" *newline*
+          (indent "var id = " (ls-compile id env) ";" *newline*
+                  "try {" *newline*
+                  (indent "return " (ls-compile `(progn ,@body))
+                          ";" *newline*)
+                  "}" *newline*
+                  "catch (cf){" *newline*
+                  "    if (cf.type == 'catch' && cf.id == id)" *newline*
+                  "        return cf.value;" *newline*
+                  "    else" *newline*
+                  "        throw cf;" *newline*
+                  "}" *newline*)
+          "})()"))
+
+(define-compilation throw (id &optional value)
+  (concat "(function(){ throw ({"
+          "type: 'catch', "
+          "id: " (ls-compile id env) ", "
+          "value: " (ls-compile value env) ", "
+          "message: 'Throw uncatched.'"
+          "})})()"))
+
+
 ;;; A little backquote implementation without optimizations of any
 ;;; kind for ecmalisp.
 (defun backquote-expand-1 (form)