Implement ecmascript try/catch using with-exception-handler/rais-exception respectively so that it is straight-forward to interact with ecmascript exceptions from scheme.
* module/language/ecmascript/compile-tree-il.scm: Compile try/catch * module/language/ecmascript/impl.scm: Provide js-try and js-catch procedures --- .../language/ecmascript/compile-tree-il.scm | 25 +++++++++++++++++++ module/language/ecmascript/impl.scm | 18 ++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/module/language/ecmascript/compile-tree-il.scm b/module/language/ecmascript/compile-tree-il.scm index 074674142..6f6af5210 100644 --- a/module/language/ecmascript/compile-tree-il.scm +++ b/module/language/ecmascript/compile-tree-il.scm @@ -355,6 +355,31 @@ ,(with-return-prompt (lambda () (comp-body e body formals syms)))))))) + ((try (block . ,body) + (catch ,err (block . ,catch)) + ,finally) + (let ((err-sym (gensym (symbol->string err)))) + `(call ,(@implv js-try) + (lambda () + (lambda-case + ((() #f #f #f () ()) + (begin ,@(map (lambda (x) (comp x e)) body))))) + (lambda ((,err . ,err-sym)) + (lambda-case + (((,err) #f #f #f () (,err-sym)) + ,(let ((e (econs err err-sym e))) + `(begin ,@(map (lambda (x) (comp x e)) catch)))))) + (lambda () + (lambda-case + ((() #f #f #f () ()) + ,(pmatch/source finally + ((finally (block . ,finally)) + `(begin ,@(map (lambda (x) (comp x e)) finally))) + (#f '(void)) + (else (error "syntax error: invalid try statement: " x))))))))) + ((throw ,expr) + `(call ,(@implv js-throw) + ,(comp expr e))) ((call/this ,obj ,prop . ,args) (@impl call/this* obj diff --git a/module/language/ecmascript/impl.scm b/module/language/ecmascript/impl.scm index 27c077aed..b1be63403 100644 --- a/module/language/ecmascript/impl.scm +++ b/module/language/ecmascript/impl.scm @@ -33,7 +33,9 @@ shift mod band bxor bior - make-enumerator)) + make-enumerator + js-throw + js-try)) (define-class <js-module-object> (<js-object>) @@ -87,6 +89,20 @@ (fluid-set! *this* (make <js-global-object>)) (init-js-bindings! (current-module))))) +(define (js-throw obj) + (raise-exception obj #:continuable? #t)) + +(define (js-try body-thunk catch-handler finally-thunk) + (with-exception-handler (lambda (e) + (catch-handler e) + (finally-thunk) + *undefined*) + (lambda () + (body-thunk) + (finally-thunk) + *undefined*) + #:unwind? #t)) + (define (get-this) (fluid-ref *this*)) -- 2.29.1