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
|
implement Pretty, Mainmodule;
include "sys.m";
sys: Sys;
include "draw.m";
include "sh.m";
sh: Sh;
n_BLOCK, n_VAR, n_BQ, n_BQ2, n_REDIR,
n_DUP, n_LIST, n_SEQ, n_CONCAT, n_PIPE, n_ADJ,
n_WORD, n_NOWAIT, n_SQUASH, n_COUNT,
n_ASSIGN, n_LOCAL,
GLOB: import Sh;
include "alphabet/reports.m";
reports: Reports;
Report, report: import reports;
include "alphabet.m";
alphabet: Alphabet;
Value: import alphabet;
Pretty: module {};
typesig(): string
{
return "sc";
}
init()
{
sys = load Sys Sys->PATH;
alphabet = load Alphabet Alphabet->PATH;
sh = load Sh Sh->PATH;
sh->initialise();
}
quit()
{
}
run(nil: ref Draw->Context, nil: ref Reports->Report, nil: chan of string,
nil: list of (int, list of ref Value),
args: list of ref Value): ref Value
{
{
return ref Value.Vs(pretty((hd args).c().i, 0));
}exception{
"bad expr" =>
return nil;
}
}
pretty(n: ref Sh->Cmd, depth: int): string
{
if (n == nil)
return nil;
s: string;
case n.ntype {
n_BLOCK =>
s = "{\n"+tabs(depth+1)+pretty(n.left,depth+1) + "\n"+tabs(depth)+"}";
n_VAR =>
s = "$" + pretty(n.left, depth);
n_LIST =>
s = "(" + pretty(n.left, depth) + ")";
n_SEQ =>
s = pretty(n.left, depth) + "\n"+tabs(depth)+pretty(n.right, depth);
n_PIPE =>
s = pretty(n.left, depth) + " |\n"+tabs(depth)+pretty(n.right, depth);
n_ADJ =>
s = pretty(n.left, depth) + " " + pretty(n.right, depth);
n_WORD =>
s = quote(n.word, 1);
n_BQ2 =>
# if we can't do it, revert to ugliness.
{
s = "\"" + pretty(n.left, depth);
} exception {
"bad expr" =>
s = sh->cmd2string(n);
}
* =>
raise "bad expr";
}
return s;
}
tabs(n: int): string
{
s: string;
while(n-- > 0)
s[len s] = '\t';
return s;
}
# stolen from sh.y
quote(s: string, glob: int): string
{
needquote := 0;
t := "";
for (i := 0; i < len s; i++) {
case s[i] {
'{' or '}' or '(' or ')' or '`' or '&' or ';' or '=' or '>' or '<' or '#' or
'|' or '*' or '[' or '?' or '$' or '^' or ' ' or '\t' or '\n' or '\r' =>
needquote = 1;
'\'' =>
t[len t] = '\'';
needquote = 1;
GLOB =>
if (glob) {
if (i < len s - 1)
i++;
}
}
t[len t] = s[i];
}
if (needquote || t == nil)
t = "'" + t + "'";
return t;
}
|