mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 20:00:19 +02:00
* doc/ref/repl-modules.texi: Remove section on Value History, it's covered in scheme-using. * doc/ref/scheme-using.texi: Rename "Value Historyx" section to "Value History". * doc/ref/guile.texi: Update xref.
1299 lines
44 KiB
Text
1299 lines
44 KiB
Text
@c -*-texinfo-*-
|
|
@c This is part of the GNU Guile Reference Manual.
|
|
@c Copyright (C) 2006, 2010
|
|
@c Free Software Foundation, Inc.
|
|
@c See the file guile.texi for copying conditions.
|
|
|
|
@node Using Guile Interactively
|
|
@section Using Guile Interactively
|
|
|
|
When you start up Guile by typing just @code{guile}, without a
|
|
@code{-c} argument or the name of a script to execute, you get an
|
|
interactive interpreter where you can enter Scheme expressions, and
|
|
Guile will evaluate them and print the results for you. Here are some
|
|
simple examples.
|
|
|
|
@lisp
|
|
scheme@@(guile-user)> (+ 3 4 5)
|
|
$1 = 12
|
|
scheme@@(guile-user)> (display "Hello world!\n")
|
|
Hello world!
|
|
scheme@@(guile-user)> (values 'a 'b)
|
|
$2 = a
|
|
$3 = b
|
|
@end lisp
|
|
|
|
@noindent
|
|
This mode of use is called a @dfn{REPL}, which is short for
|
|
``Read-Eval-Print Loop'', because the Guile interpreter first reads the
|
|
expression that you have typed, then evaluates it, and then prints the
|
|
result.
|
|
|
|
The prompt shows you what language and module you are in. In this case, the
|
|
current language is @code{scheme}, and the current module is
|
|
@code{(guile-user)}. @xref{Other Languages}, for more information on Guile's
|
|
support for languages other than Scheme.
|
|
|
|
@menu
|
|
* Readline::
|
|
* Value History::
|
|
* REPL Commands::
|
|
* Error Handling::
|
|
* Interactive Debugging::
|
|
@end menu
|
|
|
|
|
|
@node Readline
|
|
@subsection Readline
|
|
|
|
To make it easier for you to repeat and vary previously entered
|
|
expressions, or to edit the expression that you're typing in, Guile
|
|
can use the GNU Readline library. This is not enabled by default
|
|
because of licensing reasons, but all you need to activate Readline is
|
|
the following pair of lines.
|
|
|
|
@lisp
|
|
scheme@@(guile-user)> (use-modules (ice-9 readline))
|
|
scheme@@(guile-user)> (activate-readline)
|
|
@end lisp
|
|
|
|
It's a good idea to put these two lines (without the ``scheme@@(guile-user)>''
|
|
prompts) in your @file{.guile} file. Guile reads this file when it
|
|
starts up interactively, so anything in this file has the same effect
|
|
as if you type it in by hand at the ``scheme@@(guile-user)>'' prompt.
|
|
|
|
|
|
@node Value History
|
|
@subsection Value History
|
|
|
|
Just as Readline helps you to reuse a previous input line, @dfn{value
|
|
history} allows you to use the @emph{result} of a previous evaluation
|
|
in a new expression. When value history is enabled, each evaluation
|
|
result is automatically assigned to the next in the sequence of
|
|
variables @code{$1}, @code{$2}, @dots{}, and you can then use these
|
|
variables in subsequent expressions.
|
|
|
|
@lisp
|
|
scheme@@(guile-user)> (iota 10)
|
|
$1 = (0 1 2 3 4 5 6 7 8 9)
|
|
scheme@@(guile-user)> (apply * (cdr $1))
|
|
$2 = 362880
|
|
scheme@@(guile-user)> (sqrt $2)
|
|
$3 = 602.3952191045344
|
|
scheme@@(guile-user)> (cons $2 $1)
|
|
$4 = (362880 0 1 2 3 4 5 6 7 8 9)
|
|
@end lisp
|
|
|
|
Value history is enabled by default, because Guile's REPL imports the
|
|
@code{(ice-9 history)} module. Value history may be turned off or on within the
|
|
repl, using the options interface:
|
|
|
|
@lisp
|
|
scheme@@(guile-user)> ,option value-history #f
|
|
scheme@@(guile-user)> 'foo
|
|
foo
|
|
scheme@@(guile-user)> ,option value-history #t
|
|
scheme@@(guile-user)> 'bar
|
|
$5 = bar
|
|
@end lisp
|
|
|
|
Note that previously recorded values are still accessible, even if value history
|
|
is off. In rare cases, these references to past computations can cause Guile to
|
|
use too much memory. One may clear these values, possibly enabling garbage
|
|
collection, via the @code{clear-value-history!} procedure, described below.
|
|
|
|
The programmatic interface to value history is in a module:
|
|
|
|
@lisp
|
|
(use-modules (ice-9 history))
|
|
@end lisp
|
|
|
|
@deffn {Scheme Procedure} value-history-enabled?
|
|
Return true iff value history is enabled.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} enable-value-history!
|
|
Turn on value history, if it was off.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} disable-value-history!
|
|
Turn off value history, if it was on.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} clear-value-history!
|
|
Clear the value history. If the stored values are not captured by some other
|
|
data structure or closure, they may then be reclaimed by the garbage collector.
|
|
@end deffn
|
|
|
|
|
|
@node REPL Commands
|
|
@subsection REPL Commands
|
|
|
|
@cindex commands
|
|
The REPL exists to read expressions, evaluate them, and then print their
|
|
results. But sometimes one wants to tell the REPL to evaluate an
|
|
expression in a different way, or to do something else altogether. A
|
|
user can affect the way the REPL works with a @dfn{REPL command}.
|
|
|
|
The previous section had an example of a command, in the form of
|
|
@code{,option}.
|
|
|
|
@lisp
|
|
scheme@@(guile-user)> ,option value-history #t
|
|
@end lisp
|
|
|
|
@noindent
|
|
Commands are distinguished from expressions by their initial comma
|
|
(@samp{,}). Since a comma cannot begin an expression in most languages,
|
|
it is an effective indicator to the REPL that the following text forms a
|
|
command, not an expression.
|
|
|
|
REPL commands are convenient because they are always there. Even if the
|
|
current module doesn't have a binding for @code{pretty-print}, one can
|
|
always @code{,pretty-print}.
|
|
|
|
The following sections document the various commands, grouped together
|
|
by functionality. Many of the commands have abbreviations; see the
|
|
online help (@code{,help}) for more information.
|
|
|
|
@menu
|
|
* Help Commands::
|
|
* Module Commands::
|
|
* Language Commands::
|
|
* Compile Commands::
|
|
* Profile Commands::
|
|
* Debug Commands::
|
|
* Inspect Commands::
|
|
* System Commands::
|
|
@end menu
|
|
|
|
@node Help Commands
|
|
@subsubsection Help Commands
|
|
|
|
When Guile starts interactively, it notifies the user that help can be
|
|
had by typing @samp{,help}. Indeed, @code{help} is a command, and a
|
|
particularly useful one, as it allows the user to discover the rest of
|
|
the commands.
|
|
|
|
@deffn {REPL Command} help [@samp{all} | group | @samp{[-c]} command]
|
|
Show help.
|
|
|
|
With one argument, tries to look up the argument as a group name, giving
|
|
help on that group if successful. Otherwise tries to look up the
|
|
argument as a command, giving help on the command.
|
|
|
|
If there is a command whose name is also a group name, use the @samp{-c
|
|
@var{command}} form to give help on the command instead of the group.
|
|
|
|
Without any argument, a list of help commands and command groups
|
|
are displayed.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} show [topic]
|
|
Gives information about Guile.
|
|
|
|
With one argument, tries to show a particular piece of information;
|
|
currently supported topics are `warranty' (or `w'), `copying' (or `c'),
|
|
and `version' (or `v').
|
|
|
|
Without any argument, a list of topics is displayed.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} apropos regexp
|
|
Find bindings/modules/packages.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} describe obj
|
|
Show description/documentation.
|
|
@end deffn
|
|
|
|
@node Module Commands
|
|
@subsubsection Module Commands
|
|
|
|
@deffn {REPL Command} module [module]
|
|
Change modules / Show current module.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} import [module ...]
|
|
Import modules / List those imported.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} load file
|
|
Load a file in the current module.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} binding
|
|
List current bindings.
|
|
@end deffn
|
|
|
|
@node Language Commands
|
|
@subsubsection Language Commands
|
|
|
|
@deffn {REPL Command} language language
|
|
Change languages.
|
|
@end deffn
|
|
|
|
@node Compile Commands
|
|
@subsubsection Compile Commands
|
|
|
|
@deffn {REPL Command} compile exp
|
|
Generate compiled code.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} compile-file file
|
|
Compile a file.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} disassemble exp
|
|
Disassemble a compiled procedure.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} disassemble-file file
|
|
Disassemble a file.
|
|
@end deffn
|
|
|
|
@node Profile Commands
|
|
@subsubsection Profile Commands
|
|
|
|
@deffn {REPL Command} time exp
|
|
Time execution.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} profile exp
|
|
Profile execution.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} trace exp
|
|
Trace execution.
|
|
@end deffn
|
|
|
|
@node Debug Commands
|
|
@subsubsection Debug Commands
|
|
|
|
These debugging commands are only available within a recursive REPL;
|
|
they do not work at the top level.
|
|
|
|
@deffn {REPL Command} backtrace [count] [#:width w] [#:full? f]
|
|
Print a backtrace.
|
|
|
|
Print a backtrace of all stack frames, or innermost @var{COUNT} frames.
|
|
If @var{count} is negative, the last @var{count} frames will be shown.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} up [count]
|
|
Select a calling stack frame.
|
|
|
|
Select and print stack frames that called this one.
|
|
An argument says how many frames up to go.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} down [count]
|
|
Select a called stack frame.
|
|
|
|
Select and print stack frames called by this one.
|
|
An argument says how many frames down to go.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} frame [idx]
|
|
Show a frame.
|
|
|
|
Show the selected frame. With an argument, select a frame by index,
|
|
then show it.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} procedure
|
|
Print the procedure for the selected frame.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} locals
|
|
Show local variables.
|
|
|
|
Show locally-bound variables in the selected frame.
|
|
@end deffn
|
|
|
|
@c FIXME: whenever we regain support for stepping, here are the docs..
|
|
|
|
@c The commands in this subsection all apply only when the stack is
|
|
@c @dfn{continuable} --- in other words when it makes sense for the program
|
|
@c that the stack comes from to continue running. Usually this means that
|
|
@c the program stopped because of a trap or a breakpoint.
|
|
|
|
@c @deffn {Debugger Command} step [n]
|
|
@c Tell the debugged program to do @var{n} more steps from its current
|
|
@c position. One @dfn{step} means executing until the next frame entry or
|
|
@c exit of any kind. @var{n} defaults to 1.
|
|
@c @end deffn
|
|
|
|
@c @deffn {Debugger Command} next [n]
|
|
@c Tell the debugged program to do @var{n} more steps from its current
|
|
@c position, but only counting frame entries and exits where the
|
|
@c corresponding source code comes from the same file as the current stack
|
|
@c frame. (See @ref{Step Traps} for the details of how this works.) If
|
|
@c the current stack frame has no source code, the effect of this command
|
|
@c is the same as of @code{step}. @var{n} defaults to 1.
|
|
@c @end deffn
|
|
|
|
@c @deffn {Debugger Command} finish
|
|
@c Tell the program being debugged to continue running until the completion
|
|
@c of the current stack frame, and at that time to print the result and
|
|
@c reenter the command line debugger.
|
|
@c @end deffn
|
|
|
|
@c @deffn {Debugger Command} continue
|
|
@c Tell the program being debugged to continue running. (In fact this is
|
|
@c the same as the @code{quit} command, because it exits the debugger
|
|
@c command loop and so allows whatever code it was that invoked the
|
|
@c debugger to continue.)
|
|
@c @end deffn
|
|
|
|
@c The @code{evaluate} command is most useful for querying the value of a
|
|
@c variable, either global or local, in the environment of the selected
|
|
@c stack frame, but it can be used more generally to evaluate any
|
|
@c expression.
|
|
|
|
@c @deffn {Debugger Command} evaluate expression
|
|
@c Evaluate an expression in the environment of the selected stack frame.
|
|
@c The expression must appear on the same line as the command, however it
|
|
@c may be continued over multiple lines.
|
|
@c @end deffn
|
|
|
|
@node Inspect Commands
|
|
@subsubsection Inspect Commands
|
|
|
|
@deffn {REPL Command} inspect EXP
|
|
Inspect the result(s) of evaluating @var{exp}.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} pretty-print EXP
|
|
Pretty-print the result(s) of evaluating @var{exp}.
|
|
@end deffn
|
|
|
|
@node System Commands
|
|
@subsubsection System Commands
|
|
|
|
@deffn {REPL Command} gc
|
|
Garbage collection.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} statistics
|
|
Display statistics.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} option [key value]
|
|
List/show/set options.
|
|
@end deffn
|
|
|
|
@deffn {REPL Command} quit
|
|
Quit this session.
|
|
@end deffn
|
|
|
|
|
|
@node Error Handling
|
|
@subsection Error Handling
|
|
|
|
When code being evaluated from the REPL hits an error, Guile enters a
|
|
new prompt, allowing you to inspect the context of the error.
|
|
|
|
@lisp
|
|
scheme@@(guile-user)> (map string-append '("a" "b") '("c" #\d))
|
|
ERROR: In procedure string-append:
|
|
ERROR: Wrong type (expecting string): #\d
|
|
Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue.
|
|
scheme@@(guile-user) [1]>
|
|
@end lisp
|
|
|
|
The new prompt runs inside the old one, in the dynamic context of the
|
|
error. It is a recursive REPL, augmented with a reified representation
|
|
of the stack, ready for debugging.
|
|
|
|
@code{,backtrace} (abbreviated @code{,bt}) displays the Scheme call
|
|
stack at the point where the error occurred:
|
|
|
|
@lisp
|
|
scheme@@(guile-user) [1]> ,bt
|
|
1 (map #<procedure string-append _> ("a" "b") ("c" #\d))
|
|
0 (string-append "b" #\d)
|
|
@end lisp
|
|
|
|
In the above example, the backtrace doesn't have much source
|
|
information, as @code{map} and @code{string-append} are both
|
|
primitives. But in the general case, the space on the left of the
|
|
backtrace indicates the line and column in which a given procedure calls
|
|
another.
|
|
|
|
You can exit a recursive REPL in the same way that you exit any REPL:
|
|
via @samp{(quit)}, @samp{,quit} (abbreviated @samp{,q}), or
|
|
@kbd{C-d}, among other options.
|
|
|
|
|
|
@node Interactive Debugging
|
|
@subsection Interactive Debugging
|
|
|
|
A recursive debugging REPL exposes a number of other meta-commands that
|
|
inspect the state of the computation at the time of the error. These
|
|
commands allow you to
|
|
|
|
@itemize @bullet
|
|
@item
|
|
display the Scheme call stack at the point where the error occurred;
|
|
|
|
@item
|
|
move up and down the call stack, to see in detail the expression being
|
|
evaluated, or the procedure being applied, in each @dfn{frame}; and
|
|
|
|
@item
|
|
examine the values of variables and expressions in the context of each
|
|
frame.
|
|
@end itemize
|
|
|
|
@noindent
|
|
@xref{Debug Commands}, for documentation of the individual
|
|
commands. This section aims to give more of a walkthrough of a typical
|
|
debugging session.
|
|
|
|
First, we're going to need a good error. Let's try to macroexpand the
|
|
expression @code{(unquote foo)}, outside of a @code{quasiquote} form,
|
|
and see how the macroexpander reports this error.
|
|
|
|
@lisp
|
|
scheme@@(guile-user)> (macroexpand '(unquote foo))
|
|
ERROR: In procedure macroexpand:
|
|
ERROR: unquote: expression not valid outside of quasiquote in (unquote foo)
|
|
Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue.
|
|
scheme@@(guile-user) [1]>
|
|
@end lisp
|
|
|
|
The @code{backtrace} command, which can also be invoked as @code{bt},
|
|
displays the call stack (aka backtrace) at the point where the debugger
|
|
was entered:
|
|
|
|
@lisp
|
|
scheme@@(guile-user) [1]> ,bt
|
|
In ice-9/psyntax.scm:
|
|
1130:21 3 (chi-top (unquote foo) () ((top)) e (eval) (hygiene #))
|
|
1071:30 2 (syntax-type (unquote foo) () ((top)) #f #f (# #) #f)
|
|
1368:28 1 (chi-macro #<procedure de9360 at ice-9/psyntax.scm...> ...)
|
|
In unknown file:
|
|
0 (scm-error syntax-error macroexpand "~a: ~a in ~a" # #f)
|
|
@end lisp
|
|
|
|
A call stack consists of a sequence of stack @dfn{frames}, with each
|
|
frame describing one procedure which is waiting to do something with the
|
|
values returned by another. Here we see that there are four frames on
|
|
the stack.
|
|
|
|
Note that @code{macroexpand} is not on the stack -- it must have made a
|
|
tail call to @code{chi-top}, as indeed we would find if we searched
|
|
@code{ice-9/psyntax.scm} for its definition.
|
|
|
|
When you enter the debugger, the innermost frame is selected, which
|
|
means that the commands for getting information about the ``current''
|
|
frame, or for evaluating expressions in the context of the current
|
|
frame, will do so by default with respect to the innermost frame. To
|
|
select a different frame, so that these operations will apply to it
|
|
instead, use the @code{up}, @code{down} and @code{frame} commands like
|
|
this:
|
|
|
|
@lisp
|
|
scheme@@(guile-user) [1]> ,up
|
|
In ice-9/psyntax.scm:
|
|
1368:28 1 (chi-macro #<procedure de9360 at ice-9/psyntax.scm...> ...)
|
|
scheme@@(guile-user) [1]> ,frame 3
|
|
In ice-9/psyntax.scm:
|
|
1130:21 3 (chi-top (unquote foo) () ((top)) e (eval) (hygiene #))
|
|
scheme@@(guile-user) [1]> ,down
|
|
In ice-9/psyntax.scm:
|
|
1071:30 2 (syntax-type (unquote foo) () ((top)) #f #f (# #) #f)
|
|
@end lisp
|
|
|
|
Perhaps we're interested in what's going on in frame 2, so we take a
|
|
look at its local variables:
|
|
|
|
@lisp
|
|
scheme@@(guile-user) [1]> ,locals
|
|
Local variables:
|
|
$1 = e = (unquote foo)
|
|
$2 = r = ()
|
|
$3 = w = ((top))
|
|
$4 = s = #f
|
|
$5 = rib = #f
|
|
$6 = mod = (hygiene guile-user)
|
|
$7 = for-car? = #f
|
|
$8 = first = unquote
|
|
$9 = ftype = macro
|
|
$10 = fval = #<procedure de9360 at ice-9/psyntax.scm:2817:2 (x)>
|
|
$11 = fe = unquote
|
|
$12 = fw = ((top))
|
|
$13 = fs = #f
|
|
$14 = fmod = (hygiene guile-user)
|
|
@end lisp
|
|
|
|
All of the values are accessible by their value-history names
|
|
(@code{$@var{n}}):
|
|
|
|
@lisp
|
|
scheme@@(guile-user) [1]> $10
|
|
$15 = #<procedure de9360 at ice-9/psyntax.scm:2817:2 (x)>
|
|
@end lisp
|
|
|
|
We can even invoke the procedure at the REPL directly:
|
|
|
|
@lisp
|
|
scheme@@(guile-user) [1]> ($10 'not-going-to-work)
|
|
ERROR: In procedure macroexpand:
|
|
ERROR: source expression failed to match any pattern in not-going-to-work
|
|
Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue.
|
|
@end lisp
|
|
|
|
Well at this point we've caused an error within an error. Let's just
|
|
quit back to the top level:
|
|
|
|
@lisp
|
|
scheme@@(guile-user) [2]> ,q
|
|
scheme@@(guile-user) [1]> ,q
|
|
scheme@@(guile-user)>
|
|
@end lisp
|
|
|
|
Finally, as a word to the wise: hackers close their REPL prompts with
|
|
@kbd{C-d}.
|
|
|
|
|
|
@node Using Guile in Emacs
|
|
@section Using Guile in Emacs
|
|
|
|
@cindex GDS
|
|
@cindex Emacs
|
|
There are several options for working on Guile Scheme code in Emacs.
|
|
The simplest are to use Emacs's standard @code{scheme-mode} for
|
|
editing code, and to run the interpreter when you need it by typing
|
|
``guile'' at the prompt of a @code{*shell*} buffer, but there are
|
|
Emacs libraries available which add various bells and whistles to
|
|
this. The following diagram shows these libraries and how they relate
|
|
to each other, with the arrows indicating ``builds on'' or
|
|
``extends''. For example, the Quack library builds on cmuscheme,
|
|
which in turn builds on the standard scheme mode.
|
|
|
|
@iftex
|
|
@center @image{scheme,5in}
|
|
@end iftex
|
|
@ifnottex
|
|
@example
|
|
@verbatiminclude scheme.txt
|
|
@end example
|
|
@end ifnottex
|
|
|
|
@dfn{scheme}, written by Bill Rozas and Dave Love, is Emacs's standard
|
|
mode for Scheme code files. It provides Scheme-sensitive syntax
|
|
highlighting, parenthesis matching, indentation and so on.
|
|
|
|
@dfn{cmuscheme}, written by Olin Shivers, provides a comint-based Scheme
|
|
interaction buffer, so that you can run an interpreter more directly
|
|
than with the @code{*shell*} buffer approach by typing @kbd{M-x
|
|
run-scheme}. It also extends @code{scheme-mode} so that there are key
|
|
presses for sending selected bits of code from a Scheme buffer to this
|
|
interpreter. This means that when you are writing some code and want to
|
|
check what an expression evaluates to, you can easily select that code
|
|
and send it to the interpreter for evaluation, then switch to the
|
|
interpreter to see what the result is. cmuscheme is included in the
|
|
standard Emacs distribution.
|
|
|
|
@dfn{Quack}, written by Neil Van Dyke, adds a number of incremental
|
|
improvements to the scheme/cmuscheme combination: convenient menu
|
|
entries for looking up Scheme-related references (such as the SRFIs);
|
|
enhanced indentation rules that are customized for particular Scheme
|
|
interpreters, including Guile; an enhanced version of the
|
|
@code{run-scheme} command that knows the names of the common Scheme
|
|
interpreters and remembers which one you used last time; and so on.
|
|
Quack is available from @uref{http://www.neilvandyke.org/quack}.
|
|
|
|
@dfn{GDS}, written by Neil Jerram, also builds on the scheme/cmuscheme
|
|
combination, but with a change to the way that Scheme code fragments
|
|
are sent to the interpreter for evaluation. cmuscheme and Quack send
|
|
code fragments to the interpreter's standard input, on the assumption
|
|
that the interpreter is expecting to read Scheme expressions there,
|
|
and then monitor the interpreter's standard output to infer what the
|
|
result of the evaluation is. GDS doesn't use standard input and
|
|
output like this. Instead, it sets up a socket connection between the
|
|
Scheme interpreter and Emacs, and sends and receives messages using a
|
|
simple protocol through this socket. The messages include requests to
|
|
evaluate Scheme code, and responses conveying the results of an
|
|
evaluation, thus providing similar function to cmuscheme or Quack.
|
|
They also include requests for stack exploration and debugging, which
|
|
go beyond what cmuscheme or Quack can do. The price of this extra
|
|
power, however, is that GDS is Guile-specific. GDS requires the
|
|
Scheme interpreter to run some GDS-specific library code; currently
|
|
this code is written as a Guile module and uses features that are
|
|
specific to Guile. GDS is now included in the Guile distribution; for
|
|
previous Guile releases (1.8.4 and earlier) it can be obtained as part
|
|
of the @code{guile-debugging} package from
|
|
@uref{http://www.ossau.uklinux.net/guile}.
|
|
|
|
Finally, @dfn{xscheme} is similar to cmuscheme --- in that it starts up
|
|
a Scheme interaction process and sends commands to that process's
|
|
standard input --- and to GDS --- in that it has support beyond
|
|
cmuscheme or Quack for exploring the Scheme stack when an error has
|
|
occurred --- but is implemented specifically for MIT/GNU Scheme. Hence
|
|
it isn't really relevant to Guile work in Emacs, except as a reference
|
|
for useful features that could be implemented in one of the other
|
|
libraries mentioned here.
|
|
|
|
In summary, the best current choice for working on Guile code in Emacs
|
|
is either Quack or GDS, depending on which of these libraries' features
|
|
you find most important. For more information on Quack, please see the
|
|
website referenced above. GDS is documented further in the rest of this
|
|
section.
|
|
|
|
@menu
|
|
* GDS Introduction::
|
|
* GDS Architecture::
|
|
* GDS Getting Started::
|
|
* Working with GDS in Scheme Buffers::
|
|
* Displaying the Scheme Stack::
|
|
* Continuing Execution::
|
|
* Associating Buffers with Clients::
|
|
* An Example GDS Session::
|
|
@end menu
|
|
|
|
|
|
@node GDS Introduction
|
|
@subsection GDS Introduction
|
|
|
|
GDS aims to allow you to work on Guile Scheme code in the same kind of
|
|
way that Emacs allows you to work on Emacs Lisp code: providing easy
|
|
access to help, evaluating arbitrary fragments of code, a nice debugging
|
|
interface, and so on. The thinking behind the GDS library is that you
|
|
will usually be doing one of two things.
|
|
|
|
@enumerate
|
|
@item
|
|
Writing or editing code. The code will be in a normal Emacs Scheme mode
|
|
buffer, and GDS extends Scheme mode to add keystrokes and menu items for
|
|
the things that are likely to be useful to you when working on code:
|
|
|
|
@itemize
|
|
@item
|
|
completing the identifier at point, with respect to the set of variable
|
|
names that are known to the associated Guile process
|
|
@item
|
|
accessing Guile's built in ``help'' and ``apropos'' commands
|
|
@item
|
|
evaluating fragments of code to check what they do, with the results
|
|
popping up in a temporary Emacs window.
|
|
@end itemize
|
|
|
|
@item
|
|
Debugging a Guile Scheme program. When your program hits an error or
|
|
stops at a trap, GDS shows you the relevant code and the Scheme stack,
|
|
and makes it easy to
|
|
|
|
@itemize
|
|
@item
|
|
look at the values of local variables
|
|
@item
|
|
see what is happening at all levels of the Scheme stack
|
|
@item
|
|
continue execution, either normally or step by step.
|
|
@end itemize
|
|
|
|
The presentation makes it very easy to move up and down the stack,
|
|
showing whenever possible the source code for each frame in another
|
|
Emacs buffer. It also provides convenient keystrokes for telling Guile
|
|
what to do next; for example, you can select a stack frame and tell
|
|
Guile to run until that frame completes, at which point GDS will display
|
|
the frame's return value.
|
|
@end enumerate
|
|
|
|
GDS can provide these facilities for any number of Guile Scheme programs
|
|
(which we often refer to as ``clients'') at once, and these programs can
|
|
be started either independently of GDS, including outside Emacs, or
|
|
specifically @emph{by} GDS.
|
|
|
|
Communication between each Guile client program and GDS uses a TCP
|
|
socket, which means that it is orthogonal to any other interfaces that
|
|
the client program has. In particular GDS does not interfere with a
|
|
program's standard input and output.
|
|
|
|
|
|
@node GDS Architecture
|
|
@subsection GDS Architecture
|
|
|
|
In order to understand the following documentation fully it will help to
|
|
have a picture in mind of how GDS works, so we briefly describe that
|
|
here. GDS consists of three components.
|
|
|
|
@itemize
|
|
@item
|
|
The GDS @dfn{interface} code is written in Emacs Lisp and runs inside
|
|
Emacs. This code, consisting of the installed files @file{gds.el} and
|
|
@file{gds-server.el}, is responsible for displaying information from
|
|
Guile in Emacs windows, and for responding to Emacs commands and
|
|
keystrokes by sending instructions back to the Guile program being
|
|
worked on.
|
|
|
|
@item
|
|
The GDS @dfn{server} code is written in Scheme and runs as an Emacs
|
|
inferior process. It acts as a multiplexer between the (possibly
|
|
multiple) Guile programs being debugged and the interface code running
|
|
in Emacs. The server code is the installed file
|
|
@file{gds-server.scm}.
|
|
|
|
@item
|
|
The GDS @dfn{client} code is written in Scheme (installed file
|
|
@file{gds-client.scm}), and must be loaded as a module by each Guile
|
|
program that wants to use GDS in any way.
|
|
@end itemize
|
|
|
|
@noindent
|
|
The following diagram shows how these components are connected to each
|
|
other.
|
|
|
|
@iftex
|
|
@center @image{gds,5in}
|
|
@end iftex
|
|
@ifnottex
|
|
@example
|
|
@verbatiminclude gds.txt
|
|
@end example
|
|
@end ifnottex
|
|
|
|
@cindex TCP, use of
|
|
The data exchanged between client and server components, and between
|
|
server and interface, is a sequence of sexps (parenthesised expressions)
|
|
that are designed so as to be directly readable by both Scheme and Emacs
|
|
Lisp. The use of a TCP connection means that the server and Emacs
|
|
interface can theoretically be on a different computer from the client
|
|
programs, but in practice there are currently two problems with
|
|
this. Firstly the GDS API doesn't provide any way of specifying a
|
|
non-local server to connect to, and secondly there is no security or
|
|
authentication mechanism in the GDS protocol. These are issues that
|
|
should be addressed in the future.
|
|
|
|
|
|
@node GDS Getting Started
|
|
@subsection Getting Started with GDS
|
|
|
|
To enable the use of GDS in your own Emacs sessions, simply add
|
|
|
|
@lisp
|
|
(require 'gds)
|
|
@end lisp
|
|
|
|
@noindent
|
|
somewhere in your @file{.emacs} file. This will cause Emacs to load the
|
|
GDS Emacs Lisp code when starting up, and to start the inferior GDS
|
|
server process so that it is ready and waiting for any Guile programs
|
|
that want to use GDS.
|
|
|
|
(If GDS's Scheme code is not installed in one of the locations in
|
|
Guile's load path, you may find that the server process fails to start.
|
|
When this happens you will see an error message from Emacs:
|
|
|
|
@lisp
|
|
error in process filter: Wrong type argument: listp, Backtrace:
|
|
@end lisp
|
|
|
|
@noindent
|
|
and the @code{gds-debug} buffer will contain a Scheme backtrace ending
|
|
with the message:
|
|
|
|
@lisp
|
|
no code for module (ice-9 gds-server)
|
|
@end lisp
|
|
|
|
@noindent
|
|
The solution for this is to customize the Emacs variable
|
|
@code{gds-scheme-directory} so that it specifies where the GDS Scheme
|
|
code is installed. Then either restart Emacs or type @kbd{M-x
|
|
gds-run-debug-server} to try starting the GDS server process again.)
|
|
|
|
For evaluations, help and completion from Scheme code buffers that you
|
|
are working on, this is all you need. The first time you do any of
|
|
these things, GDS will automatically start a new Guile client program as
|
|
an Emacs subprocess. This Guile program does nothing but wait for and
|
|
act on instructions from GDS, and we refer to it as a @dfn{utility}
|
|
Guile client. Over time this utility client will accumulate the code
|
|
that you ask it to evaluate, and you can also tell it to load complete
|
|
files or modules by sending it @code{load} or @code{use-modules}
|
|
expressions.
|
|
|
|
When you want to use GDS to work on an independent Guile
|
|
application, you need to add something to that application's Scheme code
|
|
to cause it to connect to and interact with GDS at the right times. The
|
|
following subsections describe the ways of doing this.
|
|
|
|
@subsubsection Invoking GDS when an Exception Occurs
|
|
|
|
One option is to use GDS to catch and display any exceptions that
|
|
are thrown by the application's code. If you already have a
|
|
@code{lazy-catch} or @code{with-throw-handler} around the area of code
|
|
that you want to monitor, you just need to add the following to the
|
|
handler code:
|
|
|
|
@lisp
|
|
(gds-debug-trap (throw->trap-context key args))
|
|
@end lisp
|
|
|
|
@noindent
|
|
where @code{key} and @code{args} are the first and rest arguments that
|
|
Guile passes to the handler. (In other words, they assume the handler
|
|
signature @code{(lambda (key . args) @dots{})}.) With Guile 1.8 or
|
|
later, you can also do this with a @code{catch}, by adding this same
|
|
code to the catch's pre-unwind handler.
|
|
|
|
If you don't already have any of these, insert a whole
|
|
@code{with-throw-handler} expression (or @code{lazy-catch} if your Guile
|
|
is pre-1.8) around the code of interest like this:
|
|
|
|
@lisp
|
|
(with-throw-handler #t
|
|
(lambda ()
|
|
;; Protected code here.
|
|
)
|
|
(lambda (key . args)
|
|
(gds-debug-trap (throw->trap-context key args))))
|
|
@end lisp
|
|
|
|
Either way, you will need to use the @code{(ice-9 gds-client)} and
|
|
@code{(ice-9 debugging traps)} modules.
|
|
|
|
Two special cases of this are the lazy-catch that the Guile REPL code
|
|
uses to catch exceptions in user code, and the lazy-catch inside the
|
|
@code{stack-catch} utility procedure that is provided by the
|
|
@code{(ice-9 stack-catch)} module. Both of these use a handler called
|
|
@code{lazy-handler-dispatch} (defined in @file{boot-9.scm}), which you
|
|
can hook into such that it calls GDS to display the stack when an
|
|
exception occurs. To do this, use the @code{on-lazy-handler-dispatch}
|
|
procedure as follows.
|
|
|
|
@lisp
|
|
(use-modules (ice-9 gds-client)
|
|
(ice-9 debugging traps))
|
|
(on-lazy-handler-dispatch gds-debug-trap)
|
|
@end lisp
|
|
|
|
@noindent
|
|
After this the program will use GDS to display the stack whenever it
|
|
hits an exception that is protected by a @code{lazy-catch} using
|
|
@code{lazy-handler-dispatch}.
|
|
|
|
@subsubsection Accepting GDS Instructions at Any Time
|
|
|
|
In addition to setting an exception handler as described above, a
|
|
Guile program can in principle set itself up to accept new
|
|
instructions from GDS at any time, not just when it has stopped at an
|
|
exception. This would allow the GDS user to evaluate code in the
|
|
context of the running program, without having to wait for the program
|
|
to stop first.
|
|
|
|
@lisp
|
|
(use-modules (ice-9 gds-client))
|
|
(gds-accept-input #t)
|
|
@end lisp
|
|
|
|
@code{gds-accept-input} causes the calling program to loop processing
|
|
instructions from GDS, until GDS sends the @code{continue} instruction.
|
|
This blocks the thread that calls it, however, so it will normally be
|
|
more practical for the program to set up a dedicated GDS thread and call
|
|
@code{gds-accept-input} from that thread.
|
|
|
|
For @code{select}-driven applications, an alternative approach would be
|
|
for the GDS client code to provide an API which allowed the application
|
|
to
|
|
|
|
@itemize
|
|
@item
|
|
discover the file descriptors (or Scheme ports) that are used for
|
|
receiving instruction from the GDS front end, so that it could include
|
|
these in its @code{select} call
|
|
|
|
@item
|
|
call the GDS instruction handler when @code{select} indicated data
|
|
available for reading on those descriptors/ports.
|
|
@end itemize
|
|
|
|
@noindent
|
|
This approach is not yet implemented, though.
|
|
|
|
@subsubsection Utility Guile Implementation
|
|
|
|
The ``utility'' Guile client mentioned above is a simple combination
|
|
of the mechanisms that we have just described. In fact the code for
|
|
the utility Guile client is essentially just this:
|
|
|
|
@lisp
|
|
(use-modules (ice-9 gds-client))
|
|
(named-module-use! '(guile-user) '(ice-9 session))
|
|
(gds-accept-input #f))
|
|
@end lisp
|
|
|
|
The @code{named-module-use!} line ensures that the client can process
|
|
@code{help} and @code{apropos} expressions, to implement lookups in
|
|
Guile's online help. The @code{#f} parameter to
|
|
@code{gds-accept-input} means that the @code{continue} instruction
|
|
will not cause the instruction loop to exit, which makes sense here
|
|
because the utility client has nothing to do except to process GDS
|
|
instructions.
|
|
|
|
The utility client does not use @code{on-lazy-handler-dispatch} at its
|
|
top level, because it has its own mechanism for catching and reporting
|
|
exceptions in the code that it is asked to evaluate. This mechanism
|
|
summarizes the exception and gives the user a button they can click to
|
|
see the full stack, so the end result is very similar to what
|
|
@code{on-lazy-handler-dispatch} provides. Deep inside
|
|
@code{gds-accept-input}, in the part that handles evaluating
|
|
expressions from Emacs, the GDS client code uses
|
|
@code{throw->trap-context} and @code{gds-debug-trap} to implement
|
|
this.
|
|
|
|
|
|
@node Working with GDS in Scheme Buffers
|
|
@subsection Working with GDS in Scheme Buffers
|
|
|
|
The following subsections describe the facilities and key sequences that
|
|
GDS provides for working on code in @code{scheme-mode} buffers.
|
|
|
|
@menu
|
|
* Access to Guile Help and Completion::
|
|
* Evaluating Scheme Code::
|
|
@end menu
|
|
|
|
|
|
@node Access to Guile Help and Completion
|
|
@subsubsection Access to Guile Help and Completion
|
|
|
|
The following keystrokes provide fast and convenient access to Guile's
|
|
built in help, and to completion with respect to the set of defined and
|
|
accessible symbols.
|
|
|
|
@table @kbd
|
|
@item C-h g
|
|
@findex gds-help-symbol
|
|
Get Guile help for a particular symbol, with the same results as if
|
|
you had typed @code{(help SYMBOL)} into the Guile REPL
|
|
(@code{gds-help-symbol}). The symbol to query defaults to the word at
|
|
or before the cursor but can also be entered or edited in the
|
|
minibuffer. The available help is popped up in a temporary Emacs
|
|
window.
|
|
|
|
@item C-h G
|
|
@findex gds-apropos
|
|
List all accessible Guile symbols matching a given regular expression,
|
|
with the same results as if you had typed @code{(apropos REGEXP)} into
|
|
the Guile REPL (@code{gds-apropos}). The regexp to query defaults to
|
|
the word at or before the cursor but can also be entered or edited in
|
|
the minibuffer. The list of matching symbols is popped up in a
|
|
temporary Emacs window.
|
|
|
|
@item M-@key{TAB}
|
|
@findex gds-complete-symbol
|
|
Try to complete the symbol at the cursor by matching it against the
|
|
set of all defined and accessible bindings in the associated Guile
|
|
process (@code{gds-complete-symbol}). If there are any extra
|
|
characters that can be definitively added to the symbol at point, they
|
|
are inserted. Otherwise, if there are any completions available, they
|
|
are popped up in a temporary Emacs window, where one of them can be
|
|
selected using either @kbd{@key{RET}} or the mouse.
|
|
@end table
|
|
|
|
|
|
@node Evaluating Scheme Code
|
|
@subsubsection Evaluating Scheme Code
|
|
|
|
The following keystrokes and commands provide various ways of sending
|
|
code to a Guile client process for evaluation.
|
|
|
|
@table @kbd
|
|
@item M-C-x
|
|
@findex gds-eval-defun
|
|
Evaluate the ``top level defun'' that the cursor is in, in other words
|
|
the smallest balanced expression which includes the cursor and whose
|
|
opening parenthesis is in column 0 (@code{gds-eval-defun}).
|
|
|
|
@item C-x C-e
|
|
@findex gds-eval-last-sexp
|
|
Evaluate the expression that ends just before the cursor
|
|
(@code{gds-eval-last-sexp}). This is designed so that it is easy to
|
|
evaluate an expression that you have just finished typing.
|
|
|
|
@item C-c C-e
|
|
@findex gds-eval-expression
|
|
Read a Scheme expression using the minibuffer, and evaluate that
|
|
expression (@code{gds-eval-expression}).
|
|
|
|
@item C-c C-r
|
|
@findex gds-eval-region
|
|
Evaluate the Scheme code in the marked region of the current buffer
|
|
(@code{gds-eval-region}). Note that GDS does not check whether the
|
|
region contains a balanced expression, or try to expand the region so
|
|
that it does; it uses the region exactly as it is.
|
|
@end table
|
|
|
|
If you type @kbd{C-u} before one of these commands, GDS will
|
|
immediately pop up a Scheme stack buffer, showing the requested
|
|
evaluation, so that you can single step through it. (This is achieved
|
|
by setting a @code{<source-trap>} trap at the start of the requested
|
|
evaluation; see @ref{Source Traps} for more on how those work.) The
|
|
Scheme stack display, and the options for continuing through the code,
|
|
are described in the next two sections.
|
|
|
|
|
|
@node Displaying the Scheme Stack
|
|
@subsection Displaying the Scheme Stack
|
|
|
|
When you specify @code{gds-debug-trap} as the behaviour for a trap and
|
|
the Guile program concerned hits that trap, GDS displays the stack and
|
|
the relevant Scheme source code in Emacs, allowing you to explore the
|
|
state of the program and then decide what to do next. The same
|
|
applies if the program calls @code{(on-lazy-handler-dispatch
|
|
gds-debug-trap)} and then throws an exception that passes through
|
|
@code{lazy-handler-dispatch}, except that in this case you can only
|
|
explore; it isn't possible to continue normal execution after an
|
|
exception.
|
|
|
|
The following commands are available in the stack buffer for exploring
|
|
the state of the program.
|
|
|
|
@table @asis
|
|
@item @kbd{u}, @kbd{C-p}, @kbd{@key{up}}
|
|
@findex gds-up
|
|
Select the stack frame one up from the currently selected frame
|
|
(@code{gds-up}). GDS displays stack frames with the innermost at the
|
|
top, so moving ``up'' means selecting a more ``inner'' frame.
|
|
|
|
@item @kbd{d}, @kbd{C-n}, @kbd{@key{down}}
|
|
@findex gds-down
|
|
Select the stack frame one down from the currently selected frame
|
|
(@code{gds-down}). GDS displays stack frames with the innermost at the
|
|
top, so moving ``down'' means selecting a more ``outer'' frame.
|
|
|
|
@item @kbd{@key{RET}}
|
|
@findex gds-select-stack-frame
|
|
Select the stack frame at point (@code{gds-select-stack-frame}). This
|
|
is useful after clicking somewhere in the stack trace with the mouse.
|
|
@end table
|
|
|
|
Selecting a frame means that GDS will display the source code
|
|
corresponding to that frame in the adjacent window, and that
|
|
subsequent frame-sensitive commands, such as @code{gds-evaluate} (see
|
|
below) and @code{gds-step-over} (@pxref{Continuing Execution}), will
|
|
refer to that frame.
|
|
|
|
@table @kbd
|
|
@item e
|
|
@findex gds-evaluate
|
|
Evaluate a variable or expression in the local environment of the
|
|
selected stack frame (@code{gds-evaluate}). The result is displayed in
|
|
the echo area.
|
|
|
|
@item I
|
|
@findex gds-frame-info
|
|
Show summary information about the selected stack frame
|
|
(@code{gds-frame-info}). This includes what type of frame it is, the
|
|
associated expression, and the frame's source location, if any.
|
|
|
|
@item A
|
|
@findex gds-frame-args
|
|
For an application frame, display the frame's arguments
|
|
(@code{gds-frame-args}).
|
|
|
|
@item S
|
|
@findex gds-proc-source
|
|
For an application frame, show the Scheme source code of the procedure
|
|
being called (@code{gds-proc-source}). The source code (where
|
|
available) is displayed in the echo area.
|
|
@end table
|
|
|
|
@kbd{S} (@code{gds-proc-source}) is useful when the procedure being
|
|
called was created by an anonymous @code{(lambda @dots{})} expression.
|
|
Such procedures appear in the stack trace as @code{<procedure #f
|
|
(@dots{})>}, which doesn't give you much clue as to what will happen
|
|
next. @kbd{S} will show you the procedure's code, which is usually
|
|
enough for you to identify it.
|
|
|
|
|
|
@node Continuing Execution
|
|
@subsection Continuing Execution
|
|
|
|
If it makes sense to continue execution from the stack which is being
|
|
displayed, GDS provides the following further commands in the stack
|
|
buffer.
|
|
|
|
@table @asis
|
|
@item @kbd{g}, @kbd{c}, @kbd{q}
|
|
@findex gds-go
|
|
Tell the program to continue running (@code{gds-go}). It may of course
|
|
stop again if it hits another trap, or another occurrence of the same
|
|
trap.
|
|
|
|
The multiple keystrokes reflect that you can think of this as ``going'',
|
|
``continuing'' or ``quitting'' (in the sense of quitting the GDS
|
|
display).
|
|
|
|
@item @kbd{@key{SPC}}
|
|
@findex gds-step-file
|
|
Tell the program to do a single-step to the next entry or exit of a
|
|
frame whose code comes from the same source file as the selected stack
|
|
frame (@code{gds-step-file}).
|
|
|
|
In other words, you can hit @kbd{@key{SPC}} repeatedly to step through
|
|
the code in a given file, automatically stepping @emph{over} any
|
|
evaluations or procedure calls that use code from other files (or from
|
|
no file).
|
|
|
|
If the selected stack frame has no source, the effect of this command is
|
|
the same as that of @kbd{i}, described next.
|
|
|
|
@item @kbd{i}
|
|
@findex gds-step-into
|
|
Tell the debugged program to do a single-step to the next frame entry or
|
|
exit of any kind (@code{gds-step-into}). @kbd{i} therefore steps
|
|
through code at the most detailed level possible.
|
|
|
|
@item @kbd{o}
|
|
@findex gds-step-over
|
|
Tell the debugged program to continue running until the selected stack
|
|
frame completes, and then to display its result (@code{gds-step-over}).
|
|
Note that the program may stop before then if it hits another trap; in
|
|
this case the trap telling it to stop when the marked frame completes
|
|
remains in place and so will still fire at the appropriate point.
|
|
@end table
|
|
|
|
|
|
@node Associating Buffers with Clients
|
|
@subsection Associating Buffers with Clients
|
|
|
|
The first time that you use one of GDS's evaluation, help or completion
|
|
commands from a given Scheme mode buffer, GDS will ask which Guile
|
|
client program you want to use for the operation, or if you want to
|
|
start up a new ``utility'' client. After that GDS considers the buffer
|
|
to be ``associated'' with the selected client, and so sends all further
|
|
requests to that client, but you can override this by explicitly
|
|
associating the buffer with a different client, or by removing the
|
|
default association.
|
|
|
|
@table @kbd
|
|
@item M-x gds-associate-buffer
|
|
Associate (or re-associate) the current buffer with a particular Guile
|
|
client program. The available clients are listed, and you can also
|
|
choose to start up a new ``utility'' client for this buffer to associate
|
|
with.
|
|
|
|
@item M-x gds-dissociate-buffer
|
|
Dissociate the current buffer from its client, if any. This means that
|
|
the next time you use an evaluation, help or completion command, GDS
|
|
will ask you again which client to send the request to.
|
|
@end table
|
|
|
|
When a buffer is associated with a client program, the buffer's modeline
|
|
shows whether the client is currently able to accept instruction from
|
|
GDS. This is done by adding one of the following suffixes to the
|
|
``Scheme'' major mode indicator:
|
|
|
|
@table @asis
|
|
@item :ready
|
|
The client program (or one of its threads, if multithreaded) is
|
|
currently ready to accept instruction from GDS. In other words, if you
|
|
send it a help or evaluation request, you should see the result pretty
|
|
much immediately.
|
|
|
|
@item :running
|
|
The client program is not currently able to accept instruction from
|
|
GDS. This means that it (or all of its threads, if multithreaded) is
|
|
busy, or waiting for input other than from GDS.
|
|
|
|
@item :debug
|
|
The client program (or one of its threads, if multithreaded) is stopped
|
|
in ``debugging mode'' with GDS displaying the stack for a trap or
|
|
exception. It is waiting for instruction from GDS on what to do next.
|
|
@end table
|
|
|
|
|
|
@node An Example GDS Session
|
|
@subsection An Example GDS Session
|
|
|
|
Create a file, @file{testgds.scm} say, for experimenting with GDS and
|
|
Scheme code, and type this into it:
|
|
|
|
@lisp
|
|
(use-modules (ice-9 debugging traps)
|
|
(ice-9 gds-client)
|
|
(ice-9 debugging example-fns))
|
|
(install-trap (make <procedure-trap>
|
|
#:behaviour gds-debug-trap
|
|
#:procedure fact1))
|
|
@end lisp
|
|
|
|
@noindent
|
|
Now select all of this code and type @kbd{C-c C-r} to send the selected
|
|
region to Guile for evaluation. GDS will ask you which Guile process to
|
|
use; unless you know that you already have another Guile application
|
|
running and connected to GDS, choose the ``Start a new Guile'' option,
|
|
which starts one of the ``utility'' processes described in @ref{GDS
|
|
Getting Started}.
|
|
|
|
The results of the evaluation pop up in a window like this:
|
|
|
|
@lisp
|
|
(use-modules (ice-9 debugging traps)\n @dots{}
|
|
|
|
;;; Evaluating subexpression 1 in current module (guile-user)
|
|
@result{} no (or unspecified) value
|
|
|
|
;;; Evaluating subexpression 2 in current module (guile-user)
|
|
@result{} no (or unspecified) value
|
|
|
|
--:** *Guile Evaluation* (Scheme:ready)--All------------
|
|
@end lisp
|
|
|
|
@noindent
|
|
this tells you that the evaluation was successful but that the return
|
|
values were unspecified. Its effect was to load a module of example
|
|
functions and set a trap on one of these functions, @code{fact1}, that
|
|
calculates the factorial of its argument.
|
|
|
|
If you now call @code{fact1}, you can see the trap and GDS's stack
|
|
display in action. To do this add
|
|
|
|
@lisp
|
|
(fact1 4)
|
|
@end lisp
|
|
|
|
@noindent
|
|
to your @file{testgds.scm} buffer and type @kbd{C-x C-e} (which
|
|
evaluates the expression that the cursor is just after the end of).
|
|
The result should be that a GDS stack window like the following
|
|
appears:
|
|
|
|
@lisp
|
|
Calling procedure:
|
|
=> s [fact1 4]
|
|
s [primitive-eval (fact1 4)]
|
|
|
|
|
|
--:** PID 28729 (Guile-Debug)--All------------
|
|
@end lisp
|
|
|
|
This stack tells you that Guile is about to call the @code{fact1}
|
|
procedure, with argument 4, and you can step through this call in
|
|
detail by pressing @kbd{i} once and then @kbd{@key{SPC}}
|
|
(@pxref{Continuing Execution}).
|
|
|
|
(@kbd{i} is needed as the first keystroke rather than @kbd{@key{SPC}},
|
|
because the aim here is to step through code in the @code{(ice-9
|
|
debugging example-fns)} module, whose source file is
|
|
@file{@dots{}/ice-9/debugging/example-fns.scm}, but the initial
|
|
@code{(fact1 4)} call comes from the Guile session, whose ``source
|
|
file'' Guile presents as @file{standard input}. If the user starts by
|
|
pressing @kbd{@key{SPC}} instead of @kbd{i}, the effect is that the
|
|
program runs until it hits the first recursive call @code{(fact1 (- n
|
|
1))}, where it stops because of the trap on @code{fact1} firing again.
|
|
At this point, the source file @emph{is}
|
|
@file{@dots{}/ice-9/debugging/example-fns.scm}, because the recursive
|
|
@code{(fact1 (- n 1))} call comes from code in that file, so further
|
|
pressing of @kbd{@key{SPC}} successfully single-steps through this
|
|
file.)
|
|
|
|
|
|
@c Local Variables:
|
|
@c TeX-master: "guile.texi"
|
|
@c End:
|