rename translate.scm to compile-ghil.scm, and more work on compiler.texi
authorAndy Wingo <wingo@pobox.com>
Fri, 9 Jan 2009 16:49:09 +0000 (17:49 +0100)
committerAndy Wingo <wingo@pobox.com>
Fri, 9 Jan 2009 16:49:09 +0000 (17:49 +0100)
* doc/ref/api-evaluation.texi: Fix some typos and xrefs.

* doc/ref/compiler.texi (The Scheme Compiler): Document the scheme
  compiler, and start documenting the GHIL language.

* doc/ref/guile.texi (Guile Implementation): Whoops, put autoconf after
  the implementation foo. Unless we want it before?

* doc/ref/history.texi (The Emacs Thesis): Fix typo.

* doc/ref/vm.texi (Environment Control Instructions): Rename offset to
  index.

* module/language/ghil.scm (parse-ghil): Fix what I think was a bug --
  the consumer in a mv-call shouldn't be a rest arg.

* module/language/scheme/Makefile.am (SOURCES):
* module/language/scheme/compile-ghil.scm: Rename this file from
  translate.scm.

* module/oop/goops.scm:
* module/language/scheme/spec.scm: Deal with renaming.

doc/ref/api-evaluation.texi
doc/ref/compiler.texi
doc/ref/guile.texi
doc/ref/history.texi
doc/ref/vm.texi
module/language/ghil.scm
module/language/scheme/Makefile.am
module/language/scheme/compile-ghil.scm [moved from module/language/scheme/translate.scm with 98% similarity]
module/language/scheme/spec.scm
module/oop/goops.scm

index 2825426..d841215 100644 (file)
@@ -424,7 +424,7 @@ desired results. This is known as @dfn{compilation}.
 
 While it is possible to compile simple Scheme expressions such as
 @code{(+ 2 2)} or even @code{"Hello world!"}, compilation is most
-interesting in th context of procedures. Compiling a lambda expression
+interesting in the context of procedures. Compiling a lambda expression
 produces a compiled procedure, which is just like a normal procedure
 except typically much faster, because it can bypass the generic
 interpreter.
@@ -446,8 +446,8 @@ computation are fulfilled by macros and closures. Of course one good
 counterexample is the REPL itself, or any code that reads expressions
 from a port.)
 
-For more information on the compiler itself, @xref{Compiling to the
-Virtual Machine}. For information on the virtual machine, @xref{A
+For more information on the compiler itself, see @ref{Compiling to the
+Virtual Machine}. For information on the virtual machine, see @ref{A
 Virtual Machine for Guile}.
 
 @deffn {Scheme Procedure} compile exp [env=#f] [from=(current-language)] [to=value] [opts=()]
index c40a82e..b7054db 100644 (file)
@@ -68,7 +68,7 @@ for Scheme:
   #:version    "0.5"
   #:reader     read
   #:read-file  read-file
-  #:compilers   `((,ghil . ,translate))
+  #:compilers   `((,ghil . ,compile-ghil))
   #:evaluator  (lambda (x module) (primitive-eval x))
   #:printer    write)
 @end example
@@ -158,28 +158,191 @@ different worlds indefinitely, as shown by the following quine:
 @node The Scheme Compiler
 @subsection The Scheme Compiler
 
-macro expansion
+The job of the Scheme compiler is to expand all macros and to resolve
+all symbols to lexical variables. Its target language, GHIL, is fairly
+close to Scheme itself, so this process is not very complicated.
 
-define-scheme-translator
+The Scheme compiler is driven by a table of @dfn{translators},
+declared with the @code{define-scheme-translator} form, defined in the
+module, @code{(language scheme compile-ghil)}.
 
-inlining
+@deffn {Scheme Syntax} define-scheme-translator head clause1 clause2...
+The best documentation of this form is probably an example. Here is
+the translator for @code{if}:
 
-format of the environment
+@example
+(define-scheme-translator if
+  ;; (if TEST THEN [ELSE])
+  ((,test ,then)
+   (make-ghil-if e l (retrans test) (retrans then) (retrans '(begin))))
+  ((,test ,then ,else)
+   (make-ghil-if e l (retrans test) (retrans then) (retrans else))))
+@end example
 
-compile-time-environment
+The match syntax is from the @code{pmatch} macro, defined in
+@code{(system base pmatch)}. The result of a clause should be a valid
+GHIL value. If no clause matches, a syntax error is signalled.
+
+In the body of the clauses, the following bindings are introduced:
+@itemize
+@item @code{e}, the current environment
+@item @code{l}, the current source location (or @code{#f})
+@item @code{retrans}, a procedure that may be called to compile
+subexpressions
+@end itemize
+
+Note that translators are looked up by @emph{value}, not by name. That
+is to say, the translator is keyed under the @emph{value} of
+@code{if}, which normally prints as @code{#<primitive-builtin-macro!
+if>}.
+@end deffn
+
+Users can extend the compiler by defining new translators.
+Additionally, some forms can be inlined directly to
+instructions -- @xref{Inlined Scheme Instructions}, for a list. The
+actual inliners are defined in @code{(language scheme inline)}:
+
+@deffn {Scheme Syntax} define-inline head arity1 result1 arity2 result2...
+Defines an inliner for @code{head}. As in
+@code{define-scheme-translator}, inliners are keyed by value and not
+by name.
+
+Expressions are matched on their arities. For example:
+
+@example
+(define-inline eq?
+  (x y) (eq? x y))
+@end example
 
-symbols resolved as local, external, or toplevel
+This inlines calls to the Scheme procedure, @code{eq?}, to the
+instruction @code{eq?}.
+
+A more complicated example would be:
+
+@example
+(define-inline +
+  () 0
+  (x) x
+  (x y) (add x y)
+  (x y . rest) (add x (+ y . rest)))
+@end example
+@end deffn
+
+Compilers take two arguments, an expression and an environment, and
+return two values as well: an expression in the target language, and
+an environment suitable for the target language. The format of the
+environment is language-dependent.
+
+For Scheme, an environment may be one of three things:
+@itemize
+@item @code{#f}, in which case compilation is performed in the context
+of the current module;
+@item a module, which specifies the context of the compilation; or
+@item a @dfn{compile environment}, which specifies lexical variables
+as well.
+@end itemize
+
+The format of a compile environment for scheme is @code{(@var{module}
+@var{lexicals} . @var{externals})}, though users are strongly
+discouraged from constructing these environments themselves. Instead,
+if you need this functionality -- as in GOOPS' dynamic method compiler
+-- capture an environment with @code{compile-time-environment}, then
+pass that environment to @code{compile}.
+
+@deffn {Scheme Procedure} compile-time-environment
+A special function known to the compiler that, when compiled, will
+return a representation of the lexical environment in place at compile
+time. Useful for supporting some forms of dynamic compilation. Returns
+@code{#f} if called from the interpreter.
+@end deffn
 
 @node GHIL
 @subsection GHIL
 
-ghil environments
-
 structured, typed intermediate language, close to scheme
 with an s-expression representation
 
 ,lang ghil
 
+document reified format, as it's more interesting, and gives you an idea
+
+all have environment and location pointers
+
+@deffn {GHIL Expression} quote exp
+A quoted expression.
+@end deffn
+@deffn {GHIL Expression} quasiquote exp
+A quasiquoted expression. The parse format understands the normal
+@code{unquote} and @code{unquote-splicing} forms as in normal Scheme.
+When constructing @var{exp} programmatically, you will need to call
+@code{make-ghil-unquote} and @code{make-ghil-unquote-splicing} as
+appropriate.
+@end deffn
+@deffn {GHIL Expression} lambda syms rest meta . body
+A closure. @var{syms} is the argument list, as a list of symbols.
+@var{rest} is a boolean, which is @code{#t} iff the last argument is a
+rest argument. @var{meta} is an association list of properties. The
+actual @var{body} should be a list of GHIL expressions.
+@end deffn
+@deffn {GHIL Expression} void
+The unspecified value.
+@end deffn
+@deffn {GHIL Expression} begin . body
+Like Scheme's @code{begin}.
+@end deffn
+@deffn {GHIL Expression} bind syms exprs . body
+Like a deconstructed @code{let}: each element of @var{syms} will be
+bound to the corresponding GHIL expression in @var{exprs}.
+@end deffn
+@deffn {GHIL Expression} bindrec syms exprs . body
+As @code{bind} is to @code{let}, so @code{bindrec} is to
+@code{letrec}.
+@end deffn
+@deffn {GHIL Expression} set! sym val
+Like Scheme's @code{set!}.
+@end deffn
+@deffn {GHIL Expression} define sym val
+Like Scheme's @code{define}, but without the lambda sugar of course.
+@end deffn
+@deffn {GHIL Expression} if test then else
+A conditional. Note that @var{else} is not optional.
+@end deffn
+@deffn {GHIL Expression} and . exps
+Like Scheme's @code{and}.
+@end deffn
+@deffn {GHIL Expression} or . exps
+Like Scheme's @code{or}.
+@end deffn
+@deffn {GHIL Expression} mv-bind syms rest producer . body
+Like Scheme's @code{receive} -- binds the values returned by
+applying @code{producer}, which should be a thunk, to the
+@code{lambda}-like bindings described by @var{syms} and @var{rest}.
+@end deffn
+@deffn {GHIL Expression} call proc . args
+A procedure call.
+@end deffn
+@deffn {GHIL Expression} mv-call producer consumer
+Like Scheme's @code{call-with-values}.
+@end deffn
+@deffn {GHIL Expression} inline op . args
+An inlined VM instruction. @var{op} should be the instruction name as
+a symbol, and @var{args} should be its arguments, as GHIL expressions.
+@end deffn
+@deffn {GHIL Expression} values . values
+Like Scheme's @code{values}.
+@end deffn
+@deffn {GHIL Expression} values* . values
+@var{values} are as in the Scheme expression, @code{(apply values .
+@var{vals})}.
+@end deffn
+@deffn {GHIL Expression} compile-time-environment
+Produces, at runtime, a reification of the environment at compile
+time.
+@end deffn
+
+ghil environments
+ghil-var-for-ref!, ghil-var-for-set!, ghil-var-define!, ghil-var-at-module!
+
 some pre-optimization
 
 real name of the game is closure elimination -- fixing letrec
index 7968e98..50cce49 100644 (file)
@@ -365,8 +365,6 @@ available through both Scheme and C interfaces.
 @include scsh.texi
 @include scheme-debugging.texi
 
-@include autoconf.texi
-
 @node Guile Implementation
 @chapter Guile Implementation
 
@@ -390,6 +388,8 @@ Also Schemers as closet compiler writers.
 @include vm.texi
 @include compiler.texi
 
+@include autoconf.texi
+
 @include fdl.texi
 
 @iftex
index b2b2e2d..a258844 100644 (file)
@@ -42,9 +42,9 @@ seen in Emacs' current and continued existence, spanning more than a
 quarter-century.
 
 Besides providing for modification of a program by others, extension
-languages are good for /intension/ as well. Programs built in ``the
-Emacs way'' are pleasurable and easy for their authors to flesh out
-with the features that they need.
+languages are good for @emph{intension} as well. Programs built in
+``the Emacs way'' are pleasurable and easy for their authors to flesh
+out with the features that they need.
 
 After the Emacs experience was appreciated more widely, a number of
 hackers started to consider how to spread this experience to the rest
index 21817b2..5747e1f 100644 (file)
@@ -388,46 +388,46 @@ These instructions access and mutate the environment of a compiled
 procedure -- the local bindings, the ``external'' bindings, and the
 toplevel bindings.
 
-@deffn Instruction local-ref offset
+@deffn Instruction local-ref index
 Push onto the stack the value of the local variable located at
-@var{offset} within the current stack frame.
+@var{index} within the current stack frame.
 
 Note that arguments and local variables are all in one block. Thus the
-first argument, if any, is at offset 0, and local bindings follow the
+first argument, if any, is at index 0, and local bindings follow the
 arguments.
 @end deffn
 
-@deffn Instruction local-set offset
+@deffn Instruction local-set index
 Pop the Scheme object located on top of the stack and make it the new
-value of the local variable located at @var{offset} within the current
+value of the local variable located at @var{index} within the current
 stack frame.
 @end deffn
 
-@deffn Instruction external-ref offset
+@deffn Instruction external-ref index
 Push the value of the closure variable located at position
-@var{offset} within the program's list of external variables.
+@var{index} within the program's list of external variables.
 @end deffn
 
-@deffn Instruction external-set offset
+@deffn Instruction external-set index
 Pop the Scheme object located on top of the stack and make it the new
-value of the closure variable located at @var{offset} within the
+value of the closure variable located at @var{index} within the
 program's list of external variables.
 @end deffn
 
 The external variable lookup algorithm should probably be made more
-efficient in the future via addressing by frame and offset. Currently,
+efficient in the future via addressing by frame and index. Currently,
 external variables are all consed onto a list, which results in O(N)
 lookup time.
 
 @deffn Instruction externals
 Pushes the current list of external variables onto the stack. This
 instruction is used in the implementation of
-@code{compile-time-environment}.
+@code{compile-time-environment}. @xref{The Scheme Compiler}.
 @end deffn
 
-@deffn Instruction toplevel-ref offset
+@deffn Instruction toplevel-ref index
 Push the value of the toplevel binding whose location is stored in at
-position @var{offset} in the object table.
+position @var{index} in the object table.
 
 Initially, a cell in the object table that is used by
 @code{toplevel-ref} is initialized to one of two forms. The normal
@@ -453,9 +453,9 @@ variable has been successfully resolved.
 This instruction pushes the value of the variable onto the stack.
 @end deffn
 
-@deffn Instruction toplevel-ref offset
+@deffn Instruction toplevel-ref index
 Pop a value off the stack, and set it as the value of the toplevel
-variable stored at @var{offset} in the object table. If the variable
+variable stored at @var{index} in the object table. If the variable
 has not yet been looked up, we do the lookup as in
 @code{toplevel-ref}.
 @end deffn
@@ -490,15 +490,13 @@ All the conditional branch instructions described below work in the
 same way:
 
 @itemize
-@item They take the Scheme object located on the stack and use it as
+@item They pop off the Scheme object located on the stack and use it as
 the branch condition;
-@item If the condition is false, then program execution continues with
-the next instruction;
 @item If the condition is true, then the instruction pointer is
 increased by the offset passed as an argument to the branch
 instruction;
-@item Finally, when the instruction finished, the condition object is
-removed from the stack.
+@item Program execution proceeds with the next instruction (that is,
+the one to which the instruction pointer points).
 @end itemize
 
 Note that the offset passed to the instruction is encoded on two 8-bit
index 5180073..336cd95 100644 (file)
      ((call ,proc . ,args)
       (make-ghil-call env loc (retrans proc) (map retrans args)))
 
-     ((mv-call ,producer ,consumer)
+     ((mv-call ,producer ,consumer)
       (make-ghil-mv-call env loc (retrans producer) (retrans consumer)))
 
      ((inline ,op . ,args)
index 468543b..ca1d662 100644 (file)
@@ -1,3 +1,3 @@
-SOURCES = translate.scm spec.scm inline.scm
+SOURCES = compile-ghil.scm spec.scm inline.scm
 modpath = language/scheme
 include $(top_srcdir)/am/guilec
similarity index 98%
rename from module/language/scheme/translate.scm
rename to module/language/scheme/compile-ghil.scm
index 0132ff7..19ced1d 100644 (file)
@@ -19,7 +19,7 @@
 
 ;;; Code:
 
-(define-module (language scheme translate)
+(define-module (language scheme compile-ghil)
   #:use-module (system base pmatch)
   #:use-module (system base language)
   #:use-module (language ghil)
@@ -29,7 +29,7 @@
   #:use-module (ice-9 optargs)
   #:use-module ((ice-9 syncase) #:select (sc-macro))
   #:use-module ((system base compile) #:select (syntax-error))
-  #:export (translate translate-1
+  #:export (compile-ghil translate-1
             *translate-table* define-scheme-translator))
 
 
@@ -59,7 +59,7 @@
 
 \f
 
-(define (translate x e opts)
+(define (compile-ghil x e opts)
   (save-module-excursion
    (lambda ()
      (and=> (cenv-module e) set-current-module)
 (define *translate-table* (make-hash-table))
 
 (define-macro (define-scheme-translator sym . clauses)
-  `(hashq-set! (@ (language scheme translate) *translate-table*)
+  `(hashq-set! (@ (language scheme compile-ghil) *translate-table*)
                ,sym
                (lambda (e l exp)
                  (define (retrans x)
-                   ((@ (language scheme translate) translate-1) e #f x))
+                   ((@ (language scheme compile-ghil) translate-1) e #f x))
                  (define syntax-error (@ (system base compile) syntax-error))
                  (pmatch (cdr exp)
                          ,@clauses
index 3f5a709..ddcd69f 100644 (file)
@@ -21,7 +21,7 @@
 
 (define-module (language scheme spec)
   #:use-module (system base language)
-  #:use-module (language scheme translate)
+  #:use-module (language scheme compile-ghil)
   #:use-module (language ghil spec)
   #:export (scheme))
 
@@ -46,7 +46,7 @@
   #:version    "0.5"
   #:reader     read
   #:read-file  read-file
-  #:compilers   `((,ghil . ,translate))
+  #:compilers   `((,ghil . ,compile-ghil))
   #:evaluator  (lambda (x module) (primitive-eval x))
   #:printer    write
   )
index 2f6625c..453e0a9 100644 (file)
 
 (eval-case
  ((load-toplevel compile-toplevel)
-  (use-modules ((language scheme translate) :select (define-scheme-translator))
+  (use-modules ((language scheme compile-ghil) :select (define-scheme-translator))
                ((language ghil) :select (make-ghil-inline))
                (system base pmatch))