[gambit-list] Compiling to Javascript

Marc Feeley feeley at iro.umontreal.ca
Fri Jul 5 06:46:44 EDT 2019


I’m currently working on implementing an intelligent linker that can remove the parts of the runtime library that are not needed by the application.  For the moment, to get a compact executable you need to write your own runtime library for the functions you need.  If you only need basic stuff, this may be a reasonable undertaking.

Below is a sample application split in 2 files: “lib.scm” is the runtime library and “app.scm” is the main program.  The library contains definitions of for-each, append, etc.  Note that some operations like fx+, fx-, fx<, cons, car, cdr, println don’t need to be defined because the Gambit compiler treats them as inlined primitives (they compile to the corresponding JavaScript code instead of being actual Scheme procedure calls).

Here is how this application is linked, and the result of executing the app:

% make
gsc -target js -c lib.scm
gsc -target js -c app.scm
gsc -target js -link -l lib app.js
gsc -target js -c lib.scm
cat app_.js lib.js app.js > linked_app.js
wc *.js
     339     870    7244 app.js
     651    1931   14992 app_.js
     335     853    7937 lib.js
    1325    3654   30173 linked_app.js
    2650    7308   60346 total
node linked_app.js
>>> lib.scm
>>> app.scm
1
1
2
3
5
8
410
9227465

The JavaScript code is 30K bytes, and half of that is in app_.js that is the runtime system (which won’t grow much if the application is bigger).

Aside from the intelligent linker, a more compact code could be obtained by minimizing the JavaScript code either with an external minimizer or by reducing the size of the identifiers that are emitted by the compiler and not pretty-printing the JavaScipt code which adds lots of spaces for indentation.

Marc



------------------------------------------------------------
# makefile

#GSC=../gsc/gsc -:=.. -target js
GSC=gsc -target js

all: run

lib.js: lib.scm
	$(GSC) -c lib.scm

app.js: app.scm
	$(GSC) -c app.scm

app_.js: lib.js app.js
	$(GSC) -link -l lib app.js

linked_app.js: lib.js app.js app_.js
	$(GSC) -c lib.scm
	cat app_.js lib.js app.js > linked_app.js
	wc *.js

run: linked_app.js
	node linked_app.js

clean:
	rm -f lib.js app.js app_.js linked_app.js
------------------------------------------------------------
;; file: lib.scm

(declare (standard-bindings) (extended-bindings) (not safe) (not run-time-bindings))

(println ">>> lib.scm")

(define (for-each f lst)
  (if (pair? lst)
      (begin
        (f (car lst))
        (for-each f (cdr lst)))))

(define (append lst1 lst2)
  (if (pair? lst1)
      (cons (car lst1) (append (cdr lst1) lst2))
      lst2))

(define (current-milliseconds)
  (##inline-host-expression "Date.now()"))

(define (js-alert obj)
  (##inline-host-statement "alert(g_scm2js(@1@));" obj))

(app#) ;; execute app.scm module
------------------------------------------------------------
;; file: app.scm

(declare (standard-bindings) (extended-bindings) (not safe) (not run-time-bindings))

(println ">>> app.scm")

(define (fib n) (if (fx< n 2) n (fx+ (fib (fx- n 1)) (fib (fx- n 2)))))

(for-each
 (lambda (x)
   (println (fib x)))
 (append '(1 2 3)
         '(4 5 6)))

(let* ((start (current-milliseconds))
       (result (fib 35))
       (end (current-milliseconds)))
  (js-alert (fx- end start))
  (js-alert result))
------------------------------------------------------------


> On Jun 29, 2019, at 10:59 AM, hashavtech at outlook.com wrote:
> 
> There are some messages in 2013 and 2016 that gave me a hint of what needs to be done in order to compile to js. But it seems that some things have changed (for example the gsc with -target js does not seem to produce a .js file, it gave me an .o1 file that contained Javascript). I was able to compile a working example once but the .js file contains the whole _gambit.js library and is 22 MB in size. That isn't really what I was hoping for. I've seen it mentioned that there was some work done on only including the necessary parts of the library, but I was unable to figure out how to do it (I'm new to Gambit although not to Lisp). 
> 
> I'd be glad for some help getting from a Scheme file to a working and reasonably-sized file. My goal is to include scheme-sourced parts in a web app, so there probably will be some interoperability issues, but at the moment I'm stuck at the compilation stage.
> 
> _______________________________________________
> Gambit-list mailing list
> Gambit-list at iro.umontreal.ca
> https://mailman.iro.umontreal.ca/cgi-bin/mailman/listinfo/gambit-list





More information about the Gambit-list mailing list