This section assumes some knowledge about S-Lang and is designed to
explain how to debug S-Lang routines quickly. For information about
S-Lang, read slang.txt
.
There are two ways of loading a file of S-Lang code into jed. The
most common way is through the function evalfile
. If an error
occurs while loading a file, jed will give some indication of where the
problem lies by displaying the line number and the offending bit of
S-Lang code in the minibuffer. In practice though, this can be quite
inefficient. The evalfile
function is primarily designed to load
debugged and tested S-Lang code.
The best way to develop and test S-Lang code with jed is to use the
function evalbuffer
. Simply load the piece of code into jed as an
ordinary file, press ESC X and enter the function
evalbuffer
If the piece of code in the buffer has any syntax
errors, jed will put the cursor on the error. This is the best way to
spot compile time errors such as syntax errors. However, this will not
catch runtime errors.
When a runtime error occurs, jed will put the cursor on the top level
function where the original call was made and NOT the actual location of
the function. To aid in determining where an error occurs, jed can be
made to give a symbolic traceback. As the S-Lang runtime stack unwinds,
S-Lang will simply print the name of function at that particular level.
If the function includes local variables, their values will be dumped as
well. Hence, it is easy to quickly narrow the location of an error down
to function where the error occurs. By default, the traceback is
disabled. The traceback is enabled by setting the S-Lang variable
_traceback
to a non-zero value. It is simpliest to just press
CTRL-X ESC and enter _traceback = 1
at the S-Lang
prompt. This is one of those times where one needs access to the
S-Lang> prompt and not the M-x prompt. For example, consider
the following piece of code:
define fun_two () {forever {}} % loops forever define fun_one () {fun_two ()} % calls fun_two-- never returnsSimply enter the above into an empty jed
*scratch*
buffer, then
press CTRL-X ESC and enter:
_traceback = 1; () = evalbuffer (); fun_one ();This will turn on tracebacks, evaluate the buffer and call the function
fun_one
. jed will then be put into an infinite loop which
can only be stopped by pressing the abort character which by default is
CTRL-G. Doing so, will produce the traceback messages
S-Lang Traceback: fun_two S-Lang Traceback: fun_onein addition to the error message User Break!. Of course, this technique only narrows down the source of an error to a particular function. To proceed further, it may necessary to put ``print'' statements at suitable places in the function. There are several ways to do this:
insert
function to insert the contents of a variable
into the current buffer.
error
function to abort the function and display the
value of a variable in the minibuffer.
message
function to display the value of a variable in
the minibuffer. Unlike error
, the message
function does
not abort the execution of the function.
Since each of these functions require a string argument, it is usually
best to call the string
function first for the conversion followed
by the output function. This has to be done anyway if it is desired to
get the contents of an integer variable. Although the second approach is
prehaps the most useful in practice, it is somtimes appropriate to use a
combination of these techniques.
Finally, to print the entire stack, one can use the print_stack
function. This function dumps the S-Lang runtime stack into the
*traceback* buffer.
Since S-Lang is an interpreted language, judicious application of the above techniques should lead very quickly to the source of any errors.