By default hobbit assumes that only immediate (ie small, up to 30 bits) integers are used. It will automatically assume general arithmetics in case it finds any non-immediate numbers like 1.2 or 10000000000000 or real-only procedures like real-sin anywhere in the source.
Another way to make Hobbit assume that generic arithmetic supported by SCM (ie exact and/or inexact reals, bignums) is also used, is to put the following line somewhere in your scheme source file:
(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 The Language Compiled.
By default hobbit assumes that neither primitives nor compiled procedures are redefined, neither before the compiled program is initialized, during its work or later via the interpreter.
Hobbit checks the compiled source and whenever some variable bar is defined as a procedure, but is later redefined, or set! is applied to bar, then hobbit assumes thas this particular variable bar is redefinable. bar may be a primitive (eg ‘car’) or a name of a compiled procedure.
Note Bene: According to the Report 4 it is NOT allowed to use scheme keywords as variables (you may redefine these as macros defined by defmacro, though):
=> and begin case cond define delay do else if lambda let let letrec or quasiquote quote set! unquote unquote-splicing
If 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.
You may inline top-level-defined variables and procedures. Notice that inlining is DIFFERENT for variables and procedures!
NEVER inline variables or procedures which are set! or redefined anywhere in you program: this will produce wrong code.
(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
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.
To see the output of compiler passes, change the following definition in hobbit.scm.
(define *build-intermediate-files* #f)
(define *build-intermediate-files* #t)
It may happen that several originally different scheme variable names are represented by one and the same C variable. This will happen, for example, if you have separate variables a-1 and a_1.
If such (or any other) name clashes occur you may need to change some control variables in the first sections of hobbit.scm (up to the section "global variable defs") or just rename some variables in your scheme program.
See various control variables in the first sections of hobbit.scm (up to section "global variable defs").