gambiteer on master
Speed up implementation of SRFI… (compare)
feeley on master
Universal backend: add URL whit… (compare)
(define (attach-docstring docstring proc) (lambda args (##first-argument docstring) (apply proc args))) (define docstring-closure (attach-docstring "" list)) (define (get-docstring proc) (and (##closure? proc) (eq? (##closure-code proc) (##closure-code docstring-closure)) (##closure-ref proc 1))) (define hello (attach-docstring "hello is a neat function" (lambda (who) (println "hello " who "!")))) (pp (get-docstring car)) ;; prints #f (pp (get-docstring hello)) ;; prints "hello is a neat function" (hello "world")
some stuff I would be happy to work on:
Does anything there sound like its worth prioritizing? Does any of it not align with the goals of gambit?
% cd lib % make _gambit.js % make _gambit.py % make _gambit.rb % cd ..
-target <BACKEND> option when invoking gsc, where
% cat test.scm (println "hello!") % gsc/gsc -:=. -target js -exe test.scm % ./test hello!
Note that the file
test. For example bignums and pretty-printing are available:
% cat test.scm ;; print sqrt of 2 to 50 decimal places (pp (integer-sqrt (* 2 (expt 10 100)))) % gsc/gsc -:=. -target js -exe test.scm % ./test 141421356237309504880168872420969807856967187537694
% cat test.scm (console.log "hello!") % cat rts.scm (declare (extended-bindings) (not safe)) (define (console.log str) (##inline-host-statement "console.log(g_scm2host(@1@));" str)) ;; run each linked module (except for this file) (let ((module-descrs (##vector-ref ##program-descr 0))) (let loop ((i 1)) (if (##fx< i (##vector-length module-descrs)) (begin ((##vector-ref (##vector-ref module-descrs i) 1)) (loop (##fx+ i 1)))))) % gsc/gsc -:=. -target js -c rts.scm % gsc/gsc -:=. -target js -link -l rts.js test.scm % cat test_.js test.js rts.js > app.js % node app.js hello! % wc app.js 768 2238 18107 app.js
It is much smaller at 768 lines of code. Although you get a minimal runtime library, this may be a good approach to use Scheme code in a Web page with a minimal footprint.
The Gambit runtime library (in the lib directory) must also be compiled for your target platform. The C code generated by the Gambit compiler for your app must then be linked with the Gambit runtime library. A good way to understand the required low-level steps is to pass the
-verbose option to gsc. It will show the invocations of the C compiler. For example, if "app.scm" contains your program:
% gsc -exe -verbose app.scm Parsing: "expr" Compiling: Dumping: #<primitive app#> Compilation finished. gcc -O1 -Wno-unused -Wno-write-strings -Wdisabled-optimization -fwrapv -fno-strict-aliasing -fno-math-errno -fomit-frame-pointer -fPIC -fno-common -D___SINGLE_HOST -I"/Library/Gambit/v4.9.0/include" -c -o "app.o" app.c gcc -O1 -Wno-unused -Wno-write-strings -Wdisabled-optimization -fwrapv -fno-strict-aliasing -fno-math-errno -fomit-frame-pointer -fPIC -fno-common -D___SINGLE_HOST -I"/Library/Gambit/v4.9.0/include" -c -o "app_.o" app_.c gcc -Wno-unused -Wno-write-strings -Wdisabled-optimization -fwrapv -fno-strict-aliasing -fno-math-errno -fomit-frame-pointer -fPIC -fno-common -D___SINGLE_HOST -I"/Library/Gambit/v4.9.0/include" -o "app" app_.o app.o "/Library/Gambit/v4.9.0/lib/libgambit.a"
As you can see the last step links the executable with libgambit.a, the Gambit runtime library. It is the Gambit runtime library that contains the GC and the interface to the operating system (for file I/O, networking, time, etc).
--enable-ansi-cconfigure option that forces the Gambit runtime system to only use (and be linked to) functions provided by ANSI-C (https://www.cs.auckland.ac.nz/references/unix/digital/AQTLTBTE/DOCU_085.HTM). This is pretty "bare-bones" as it will disable many features (such as networking, subprocesses, etc) but it is a good approach to get started quickly. After that works, you can enable more advanced features to see which features work on the target platform (see include/config.h).
Hi! Is there a way to generate scheme objects out of C constant values? That's what I'm currently doing:
(define-macro (c-const-return name c-type c-value) (let ((acstring (eval `(string-append "___return(" ,c-value ");" )))) `(begin (##define ,name #f) (##set! ,name ((c-lambda () ,c-type ,acstring)))))) (c-const-return urE_KEYDOWN ur-stringhash "E_KEYDOWN") ;; const (c-const-return urP_KEY int "KeyDown::P_KEY") ;; const too
This is somewhat cumbersome, the resulting routines -- a couple thousand in my humble case -- will never be optimized away by compiler.
It works well, but not fast and prone to code bloat. C #defines, enums and C++ const T values are well known at compile time .. is there a way to inject the relevant macros inside Gambit's C product ? e.g. something like
(c-initialize " ___NEW_SCMOBJ(foobaz, int, KeyDown::P_KEY);") or even better a
(define foobaz (c-import int "KeyDown::P_KeY")) ?
Sorry if I am asking something obvious and thanks for all the fish!
gcc -Iinclude -o a.out lib/main.o lib/setup.o lib/mem.o lib/os_setup.o lib/os_base.o lib/os_thread.o lib/os_time.o lib/os_shell.o lib/os_files.o lib/os_dyn.o lib/os_tty.o lib/os_io.o lib/c_intf.o lib/actlog.o lib/_kernel.o lib/_system.o lib/_num.o lib/_std.o lib/_eval.o lib/_io.o lib/_nonstd.o lib/_thread.o lib/_repl.o lib/_gambit.o hw.c hw_.c
C_COMPILE_TO_EXE="$C_COMPILER -Iinclude -o $EXE_NAME"