Appendix A: STklos Idiosyncrasies
A.1. STklos libraries
This section describes the standard libraries provided by STklos.
A.1.1. The (scheme …) Libraries
R7RS Small Libraries
STklos offers all the libraries defined by R7RS:
-
base
-
case-lambda
-
char
-
complex
-
cxr
-
eval
-
file
-
inexact
-
lazy
-
load
-
process-context
-
r5rs
-
read
-
repl
-
time
-
write
See the [R7RS] document for more information.
R7RS Large Libraries
STklos supports some libraries of the (under development) R7RS Large editions.
For now, supported libraries of the Red edition are
-
bytevector (R6RS bytevectors)
-
box (srfi 111)
-
charset (srfi 14)
-
comparator (srfi 128)
-
generator (srfi 158) — Red edition included SRFI 121, but it was superseded by SRFI 158.
-
hash-table (srfi 125)
-
ideque (srfi 134)
-
ilist (srfi 116)
-
list (srfi 1)
-
list-queue (srfi 117)
-
lseq (srfi 127)
-
set (srfi 113)
-
sort (srfi 132)
-
stream (srfi 41)
-
text (srfi 135)
-
vector (srfi 133)
For now, supported libraries of the Tangerine edition are
-
bitwise (srfi 151)
-
bytevector (scheme bytevector)- not a SRFI: this one is a chapter from R6RS.
-
division (srfi 141)
-
fixnum (srfi 143)
-
flonum (srfi 144)
-
generator (srfi 158)
-
vector @ (srfi 160)
(scheme bytevector) functions
Importing (scheme bytevector)
gives access to the supplemental following
bytevector functions.
STklos procedure
The bytevector-s8-ref
procedure returns the byte at index k
of
bytevector
, as a signed byte.
(let ((b1 (make-bytevector 16 -127))
(b2 (make-bytevector 16 255)))
(list
(bytevector-s8-ref b1 0)
(bytevector-u8-ref b1 0)
(bytevector-s8-ref b2 0)
(bytevector-u8-ref b2 0)))
=> (-127 129 -1 255)
STklos procedure
K
must be a valid index of bytevector.
The bytevector-s8-set!
procedure stores the two’s-complement
representation of byte
in element k
of bytevector
.
This procedure return an unspecified value.
(let ((b (make-bytevector 16 -127)))
(bytevector-s8-set! b 0 -126)
(bytevector-u8-set! b 1 246)
(list
(bytevector-s8-ref b 0)
(bytevector-u8-ref b 0)
(bytevector-s8-ref b 1)
(bytevector-u8-ref b 1)))
=> (-126 130 -10 246)
STklos procedure
The fill
argument is as in the description of the make-bytevector
procedure. The bytevector-fill!
procedure stores fill
in every
element of bytevector and returns unspecified values. Analogous to
vector-fill!
.
STklos procedure
Returns true if bytevector1
and bytevector2
are equal—that
is, if they have the same length and equal bytes at all valid
indices. It returns false otherwise.
STklos procedure
The bytevector-uint-ref
procedure retrieves the exact
integer object corresponding to the unsigned representation
of size size
and specified by endianness
at indices
k , … , k + size − 1
.
The bytevector-sint-ref
procedure retrieves the exact
integer object corresponding to the two’s-complement
representation of size size
and specified by endianness
at indices k , … , k + size − 1
.
For bytevector-uint-set!
, n
must be an exact integer
object in the interval {0, … , 256^size − 1}
.
The bytevector-uint-set!
procedure stores the unsigned
representation of size size
and specified by endianness
into bytevector
at indices k , … , k + size − 1
.
For bytevector-sint-set!, n must be an exact integer
object in the interval {−256^size /2, … , 256^size /2 − 1}
.
Bytevector-sint-set!
stores the two’s-complement
representation of size size
and specified by endianness
into bytevector
at indices k , … , k + size − 1
.
The …-set!
procedures return unspecified values.
(define b (make-bytevector 16 -127))
(bytevector-uint-set! b 0 (- (expt 2 128) 3)
(endianness little) 16)
(bytevector-uint-ref b 0 (endianness little) 16)
=> #xfffffffffffffffffffffffffffffffd
(bytevector-sint-ref b 0 (endianness little) 16)
=> -3
(bytevector->u8-list b)
=> (253 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255)
(bytevector-uint-set! b 0 (- (expt 2 128) 3)
(endianness big) 16)
(bytevector-uint-ref b 0 (endianness big) 16)
=> #xfffffffffffffffffffffffffffffffd
(bytevector-sint-ref b 0 (endianness big) 16)
=>-3
(bytevector->u8-list b)
=> (255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 253))
R5RS procedure
The name of endianness-symbol
must be a symbol describing an
endianness. An implementation must support at least the symbols big
and little, but may support other endianness symbols.
(endianness endianness-symbol)
evaluates to the symbol named
endianness-symbol
. Whenever one of the procedures operating on
bytevectors accepts an endianness as an argument, that argument must
be one of these symbols. It is a syntax violation for endianness-symbol
to be anything other than little
or big
.
STklos procedure
Returns the endianness symbol of the underlying machine.
A.1.2. The (srfi …) Libraries
All the SRFI supported by STklos are placed under
the srfi
meta library and their name is SRFI number. Hence, to use
the exported symbols of SRFI-1, you’ll have to import the
(srfi 1)
library.
See Chapter 13 for more information
A.1.3. The (stklos …) Libraries
This section describes the standard libraries which are placed under
the stklos
meta library. Note that STklos extensions can add
some libraries in the stklos
meta library; they will be described in
the extension documentation.
(stklos itrie) Library
This library was designed by Jerônimo Pellegrini (@jpellegrini).
Small description needed |
The symbols exported by (stklos itrie)
are described below:
STklos procedure
Returns a newly allocated fxmapping containing the associations of alist. It is an error if the car of any pair in alist is not a fixnum. If an integer k appears as the key of multiple associations in alist (i.e. as the car of multiple pairs), then the first association for k is preferred.
(fxmapping->alist
(alist->fxmapping '((1 . b) (0 . a) (2 . c))))
=> ((0 . a) (1 . b) (2 . c))
(fxmapping->alist
(alist->fxmapping '((-10 . "yar") (-10 . "worf"))))
=> ((-10 . "yar"))
STklos procedure
Builds a fixnum map containing the integer keys k1
, k2
, …, kn
with respective associated values v1
, v2
, … vn
.
It is an error if any of the keys is not an integer, or if the number of arguments is not even.
STklos procedure
Builds a fixnum set containing the fixnums n1
, n2
, …, nk
.
It is an error if any of the keys is not an integer.
STklos procedure
Returns a fxmapping containing all of the associations of fxmap
as
well as the associations (k1, obj1)
, (k2, obj2)
, … The number of
key/value arguments must be even.
If any of the keys already have associations in fxmap
, the old
associations are preserved.
(fxmapping->alist (fxmapping-adjoin (fxmapping 1 'b) 0 'a))
=> ((0 . a) (1 . b))
STklos procedure
Returns true if map
contains an association for element
, and false otherwise.
STklos procedure
Returns #t
is obj
is an empty fxmapping and #f
if it
is an fxmapping containing at least one key.
If obj
is not an fxmapping object, an error is sginaled.
STklos procedure
Returns the height of the internal trie of an fxmap. The expected running time of searches and insertions is proportional to this value.
STklos procedure
Returns the keys of fxmap
as a list in ascending numerical order.
(fxmapping-keys (fxmapping 137 'a -24 'b -5072 'c))
=> (-5072 -24 137)
STklos procedure
Returns #t
is obj
is a mutable fxmapping and #f
otherwise.
STklos procedure
If an association (k, v)
occurs in map
, returns v
. Otherwise, returns obj
.
(fxmapping-ref/default (fxmapping 36864 'zap) 36864 #f) => zap
(fxmapping-ref/default (fxmapping 0 'a) 36864 #f) => #f
STklos procedure
Returns the number of key/value pairs in an fxmap.
STklos procedure
Returns the values of fxmap
as a list in ascending numerical order of
key. That is, if (k1, v1), …, (kn, vn)
are the associations of fxmap
ordered so that k1 ⇐ … ⇐ kn
, then (fxmapping-values fxmap)
produces
the list (v1 … vn)
.
(fxmapping-values (fxmapping 0 "picard" 1 "riker" 2 "troi"))
=> ("picard" "riker" "troi")
STklos procedure
Return a fxmapping whose set of associations is the union, intersection, asymmetric difference, or symmetric difference of the sets of associations of the fxmaps. Asymmetric difference is extended to more than two fxmappings by taking the difference between the first fxmapping and the union of the others. Symmetric difference is not extended beyond two fxmappings. When comparing associations, only the keys are compared. In case of duplicate keys, associations in the result fxmapping are drawn from the first fxmapping in which they appear.
(fxmapping->alist (fxmapping-union (fxmapping 0 'a 2 'c)
(fxmapping 1 'b 3 'd)))
=> ((0 . a) (1 . b) (2 . c) (3 . d))
(fxmapping->alist
(fxmapping-intersection (fxmapping 0 'a 2 'c)
(fxmapping 1 'b 2 'c 3 'd)
(fxmapping 2 'c 4 'e)))
=> ((2 . c))
(fxmapping->alist
(fxmapping-difference (fxmapping 0 'a 1 'b 2 'c)
(fxmapping 2 "worf")
(fxmapping 1 "data")))
=> ((0 . a))
STklos procedure
Returns #t
is obj
is an fxmapping object and #f
otherwise.
STklos procedure
These procedures return true when each set is
equal (iset=?
) or a proper subset (iset<?
), a proper
superset (iset>?
), a subset (iset⇐?
) or a superset
(iset>=?
) of the next one.
(iset=? (iset 1 2 3) (iset 3 1 2)) => #t
(iset<? (iset 3 1 2) (iset 4 2 1 3)) => #t
(iset>=? (iset 3 0 1) (iset 0 1) (iset 0 1)) => #t
STklos procedure
Returns a newly allocated list containing the members of
set
in increasing numerical order.
(iset->list (iset 2 3 5 7 11)) => (2 3 5 7 11)
STklos procedure
The iset-adjoin
procedure returns a newly allocated iset that contains
all the values of set
, and in addition each element unless it is
already equal to one of the existing or newly added members.
(iset->list (iset-adjoin (iset 1 3 5) 0)) => (0 1 3 5)
The iset-adjoin!
procedure is the linear update version of
iset-adjoin
. In STklos, it is an alias to iset-adjoin
.
STklos procedure
Returns true if at least one of the elements of set
satisfies
pred?
. Note that this differs from the SRFI 1 analogue because
it does not return an element of the iset.
(iset-any odd? (iset 10 2 -3 4)) => #t
(iset-any odd? (iset 10 2 -8 4 0)) => #f
STklos procedure
Procedures that return a subset of set
contained in the interval from
low
to high
. The interval may be open, closed, open below and closed
above, or open above and closed below.
(iset->list (iset-open-interval (iset 2 3 5 7 11) 2 7)) => (3 5)
(iset->list (iset-closed-interval (iset 2 3 5 7 11) 2 7)) => (2 3 5 7)
(iset->list (iset-open-closed-interval (iset 2 3 5 7 11) 2 7)) => (3 5 7)
(iset->list (iset-closed-open-interval (iset 2 3 5 7 11) 2 7)) => (2 3 5)
STklos procedure
Returns true if set
contains element
, and false otherwise.
STklos procedure
Returns a newly allocated iset containing the elements of set
.
STklos procedure
Returns the number of elements of set
that satisfy
pred?
as an exact integer.
(iset-count odd? (iset 10 2 1 -3 9 4 3)) => 4
STklos procedure
The iset-delete
procedure returns a newly allocated iset containing
all the values of set
except for any that are equal to one or more of
the elements. Any element that is not equal to some member of the set
is ignored.
The iset-delete!
procedure is the same as iset-delete
.
is permitted to mutate and return the iset argument rather than
allocating a new iset — but in STklos, it doesn’t.
The iset-delete-all
and iset-delete-all!
procedures are the same as
iset-delete
and iset-delete!
, except that they accept a single
argument which is a list of elements to be deleted.
(iset->list (iset-delete (iset 1 3 5) 3)) => (1 5)
(iset->list (iset-delete-all (iset 2 3 5 7 11)
'(3 4 5))) => (2 7 11)
STklos procedure
Returns two values: the smallest/largest integer n in set
and a
newly-allocated iset that contains all elements of set
except for
n. It is an error if iset is empty.
The iset-delete-min!
and iset-delete-max!
procedures are the same as
iset-delete-min
and iset-delete-max
, respectively, except that they
are permitted to mutate and return the set
argument instead of
allocating a new iset. In STklos, they do not.
(let-values (((n set) (iset-delete-min (iset 2 3 5 7 11))))
(list n (iset->list set)))
=> (2 (3 5 7 11))
(let-values (((n set) (iset-delete-max (iset 2 3 5 7 11))))
(list n (iset->list set)))
=> (11 (2 3 5 7))
STklos procedure
Returns #t
if iset1
and iset2
have no elements in common and #f
otherwise.
(iset-disjoint? (iset 1 3 5) (iset 0 2 4)) => #t
(iset-disjoint? (iset 1 3 5) (iset 2 3 4)) => #f
STklos procedure
Returns #t
is obj
is an empty iset and #f
if it
is an iset containing at least one key.
If obj
is not an iset object, an error is sginaled.
STklos procedure
Returns #t
if every element of set
satisfies predicate
, or #f
otherwise. Note that this differs from the SRFI 1 analogue because it
does not return an element of the iset.
(iset-every? (lambda (x) (< x 5)) (iset -2 -1 1 2)) => #t
(iset-every? positive? (iset -2 -1 1 2)) => #f
STklos procedure
Returns a newly allocated iset containing just the elements
of set
that satisfy predicate
.
(iset->list (iset-filter (lambda (x) (< x 6)) (iset 2 3 5 7 11)))
=> (2 3 5)
iset-filter!
is allowed to modify set
, but in STklos it does not.
STklos procedure
Returns the smallest element of set
that satisfies predicate, or
the result of invoking failure
with no arguments if there is none.
(iset-find positive? (iset -1 1) (lambda () #f)) => 1
(iset-find zero? (iset -1 1) (lambda () #f)) => #f
STklos procedure
Invokes proc
on each member of set
in increasing/decreasing numerical
order, passing the result of the previous invocation as a second
argument. For the first invocation, nil
is used as the second
argument. Returns the result of the last invocation, or nil
if there
was no invocation.
(iset-fold + 0 (iset 2 3 5 7 11)) => 28
(iset-fold cons '() (iset 2 3 5 7 11)) => (11 7 5 3 2)
(iset-fold-right cons '() (iset 2 3 5 7 11)) => (2 3 5 7 11)
STklos procedure
Applies proc
to set
in increasing numerical order, discarding the
returned values. Returns an unspecified result.
(let ((sum 0))
(iset-for-each (lambda (x) (set! sum (+ sum x)))
(iset 2 3 5 7 11))
sum)
=> 28
STklos procedure
Returns the height of the internal trie of an iset. The expected running time of searches and insertions is proportional to this value.
STklos procedure
Applies proc
to each element of set
in arbitrary order and returns a
newly allocated iset, created as if by iset, which contains the
results of the applications. It is an error if proc
returns a value
that is not an exact integer.
(iset-map (lambda (x) (* 10 x)) (iset 1 11 21))
=> (iset 10 110 210)
(iset-map (lambda (x) (quotient x 2))
(iset 1 2 3 4 5))
=> (iset 0 1 2)
STklos procedure
Returns the smallest or largest integer in set
, or #f
if there is none.
(iset-min (iset 2 3 5 7 11)) => 2
(iset-max (iset 2 3 5 7 11)) => 11
(iset-max (iset)) => #f
STklos procedure
Returns the element of set
that is equal to element
. If element
is not a member
of set
, then default
is returned.
STklos procedure
Returns #t
is obj
is a mutable iset and #f
otherwise.
STklos procedure
Returns two values: a newly allocated iset that contains just the
elements of set
that satisfy predicate
and another newly allocated
iset that contains just the elements of set
that do not satisfy
predicate
.
(let-values (((low high) (iset-partition (lambda (x) (< x 6))
(iset 2 3 5 7 11))))
(list (iset->list low) (iset->list high)))
=> ((2 3 5) (7 11))
STklos procedure
Returns a newly allocated set
containing just the elements of set
that do not satisfy predicate
.
(iset->list (iset-remove (lambda (x) (< x 6)) (iset 2 3 5 7 11)))
=> (7 11)
Iset-remove!
is allowed to modify set
, but in STklos it does not.
STklos procedure
Set
is searched from lowest to highest value for element
. If it
is not found, then the failure
procedure is tail-called with two
continuation arguments, insert
and ignore
, and is expected to
tail-call one of them. If element
is found, then the success
procedure
is tail-called with the matching element of set
and two
continuations, update
and remove
, and is expected to tail-call one of
them.
The effects of the continuations are as follows (where obj
is any
Scheme object):
Invoking (insert obj)
causes element
to be inserted into iset.
Invoking (ignore obj)
causes set
to remain unchanged.
Invoking (update new-element obj)
causes new-element
to be
inserted into set
in place of element
.
Invoking (remove obj)
causes the matching element of set
to
be removed from it.
In all cases, two values are returned: an iset and obj
.
The iset-search!
procedure is the same as iset-search
, except that it
is permitted to mutate and return the iset argument rather than
allocating a new iset. In STklos, it does not.
STklos procedure
Returns the number of fixnums in set
.
STklos procedure
Create a newly allocated iset as if by iset. If the result of
applying the predicate stop?
to seed
is true, return the
iset. Otherwise, apply the procedure mapper
to seed
. The
value that mapper
returns is added to the iset. Then get a
new seed by applying the procedure successor
to seed
, and
repeat this algorithm.
(iset->list (iset-unfold (lambda (n) (> n 64))
values
(lambda (n) (* n 2))
2))
=> (2 4 8 16 32 64)
STklos procedure
Return a newly allocated iset that is the union, intersection, asymmetric difference, or symmetric difference of the isets. Asymmetric difference is extended to more than two isets by taking the difference between the first iset and the union of the others. Symmetric difference is not extended beyond two isets. Elements in the result iset are drawn from the first iset in which they appear.
(iset->list (iset-union (iset 0 1 3) (iset 0 2 4))) => (0 1 2 3 4)
(iset->list (iset-intersection (iset 0 1 3 4) (iset 0 2 4))) => (0 4)
(iset->list (iset-difference (iset 0 1 3 4) (iset 0 2) (iset 0 4))) => (1 3)
(iset->list (iset-xor (iset 0 1 3) (iset 0 2 4))) => (1 2 3 4)
The procedures whose name end in !
are linear update procedures.
The specification says they may or may not alter their argument. In
STklos they do not: in fact, they are aliases to the pure functional
versions.
STklos procedure
Returns #t
is obj
is an iset and #f
otherwise.
STklos procedure
Procedures that return an integer set containing the elements of set
that are equal to, less than, less than or equal to, greater than, or
greater than or equal to k
. Note that the result of isubset=
contains
at most one element.
(iset->list (isubset= (iset 2 3 5 7 11) 7)) => (7)
(iset->list (isubset< (iset 2 3 5 7 11) 7)) => (2 3 5)
(iset->list (isubset>= (iset 2 3 5 7 11) 7)) => (7 11)
STklos procedure
Returns a newly allocated iset, created as if by iset, that contains
the elements of list
. Duplicate elements are omitted.
(list->iset '(-3 -1 0 2)) = (iset -3 -1 0 2)
list→iset!
may mutate set
rather than allocating a new iset,
but in STklos it does not.
(iset->list (list->iset! (iset 2 3 5) '(-3 -1 0))) ⇒ (-3 -1 0 2 3 5)
STklos procedure
Returns a newly allocated iset specified by an inclusive lower bound
start
, an exclusive upper bound `e`nd, and a step value (default 1), all
of which are exact integers. This constructor produces an iset
containing the sequence
start, (+ start step), (+ start (* 2 step)), …, (+ start (* n step))
,
where n
is the greatest integer such that (+ start (* n step)) < end
if step
is positive, or such that (+ start (* n step)) > end
if step
is negative. It is an error if step
is zero.
(iset->list (make-range-iset 25 30)) => (25 26 27 28 29)
(iset->list (make-range-iset -10 10 6)) => (-10 -4 2 8)
(stklos preproc) Library
This library must be described |
A.2. STklos compiler
STklos always compiles code into bytecode before executing — it is not an interpreter, but a bytecode compiler with an ad-hoc virtual machine. The compiler is available as a standalone tool, to be used in shell scripts, and also through primitive procedures.
The command stklos-compile
compiles a file into STklos bytecode.
Please refer to its manpage for more information.
Compiling files from Scheme programs can be done with the
compile-file
procedure.
STklos procedure
Compiles the file whose name is input
into a bytecode executable
whose name is output
(if compile-file
fails, output
file is
deleted).
This command accepts two optional keywords:
-
#:prepend
: it must be a list of expressions, which will be compiled before the rest of the input file. This can be used to define variables that the compiled program will use (but it does not affect the compiler itself). -
#:case-sensitive
: it tells if the compiler reads symbols in case sensitive mode (as R7RS) or not not (as R5RS). By default the compiler is in case sensitive mode.
This procedure will not set the executable bit on the generated file.
A.2.1. Compiler flags
STklos compiler behaviour can be customized by several parameters. Those parameters are described below.
STklos procedure
This parameter controls if the time used for compiling a file must be
displayed or not. It defaults to #t
.
STklos procedure
This parameter controls if the compiled code must embed indications of
the file location of the of the source expressions. When set, this
parameter makes programs slower and bigger. However, it can be useful
when debugging a program. This parameter defaults to #f
(but is set to
`#t
when STklos is launched in debug mode).
STklos procedure
This parameter controls if the object files produced by the STklos
compiler code must embed a readable version of the code. The code is placed
at the beginning of the produced file. This parameter defaults to #f
.
STklos procedure
This parameter controls if the compiler must try to inline the most common
Scheme primitives (simple arithmetic, main list or vector functions, …).
Code produced when this parameter is set is more efficient. Note that the
compiler can sometimes be misleaded if those functions are redefined, hence
the existence of this parameter. compiler:inline-common-functions
is set
by default to #t
.
> (compiler:inline-common-functions #t)
> (disassemble-expr '(begin (car '(1 2 3)) (+ a 1)) #t)
000: CONSTANT 0
002: IN-CAR
003: GLOBAL-REF 1
005: IN-INCR
006:
Constants:
0: (1 2 3)
1: a
> (compiler:inline-common-functions #f)
> (disassemble-expr '(begin (car '(1 2 3)) (+ a 1)) #t)
000: PREPARE-CALL
001: CONSTANT-PUSH 0
003: GREF-INVOKE 1 1
006: PREPARE-CALL
007: GLOBAL-REF-PUSH 2
009: ONE-PUSH
010: GREF-INVOKE 3 2
013:
Constants:
0: (1 2 3)
1: car
2: a
3: +
STklos procedure
This parameter determines if compiler tries to rewrite some expressions in
simpler ones. For instance, it permit to eliminate the unneeded expression
in a begin
form, or to evaluate some simple expression. For instance,
(begin 100 foo (display "Hello") "Hi" (not #f))
is rewritten in
(begin (display "Hello") #t)
This parameter defaults to #t
.
STklos procedure
This parameter controls if the formal parameters of a user procedure is kept
at runtime. The formal parameters can be accessed with the primitive
<<"procedure-formals">>.
Default value for compiler:keep-formals
is #f
.
> (compiler:keep-formals #f)
> (define (foo a b) ( + a b 1))
> foo
#[closure foo]
> (procedure-formals foo)
#f
> (compiler:keep-formals #t)
> (define (foo a b) ( + a b 1))
> foo
#[closure foo (a b)]
> (procedure-formals foo)
(a b)
STklos procedure
This parameter controls if the source of a user procedure is kept
at runtime. The source of a procedure can be accessed with the primitive
<<"procedure-source">>.
Default value for compiler:keep-source
is #f
.
> (compiler:keep-source #t)
> (define fib
(lambda (n) (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))))
> (pretty-print (procedure-source fib))
(lambda (n)
(if (< n 2)
n
(+ (fib (- n 1))
(fib (- n 2)))))
STklos procedure
This parameter controls the number of iterations to be unrolled in
loops. Currently, only repeat
loops are unrolled. The argument
n
must be a positive integer.
STklos procedure
This parameter determines if the peephole optimizer is used when compiling.
The default value for this parameter is #t
. The next example illustrates
how it works.
(compiler:peephole-optimizer #f)
(disassemble-expr '(+ a #f) #t)
will print
000: GLOBAL-REF 0
002: PUSH
003: IM-FALSE
004: IN-ADD2
005:
Now, if we change the parameter,
(compiler:peephole-optimizer #t)
(disassemble-expr '(+ a #f) #t)
then the result is
```scheme
000: GLOBAL-REF-PUSH 0
002: IM-FALSE
003: IN-ADD2
004:
See that the GLOBAL-REF
and PUSH
were turned by the peephole optimizer
into GLOBAL-REF-PUSH
.