Next: compiler recordize specials, Up: compiler recordize [Index]
The core language forms that define bindings are:
(library-letrec* ((?lhs ?loc ?rhs) ...) ?body) (let ((?lhs ?rhs) ...) ?body) (letrec ((?lhs ?rhs) ...) ?body) (letrec* ((?lhs ?rhs) ...) ?body) (lambda ?formals ?body) (case-lambda (?formals ?body) ...) (annotated-case-lambda ?annotation (?formals ?body) ...)
and as special case:
(set! ?lhs ?rhs)
when present at the top level. In all these expressions ?lhs is a lexical gensym uniquely identifying the binding.
The recordisation process transforms:
library-letrec*
and letrec*
forms into rec*bind
structs, in which defined lex gensyms are substituted with
prelex
structs.
letrec
forms into recbind
structs, in which defined lex
gensyms are substituted with prelex
structs.
let
forms into bind
structs, in which defined lex
gensyms are substituted with prelex
structs.
lambda
, case-lambda
and annotated-case-lambda
forms
into clambda
structs, in which lex gensyms representing
bindings defined by function arguments are substituted with
prelex
structs.
In the core language input expression: if a binding is defined by the
expression itself, its lex gensym is present as left–hand side in a
let
, letrec
, letrec*
, library-letrec*
form
or as formal argument in a lambda
, case-lambda
,
annotated-case-lambda
form. Otherwise the lex gensym represents
an undefined binding or a binding defined outside the input form.
Every symbol in the input form not present as left–hand side in a
bind
, recbind
, rec*bind
struct or formal
argument in a clambda
struct is interpreted as a reference to
undefined or previously defined binding. This interpretation includes:
(set! ?lhs ?rhs)
like the definitions of syntax transformers in the visit code generated by the expander or standalone expressions evaluated at the REPL; such assignments to undefined bindings cause a new binding to be generated.
for all these cases: the lex gensym acts also as loc gensym.
After the recordisation process:
(funcall (primref top-level-value) (constant ?loc))
where ?loc is the loc gensym of the binding. If this binding is
truly undefined: the call to top-level-value
will raise an
exception at run–time.
(funcall (primref $init-symbol-value!) (constant ?loc) ?rhs)
where ?loc is the loc gensym of the binding; this is the run–time definition of a new binding.
so all the prelex
structs introduced by recordize
represent bindings defined by the input expression.
NOTE As specified by R6RS, bindings defined by imported libraries must not be mutated; this means core language forms like:
(set! ?loc ?rhs)in which ?loc is the loc gensym of an imported binding are forbidden. It is the responsibility of the expander not to generate such assignment forms for bindings defined by imported libraries.
NOTE The special handling of core language assignment forms:
(set! ?lex ?rhs)in which ?lex is both the lex and loc gensym of a binding not defined by the input expression allows:
- The correct handling of visit code generated by the expander.
- The definition of bindings by
eval
(for example at the REPL) using justset!
rather than a proper binding form. This case allows bindings to be added to interaction environment using weird syntaxes; here is an example session at the REPL:vicare> (let () (set! a 1) (set! b 2) #f) $1 = #f vicare> a $1 = 1 vicare> b $1 = 2It is the responsibility of the expander to forbid such definitions when processing libraries and programs.
Next: compiler recordize specials, Up: compiler recordize [Index]