summaryrefslogtreecommitdiff
path: root/appl/alphabet/main/pretty.b
blob: 52d8b32fcd37fcecd9c167e0cd688f91d1be96a1 (plain)
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;
}