[gambit-list] Universal library improvements

Marc Feeley feeley at iro.umontreal.ca
Sun Mar 22 23:49:29 EDT 2020

With the most recent changes to the universal backend and library, Gambit's JavaScript and Python backends are now much easier to use.

The following steps will build and install the universal library with the JavaScript and Python backends:

  % make
  % make _gambit.js _gambit.py
  % make install

Scheme programs can be compiled to either JavaScript or Python shell scripts by specifying the -exe flag and the target language to gsc:

  % gsc -target js -o fib-js -exe fib.scm
  % ./fib-js
  (time (f 30))
      0.076000 secs real time
      0.076000 secs cpu time (0.076000 user, 0.000000 system)
      no collections
      no bytes allocated
      no minor faults
      no major faults
  % cat fib.scm
  (declare (standard-bindings))
  (define (f n) (if (< n 2) n (+ (f (- n 1)) (f (- n 2)))))
  (println (time (f 30)))

It is also possible to build a version of the Gambit interpreter implemented in JavaScript with:

  % gsc -target js -o gsi-js -exe -prelude '(include"../lib/header.scm")' gsi/_gsi.scm

Replacing "js" with "python" will build gsi implemented in Python:

  % ./gsi-python
  Gambit v4.9.3
  > (host-decl "import os")
  > (define (env var) (host-eval "g_host2scm(os.environ[g_scm2host(@1@)])" var))
  > (env "TERM")
  > ,q

  % ./gsi-js
  Gambit v4.9.3
  > (define (f n) (if (< n 2) n (+ (f (- n 1)) (f (- n 2)))))
  > (time (f 30))
  (time (f 30))
      2.254000 secs real time
      2.254000 secs cpu time (2.254000 user, 0.000000 system)
      no collections
      no bytes allocated
      no minor faults
      no major faults
  > (apropos 'inexact)
  "##" namespace:
    exact->inexact, fail-check-inexact-real, fail-check-inexact-real-list,
    flonum->inexact-exponential-format, inexact, inexact->exact, inexact?
  empty namespace:
    exact->inexact, inexact, inexact->exact, inexact?
  > (define (show x) (host-exec "console.log(g_scm2host(@1@));" x))
  > (show "hello")
  > (show (host-eval "g_host2scm(new Date().toString())"))
  Sun Mar 22 2020 23:20:29 GMT-0400 (GMT-04:00)
  > ,q

The universal library is quite large (> 30MB)... so the memory conscious may choose to link with a custom runtime library that defines only the procedures needed.  The compiler's -l flag is useful to specify the library to link with.

  ;;; minlib.scm

  (println "running minlib.scm")

  (define (twice thunk) ;; exported procedure

  (define (##run-each-module)
    (declare (extended-bindings) (not safe))
    (let ((mods (##vector-ref ##program-descr 0)))
      (let loop ((i 1)) ;; start at module after the current one
        (if (##fx< i (##vector-length mods))
            (let ((mod (##vector-ref mods i)))
              ((##vector-ref mod 4)) ;; call module's init procedure
              (loop (##fx+ i 1)))))))

  (##run-each-module) ;; run each module (after the current one)

  ;; To use this minimal library to compile a program prog.scm,
  ;; follow these steps:
  ;;   % cat prog.scm
  ;;   (twice (lambda () (println "hello")))
  ;;   % TARGET=js    # could also be python or php
  ;;   % gsc -target $TARGET -c minlib.scm
  ;;   % gsc -target $TARGET -l minlib -exe prog.scm
  ;;   % ./prog
  ;;   running minlib.scm
  ;;   hello
  ;;   hello
  ;;   % head -1 prog
  ;;   #! /usr/bin/env node

There are still some issues with the universal backend, but it is now much closer to the features offered by the C backend.


More information about the Gambit-list mailing list