/* * debug.sli * * This file is part of NEST. * * Copyright (C) 2004 The NEST Initiative * * NEST is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * NEST is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NEST. If not, see <http://www.gnu.org/licenses/>. * */ % Debuggin support for SLI /* BeginDocumentation Name: debug.sli - Debugging support for sli Synopsis: (debug) run Description: Defines operators which support debugging. All auxiliary operators are defined in the dictionary debugdict. Author: Marc-Oliver Gewaltig, Honda R&D FirstVersion: July 9 1999 SeeAlso: inspect */ systemdict begin %% Resume operation after a system signal /* BeginDocumentation Name: resume - Resume interrupted SLI program after a system signal. Synopsis: resume Description: resume tries to restore the state of the interpreter stacks to their state immediately before the signal. The following stacks are restored in this order: 1. operand stack from errordict /ostack 2. dictionary stack from errordict /ostack 3. execution stack from errordict /estack Author: Marc-Oliver Gewaltig, Honda R&D FirstVersion: Sept. 10 1999 SeeAlso: raiseerror */ /resume { errordict dup /errorname known { /errorname get /SystemSignal eq { errordict /errorname undef %% clear error state errordict /ostack get %% Restore operand stack restoreostack errordict /dstack get %% Restore dictionary stack restoredstack errordict /estack get %% Restore execution stack restoreestack %% Note that this operation does not return! } { errordict /dstack get %% Restore dictionary stack restoredstack %(Resume only possible after /SignalError) 100 message } ifelse } { pop (Resume only possible after /SignalError) 100 message } ifelse } def /debugdict << /SingleStepMode false >> def /* BeginDocumentation Name: inspect - inspect an object Synopsis: any inspect -> - any ? -> - Description: inspect (or ?) displays the contents of an object in a formatted form. SLI procedures are displayed with indentation according to their nesting level. The amount of indentation is controlled by the value of :INDENTATION, which is defined in debugdir. The most common usage is to apply inspect to a literal. Inspect resolves the name in the current dictionary context and gives a formatted output of the contents. Numeric values are displayed with the letters (d) or (i) to indicate the type of the numeral. The display of arrays is truncated, if they are longer than the value of :ARRAYLIMIT. the remaining entries are replaced by an elipsis ( ... ). Examples: /stack inspect /stack : proceduretype := { 0i 1i -count- 3i -sub_ii- { -index- = } -for- } SLI ] [10] Range inspect [ 1i 2i 3i 4i 5i ... ] SLI ] [1. 10.] Range inspect [ 1d 2d 3d 4d 5d ... ] Bugs: The displays of TypeTrees and Procedures could be more elaborated. Maybe the next version will show the individual parameter-lists of a TypeTree. Author: Marc-Oliver Gewaltig, Honda R&D FirstVersion: July 9 1999 Remarks: ? can be used as shortcut to inspect SeeAlso: */ /inspect { debugdict begin inspect end } bind def /? /inspect load def end debugdict begin /bdef {bind def} bind def /:INDENTATION 2 def /:INDENTCOUNT 0 def /:ARRAYLIMIT 5 def /:FILLCHAR ( ) def % ostream tab /tab { :INDENTCOUNT { :FILLCHAR <- } repeat } bdef /lf { (\n) <- } bdef /moreindent { /:INDENTCOUNT dup load :INDENTATION add def } def /lessindent { /:INDENTCOUNT dup load :INDENTATION sub def } def % ostream proc inspect /:pr_p { exch % proc ostream ({) <- endl moreindent exch % ostream proc cvlit % ostream array { % ostream item exch tab exch pr endl } forall lessindent tab (}) <- } def % ostream litproc pprint /:pr_lp { exec :pr_p } def % ostream array /:pr_a { size 0 eq { <-- } { dup 3 -1 roll tab ([ ) <- exch 0 :ARRAYLIMIT getinterval { pr ( ) <- } forall exch length :ARRAYLIMIT gt { ( ... ) <- } if (]) <- } ifelse } bdef /:pr_d { exch showpoint exch <- noshowpoint } def /:pr_i { <- } def /:pr_t { % stream trie -> stream 1 index exch trieinfo } def /:pr_any /<-- load def /:pr trie [/ostreamtype /anytype] /:pr_any load addtotrie [/ostreamtype /proceduretype] /:pr_p load addtotrie [/ostreamtype /arraytype] /:pr_a load addtotrie [/ostreamtype /literalproceduretype] /:pr_lp load addtotrie [/ostreamtype /doubletype] /:pr_d load addtotrie [/ostreamtype /integertype] /:pr_i load addtotrie [/ostreamtype /trietype] /:pr_t load addtotrie def /pr_any { :pr } def /pr trie [/ostreamtype /anytype] /pr_any load addtotrie def /inspect_any { debugdict begin cout exch pr endl ; end } def /inspect_l { debugdict begin dup cout exch % /lit ostream /lit <-- ( : ) <- 1 index lookup { type <- ( := ) <- lf exch load pr endl ; } { (undefined) <- endl 2 npop } ifelse end } def /inspect trie [/anytype] /inspect_any load addtotrie [/literaltype] /inspect_l load addtotrie def /? { inspect } bdef end /* BeginDocumentation Name: break - interrupt the execution of a procedure for inspection SeeAlso: continue */ /debugprompt { (break mode ) count 1 gt_ii % counter has to be corrected for operative { % objects on the stack ([) join_s count 1 sub_ii cvs join_s } if (] ) join_s } bind def /break { { { debugprompt GNUreadline { cst cvx_a stopped {handleerror} if } if } stopped {handleerror} if % to catch signals } loop } bind def /* BeginDocumentation Name: continue - continue an interrupted procedure SeeAlso: break */ /continue /exit load def