[gambit-list] Javascript Backend

Marc Feeley feeley at iro.umontreal.ca
Thu Mar 6 02:22:53 EST 2014


On Mar 5, 2014, at 5:19 PM, Bob Coleman <bobcolem at yahoo.com> wrote:

> Greetings,
> 
> I have been playing around with the javascript backend and have been impressed with it's capabilities.

I’m glad you like it.  Over the past week I have made several enhancements with the short term goal of implementing a remote debugger (so that Scheme code running in the browser can be debugged live using a REPL running on the server).  Just a few minutes ago I committed the support for first-class continuations which are needed for the exception handling of the REPL.

>  Interacting with other javascript libraries is not a problem, but I haven't found a way for other javascript code to call scheme defined functions.  Is there a way to define functions to be called by javascript similar to c-lambda or c-define?

It is quite easy to interface to JavaScript functions from Scheme.  In fact, using JavaScript’s eval gives a much simpler approach than using Gambit’s C interface for the C back-end.  For example, you can define

 (define js
   (##inline-host-expression "Gambit_js2scm(eval)"))

This creates a Scheme callable function which performs a JavaScript eval.  Then, in your code you can say:

 (define alert (js "alert"))
 (alert "hello!")

This will “convert” the JavaScript “alert” function to a Scheme function.

For the other way around (exporting a Scheme function callable from JavaScript), the js function can be used like this:

 (define setglo (js "function (name,val) { window[name] = val; }"))

then

 (setglo "foo" (lambda (n) (* n n)))

And then in JavaScript land your can call (foo 10).

> Also, is it possible to access the value of the -target flag in scheme?  I would like to define some functions differently based on whether the program is being built for the C or javascript backend.

Define this macro:

 (##define-macro (case-target . clauses)
   (let ((target (if (and (pair? ##compilation-options)
                          (pair? (car ##compilation-options)))
                     (let ((t (assq 'target ##compilation-options)))
                       (if t (cadr t) 'c))
                     'c)))
     (let loop ((clauses clauses))
       (if (pair? clauses)
           (let* ((clause (car clauses))
                  (cases (car clause)))
             (if (or (eq? cases 'else)
                     (memq target cases))
                 `(begin ,@(cdr clause))
                 (loop (cdr clauses))))
           `(begin)))))

and use it like this:

 (case-target
   ((c)
    (define foo (c-lambda () int "foo")))
   ((js)
    (define foo (lambda () (##inline-host-expression "42")))))

Marc





More information about the Gambit-list mailing list