1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
############################################################################
#
# File: scat.icn
#
# Subject: Program to produce call/result scatterplot
#
# Author: Clinton Jeffery
#
# Date: November 11, 1997
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# Press the left mouse button atop any plotted point to see the list of
# procedures at that point. Execution (and point motion) is suspended
# until the mouse button is released.
#
############################################################################
#
# Requires: Version 9 graphics
#
############################################################################
#
# Links: eemutils, vinit
#
############################################################################
#
# Includes: evdefs.icn
#
############################################################################
$include "evdefs.icn"
link emutils
link evinit
global at, # table of counts of procedures at a given point
call, # table of call counts
rslt # table of result counts
record activation (p, parent, children)
procedure main(av)
local mask, maxmax, maxmatch, current_proc, L, max, i, k, child, e
EvInit(av) | stop("*** cannot load SP")
kill_output()
&window := open("scat","x","geometry=150x180") | stop("can't open window")
current_proc := activation(,activation(,,,,[]),[])
call := table(0)
rslt := table(0)
at := table(0)
mask := ProcMask ++ E_MXevent
maxmax := 0
maxmatch := 0
while EvGet(mask) do {
case &eventcode of {
E_Pcall: {
move(&eventvalue, 1, 0)
current_proc := activation(&eventvalue, current_proc, [])
put(current_proc.parent.children, current_proc)
}
E_Psusp: {
move(current_proc.p, 0, 1)
current_proc := current_proc.parent
}
E_Presum: {
current_proc := current_proc.children[-1]
}
E_Pret: {
move(current_proc.p, 0, 1)
pull(current_proc.parent.children)
current_proc := current_proc.parent
}
E_Pfail: {
pull(current_proc.parent.children)
current_proc := current_proc.parent
}
E_Prem: {
child := pull(current_proc.children)
current_proc.children |||:= child.children
}
E_MXevent: {
case &eventvalue of {
"q" | "\033": stop("terminated")
&lpress | &ldrag : {
repeat {
L := []
every k := key(call) do {
if -3 < 2*log(call[k]+2,1.25)+2 - &x < 3 &
-3 < 2*log(rslt[k]+2,1.25)+2 - &y < 3 then {
put(L, procedure_name(k))
}
}
if max := * (L[1]) then {
every max <:= *( !L )
maxmax <:= max
}
maxmatch <:= *L
&col := WAttrib("columns") - maxmax
&row := WAttrib("lines") - maxmatch - 1
EraseArea(&x,&y)
if *L > 0 then {
every i := 1 to *L do {
GotoRC(WAttrib("lines")-*L+i,WAttrib("columns")-max)
writes(&window,L[i])
}
e := Event()
every i := 1 to *L do {
GotoRC(WAttrib("lines")-*L+i,WAttrib("columns")-max)
writes(&window,L[i])
}
}
else e := Event()
if e === &lrelease then break
}
}
}
}
}
}
end
procedure procedure_name(p)
return image(p) ? { ="procedure "; tab(0) }
end
procedure move(who, iscall, isrslt)
if (at[integer(2*log(call[who]+2,1.25)) || "," || integer(2*log(rslt[who]+2,1.25))] -:= 1) = 0 then
EraseArea(2*log(call[who]+2,1.25) + 2, 2*log(rslt[who]+2,1.25) + 2, 2, 2)
call[who] +:= iscall
rslt[who] +:= isrslt
if (at[integer(2*log(call[who]+2,1.25)) || "," || integer(2*log(rslt[who]+2,1.25))] +:= 1) = 1 then
FillRectangle(2*log(call[who]+2,1.25) + 2, 2*log(rslt[who]+2,1.25) + 2, 2, 2)
end
|