Next: Eight Bit Clean Issues Up: Customization Previous: Hooks Contents

## S-Lang Programming Hints (Debugging)

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 returns

Simply 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_one

in 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:

1. Use the `insert` function to insert the contents of a variable into the current buffer.

2. Use the `error` function to abort the function and display the value of a variable in the minibuffer.

3. Use the `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.

Next: Eight Bit Clean Issues Up: Customization Previous: Hooks Contents