1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 #include "go.h"
6
7 enum
8 {
9 PFIXME = 0,
10 };
11
12 void
13 exprlistfmt(Fmt *f, NodeList *l)
14 {
15 for(; l; l=l->next) {
16 exprfmt(f, l->n, 0);
17 if(l->next)
18 fmtprint(f, ", ");
19 }
20 }
21
22 void
23 exprfmt(Fmt *f, Node *n, int prec)
24 {
25 int nprec;
26 char *p;
27
28 nprec = 0;
29 if(n == nil) {
30 fmtprint(f, "<nil>");
31 return;
32 }
33
34 if(n->implicit) {
35 exprfmt(f, n->left, prec);
36 return;
37 }
38
39 switch(n->op) {
40 case OAPPEND:
41 case ONAME:
42 case ONONAME:
43 case OPACK:
44 case OLITERAL:
45 case ODOT:
46 case ODOTPTR:
47 case ODOTINTER:
48 case ODOTMETH:
49 case ODOTTYPE:
50 case ODOTTYPE2:
51 case OXDOT:
52 case OARRAYBYTESTR:
53 case OCAP:
54 case OCLOSE:
55 case OCOPY:
56 case OLEN:
57 case OMAKE:
58 case ONEW:
59 case OPANIC:
60 case OPRINT:
61 case OPRINTN:
62 case OCALL:
63 case OCALLMETH:
64 case OCALLINTER:
65 case OCALLFUNC:
66 case OCONV:
67 case OCONVNOP:
68 case OMAKESLICE:
69 case ORUNESTR:
70 case OADDR:
71 case OCOM:
72 case OIND:
73 case OMINUS:
74 case ONOT:
75 case OPLUS:
76 case ORECV:
77 case OCONVIFACE:
78 case OTPAREN:
79 case OINDEX:
80 case OINDEXMAP:
81 case OPAREN:
82 nprec = 7;
83 break;
84
85 case OMUL:
86 case ODIV:
87 case OMOD:
88 case OLSH:
89 case ORSH:
90 case OAND:
91 case OANDNOT:
92 nprec = 6;
93 break;
94
95 case OADD:
96 case OSUB:
97 case OOR:
98 case OXOR:
99 nprec = 5;
100 break;
101
102 case OEQ:
103 case OLT:
104 case OLE:
105 case OGE:
106 case OGT:
107 case ONE:
108 nprec = 4;
109 break;
110
111 case OSEND:
112 nprec = 3;
113 break;
114
115 case OANDAND:
116 nprec = 2;
117 break;
118
119 case OOROR:
120 nprec = 1;
121 break;
122
123 case OTYPE:
124 if(n->sym != S)
125 nprec = 7;
126 break;
127 }
128
129 if(prec > nprec)
130 fmtprint(f, "(");
131
132 switch(n->op) {
133 default:
134 bad:
135 fmtprint(f, "(node %O)", n->op);
136 break;
137
138 case OPAREN:
139 fmtprint(f, "(%#N)", n->left);
140 break;
141
142 case OREGISTER:
143 fmtprint(f, "%R", n->val.u.reg);
144 break;
145
146 case OLITERAL:
147 if(n->sym != S) {
148 fmtprint(f, "%S", n->sym);
149 break;
150 }
151 switch(n->val.ctype) {
152 default:
153 goto bad;
154 case CTINT:
155 fmtprint(f, "%B", n->val.u.xval);
156 break;
157 case CTBOOL:
158 if(n->val.u.bval)
159 fmtprint(f, "true");
160 else
161 fmtprint(f, "false");
162 break;
163 case CTCPLX:
164 fmtprint(f, "%.17g+%.17gi",
165 mpgetflt(&n->val.u.cval->real),
166 mpgetflt(&n->val.u.cval->imag));
167 break;
168 case CTFLT:
169 fmtprint(f, "%.17g", mpgetflt(n->val.u.fval));
170 break;
171 case CTSTR:
172 fmtprint(f, "\"%Z\"", n->val.u.sval);
173 break;
174 case CTNIL:
175 fmtprint(f, "nil");
176 break;
177 }
178 break;
179
180 case ONAME:
181 case OPACK:
182 case ONONAME:
183 fmtprint(f, "%S", n->sym);
184 break;
185
186 case OTYPE:
187 if(n->type == T && n->sym != S) {
188 fmtprint(f, "%S", n->sym);
189 break;
190 }
191 fmtprint(f, "%T", n->type);
192 break;
193
194 case OTARRAY:
195 fmtprint(f, "[]");
196 exprfmt(f, n->left, PFIXME);
197 break;
198
199 case OTPAREN:
200 fmtprint(f, "(");
201 exprfmt(f, n->left, 0);
202 fmtprint(f, ")");
203 break;
204
205 case OTMAP:
206 fmtprint(f, "map[");
207 exprfmt(f, n->left, 0);
208 fmtprint(f, "] ");
209 exprfmt(f, n->right, 0);
210 break;
211
212 case OTCHAN:
213 if(n->etype == Crecv)
214 fmtprint(f, "<-");
215 fmtprint(f, "chan");
216 if(n->etype == Csend) {
217 fmtprint(f, "<- ");
218 exprfmt(f, n->left, 0);
219 } else {
220 fmtprint(f, " ");
221 if(n->left->op == OTCHAN && n->left->sym == S && n->left->etype == Crecv) {
222 fmtprint(f, "(");
223 exprfmt(f, n->left, 0);
224 fmtprint(f, ")");
225 } else
226 exprfmt(f, n->left, 0);
227 }
228 break;
229
230 case OTSTRUCT:
231 fmtprint(f, "<struct>");
232 break;
233
234 case OTINTER:
235 fmtprint(f, "<inter>");
236 break;
237
238 case OTFUNC:
239 fmtprint(f, "<func>");
240 break;
241
242 case OAS:
243 exprfmt(f, n->left, 0);
244 fmtprint(f, " = ");
245 exprfmt(f, n->right, 0);
246 break;
247
248 case OASOP:
249 exprfmt(f, n->left, 0);
250 fmtprint(f, " %#O= ", n->etype);
251 exprfmt(f, n->right, 0);
252 break;
253
254 case OAS2:
255 case OAS2DOTTYPE:
256 case OAS2FUNC:
257 case OAS2MAPR:
258 case OAS2MAPW:
259 case OAS2RECV:
260 exprlistfmt(f, n->list);
261 fmtprint(f, " = ");
262 exprlistfmt(f, n->rlist);
263 break;
264
265 case OADD:
266 case OANDAND:
267 case OANDNOT:
268 case ODIV:
269 case OEQ:
270 case OGE:
271 case OGT:
272 case OLE:
273 case OLT:
274 case OLSH:
275 case OMOD:
276 case OMUL:
277 case ONE:
278 case OOR:
279 case OOROR:
280 case ORSH:
281 case OSEND:
282 case OSUB:
283 case OXOR:
284 exprfmt(f, n->left, nprec);
285 fmtprint(f, " %#O ", n->op);
286 exprfmt(f, n->right, nprec+1);
287 break;
288
289 case OADDR:
290 case OCOM:
291 case OIND:
292 case OMINUS:
293 case ONOT:
294 case OPLUS:
295 case ORECV:
296 fmtprint(f, "%#O", n->op);
297 if((n->op == OMINUS || n->op == OPLUS) && n->left->op == n->op)
298 fmtprint(f, " ");
299 exprfmt(f, n->left, 0);
300 break;
301
302 case OCLOSURE:
303 fmtprint(f, "func literal");
304 break;
305
306 case OCOMPLIT:
307 fmtprint(f, "composite literal");
308 break;
309
310 case OARRAYLIT:
311 if(isslice(n->type))
312 fmtprint(f, "slice literal");
313 else
314 fmtprint(f, "array literal");
315 break;
316
317 case OMAPLIT:
318 fmtprint(f, "map literal");
319 break;
320
321 case OSTRUCTLIT:
322 fmtprint(f, "struct literal");
323 break;
324
325 case OXDOT:
326 case ODOT:
327 case ODOTPTR:
328 case ODOTINTER:
329 case ODOTMETH:
330 exprfmt(f, n->left, 7);
331 if(n->right == N || n->right->sym == S)
332 fmtprint(f, ".<nil>");
333 else {
334 // skip leading type· in method name
335 p = utfrrune(n->right->sym->name, 0xb7);
336 if(p)
337 p+=2;
338 else
339 p = n->right->sym->name;
340 fmtprint(f, ".%s", p);
341 }
342 break;
343
344 case ODOTTYPE:
345 case ODOTTYPE2:
346 exprfmt(f, n->left, 7);
347 fmtprint(f, ".(");
348 if(n->right != N)
349 exprfmt(f, n->right, 0);
350 else
351 fmtprint(f, "%T", n->type);
352 fmtprint(f, ")");
353 break;
354
355 case OINDEX:
356 case OINDEXMAP:
357 exprfmt(f, n->left, 7);
358 fmtprint(f, "[");
359 exprfmt(f, n->right, 0);
360 fmtprint(f, "]");
361 break;
362
363 case OSLICE:
364 case OSLICESTR:
365 case OSLICEARR:
366 exprfmt(f, n->left, 7);
367 fmtprint(f, "[");
368 if(n->right->left != N)
369 exprfmt(f, n->right->left, 0);
370 fmtprint(f, ":");
371 if(n->right->right != N)
372 exprfmt(f, n->right->right, 0);
373 fmtprint(f, "]");
374 break;
375
376 case OCALL:
377 case OCALLFUNC:
378 case OCALLINTER:
379 case OCALLMETH:
380 exprfmt(f, n->left, 7);
381 fmtprint(f, "(");
382 exprlistfmt(f, n->list);
383 if(n->isddd)
384 fmtprint(f, "...");
385 fmtprint(f, ")");
386 break;
387
388 case OCOMPLEX:
389 fmtprint(f, "complex(");
390 exprfmt(f, n->left, 0);
391 fmtprint(f, ", ");
392 exprfmt(f, n->right, 0);
393 fmtprint(f, ")");
394 break;
395
396 case OREAL:
397 fmtprint(f, "real(");
398 exprfmt(f, n->left, 0);
399 fmtprint(f, ")");
400 break;
401
402 case OIMAG:
403 fmtprint(f, "imag(");
404 exprfmt(f, n->left, 0);
405 fmtprint(f, ")");
406 break;
407
408 case OCONV:
409 case OCONVIFACE:
410 case OCONVNOP:
411 case OARRAYBYTESTR:
412 case OSTRARRAYBYTE:
413 case ORUNESTR:
414 if(n->type == T || n->type->sym == S)
415 fmtprint(f, "(%T)(", n->type);
416 else
417 fmtprint(f, "%T(", n->type);
418 if(n->left == N)
419 exprlistfmt(f, n->list);
420 else
421 exprfmt(f, n->left, 0);
422 fmtprint(f, ")");
423 break;
424
425 case OAPPEND:
426 case OCAP:
427 case OCLOSE:
428 case OLEN:
429 case OCOPY:
430 case OMAKE:
431 case ONEW:
432 case OPANIC:
433 case OPRINT:
434 case OPRINTN:
435 fmtprint(f, "%#O(", n->op);
436 if(n->left)
437 exprfmt(f, n->left, 0);
438 else
439 exprlistfmt(f, n->list);
440 fmtprint(f, ")");
441 break;
442
443 case OMAKESLICE:
444 fmtprint(f, "make(%#T, ", n->type);
445 exprfmt(f, n->left, 0);
446 if(count(n->list) > 2) {
447 fmtprint(f, ", ");
448 exprfmt(f, n->right, 0);
449 }
450 fmtprint(f, ")");
451 break;
452
453 case OMAKEMAP:
454 case OMAKECHAN:
455 fmtprint(f, "make(%#T)", n->type);
456 break;
457
458 // Some statements
459
460 case ODCL:
461 fmtprint(f, "var %S %#T", n->left->sym, n->left->type);
462 break;
463
464 case ORETURN:
465 fmtprint(f, "return ");
466 exprlistfmt(f, n->list);
467 break;
468
469 case OPROC:
470 fmtprint(f, "go %#N", n->left);
471 break;
472
473 case ODEFER:
474 fmtprint(f, "defer %#N", n->left);
475 break;
476 }
477
478 if(prec > nprec)
479 fmtprint(f, ")");
480 }