(require 'compile)
If a file named `name1.opt' exists, then its options are
passed to the build invocation which compiles the c
files.
cd ~/scm/
scm -rcompile -e'(compile-file "example.scm")'
Starting to read example.scm
Generic (slow) arithmetic assumed: 1.0e-3 found.
** Pass 1 completed **
** Pass 2 completed **
** Pass 3 completed **
** Pass 4 completed **
** Pass 5 completed **
** Pass 6 completed **
C source file example.c is built.
C header file example.h is built.
These top level higher order procedures are not clonable (slow):
(nonkeyword_make-promise map-streams generate-vector runge-kutta-4)
These top level procedures create non-liftable closures (slow):
(nonkeyword_make-promise damped-oscillator map-streams scale-vector elementwise runge-kutta-4 integrate-system)
; Scheme (linux) script created by SLIB/batch Sun Apr 7 22:49:49 2002
; ================ Write file with C defines
(delete-file "scmflags.h")
(call-with-output-file
"scmflags.h"
(lambda (fp)
(for-each
(lambda (string) (write-line string fp))
'("#define IMPLINIT \"Init5e5.scm\""
"#define BIGNUMS"
"#define FLOATS"
"#define ARRAYS"
"#define DLL"))))
; ================ Compile C source files
(system "gcc -O2 -fpic -c -I/usr/local/lib/scm/ example.c")
(system "gcc -shared -o example.so example.o -lm -lc")
(delete-file "example.o")
; ================ Link C object files
(delete-file "slibcat")
Compilation finished at Sun Apr 7 22:49:50
If a file named `exename.opt' exists, then its options are
passed to the build invocation which compiles the c
files.
cd ~/scm/
scm -rcompile -e'(compile->executable "exscm" "example.scm")'
Starting to read example.scm
Generic (slow) arithmetic assumed: 1.0e-3 found.
** Pass 1 completed **
** Pass 2 completed **
** Pass 3 completed **
** Pass 4 completed **
** Pass 5 completed **
** Pass 6 completed **
C source file example.c is built.
C header file example.h is built.
These top level higher order procedures are not clonable (slow):
(nonkeyword_make-promise map-streams generate-vector runge-kutta-4)
These top level procedures create non-liftable closures (slow):
(nonkeyword_make-promise damped-oscillator map-streams scale-vector elementwise runge-kutta-4 integrate-system)
; Scheme (linux) script created by SLIB/batch Sun Apr 7 22:46:31 2002
; ================ Write file with C defines
(delete-file "scmflags.h")
(call-with-output-file
"scmflags.h"
(lambda (fp)
(for-each
(lambda (string) (write-line string fp))
'("#define IMPLINIT \"Init5e5.scm\""
"#define COMPILED_INITS init_example();"
"#define CCLO"
"#define FLOATS"))))
; ================ Compile C source files
(system "gcc -O2 -c continue.c scmmain.c findexec.c script.c time.c repl.c scl.c eval.c sys.c subr.c debug.c unif.c rope.c example.c scm.c")
; ================ Link C object files
(system "gcc -rdynamic -o exscm continue.o scmmain.o findexec.o script.o time.o repl.o scl.o eval.o sys.o subr.o debug.o unif.o rope.o example.o scm.o -L/usr/local/lib/scm/ -lm -lc")
Compilation finished at Sun Apr 7 22:46:44
Note Bene: `#define CCLO' must be present in `scmfig.h'.
In order to see calls to the C compiler and linker, do
(verbose 3)
before calling these functions.
Error detection during compilation is minimal. In case your scheme code is syntactically incorrect, hobbit may crash with no sensible error messages or it may produce incorrect C code.
Hobbit does not insert any type-checking code into the C output it produces. Eg, if a hobbit-compiled program applies `car' to a number, the program will probably crash with no sensible error messages.
Thus it is strongly suggested to compile only throughly debugged scheme code.
Alternatively, it is possible to compile all the primitives into calls to the SCM procedures doing type-checking. Hobbit will do this if you tell it to assume that all the primitives may be redefined. Put
(define compile-all-proc-redefined #t)
anywhere in top level of your scheme code to achieve this.
Note Bene: The compiled code using
(define compile-all-proc-redefined #t)
will typically be much slower than one produced without using
(define compile-all-proc-redefined #t).
All errors caught by hobbit will generate an error message
COMPILATION ERROR: <description of the error>
and hobbit will immediately halt compilation.
(define compile-allnumbers t)where t is arbitrary. In that case all the arithmetic primitives in all the given source files will be assumed to be generic. This will make operations with immediate integers much slower. You can use the special immediate-integer-only forms of arithmetic procedures to recover:
%negative? %number? %> %>= %= %<= %< %positive? %zero? %eqv? %+ %- %* %/See section The Language Compiled.
=> and begin case cond define delay do else if lambda let let letrec or quasiquote quote set! unquote unquote-splicingIf you want to be able to redefine some procedures, eg. `+' and `baz', then put both
(set! + +) (set! baz baz)somewhere into your file. As a consequence hobbit will generate code for `+' and `baz' using the run-time values of these variables. This is generally much slower than using non-redefined `+' and `baz' (especially for `+'). If you want to be able to redefine all the procedures, both primitives (eg `car') and the compiled procedures, then put the following into the compiled file:
(define compile-all-proc-redefined t)where t is arbitrary. If you want to be able to redefine all the compiled procedures, but not the scheme primitives, then put the following into the compiled file:
(define compile-new-proc-redefined t)where t is arbitrary. Again, remember that redefinable procedures will be typically much slower than non-redefinable procedures.
(define foo 100)then `foo' will be everywhere replaced by `100'. To declare some variables foo and bar to be inlined, put a following definition anywhere into your file:
(define compile-inline-vars '(foo bar))Usually it makes sense to inline only these variables whose value is either a small integer, character or a boolean. Note Bene: Do not use this kind of inlining for inlining procedures! Use the following for procedures:
(define (foo x) (+ x 2))then any call
(foo something)will be replaced by
(+ something 2)Inlining is NOT safe for variable clashes -- in other words, it is not "hygienic". Inlining is NOT safe for recursive procedures -- if the set of inlined procedures contains either immediate or mutual (foo calling bar, bar calling foo) recursion, the compiler will not terminate. To turn off full inlining (harmful for recursive funs), change the definition of the *full-inlining-flag* in the section "compiler options" to the value #f instead of #t. To declare some procedures foo and bar to be inlined, put a following definition anywhere into your file:
(define compile-inline '(foo bar))
(define compile-stable-vectors '(baz foo))into your file to declare that baz and foo are vector names defined once on the top level, and set! is never applied to them (vector-set! is, of course, allowed). This speeds up vector reference to those vectors by precomputing their location.
(define compile-uninterned-variables '(bazvar foovar))into your file to declare that bazvar and foovar are defined on the top level and they do always have an immediate value, ie a boolean, immediate (30-bit) integer or a character. Then bazvar and foovar will NOT be accessible from the interpreter. They'll be compiled directly into static C vars and used without an extra C *-operation prefixed to other global scheme variables.
(define *build-intermediate-files* #f)to:
(define *build-intermediate-files* #t)
When using the C compiler to compile the C code output by hobbit, always use strong optimizations (eg. `cc -xO3' for cc on Sun, `gcc -O2' or `gcc -O3' for gcc). Hobbit does not attempt to do optimizations of the kind we anticipate from the C compiler, therefore it often makes a serious difference whether the C compiler is run with a strong optimization flag or not.
For the final and fast version of your program you may want to first recompile the whole scm (scmlit for the version scm4e2) using the `-DRECKLESS' flag suppressing error checking: the hobbit-compiled code uses some SCM primitives in the compiled files with the suffix .o, and a number of these primitives become faster when error checking is disabled by `-DRECKLESS'. Notice that hobbit never inserts error checking into the code it produces.