xref: /plan9/sys/src/cmd/acid/print.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1bd389b36SDavid du Colombier #include <u.h>
2bd389b36SDavid du Colombier #include <libc.h>
3bd389b36SDavid du Colombier #include <bio.h>
4bd389b36SDavid du Colombier #include <ctype.h>
5bd389b36SDavid du Colombier #include <mach.h>
6bd389b36SDavid du Colombier #define Extern extern
7bd389b36SDavid du Colombier #include "acid.h"
8bd389b36SDavid du Colombier 
9bd389b36SDavid du Colombier static char *binop[] =
10bd389b36SDavid du Colombier {
11bd389b36SDavid du Colombier 	[OMUL]	"*",
12bd389b36SDavid du Colombier 	[ODIV]	"/",
13bd389b36SDavid du Colombier 	[OMOD]	"%",
14bd389b36SDavid du Colombier 	[OADD]	"+",
15bd389b36SDavid du Colombier 	[OSUB]	"-",
16bd389b36SDavid du Colombier 	[ORSH]	">>",
17bd389b36SDavid du Colombier 	[OLSH]	"<<",
18bd389b36SDavid du Colombier 	[OLT]	"<",
19bd389b36SDavid du Colombier 	[OGT]	">",
20bd389b36SDavid du Colombier 	[OLEQ]	"<=",
21bd389b36SDavid du Colombier 	[OGEQ]	">=",
22bd389b36SDavid du Colombier 	[OEQ]	"==",
23bd389b36SDavid du Colombier 	[ONEQ]	"!=",
24bd389b36SDavid du Colombier 	[OLAND]	"&",
25bd389b36SDavid du Colombier 	[OXOR]	"^",
26bd389b36SDavid du Colombier 	[OLOR]	"|",
27bd389b36SDavid du Colombier 	[OCAND]	"&&",
28bd389b36SDavid du Colombier 	[OCOR]	"||",
29*219b2ee8SDavid du Colombier 	[OASGN]	" = ",
30bd389b36SDavid du Colombier };
31bd389b36SDavid du Colombier 
32bd389b36SDavid du Colombier static char *tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
33*219b2ee8SDavid du Colombier char *typestr[] =
34bd389b36SDavid du Colombier {
35bd389b36SDavid du Colombier 	[TINT]		"integer",
36bd389b36SDavid du Colombier 	[TFLOAT]	"float",
37bd389b36SDavid du Colombier 	[TSTRING]	"string",
38bd389b36SDavid du Colombier 	[TLIST]		"list",
39*219b2ee8SDavid du Colombier 	[TCODE]		"code",
40bd389b36SDavid du Colombier };
41bd389b36SDavid du Colombier 
42*219b2ee8SDavid du Colombier int
43*219b2ee8SDavid du Colombier cmp(char **a, char **b)
44*219b2ee8SDavid du Colombier {
45*219b2ee8SDavid du Colombier 	return strcmp(*a, *b);
46*219b2ee8SDavid du Colombier }
47*219b2ee8SDavid du Colombier 
48*219b2ee8SDavid du Colombier void
49*219b2ee8SDavid du Colombier fundefs(void)
50*219b2ee8SDavid du Colombier {
51*219b2ee8SDavid du Colombier 	Lsym *l;
52*219b2ee8SDavid du Colombier 	char **vec;
53*219b2ee8SDavid du Colombier 	int i, j, n, max, col, f, g, s;
54*219b2ee8SDavid du Colombier 
55*219b2ee8SDavid du Colombier 	max = 0;
56*219b2ee8SDavid du Colombier 	f = 0;
57*219b2ee8SDavid du Colombier 	g = 100;
58*219b2ee8SDavid du Colombier 	vec = malloc(sizeof(char*)*g);
59*219b2ee8SDavid du Colombier 	if(vec == 0)
60*219b2ee8SDavid du Colombier 		fatal("out of memory");
61*219b2ee8SDavid du Colombier 
62*219b2ee8SDavid du Colombier 	for(i = 0; i < Hashsize; i++) {
63*219b2ee8SDavid du Colombier 		for(l = hash[i]; l; l = l->hash) {
64*219b2ee8SDavid du Colombier 			if(l->proc == 0 && l->builtin == 0)
65*219b2ee8SDavid du Colombier 				continue;
66*219b2ee8SDavid du Colombier 			n = strlen(l->name);
67*219b2ee8SDavid du Colombier 			if(n > max)
68*219b2ee8SDavid du Colombier 				max = n;
69*219b2ee8SDavid du Colombier 			if(f >= g) {
70*219b2ee8SDavid du Colombier 				g *= 2;
71*219b2ee8SDavid du Colombier 				vec = realloc(vec, sizeof(char*)*g);
72*219b2ee8SDavid du Colombier 				if(vec == 0)
73*219b2ee8SDavid du Colombier 					fatal("out of memory");
74*219b2ee8SDavid du Colombier 			}
75*219b2ee8SDavid du Colombier 			vec[f++] = l->name;
76*219b2ee8SDavid du Colombier 		}
77*219b2ee8SDavid du Colombier 	}
78*219b2ee8SDavid du Colombier         qsort(vec, f, sizeof(char*), cmp);
79*219b2ee8SDavid du Colombier 	max++;
80*219b2ee8SDavid du Colombier 	col = 60/max;
81*219b2ee8SDavid du Colombier 	s = (f+col-1)/col;
82*219b2ee8SDavid du Colombier 
83*219b2ee8SDavid du Colombier 	for(i = 0; i < s; i++) {
84*219b2ee8SDavid du Colombier 		for(j = i; j < f; j += s)
85*219b2ee8SDavid du Colombier 			Bprint(bout, "%-*s", max, vec[j]);
86*219b2ee8SDavid du Colombier 		Bprint(bout, "\n");
87*219b2ee8SDavid du Colombier 	}
88*219b2ee8SDavid du Colombier }
89*219b2ee8SDavid du Colombier 
90bd389b36SDavid du Colombier void
91bd389b36SDavid du Colombier whatis(Lsym *l)
92bd389b36SDavid du Colombier {
93bd389b36SDavid du Colombier 	int t;
94bd389b36SDavid du Colombier 	int def;
95bd389b36SDavid du Colombier 	Type *ti;
96bd389b36SDavid du Colombier 
97*219b2ee8SDavid du Colombier 	if(l == 0) {
98*219b2ee8SDavid du Colombier 		fundefs();
99*219b2ee8SDavid du Colombier 		return;
100*219b2ee8SDavid du Colombier 	}
101*219b2ee8SDavid du Colombier 
102bd389b36SDavid du Colombier 	def = 0;
103bd389b36SDavid du Colombier 	if(l->v->set) {
104bd389b36SDavid du Colombier 		t = l->v->type;
105*219b2ee8SDavid du Colombier 		Bprint(bout, "%s variable", typestr[t]);
106bd389b36SDavid du Colombier 		if(t == TINT || t == TFLOAT)
107bd389b36SDavid du Colombier 			Bprint(bout, " format %c", l->v->fmt);
108*219b2ee8SDavid du Colombier 		if(l->v->comt)
109*219b2ee8SDavid du Colombier 			Bprint(bout, " complex %s",
110*219b2ee8SDavid du Colombier 						l->v->comt->base->name);
111bd389b36SDavid du Colombier 		Bputc(bout, '\n');
112bd389b36SDavid du Colombier 		def = 1;
113bd389b36SDavid du Colombier 	}
114bd389b36SDavid du Colombier 	if(l->lt) {
115*219b2ee8SDavid du Colombier 		Bprint(bout, "complex %s {\n", l->name);
116*219b2ee8SDavid du Colombier 		for(ti = l->lt; ti; ti = ti->next) {
117*219b2ee8SDavid du Colombier 			if(ti->type) {
118*219b2ee8SDavid du Colombier 				if(ti->fmt == 'a') {
119*219b2ee8SDavid du Colombier 					Bprint(bout, "\t%s %d %s;\n",
120*219b2ee8SDavid du Colombier 					ti->type->name, ti->offset,
121*219b2ee8SDavid du Colombier 					ti->tag->name);
122*219b2ee8SDavid du Colombier 				}
123*219b2ee8SDavid du Colombier 				else {
124*219b2ee8SDavid du Colombier 					Bprint(bout, "\t'%c' %s %d %s;\n",
125*219b2ee8SDavid du Colombier 					ti->fmt, ti->type->name, ti->offset,
126*219b2ee8SDavid du Colombier 					ti->tag->name);
127*219b2ee8SDavid du Colombier 				}
128*219b2ee8SDavid du Colombier 			}
129*219b2ee8SDavid du Colombier 			else
130*219b2ee8SDavid du Colombier 				Bprint(bout, "\t'%c' %d %s;\n",
131*219b2ee8SDavid du Colombier 				ti->fmt, ti->offset, ti->tag->name);
132*219b2ee8SDavid du Colombier 		}
133*219b2ee8SDavid du Colombier 		Bprint(bout, "};\n");
134bd389b36SDavid du Colombier 		def = 1;
135bd389b36SDavid du Colombier 	}
136bd389b36SDavid du Colombier 	if(l->proc) {
137bd389b36SDavid du Colombier 		Bprint(bout, "defn %s(", l->name);
138bd389b36SDavid du Colombier 		pexpr(l->proc->left);
139*219b2ee8SDavid du Colombier 		Bprint(bout, ") {\n");
140bd389b36SDavid du Colombier 		pcode(l->proc->right, 1);
141bd389b36SDavid du Colombier 		Bprint(bout, "}\n");
142bd389b36SDavid du Colombier 		def = 1;
143bd389b36SDavid du Colombier 	}
144bd389b36SDavid du Colombier 	if(l->builtin) {
145bd389b36SDavid du Colombier 		Bprint(bout, "builtin function\n");
146bd389b36SDavid du Colombier 		def = 1;
147bd389b36SDavid du Colombier 	}
148bd389b36SDavid du Colombier 	if(def == 0)
149bd389b36SDavid du Colombier 		Bprint(bout, "%s is undefined\n", l->name);
150bd389b36SDavid du Colombier }
151bd389b36SDavid du Colombier 
152bd389b36SDavid du Colombier void
153bd389b36SDavid du Colombier slist(Node *n, int d)
154bd389b36SDavid du Colombier {
155bd389b36SDavid du Colombier 	if(n == 0)
156bd389b36SDavid du Colombier 		return;
157bd389b36SDavid du Colombier 	if(n->op == OLIST)
158bd389b36SDavid du Colombier 		Bprint(bout, "%.*s{\n", d-1, tabs);
159bd389b36SDavid du Colombier 	pcode(n, d);
160bd389b36SDavid du Colombier 	if(n->op == OLIST)
161bd389b36SDavid du Colombier 		Bprint(bout, "%.*s}\n", d-1, tabs);
162bd389b36SDavid du Colombier }
163bd389b36SDavid du Colombier 
164bd389b36SDavid du Colombier void
165bd389b36SDavid du Colombier pcode(Node *n, int d)
166bd389b36SDavid du Colombier {
167bd389b36SDavid du Colombier 	Node *r, *l;
168bd389b36SDavid du Colombier 
169bd389b36SDavid du Colombier 	if(n == 0)
170bd389b36SDavid du Colombier 		return;
171bd389b36SDavid du Colombier 
172bd389b36SDavid du Colombier 	r = n->right;
173bd389b36SDavid du Colombier 	l = n->left;
174bd389b36SDavid du Colombier 
175bd389b36SDavid du Colombier 	switch(n->op) {
176bd389b36SDavid du Colombier 	default:
177bd389b36SDavid du Colombier 		Bprint(bout, "%.*s", d, tabs);
178bd389b36SDavid du Colombier 		pexpr(n);
179bd389b36SDavid du Colombier 		Bprint(bout, ";\n");
180bd389b36SDavid du Colombier 		break;
181bd389b36SDavid du Colombier 	case OLIST:
182bd389b36SDavid du Colombier 		pcode(n->left, d);
183bd389b36SDavid du Colombier 		pcode(n->right, d);
184bd389b36SDavid du Colombier 		break;
185bd389b36SDavid du Colombier 	case OLOCAL:
186*219b2ee8SDavid du Colombier 		Bprint(bout, "%.*slocal", d, tabs);
187*219b2ee8SDavid du Colombier 		while(l) {
188*219b2ee8SDavid du Colombier 			Bprint(bout, " %s", l->sym->name);
189*219b2ee8SDavid du Colombier 			l = l->left;
190*219b2ee8SDavid du Colombier 			if(l == 0)
191*219b2ee8SDavid du Colombier 				Bprint(bout, ";\n");
192*219b2ee8SDavid du Colombier 			else
193*219b2ee8SDavid du Colombier 				Bprint(bout, ",");
194*219b2ee8SDavid du Colombier 		}
195bd389b36SDavid du Colombier 		break;
196bd389b36SDavid du Colombier 	case OCOMPLEX:
197bd389b36SDavid du Colombier 		Bprint(bout, "%.*scomplex %s %s;\n", d, tabs, n->sym->name, l->sym->name);
198bd389b36SDavid du Colombier 		break;
199bd389b36SDavid du Colombier 	case OIF:
200bd389b36SDavid du Colombier 		Bprint(bout, "%.*sif ", d, tabs);
201bd389b36SDavid du Colombier 		pexpr(l);
202bd389b36SDavid du Colombier 		d++;
203bd389b36SDavid du Colombier 		Bprint(bout, " then\n", d, tabs);
204bd389b36SDavid du Colombier 		if(r && r->op == OELSE) {
205bd389b36SDavid du Colombier 			slist(r->left, d);
206bd389b36SDavid du Colombier 			Bprint(bout, "%.*selse\n", d-1, tabs, d, tabs);
207bd389b36SDavid du Colombier 			slist(r->right, d);
208bd389b36SDavid du Colombier 		}
209bd389b36SDavid du Colombier 		else
210bd389b36SDavid du Colombier 			slist(r, d);
211bd389b36SDavid du Colombier 		break;
212bd389b36SDavid du Colombier 	case OWHILE:
213bd389b36SDavid du Colombier 		Bprint(bout, "%.*swhile ", d, tabs);
214bd389b36SDavid du Colombier 		pexpr(l);
215bd389b36SDavid du Colombier 		d++;
216bd389b36SDavid du Colombier 		Bprint(bout, " do\n", d, tabs);
217bd389b36SDavid du Colombier 		slist(r, d);
218bd389b36SDavid du Colombier 		break;
219bd389b36SDavid du Colombier 	case ORET:
220bd389b36SDavid du Colombier 		Bprint(bout, "%.*sreturn ", d, tabs);
221bd389b36SDavid du Colombier 		pexpr(l);
222bd389b36SDavid du Colombier 		Bprint(bout, ";\n");
223bd389b36SDavid du Colombier 		break;
224bd389b36SDavid du Colombier 	case ODO:
225bd389b36SDavid du Colombier 		Bprint(bout, "%.*sloop ", d, tabs);
226bd389b36SDavid du Colombier 		pexpr(l->left);
227bd389b36SDavid du Colombier 		Bprint(bout, ", ");
228bd389b36SDavid du Colombier 		pexpr(l->right);
229bd389b36SDavid du Colombier 		Bprint(bout, " do\n");
230bd389b36SDavid du Colombier 		slist(r, d+1);
231bd389b36SDavid du Colombier 	}
232bd389b36SDavid du Colombier }
233bd389b36SDavid du Colombier 
234bd389b36SDavid du Colombier void
235bd389b36SDavid du Colombier pexpr(Node *n)
236bd389b36SDavid du Colombier {
237bd389b36SDavid du Colombier 	Node *r, *l;
238bd389b36SDavid du Colombier 
239bd389b36SDavid du Colombier 	if(n == 0)
240bd389b36SDavid du Colombier 		return;
241bd389b36SDavid du Colombier 
242bd389b36SDavid du Colombier 	r = n->right;
243bd389b36SDavid du Colombier 	l = n->left;
244bd389b36SDavid du Colombier 
245bd389b36SDavid du Colombier 	switch(n->op) {
246bd389b36SDavid du Colombier 	case ONAME:
247bd389b36SDavid du Colombier 		Bprint(bout, "%s", n->sym->name);
248bd389b36SDavid du Colombier 		break;
249bd389b36SDavid du Colombier 	case OCONST:
250bd389b36SDavid du Colombier 		switch(n->type) {
251bd389b36SDavid du Colombier 		case TINT:
252bd389b36SDavid du Colombier 			Bprint(bout, "%d", n->ival);
253bd389b36SDavid du Colombier 			break;
254bd389b36SDavid du Colombier 		case TFLOAT:
255bd389b36SDavid du Colombier 			Bprint(bout, "%g", n->fval);
256bd389b36SDavid du Colombier 			break;
257bd389b36SDavid du Colombier 		case TSTRING:
258bd389b36SDavid du Colombier 			pstr(n->string);
259bd389b36SDavid du Colombier 			break;
260bd389b36SDavid du Colombier 		case TLIST:
261bd389b36SDavid du Colombier 			break;
262bd389b36SDavid du Colombier 		}
263bd389b36SDavid du Colombier 		break;
264bd389b36SDavid du Colombier 	case OMUL:
265bd389b36SDavid du Colombier 	case ODIV:
266bd389b36SDavid du Colombier 	case OMOD:
267bd389b36SDavid du Colombier 	case OADD:
268bd389b36SDavid du Colombier 	case OSUB:
269bd389b36SDavid du Colombier 	case ORSH:
270bd389b36SDavid du Colombier 	case OLSH:
271bd389b36SDavid du Colombier 	case OLT:
272bd389b36SDavid du Colombier 	case OGT:
273bd389b36SDavid du Colombier 	case OLEQ:
274bd389b36SDavid du Colombier 	case OGEQ:
275bd389b36SDavid du Colombier 	case OEQ:
276bd389b36SDavid du Colombier 	case ONEQ:
277bd389b36SDavid du Colombier 	case OLAND:
278bd389b36SDavid du Colombier 	case OXOR:
279bd389b36SDavid du Colombier 	case OLOR:
280bd389b36SDavid du Colombier 	case OCAND:
281bd389b36SDavid du Colombier 	case OCOR:
282*219b2ee8SDavid du Colombier 		Bputc(bout, '(');
283*219b2ee8SDavid du Colombier 		pexpr(l);
284*219b2ee8SDavid du Colombier 		Bprint(bout, binop[n->op]);
285*219b2ee8SDavid du Colombier 		pexpr(r);
286*219b2ee8SDavid du Colombier 		Bputc(bout, ')');
287*219b2ee8SDavid du Colombier 		break;
288bd389b36SDavid du Colombier 	case OASGN:
289bd389b36SDavid du Colombier 		pexpr(l);
290bd389b36SDavid du Colombier 		Bprint(bout, binop[n->op]);
291bd389b36SDavid du Colombier 		pexpr(r);
292bd389b36SDavid du Colombier 		break;
293bd389b36SDavid du Colombier 	case OINDM:
294bd389b36SDavid du Colombier 		Bprint(bout, "*");
295bd389b36SDavid du Colombier 		pexpr(l);
296bd389b36SDavid du Colombier 		break;
297bd389b36SDavid du Colombier 	case OEDEC:
298bd389b36SDavid du Colombier 		Bprint(bout, "--");
299bd389b36SDavid du Colombier 		pexpr(l);
300bd389b36SDavid du Colombier 		break;
301bd389b36SDavid du Colombier 	case OEINC:
302bd389b36SDavid du Colombier 		Bprint(bout, "++");
303bd389b36SDavid du Colombier 		pexpr(l);
304bd389b36SDavid du Colombier 		break;
305bd389b36SDavid du Colombier 	case OPINC:
306bd389b36SDavid du Colombier 		pexpr(l);
307bd389b36SDavid du Colombier 		Bprint(bout, "++");
308bd389b36SDavid du Colombier 		break;
309bd389b36SDavid du Colombier 	case OPDEC:
310bd389b36SDavid du Colombier 		pexpr(l);
311bd389b36SDavid du Colombier 		Bprint(bout, "--");
312bd389b36SDavid du Colombier 		break;
313bd389b36SDavid du Colombier 	case ONOT:
314bd389b36SDavid du Colombier 		Bprint(bout, "!");
315bd389b36SDavid du Colombier 		pexpr(l);
316bd389b36SDavid du Colombier 		break;
317bd389b36SDavid du Colombier 	case OLIST:
318bd389b36SDavid du Colombier 		pexpr(l);
319bd389b36SDavid du Colombier 		if(r) {
320bd389b36SDavid du Colombier 			Bprint(bout, ",");
321bd389b36SDavid du Colombier 			pexpr(r);
322bd389b36SDavid du Colombier 		}
323bd389b36SDavid du Colombier 		break;
324bd389b36SDavid du Colombier 	case OCALL:
325bd389b36SDavid du Colombier 		pexpr(l);
326bd389b36SDavid du Colombier 		Bprint(bout, "(");
327bd389b36SDavid du Colombier 		pexpr(r);
328bd389b36SDavid du Colombier 		Bprint(bout, ")");
329bd389b36SDavid du Colombier 		break;
330bd389b36SDavid du Colombier 	case OCTRUCT:
331bd389b36SDavid du Colombier 		Bprint(bout, "{");
332bd389b36SDavid du Colombier 		pexpr(l);
333bd389b36SDavid du Colombier 		Bprint(bout, "}");
334bd389b36SDavid du Colombier 		break;
335bd389b36SDavid du Colombier 	case OHEAD:
336bd389b36SDavid du Colombier 		Bprint(bout, "head ");
337bd389b36SDavid du Colombier 		pexpr(l);
338bd389b36SDavid du Colombier 		break;
339bd389b36SDavid du Colombier 	case OTAIL:
340bd389b36SDavid du Colombier 		Bprint(bout, "tail ");
341bd389b36SDavid du Colombier 		pexpr(l);
342bd389b36SDavid du Colombier 		break;
343bd389b36SDavid du Colombier 	case OAPPEND:
344bd389b36SDavid du Colombier 		Bprint(bout, "append ");
345bd389b36SDavid du Colombier 		pexpr(l);
346bd389b36SDavid du Colombier 		Bprint(bout, ",");
347bd389b36SDavid du Colombier 		pexpr(r);
348bd389b36SDavid du Colombier 		break;
349*219b2ee8SDavid du Colombier 	case ODELETE:
350*219b2ee8SDavid du Colombier 		Bprint(bout, "delete ");
351*219b2ee8SDavid du Colombier 		pexpr(l);
352*219b2ee8SDavid du Colombier 		Bprint(bout, ",");
353*219b2ee8SDavid du Colombier 		pexpr(r);
354*219b2ee8SDavid du Colombier 		break;
355bd389b36SDavid du Colombier 	case ORET:
356bd389b36SDavid du Colombier 		Bprint(bout, "return ");
357bd389b36SDavid du Colombier 		pexpr(l);
358bd389b36SDavid du Colombier 		break;
359bd389b36SDavid du Colombier 	case OINDEX:
360bd389b36SDavid du Colombier 		pexpr(l);
361bd389b36SDavid du Colombier 		Bprint(bout, "[");
362bd389b36SDavid du Colombier 		pexpr(r);
363bd389b36SDavid du Colombier 		Bprint(bout, "]");
364bd389b36SDavid du Colombier 		break;
365bd389b36SDavid du Colombier 	case OINDC:
366bd389b36SDavid du Colombier 		Bprint(bout, "@");
367bd389b36SDavid du Colombier 		pexpr(l);
368bd389b36SDavid du Colombier 		break;
369bd389b36SDavid du Colombier 	case ODOT:
370*219b2ee8SDavid du Colombier 		pexpr(l);
371*219b2ee8SDavid du Colombier 		Bprint(bout, ".%s", n->sym->name);
372*219b2ee8SDavid du Colombier 		break;
373bd389b36SDavid du Colombier 	case OFRAME:
374*219b2ee8SDavid du Colombier 		Bprint(bout, "%s:%s", n->sym->name, l->sym->name);
375*219b2ee8SDavid du Colombier 		break;
376*219b2ee8SDavid du Colombier 	case OCAST:
377*219b2ee8SDavid du Colombier 		Bprint(bout, "(%s)", n->sym->name);
378*219b2ee8SDavid du Colombier 		pexpr(l);
379*219b2ee8SDavid du Colombier 		break;
380*219b2ee8SDavid du Colombier 	case OFMT:
381*219b2ee8SDavid du Colombier 		pexpr(l);
382*219b2ee8SDavid du Colombier 		Bprint(bout, "\\%c", r->ival);
383*219b2ee8SDavid du Colombier 		break;
384*219b2ee8SDavid du Colombier 	case OEVAL:
385*219b2ee8SDavid du Colombier 		Bprint(bout, "eval ");
386*219b2ee8SDavid du Colombier 		pexpr(l);
387*219b2ee8SDavid du Colombier 		break;
388*219b2ee8SDavid du Colombier 	case OWHAT:
389*219b2ee8SDavid du Colombier 		Bprint(bout, "whatis", n->sym->name);
390*219b2ee8SDavid du Colombier 		if(n->sym)
391*219b2ee8SDavid du Colombier 			Bprint(bout, " %s", n->sym->name);
392bd389b36SDavid du Colombier 		break;
393bd389b36SDavid du Colombier 	}
394bd389b36SDavid du Colombier }
395bd389b36SDavid du Colombier 
396bd389b36SDavid du Colombier void
397bd389b36SDavid du Colombier pstr(String *s)
398bd389b36SDavid du Colombier {
399bd389b36SDavid du Colombier 	int i, c;
400bd389b36SDavid du Colombier 
401bd389b36SDavid du Colombier 	Bputc(bout, '"');
402bd389b36SDavid du Colombier 	for(i = 0; i < s->len; i++) {
403bd389b36SDavid du Colombier 		c = s->string[i];
404bd389b36SDavid du Colombier 		switch(c) {
405bd389b36SDavid du Colombier 		case '\0':
406bd389b36SDavid du Colombier 			c = '0';
407bd389b36SDavid du Colombier 			break;
408bd389b36SDavid du Colombier 		case '\n':
409bd389b36SDavid du Colombier 			c = 'n';
410bd389b36SDavid du Colombier 			break;
411bd389b36SDavid du Colombier 		case '\r':
412bd389b36SDavid du Colombier 			c = 'r';
413bd389b36SDavid du Colombier 			break;
414bd389b36SDavid du Colombier 		case '\t':
415bd389b36SDavid du Colombier 			c = 't';
416bd389b36SDavid du Colombier 			break;
417bd389b36SDavid du Colombier 		case '\b':
418bd389b36SDavid du Colombier 			c = 'b';
419bd389b36SDavid du Colombier 			break;
420bd389b36SDavid du Colombier 		case '\f':
421bd389b36SDavid du Colombier 			c = 'f';
422bd389b36SDavid du Colombier 			break;
423bd389b36SDavid du Colombier 		case '\a':
424bd389b36SDavid du Colombier 			c = 'a';
425bd389b36SDavid du Colombier 			break;
426bd389b36SDavid du Colombier 		case '\v':
427bd389b36SDavid du Colombier 			c = 'v';
428bd389b36SDavid du Colombier 			break;
429bd389b36SDavid du Colombier 		case '\\':
430bd389b36SDavid du Colombier 			c = '\\';
431bd389b36SDavid du Colombier 			break;
432bd389b36SDavid du Colombier 		case '"':
433bd389b36SDavid du Colombier 			c = '"';
434bd389b36SDavid du Colombier 			break;
435bd389b36SDavid du Colombier 		default:
436bd389b36SDavid du Colombier 			Bputc(bout, c);
437bd389b36SDavid du Colombier 			continue;
438bd389b36SDavid du Colombier 		}
439bd389b36SDavid du Colombier 		Bputc(bout, '\\');
440bd389b36SDavid du Colombier 		Bputc(bout, c);
441bd389b36SDavid du Colombier 	}
442bd389b36SDavid du Colombier 	Bputc(bout, '"');
443bd389b36SDavid du Colombier }
444