feeley on master
CI: use gcc-11 on macOS (gcc-9 … (compare)
feeley on master
Create temp dir in /tmp when no… (compare)
gambiteer on master
Correct test directories and fi… (compare)
$ gsc -v
v4.9.3 20180930122740 x86_64-unknown-linux-gnu "./configure '--prefix=/nix/store/w3pg7qf91b63yp5qr1pp3cxyfrww0hvw-gambit-4.9.3/gambit' ..."
$ gsc -h
*** WARNING -- Unknown or improperly placed -h option
this happens for many other flags, it's a clean install on nixos btw
@twoplustwo:matrix.org Take number->string
… the first parameter (a number) is required, and the second parameter is optional (a number that is the base) and you cannot pass more than 2 parameters:
> (number->string 42)
"42"
> (number->string 42 2)
"101010"
> (number->string 42 2 111 222 333)
*** ERROR IN (stdin)@3.1 -- Wrong number of arguments passed to procedure
(number->string 42 2 111 222 333)
But sometimes you want to accept any number of parameters, for example the -
procedures requires one parameter, but can have any number of additional parameters:
> (- 5)
-5
> (- 5 2)
3
> (- 5 2 1)
2
> (- 5 2 1 111 222 333)
-664
For this situation you need to define the procedure using a rest parameter which will be a list of all the remaining parameters:
> (define (- first . rest) (list 'first= first 'rest= rest))
> (- 5)
(first= 5 rest= ())
> (- 5 2 1 111 222 333)
(first= 5 rest= (2 1 111 222 333))
> (define (a x y #!optional z) (list 'x= x 'y= y 'z= z))
> (define (b x y #!optional z #!rest rest) (list 'x= x 'y= y 'z= z 'rest= rest))
> (a 1 2)
(x= 1 y= 2 z= #f)
> (a 1 2 3)
(x= 1 y= 2 z= 3)
> (a 1 2 3 4)
*** ERROR IN (stdin)@5.1 -- Wrong number of arguments passed to procedure
(a 1 2 3 4)
1> ,t
> (b 1 2)
(x= 1 y= 2 z= #f rest= ())
> (b 1 2 3)
(x= 1 y= 2 z= 3 rest= ())
> (b 1 2 3 4)
(x= 1 y= 2 z= 3 rest= (4))
> (b 1 2 3 4 5)
(x= 1 y= 2 z= 3 rest= (4 5))
(define (h1 a #!rest r #!key k) (list a k r))
is this possible?
> (define (foo x #!key y z . rest) (list 'x= x 'y= y 'z= z 'rest= rest))
> (foo 1)
(x= 1 y= #f z= #f rest= ())
> (foo 1 z: 2)
(x= 1 y= #f z= 2 rest= ())
> (foo 1 z: 2 y: 3)
(x= 1 y= 3 z= 2 rest= ())
> (foo 1 z: 2 y: 3 4)
(x= 1 y= 3 z= 2 rest= (4))
> (foo 1 z: 2 y: 3 4 5)
(x= 1 y= 3 z= 2 rest= (4 5))
(define (string-substitute str delim proc-or-alist)
(define (index-of c start)
(let loop ((i start))
(if (fx< i (string-length str))
(if (char=? c (string-ref str i))
i
(loop (fx+ i 1)))
i)))
(let loop ((i 0) (j 0) (out '()))
(let ((start (index-of delim j)))
(if (fx< start (string-length str))
(let ((end (index-of delim (fx+ start 1))))
(if (fx< end (string-length str))
(if (fx= start (fx- end 1)) ;; two delimiters in a row?
(loop (fx+ end 1)
(fx+ end 1)
(cons (substring str i end)
out))
(let* ((var
(substring str (fx+ start 1) end))
(subst
(if (procedure? proc-or-alist)
(proc-or-alist var)
(let ((x (assoc var proc-or-alist)))
(and x (cdr x))))))
(if subst
(loop (fx+ end 1)
(fx+ end 1)
(cons subst
(cons (substring str i start)
out)))
(error "Unbound substitution variable in" str))))
(error "Unbalanced delimiter in" str)))
(string-concatenate
(reverse (cons (substring str i start) out)))))))
(pp (string-substitute "@a@ plus 1 is @b@" #\@ '(("a" ."two") ("b" . "three"))))
Hello, I'm trying gambit for the first time, starting with the javascript support in 4.9.4. I am able to reproduce the instructions at
http://www.gambitscheme.org/latest/manual/#Compiling-Modules
However, if I change much from that basic scenario, stuff stops working. For example, here is my attempt to extend to importing SRFI 78:
git clone https://github.com/scheme-requests-for-implementation/srfi-78
cat srfi-78/srfi-78.sld
(define-library (srfi-78)
(import (scheme base))
(export hello-world)
(include "check.scm")
(begin
(define (hello-world)
(display "hello world\n"))
))
cat hello-test/hello-test.sld
(define-library (hello-test)
(import (srfi-78) (scheme base) (scheme write))
(begin
(display
(cond-expand
((compilation-target C) "compiled to C\n")
((compilation-target (_)) "interpreted\n")
(else "compiled to other\n")))
(hello-world)
(newline)))
gsc -target js . srfi-78 hello-test
Building module: srfi-78
gsc -target js . srfi-78
<no output>
gsc -target js . hello-test
<no output>
gsc -target js -exe -nopreload . srfi-78/srfi-78.sld hello-test/hello-test.sld
srfi-78/srfi-78.sld:
/home/jeff/srchome/src/zipper/srfi-78/srfi-78.js:
hello-test/hello-test.sld:
/home/jeff/srchome/src/zipper/hello-test/hello-test.js:
/home/jeff/srchome/src/zipper/hello-test/hello-test_.js:
hello-test/hello-test
compiled to other
*** ERROR IN hello-test# -- Operator is not a PROCEDURE
(#!void "hello world\n")
Now:
gsc -target js . srfi-78 hello-test && \
gsc -target js -exe -nopreload . srfi-78/srfi-78.sld hello-test/hello-test.sld && \
node hello-test/hello-test
emits:
Building module: srfi-78
srfi-78/srfi-78.sld:
/home/jeff/srchome/src/zipper/srfi-78/srfi-78.js:
hello-test/hello-test.sld:
/home/jeff/srchome/src/zipper/hello-test/hello-test.js:
/home/jeff/srchome/src/zipper/hello-test/hello-test_.js:
compiled to other
hello world
(define-library (srfi-78)
(import (scheme base) (scheme write))
(export hello-world check check-passed? check-report check-reset! check-set-mode!
check:add-correct! check:add-failed! check:correct check:failed
check:mode check:proc check:proc-ec check:report-actual-result
check:report-correct check:report-expression check:report-failed
check:write)
(include "check.scm")
(begin
(define (hello-world)
(display "hello world\n"))
))
-warnings
option to gsc
is useful in this situation
I'm looking for a workflow to incrementally develop a library in the r7rs define-library style, including the ability to test in a repl. Currently using emacs scheme-mode for sending to the repl.
Suppose I want to change the library and then as quickly as possible test with the repl. I wrote a wrapper script to run gsi which finds the correct directory to pass with -:search so that my import will work. But after making a change I noticed when doing import as above in gsi that I can't seem to do import again and pick up the change. I'm okay with clearing out my environment to do so.
I suppose I could script this with a custom emacs command or subprocess tty hacks, but I was hoping to stay within gambit for editor independence. Is there any similar api available?
(display "hello $HOME/.gambini\n")
(define (dir-for-project)
(let loop ((d (path-strip-trailing-directory-separator (current-directory))))
(let ((files (directory-files (list (string->keyword "path") d (string->keyword "ignore-hidden") #f))))
(if (or (equal? 0 (string-length d))
(member ".gambini-local" files))
d
(loop (path-strip-trailing-directory-separator (path-directory d)))))))
(map display `(about to add ,(dir-for-project) "\n"))
(module-search-order-add! (dir-for-project))
;; TODO: look for project-specific modules to load in .gambini-local
;; For now, simulate by hard-coding:
;;(import (srfi-78))
;; =>
;; Cannot find library (srfi-78)
(eval "(define foo 123)")
;; does not cause error, but foo is not bound in the repl
eval
you want: (eval ‘(define foo 123))
(eval “a string”)
=> ”a string”
#|
Initializes project-specific path and imports for repl-based testing.
Place initialization code for your gambit based project in the project
root directory.
For example:
mkdir -p srfi-78
git clone https://github.com/scheme-requests-for-implementation/srfi-78 srfi-78/srfi-78
cat > srfi-78/srfi-78.sld
(define-library (srfi-78)
(import (scheme base) (scheme write))
(export hello-world check check-passed? check-report check-reset! check-set-mode!
check:add-correct! check:add-failed! check:correct check:failed
check:mode check:proc check:proc-ec check:report-actual-result
check:report-correct check:report-expression check:report-failed
check:write)
(include "srfi-78/check.scm")
(begin
(define (hello-world)
(display "hello world\n"))
))
cat > .gambini-local
(import (srfi-78))
(define bar 456)
gsi
hello HOME/.gambini
Found .gambini-local. Will module-search-order add ../src/zipper
About to eval: (begin (import (srfi-78)) (define bar 456))
Gambit v4.9.4
> bar
456
> (check (+ 2 2) => 4)
(+ 2 2) => 4 ; correct
>
|#
(import (srfi 28))
(define rfile-local ".gambini-local")
(define (dir-for-project)
(let loop ((d (path-strip-trailing-directory-separator (current-directory))))
(let ((files (directory-files (list (string->keyword "path") d (string->keyword "ignore-hidden") #f))))
(cond
((equal? 0 (string-length d)) #f)
((member rfile-local files) d)
(else
(loop (path-strip-trailing-directory-separator (path-directory d))))))))
(define (file-for-project)
(path-expand rfile-local (dir-for-project)))
(if (dir-for-project)
(begin
(display (format "Found .gambini-local. Will module-search-order add ~a\n" (dir-for-project)))
(module-search-order-add! (dir-for-project))
(let ((sexp-local `(begin ,@(with-input-from-file ".gambini-local" (lambda () (read-all (current-input-port)))))))
(display (format "About to eval: ~a\n" sexp-local))
(eval sexp-local))))