From 00ce5125837c139ecd80f2f056b63ffdef4b9332 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Thu, 8 Jan 2009 22:05:59 +0100 Subject: [PATCH] start at documenting the compiler * doc/ref/api-evaluation.texi: Add documentation for the standard compilation interface, and some notes about compiled files. * doc/ref/api-procedures.texi (Compiled Procedures): A stub at documenting compiled procedures. * doc/ref/compiler.texi (Compiling to the Virtual Machine): Flesh out with some structure, though much of the text remains to be written. This stuff is hard to write! --- doc/ref/api-evaluation.texi | 108 +++++++++++++++++++++++++++++-- doc/ref/api-procedures.texi | 16 +++++ doc/ref/compiler.texi | 123 ++++++++++++++++++++++++++++++++++++ doc/ref/guile.texi | 2 +- doc/ref/vm.texi | 6 +- 5 files changed, 247 insertions(+), 8 deletions(-) diff --git a/doc/ref/api-evaluation.texi b/doc/ref/api-evaluation.texi index 6fd363df2..2825426a4 100644 --- a/doc/ref/api-evaluation.texi +++ b/doc/ref/api-evaluation.texi @@ -5,20 +5,22 @@ @c See the file guile.texi for copying conditions. @page -@node Read/Load/Eval +@node Read/Load/Eval/Compile @section Reading and Evaluating Scheme Code This chapter describes Guile functions that are concerned with reading, -loading and evaluating Scheme code at run time. +loading, evaluating, and compiling Scheme code at run time. @menu * Scheme Syntax:: Standard and extended Scheme syntax. * Scheme Read:: Reading Scheme code. * Fly Evaluation:: Procedures for on the fly evaluation. +* Compilation:: How to compile Scheme files and procedures. * Loading:: Loading Scheme code from file. * Delayed Evaluation:: Postponing evaluation until it is needed. * Local Evaluation:: Evaluation in a local environment. * Evaluator Behaviour:: Modifying Guile's evaluator. +* VM Behaviour:: Modifying Guile's virtual machine. @end menu @@ -411,6 +413,69 @@ the current module. @end deffn +@node Compilation +@subsection Compiling Scheme Code + +The @code{eval} procedure directly interprets the S-expression +representation of Scheme. An alternate strategy for evaluation is to +determine ahead of time what computations will be necessary to +evaluate the expression, and then use that recipe to produce the +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 +produces a compiled procedure, which is just like a normal procedure +except typically much faster, because it can bypass the generic +interpreter. + +Functions from system modules in a Guile installation are normally +compiled already, so they load and run quickly. + +Note that well-written Scheme programs will not typically call the +procedures in this section, for the same reason that it is often bad +taste to use @code{eval}. The normal interface to the compiler is the +command-line file compiler, which can be invoked from the shell as +@code{guile-tools compile @var{foo.scm}}. This interface needs more +documentation. + +(Why are calls to @code{eval} and @code{compile} usually in bad taste? +Because they are limited, in that they can only really make sense for +top-level expressions. Also, most needs for ``compile-time'' +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 +Virtual Machine for Guile}. + +@deffn {Scheme Procedure} compile exp [env=#f] [from=(current-language)] [to=value] [opts=()] +Compile the expression @var{exp} in the environment @var{env}. If +@var{exp} is a procedure, the result will be a compiled procedure; +otherwise @code{compile} is mostly equivalent to @code{eval}. + +For a discussion of languages and compiler options, @xref{Compiling to +the Virtual Machine}. +@end deffn + +@deffn {Scheme Procedure} compile-file file [to=objcode] [opts='()] +Compile the file named @var{file}. + +Output will be written to a file in the current directory whose name +is computed as @code{(compiled-file-name @var{file})}. +@end deffn + +@deffn {Scheme Procedure} compiled-file-name file +Compute an appropriate name for a compiled version of a Scheme file +named @var{file}. + +Usually, the result will be the original file name with the +@code{.scm} suffix replaced with @code{.go}, but the exact behavior +depends on the contents of the @code{%load-extensions} and +@code{%load-compiled-extensions} lists. +@end deffn + @node Loading @subsection Loading Scheme Code from File @@ -435,9 +500,19 @@ procedure that will be called before any code is loaded. See documentation for @code{%load-hook} later in this section. @end deffn +@deffn {Scheme Procedure} load-compiled filename +Load the compiled file named @var{filename}. The load paths are not +searched. + +Compiling a source file (@pxref{Read/Load/Eval/Compile}) and then +calling @code{load-compiled} on the resulting file is equivalent to +calling @code{load} on the source file. +@end deffn + @deffn {Scheme Procedure} load-from-path filename Similar to @code{load}, but searches for @var{filename} in the load -paths. +paths. Preferentially loads a compiled version of the file, if it is +available and up-to-date. @end deffn @deffn {Scheme Procedure} primitive-load filename @@ -461,7 +536,8 @@ documentation for @code{%load-hook} later in this section. Search @code{%load-path} for the file named @var{filename} and load it into the top-level environment. If @var{filename} is a relative pathname and is not found in the list of search paths, -an error is signalled. +an error is signalled. Preferentially loads a compiled version of the +file, if it is available and up-to-date. @end deffn @deffn {Scheme Procedure} %search-load-path filename @@ -639,6 +715,30 @@ trap handlers. Option interface for the evaluator trap options. @end deffn +@node VM Behaviour +@subsection VM Behaviour + +Like the procedures from the previous section that operate on the +evaluator, there are also procedures to modify the behavior of a +virtual machine. + +The most useful thing that a user can do is to add to one of the +virtual machine's predefined hooks: + +@deffn {Scheme Procedure} vm-next-hook vm +@deffnx {Scheme Procedure} vm-apply-hook vm +@deffnx {Scheme Procedure} vm-boot-hook vm +@deffnx {Scheme Procedure} vm-return-hook vm +@deffnx {Scheme Procedure} vm-break-hook vm +@deffnx {Scheme Procedure} vm-exit-hook vm +@deffnx {Scheme Procedure} vm-halt-hook vm +@deffnx {Scheme Procedure} vm-enter-hook vm +Accessors to a virtual machine's hooks. Usually you pass +@code{(the-vm)} as the @var{vm}. +@end deffn + +@xref{A Virtual Machine for Guile}, for more information on Guile's +virtual machine. @c Local Variables: @c TeX-master: "guile.texi" diff --git a/doc/ref/api-procedures.texi b/doc/ref/api-procedures.texi index 7fd0f4fa4..fd3a8d15b 100644 --- a/doc/ref/api-procedures.texi +++ b/doc/ref/api-procedures.texi @@ -11,6 +11,7 @@ @menu * Lambda:: Basic procedure creation using lambda. * Primitive Procedures:: Procedures defined in C. +* Compiled Procedures:: Scheme procedures can be compiled. * Optional Arguments:: Handling keyword, optional and rest arguments. * Procedure Properties:: Procedure properties and meta-information. * Procedures with Setters:: Procedures with setters. @@ -131,6 +132,21 @@ use @code{scm_c_make_subr} and also @code{scm_makcclo} if necessary. It is advisable to use the gsubr variants since they provide a slightly higher-level abstraction of the Guile implementation. +@node Compiled Procedures +@subsection Compiled Procedures + +Procedures that were created when loading a compiled file are +themselves compiled. (In contrast, procedures that are defined by +loading a Scheme source file are interpreted, and often not as fast as +compiled procedures.) + +Loading compiled files is the normal way that compiled procedures come +to being, though procedures can be compiled at runtime as well. +@xref{Read/Load/Eval/Compile}, for more information on runtime +compilation. + +here document things from (system vm program) + @node Optional Arguments @subsection Optional Arguments diff --git a/doc/ref/compiler.texi b/doc/ref/compiler.texi index e48022ef9..125ec92a5 100644 --- a/doc/ref/compiler.texi +++ b/doc/ref/compiler.texi @@ -7,3 +7,126 @@ @node Compiling to the Virtual Machine @section Compiling to the Virtual Machine +Compilers have a mystique about them that is attractive and +off-putting at the same time. They are attractive because they are +magical -- they transform inert text into live results, like throwing +the switch on Frankenstein. However, this magic is perceived by many +to be impenetrable. + +This section aims to pull back the veil from over Guile's compiler +implementation, some reference to the wizard of oz FIXME. + +REFFIXME, if you're lost and you just wanted to know how to compile +your .scm file. + +@menu +* Compiler Tower:: +* The Scheme Compiler:: +* GHIL:: +* GLIL:: +* Object Code:: +@end menu + +@node Compiler Tower +@subsection Compiler Tower + +Guile's compiler is quite simple, actually -- its @emph{compilers}, to +put it more accurately. Guile defines a tower of languages, starting +at Scheme and progressively simplifying down to languages that +resemble the VM instruction set (REFFIXME). + +Each language knows how to compile to the next, so each step is simple +and understandable. Furthermore, this set of languages is not +hardcoded into Guile, so it is possible for the user to add new +high-level languages, new passes, or even different compilation +targets. + +lookup-language +(lang xxx spec) + +(system-base-language) + +describe: + +(define-record + name + title + version + reader + printer + (parser #f) + (read-file #f) + (compilers '()) + (evaluator #f)) + +(define-macro (define-language name . spec) + +(lookup-compilation-order from to) + +language definition + +compiling from here to there + +the normal tower: scheme, ghil, glil, object code +maybe from there serialized to disk +or if at repl, brought back to life by compiling to ``value'' + +compile-file defaults to compiling to objcode +compile defaults to compiling to value + +((lambda (x) ((compile x) x)) '(lambda (x) ((compile x) x))) +quine + +@node The Scheme Compiler +@subsection The Scheme Compiler + +macro expansion + +define-scheme-translator + +inlining + +format of the environment + +compile-time-environment + +symbols resolved as local, external, or toplevel + +@node GHIL +@subsection GHIL + +ghil environments + +structured, typed intermediate language, close to scheme +with an s-expression representation + +,lang ghil + +some pre-optimization + +real name of the game is closure elimination -- fixing letrec + +@node GLIL +@subsection GLIL + +structured, typed intermediate language, close to object code + +passes through the env + +no let, no lambda, no closures, just labels and branches and constants +and code. Well, there's a bit more, but that's the flavor of GLIL. + +Compiled code will effectively be a thunk, of no arguments, but +optionally closing over some number of variables (which should be +captured via `make-closure' REFFIXME. + +@node Object Code +@subsection Object Code + +describe the env -- module + externals (the actual values!) + +The env is used when compiling to value -- effectively calling the +thunk from objcode->program with a certain current module and with +those externals. so you can recompile a closure at runtime, a trick +that goops uses. + diff --git a/doc/ref/guile.texi b/doc/ref/guile.texi index 983080a08..7968e989d 100644 --- a/doc/ref/guile.texi +++ b/doc/ref/guile.texi @@ -301,7 +301,7 @@ available through both Scheme and C interfaces. * Binding Constructs:: Definitions and variable bindings. * Control Mechanisms:: Controlling the flow of program execution. * Input and Output:: Ports, reading and writing. -* Read/Load/Eval:: Reading and evaluating Scheme code. +* Read/Load/Eval/Compile:: Reading and evaluating Scheme code. * Memory Management:: Memory management and garbage collection. * Objects:: Low level object orientation support. * Modules:: Designing reusable code libraries. diff --git a/doc/ref/vm.texi b/doc/ref/vm.texi index b386b883f..1075ae71b 100644 --- a/doc/ref/vm.texi +++ b/doc/ref/vm.texi @@ -25,7 +25,7 @@ machine. * VM Concepts:: * Stack Layout:: * Variables and the VM:: -* Compiled Procedures:: +* VM Programs:: * Instruction Set:: @end menu @@ -258,8 +258,8 @@ counterintuitively, what would seem ``closer to the metal'', viz @code{set!}, actually forces heap allocation instead of stack allocation. -@node Compiled Procedures -@subsection Compiled Procedures +@node VM Programs +@subsection Compiled Procedures are VM Programs By default, when you enter in expressions at Guile's REPL, they are first compiled to VM object code, then that VM object code is executed -- 2.20.1