ref: babf901b4a508c3ec5d1f89655f10377bbdf9637
dir: /appl/cmd/mash/dump.b/
#
# Output routines.
#
#
# Echo list of strings.
#
echo(e: ref Env, s: list of string)
{
out := e.outfile();
if (out == nil)
return;
out.putc('+');
for (t := s; t != nil; t = tl t) {
out.putc(' ');
out.puts(hd t);
}
out.putc('\n');
out.close();
}
#
# Return text representation of Word/Item/Cmd.
#
Word.word(w: self ref Word, d: string): string
{
if (w == nil)
return nil;
if (d != nil)
return d + w.text;
if (w.flags & Wquoted)
return enquote(w.text);
return w.text;
}
Item.text(i: self ref Item): string
{
if (i == nil)
return nil;
case i.op {
Icaret =>
return i.left.text() + " ^ " + i.right.text();
Iicaret =>
return i.left.text() + i.right.text();
Idollarq =>
return i.word.word("$\"");
Idollar or Imatch =>
return i.word.word("$");
Iword =>
return i.word.word(nil);
Iexpr =>
return "(" + i.cmd.text() + ")";
Ibackq =>
return "`" + group(i.cmd);
Iquote =>
return "\"" + group(i.cmd);
Iinpipe =>
return "<" + group(i.cmd);
Ioutpipe =>
return ">" + group(i.cmd);
* =>
return "?" + string i.op;
}
}
words(l: list of ref Item): string
{
s: string;
while (l != nil) {
if (s == nil)
s = (hd l).text();
else
s = s + " " + (hd l).text();
l = tl l;
}
return s;
}
redir(s: string, c: ref Cmd): string
{
if (c == nil)
return s;
for (l := c.redirs; l != nil; l = tl l) {
r := hd l;
s = s + " " + rdsymbs[r.op] + " " + r.word.text();
}
return s;
}
cmd2in(c: ref Cmd, s: string): string
{
return c.left.text() + " " + s + " " + c.right.text();
}
group(c: ref Cmd): string
{
if (c == nil)
return "{ }";
return redir("{ " + c.text() + " }", c);
}
sequence(c: ref Cmd): string
{
s: string;
do {
r := c.right;
t := ";";
if (r.op == Casync) {
r = r.left;
t = "&";
}
if (s == nil)
s = r.text() + t;
else
s = r.text() + t + " " + s;
c = c.left;
} while (c != nil);
return s;
}
Cmd.text(c: self ref Cmd): string
{
if (c == nil)
return nil;
case c.op {
Csimple =>
return redir(words(c.words), c);
Cseq =>
return sequence(c);
Cfor =>
return "for (" + c.item.text() + " in " + words(c.words) + ") " + c.left.text();
Cif =>
return "if (" + c.left.text() +") " + c.right.text();
Celse =>
return c.left.text() +" else " + c.right.text();
Cwhile =>
return "while (" + c.left.text() +") " + c.right.text();
Ccase =>
return redir("case " + c.left.text() + " { " + c.right.text() + "}", c);
Ccases =>
s := c.left.text();
if (s[len s - 1] != '&')
return s + "; " + c.right.text();
return s + " " + c.right.text();
Cmatched =>
return cmd2in(c, "=>");
Cdefeq =>
return c.item.text() + " := " + words(c.words);
Ceq =>
return c.item.text() + " = " + words(c.words);
Cfn =>
return "fn " + c.item.text() + " " + group(c.left);
Crescue =>
return "rescue " + c.item.text() + " " + group(c.left);
Casync =>
return c.left.text() + "&";
Cgroup =>
return group(c.left);
Clistgroup =>
return ":" + group(c.left);
Csubgroup =>
return "@" + group(c.left);
Cnop =>
return nil;
Cword =>
return c.item.text();
Ccaret =>
return cmd2in(c, "^");
Chd =>
return "hd " + c.left.text();
Clen =>
return "len " + c.left.text();
Cnot =>
return "!" + c.left.text();
Ctl =>
return "tl " + c.left.text();
Ccons =>
return cmd2in(c, "::");
Ceqeq =>
return cmd2in(c, "==");
Cnoteq =>
return cmd2in(c, "!=");
Cmatch =>
return cmd2in(c, "~");
Cpipe =>
return cmd2in(c, "|");
Cdepend =>
return words(c.words) + " : " + words(c.left.words) + " " + c.left.text();
Crule =>
return c.item.text() + " :~ " + c.left.item.text() + " " + c.left.text();
* =>
if (c.op >= Cprivate)
return "Priv+" + string (c.op - Cprivate);
else
return "?" + string c.op;
}
return nil;
}