For an example, see the code for SRFI 41: 41.scm
contains
(define-procedure
(stream-car (strm stream))
(if (stream-null? strm)
(error-stream-null 'stream-car))
(stream-force (stream-car* (stream-force strm))))
which expands to
(define stream-car
(lambda (%strm) (if (stream? %strm) (begin (if (stream-null? %strm) (##error 'stream-car "null-stream argument") #!void) (stream-force (stream-car* (stream-force %strm)))) (##fail-check-stream '(1 . strm) stream-car %strm))))
It's a poor man's way to automatically add type checks to the arguments of a procedure.
(apropos)
in the normal REPL I get some procedure names, but I am not sure which one is available in js runtime
@amirouche I’m not sure what you mean by the “normal REPL” but if you execute (apropos)
in the web app REPL then you will get the procedures defined in the web app’s Scheme library. Unfortunately the web app’s REPL will only show the last few lines of output, so you might want to evaluate this instead (tested on the last page of https://udem-dlteam.github.io/webapp-tutorial):
(define (show thunk)
(host-exec
"var text = g_scm2host(@1@);
var parent = document.querySelector('.slide.present') || document.body;
var elem = document.createElement('textarea');
elem.style = 'position: absolute; font-family: monospace; font-size: 10px; height: 500px; width: 500px; left: 0px; top: 0px; z-index: 99999; overflow-y: scroll;';
elem.value = text;
elem.addEventListener('dblclick', function (event) { event.target.parentNode.removeChild(event.target); });
parent.appendChild(elem);"
(with-output-to-string thunk)))
(show (lambda () (apropos "" (current-output-port))))
You’ll see that most of the procedures of the C backend’s Gambit library are available. Obviously some “desktop OS specific” functionality is not implemented :
> (shell-command "ls")
unimplemented ##os-environ called
*** ERROR IN (console)@1.1 -- Unknown error
(shell-command "ls")
host-exec
is a macro that is specific to the universal library. Look for "Host FFI" in lib/_univlib.scm
. There is an implementation for the JS and Python backends (languages that have a run time eval
construct). If you want to avoid host-exec
then use ##inline-host-expression
which has the same API but is static (you can’t (eval '(##inline-host-expression …))
)
% cat index.scm
(define (show thunk)
(host-exec
"var text = g_scm2host(@1@);
var parent = document.querySelector('.slide.present') || document.body;
var elem = document.createElement('textarea');
elem.style = 'position: absolute; font-family: monospace; font-size: 10px; height: 500px; width: 500px; left: 0px; top: 0px; z-index: 99999; overflow-y: scroll;';
elem.value = text;
elem.addEventListener('dblclick', function (event) { event.target.parentNode.removeChild(event.target); });
parent.appendChild(elem);"
(with-output-to-string thunk)))
(show (lambda () (apropos "" (current-output-port))))
% cat ../../scm2js.sh
#!/bin/sh
docker run -v $(pwd):/mnt --rm -it schemers/gambit:head gsc -target js -exe /mnt/$1
tail -n +2 $(basename $1 .scm) > "$(basename $1 .scm).js"
rm -f $(basename $1 .scm)
% ../../scm2js.sh index.scm
% node index.js
*** ERROR -- Operator is not a PROCEDURE
(#!void
"var text = g_scm2host(@1@);\n var parent = document.querySelector('.sl...
"\"##\" namespace:\n *, *2, +, |+2|, -, |-2|, /, /2, <, <2, <=, =, =2, >, ...
)
>
*** EOF again to exit
%
host-exec
is usable only in eval
eval
works :)
#ifdef
in C, and export dummies if not present?
I'm getting a failed unit test from make check
when trying to build the Gambit master branch with the options:
./configure --prefix=/usr/local/gambit
--enable-single-host
--enable-multiple-versions
--enable-shared
--enable-smp
--enable-gcc-opts
--enable-openssl
--enable-absolute-shared-libs
--enable-poll
--enable-bignum
The relevant make check
output is:
LD_LIBRARY_PATH=../lib:../gsi:../gsc: ../gsi/gsi -:tl,~~bin=../bin,~~lib=../lib,~~include=../include -f ./run-unit-tests.scm
[226| 0] 90% ##############.. 6.9s 13-modules/prim_exception.scm
*** FAILED 13-modules/prim_exception.scm WITH EXIT CODE HI=1 LO=0
(with-exception-handler ##list (lambda () (##cons 1 (##raise 123)))) in (include "~~lib/gambit/prim/exception#.scm") returned #<unbound-global-exception #2> but expected (1 123)
(with-exception-handler ##list (lambda () (##cons 1 (##raise 123)))) in (namespace ("##")) returned #<unbound-global-exception #3> but expected (1 123)
[250| 1] 100% ################ 7.5s
FAILED 1 UNIT TESTS OUT OF 251 (.4%)
This is my first time building Gambit with this many options. Any insights to share on why this might be happening?
(define-structure point x)
expands to
gsc -c -expansion crap.scm
Expansion:
(define ##type-1-point
('#<procedure #2 ##structure> ##type-type ('#<procedure #3 ##string->uninterned-symbol> "##type-1-point") 'point 8 #f #(x 0 #f)))
(define make-point (lambda (p1) ('#<procedure #2 ##structure> ##type-1-point p1)))
(define point-copy (lambda (obj) (##structure-copy obj)))
(define point? (lambda (obj) ('#<procedure #4 ##structure-direct-instance-of?> obj ('#<procedure #5 ##type-id> ##type-1-point))))
(define point-x
(lambda (obj)
(let ((temp.3 point-x) (temp.2 ##type-1-point))
(if ('#<procedure #4 ##structure-direct-instance-of?> obj ('#<procedure #5 ##type-id> temp.2))
('#<procedure #6 ##unchecked-structure-ref> obj 1 temp.2 temp.3)
('#<procedure #7 ##direct-structure-ref> obj 1 temp.2 temp.3)))))
(define point-x-set!
(lambda (obj val)
(let ((temp.8 point-x-set!) (temp.7 ##type-1-point))
(if ('#<procedure #4 ##structure-direct-instance-of?> obj ('#<procedure #5 ##type-id> temp.7))
('#<procedure #8 ##unchecked-structure-set!> obj val 1 temp.7 temp.8)
('#<procedure #9 ##direct-structure-set!> obj val 1 temp.7 temp.8)))))
(define point-x-set (lambda (obj val) (##direct-structure-set obj val 1 ##type-1-point point-x-set)))
How do I get rid of point-copy
? I want to define my own with that name.
feeley on master
This adds --enable-c-opt-rts to… Merge pull request #684 from ia… (compare)