In an interpreted language, it is often possible to recover from errors. When an error occurs Basis does its best to help the user understand the nature of the problem. A user variable debug governs the error message that goes to the terminal and logfile. The variable debug can be assigned the values yes or no. The default value is no, and error messages will be brief. If debug = yes, a much more thorough error message goes to the terminal and logfile. If Basis was executing, information is given about the location where the error occurred; a complete trace of all the local variables and arguments to any functions is given, and some symbolic information about the error is given. Whether debug = yes or no, a file is produced that contains the debug information. The filename is first the contents of the variable probname, then a numerical extenstion, then the file type appended.
Here is an example. The call to function boom fails when it attempts to add two arrays that are not the same length. The error message, ``Operands not compatible in size for +'' is followed by a more detailed error analysis because debug = yes.
Basis> function boom(a,b) Basis> chameleon temp Basis> temp= (a+b)/2 Basis> return [temp,temp**2] Basis> endf Basis> debug=yes;boom([2,2],[2,3,4]) parcnfm: Operands not compatible in size for + Writing traceback info to file problem.001 Returned to user input level.
The relevant contents of the file problem.001 are:
Here is the information I have on where you were: A call to boom containing the problem. The error occurred in the assignment or append statement: temp = expression The following lines contain clues(not facts) about the r. h. s. b + a+b temp Parser's action number = 115(ADD), program counter = 45. Group: Locals_boom Num Vars: 3 a(2) 1: - 2 2 b(3) 1: - 2 3 4 temp = 0
If the parser function errortrp("off") has been called, no error recovery is attempted.
A compiled routine kaboom(iflag) can be called from the parser to force a return to the parser. If iflag is greater or equal to 0 Basis acts as if an error has taken place, and produces a trace file. If iflag is set negative, Basis returns to the parser without any error messages.
function subt(a,b) if( a < b) then remark "Error: subt called with a < b" call kaboom(-1) endif return a-b endf
In interpreting the information printed out when debug = yes, you should begin with the error message itself, examine the description of the nesting levels to find out where you were generally, and examine the symbols listed for some hints about the parts of the expressions involved in the error. As a last resort, the pc counter can be used in conjunction with the list command. The value of the pc counter is given in the trace file. Do a list on the function in which the error occurred, and when asked answer `y' to the question about viewing the intermediate code. The listing which results shows the operations being performed and using the pc you should be able to pinpoint which instructions caused the error. For example, in the example above, boom reported that the error occurred at pc = 45.
Basis> list boom boom(a,b) user-defined function Minimum number of arguments: 2 Maximum number of arguments: 2 User-defined function, begins at absolute address 3967064 Function consists of 104 words of intermediate code. NAME TYPE boom varies a varies b varies Dump intermediate code? (y|n) y
pc opcode stack operation 1: 16 Enter function, set up actual parameters. 3: 421 7 REGULAR_SCOPE 5: 404 9 CHAMELEON 7: -100 10 TOKEN = 'temp' (name). 12: 412 10 SCALAR DECLARE 14: 415 10 NO INITIAL VALUE 16: 410 11 CREATE VARIABLE 18: -100 8 TOKEN = 'temp' (name). 23: 1 8 ID->LHS 25: 10 9 BEGIN RHS 27: -100 11 TOKEN = 'a' (name). 32: 1 11 ID->LHS 34: 136 11 <LHS>-><FACTOR> 36: -100 13 TOKEN = 'b' (name). 41: 1 13 ID->LHS 43: 136 13 <LHS>-><FACTOR> 45: 115 13 ADD 47: 130 12 MOVE-1 49: 136 10 <LHS>-><FACTOR> 51: -101 12 TOKEN = '2' (integer constant). value = 2. 56: 11 12 PUSH VALUE
58: 121 12 DIVIDE 60: 3 10 ASSIGN 62: -100 10 TOKEN = 'temp' (name). 67: 1 10 ID->LHS 69: 136 10 <LHS>-><FACTOR> 71: 8 10 FETCH VARIABLE 73: -100 12 TOKEN = 'temp' (name). 78: 1 12 ID->LHS 80: 136 12 <LHS>-><FACTOR> 82: -101 14 TOKEN = '2' (integer constant). value = 2. 87: 11 14 PUSH VALUE 89: 126 14 POWER 91: 101 12 EXPLIST 93: 129 11 [EXPLIST] 95: 136 9 <LHS>-><FACTOR> 97: 19 9 FETCH COPY 99: 17 9 RET 101: 18 8 NULLRET 103: 17 9 RET ***************************