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:

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.