summaryrefslogtreecommitdiff
path: root/appl/cmd/stackv.b
diff options
context:
space:
mode:
authorforsyth <forsyth@vitanuova.com>2010-08-02 14:49:50 +0100
committerforsyth <forsyth@vitanuova.com>2010-08-02 14:49:50 +0100
commit66f5808b81b1df84bc57c4f7b9d487201bc162fb (patch)
treefe09448075dcf50ecca78a673e16ad84a666d3da /appl/cmd/stackv.b
parent7781741266783e4df3b35d42a55e8e504838898b (diff)
20100802-1449
Diffstat (limited to 'appl/cmd/stackv.b')
-rw-r--r--appl/cmd/stackv.b116
1 files changed, 85 insertions, 31 deletions
diff --git a/appl/cmd/stackv.b b/appl/cmd/stackv.b
index 4688f804..be842aa5 100644
--- a/appl/cmd/stackv.b
+++ b/appl/cmd/stackv.b
@@ -16,7 +16,8 @@ include "bufio.m";
stderr: ref Sys->FD;
stdout: ref Iobuf;
-hasht := array[97] of list of string;
+
+hasht := array[97] of (int, array of int);
Stackv: module {
init: fn(ctxt: ref Draw->Context, argv: list of string);
@@ -33,7 +34,7 @@ badmodule(p: string)
currp: ref Prog;
showtypes := 1;
showsource := 0;
-sep := "\t";
+showmodule := 0;
init(nil: ref Draw->Context, argv: list of string)
{
@@ -52,7 +53,7 @@ init(nil: ref Draw->Context, argv: list of string)
stdout = bufio->fopen(sys->fildes(1), Sys->OWRITE);
arg->init(argv);
- arg->setusage("stackv [-Tl] [-i indent] [-r maxdepth] [-s dis sbl]... [pid[.sym...] ...]");
+ arg->setusage("stackv [-Tlm] [-r maxdepth] [-s dis sbl]... [pid[.sym]...] ...");
sblfile := "";
while((opt := arg->opt()) != 0){
case opt {
@@ -61,12 +62,12 @@ init(nil: ref Draw->Context, argv: list of string)
sblfile = arg->earg();
'l' =>
showsource = 1;
+ 'm' =>
+ showmodule = 1;
'r' =>
maxrecur = int arg->earg();
'T' =>
showtypes = 0;
- 'i' =>
- sep = arg->earg();
* =>
arg->usage();
}
@@ -137,7 +138,7 @@ pexp(stk: array of ref Exp, toks: list of string, depth: int)
exp := stackfindsym(stk, toks, depth);
if(exp == nil)
return;
- pname(exp, depth);
+ pname(exp, depth, nil);
stdout.putc('\n');
}
}
@@ -218,7 +219,7 @@ pfn(exp: ref Exp, depth: int)
if((e := getname(exps, "args")) != nil){
args := e.expand();
for(i := 0; i < len args; i++){
- pname(args[i], depth+1);
+ pname(args[i], depth+1, nil);
if(i != len args - 1)
stdout.puts(", ");
}
@@ -230,7 +231,15 @@ pfn(exp: ref Exp, depth: int)
locals := e.expand();
for(i := 0; i < len locals; i++){
indent(depth+1);
- pname(locals[i], depth+1);
+ pname(locals[i], depth+1, nil);
+ stdout.puts("\n");
+ }
+ }
+ if(showmodule && (e = getname(exps, "module")) != nil){
+ mvars := e.expand();
+ for(i := 0; i < len mvars; i++){
+ indent(depth+1);
+ pname(mvars[i], depth+1, "module.");
stdout.puts("\n");
}
}
@@ -256,8 +265,9 @@ strval(v: string): string
return v;
}
-pname(exp: ref Exp, depth: int)
+pname(exp: ref Exp, depth: int, prefix: string)
{
+ name := prefix+symname(exp);
(v, w) := exp.val();
if (!w && v == nil) {
stdout.puts(sys->sprint("%s: %s = novalue", symname(exp), exp.typename()));
@@ -267,18 +277,18 @@ pname(exp: ref Exp, depth: int)
Tfn =>
pfn(exp, depth);
Tint =>
- stdout.puts(sys->sprint("%s := %s", symname(exp), v));
+ stdout.puts(sys->sprint("%s := %s", name, v));
Tstring =>
- stdout.puts(sys->sprint("%s := %s", symname(exp), strval(v)));
+ stdout.puts(sys->sprint("%s := %s", name, strval(v)));
Tbyte or
Tbig or
Treal =>
- stdout.puts(sys->sprint("%s := %s %s", symname(exp), exp.typename(), v));
+ stdout.puts(sys->sprint("%s := %s %s", name, exp.typename(), v));
* =>
if(showtypes)
- stdout.puts(sys->sprint("%s: %s = ", symname(exp), exp.typename()));
+ stdout.puts(sys->sprint("%s: %s = ", name, exp.typename()));
else
- stdout.puts(sys->sprint("%s := ", symname(exp)));
+ stdout.puts(sys->sprint("%s := ", name));
pval(exp, v, w, depth);
}
}
@@ -390,7 +400,7 @@ pgenval(exp: ref Exp, v: string, w: int, depth: int)
}else{
for (i := 0; i < len exps; i++){
indent(depth+1);
- pname(exps[i], depth+1);
+ pname(exps[i], depth+1, nil);
stdout.puts("\n");
}
}
@@ -412,36 +422,80 @@ symname(exp: ref Exp): string
indent(n: int)
{
while(n-- > 0)
- stdout.puts(sep);
+ stdout.putc('\t');
+}
+
+ref2int(v: string): int
+{
+ if(v == nil)
+ error("bad empty value for ref");
+ i := 0;
+ n := len v;
+ if(v[0] == '@')
+ i = 1;
+ else{
+ # skip array bounds
+ if(v[0] == '['){
+ for(; i < n && v[i] != ']'; i++)
+ ;
+ if(i >= n - 2 || v[i+1] != ' ' || v[i+2] != '@')
+ error("bad value for ref: "+v);
+ i += 3;
+ }
+ }
+ if(n - i > 8)
+ error("64-bit pointers?");
+ p := 0;
+ for(; i < n; i++){
+ c := v[i];
+ case c {
+ '0' to '9' =>
+ p = (p << 4) + (c - '0');
+ 'a' to 'f' =>
+ p = (p << 4) + (c - 'a' + 10);
+ * =>
+ error("bad value for ref: "+v);
+ }
+ }
+ return p;
}
pref(v: string): int
{
- if(addref(v) == 0){
+ if(v == "nil"){
+ stdout.puts("nil");
+ return 0;
+ }
+ if(addref(ref2int(v)) == 0){
stdout.puts(v);
- if(v != "nil")
- stdout.puts("(qv)");
+ stdout.puts("(qv)");
return 0;
}
return 1;
}
-addref(v: string): int
+# hash table implementation that tries to be reasonably
+# parsimonious on memory usage.
+addref(v: int): int
{
- slot := hashfn(v, len hasht);
- for(l := hasht[slot]; l != nil; l = tl l)
- if((hd l) == v)
+ slot := (v & 16r7fffffff) % len hasht;
+ (n, a) := hasht[slot];
+ for(i := 0; i < n; i++)
+ if(a[i] == v)
return 0;
- hasht[slot] = v :: hasht[slot];
+ if(n == len a){
+ if(n == 0)
+ n = 3;
+ t := array[n*3/2] of int;
+ t[0:] = a;
+ hasht[slot].t1 = t;
+ }
+ a[hasht[slot].t0++] = v;
return 1;
}
-hashfn(s: string, n: int): int
+error(e: string)
{
- h := 0;
- m := len s;
- for(i:=0; i<m; i++){
- h = 65599*h+s[i];
- }
- return (h & 16r7fffffff) % n;
+ sys->fprint(sys->fildes(2), "stackv: error: %s\n", e);
+ raise "fail:error";
}