/*
* 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