xref: /inferno-os/appl/cmd/mash/dump.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1#
2#	Output routines.
3#
4
5#
6#	Echo list of strings.
7#
8echo(e: ref Env, s: list of string)
9{
10	out := e.outfile();
11	if (out == nil)
12		return;
13	out.putc('+');
14	for (t := s; t != nil; t = tl t) {
15		out.putc(' ');
16		out.puts(hd t);
17	}
18	out.putc('\n');
19	out.close();
20}
21
22#
23#	Return text representation of Word/Item/Cmd.
24#
25
26Word.word(w: self ref Word, d: string): string
27{
28	if (w == nil)
29		return nil;
30	if (d != nil)
31		return d + w.text;
32	if (w.flags & Wquoted)
33		return enquote(w.text);
34	return w.text;
35}
36
37Item.text(i: self ref Item): string
38{
39	if (i == nil)
40		return nil;
41	case i.op {
42	Icaret =>
43		return i.left.text() + " ^ " + i.right.text();
44	Iicaret =>
45		return i.left.text() + i.right.text();
46	Idollarq =>
47		return i.word.word("$\"");
48	Idollar or Imatch =>
49		return i.word.word("$");
50	Iword =>
51		return i.word.word(nil);
52	Iexpr =>
53		return "(" + i.cmd.text() + ")";
54	Ibackq =>
55		return "`" + group(i.cmd);
56	Iquote =>
57		return "\"" + group(i.cmd);
58	Iinpipe =>
59		return "<" + group(i.cmd);
60	Ioutpipe =>
61		return ">" + group(i.cmd);
62	* =>
63		return "?" + string i.op;
64	}
65}
66
67words(l: list of ref Item): string
68{
69	s: string;
70	while (l != nil) {
71		if (s == nil)
72			s = (hd l).text();
73		else
74			s = s + " " + (hd l).text();
75		l = tl l;
76	}
77	return s;
78}
79
80redir(s: string, c: ref Cmd): string
81{
82	if (c == nil)
83		return s;
84	for (l := c.redirs; l != nil; l = tl l) {
85		r := hd l;
86		s = s + " " + rdsymbs[r.op] + " " + r.word.text();
87	}
88	return s;
89}
90
91cmd2in(c: ref Cmd, s: string): string
92{
93	return c.left.text() + " " + s + " " + c.right.text();
94}
95
96group(c: ref Cmd): string
97{
98	if (c == nil)
99		return "{ }";
100	return redir("{ " + c.text() + " }", c);
101}
102
103sequence(c: ref Cmd): string
104{
105	s: string;
106	do {
107		r := c.right;
108		t := ";";
109		if (r.op == Casync) {
110			r = r.left;
111			t = "&";
112		}
113		if (s == nil)
114			s = r.text() + t;
115		else
116			s = r.text() + t + " " + s;
117		c = c.left;
118	} while (c != nil);
119	return s;
120}
121
122Cmd.text(c: self ref Cmd): string
123{
124	if (c == nil)
125		return nil;
126	case c.op {
127	Csimple =>
128		return redir(words(c.words), c);
129	Cseq =>
130		return sequence(c);
131	Cfor =>
132		return "for (" + c.item.text() + " in " + words(c.words) + ") " + c.left.text();
133	Cif =>
134		return "if (" + c.left.text() +") " + c.right.text();
135	Celse =>
136		return c.left.text() +" else " + c.right.text();
137	Cwhile =>
138		return "while (" + c.left.text() +") " + c.right.text();
139	Ccase =>
140		return redir("case " + c.left.text() + " { " + c.right.text() + "}", c);
141	Ccases =>
142		s := c.left.text();
143		if (s[len s - 1] != '&')
144			return s + "; " + c.right.text();
145		return s + " " + c.right.text();
146	Cmatched =>
147		return cmd2in(c, "=>");
148	Cdefeq =>
149		return c.item.text() + " := " + words(c.words);
150	Ceq =>
151		return c.item.text() + " = " + words(c.words);
152	Cfn =>
153		return "fn " + c.item.text() + " " + group(c.left);
154	Crescue =>
155		return "rescue " + c.item.text() + " " + group(c.left);
156	Casync =>
157		return c.left.text() + "&";
158	Cgroup =>
159		return group(c.left);
160	Clistgroup =>
161		return ":" + group(c.left);
162	Csubgroup =>
163		return "@" + group(c.left);
164	Cnop =>
165		return nil;
166	Cword =>
167		return c.item.text();
168	Ccaret =>
169		return cmd2in(c, "^");
170	Chd =>
171		return "hd " + c.left.text();
172	Clen =>
173		return "len " + c.left.text();
174	Cnot =>
175		return "!" + c.left.text();
176	Ctl =>
177		return "tl " + c.left.text();
178	Ccons =>
179		return cmd2in(c, "::");
180	Ceqeq =>
181		return cmd2in(c, "==");
182	Cnoteq =>
183		return cmd2in(c, "!=");
184	Cmatch =>
185		return cmd2in(c, "~");
186	Cpipe =>
187		return cmd2in(c, "|");
188	Cdepend =>
189		return words(c.words) + " : " + words(c.left.words) + " " + c.left.text();
190	Crule =>
191		return c.item.text() + " :~ " + c.left.item.text() + " " + c.left.text();
192	* =>
193		if (c.op >= Cprivate)
194			return "Priv+" + string (c.op - Cprivate);
195		else
196			return "?" + string c.op;
197	}
198	return nil;
199}
200