LEFT | RIGHT |
(no file at all) | |
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 <u.h> | |
6 #include <libc.h> | |
7 #include "go.h" | |
8 | |
9 enum | |
10 { | |
11 PFIXME = 0, | |
12 }; | |
13 | |
14 void | |
15 exprlistfmt(Fmt *f, NodeList *l) | |
16 { | |
17 for(; l; l=l->next) { | |
18 exprfmt(f, l->n, 0); | |
19 if(l->next) | |
20 fmtprint(f, ", "); | |
21 } | |
22 } | |
23 | |
24 void | |
25 stmtlistfmt(Fmt *f, NodeList *l) | |
26 { | |
27 for(; l; l=l->next) { | |
28 fmtprint(f, " %#N", l->n); | |
29 if(l->next) | |
30 fmtprint(f, ";"); | |
31 } | |
32 } | |
33 | |
34 void | |
35 exprfmt(Fmt *f, Node *n, int prec) | |
36 { | |
37 int nprec; | |
38 char *p; | |
39 NodeList *l; | |
40 | |
41 nprec = 0; | |
42 if(n == nil) { | |
43 fmtprint(f, "<nil>"); | |
44 return; | |
45 } | |
46 ········ | |
47 if(n->implicit) { | |
48 exprfmt(f, n->left, prec); | |
49 return; | |
50 } | |
51 | |
52 switch(n->op) { | |
53 case OAPPEND: | |
54 case ONAME: | |
55 case ONONAME: | |
56 case OPACK: | |
57 case OLITERAL: | |
58 case ODOT: | |
59 case ODOTPTR: | |
60 case ODOTINTER: | |
61 case ODOTMETH: | |
62 case ODOTTYPE: | |
63 case ODOTTYPE2: | |
64 case OXDOT: | |
65 case OARRAYBYTESTR: | |
66 case OCAP: | |
67 case OCLOSE: | |
68 case OCOPY: | |
69 case OLEN: | |
70 case OMAKE: | |
71 case ONEW: | |
72 case OPANIC: | |
73 case OPRINT: | |
74 case OPRINTN: | |
75 case OCALL: | |
76 case OCALLMETH: | |
77 case OCALLINTER: | |
78 case OCALLFUNC: | |
79 case OCONV: | |
80 case OCONVNOP: | |
81 case OMAKESLICE: | |
82 case ORUNESTR: | |
83 case OADDR: | |
84 case OCOM: | |
85 case OIND: | |
86 case OMINUS: | |
87 case ONOT: | |
88 case OPLUS: | |
89 case ORECV: | |
90 case OCONVIFACE: | |
91 case OTPAREN: | |
92 case OINDEX: | |
93 case OINDEXMAP: | |
94 case OPAREN: | |
95 nprec = 7; | |
96 break; | |
97 | |
98 case OMUL: | |
99 case ODIV: | |
100 case OMOD: | |
101 case OLSH: | |
102 case ORSH: | |
103 case OAND: | |
104 case OANDNOT: | |
105 nprec = 6; | |
106 break; | |
107 | |
108 case OADD: | |
109 case OSUB: | |
110 case OOR: | |
111 case OXOR: | |
112 nprec = 5; | |
113 break; | |
114 | |
115 case OEQ: | |
116 case OLT: | |
117 case OLE: | |
118 case OGE: | |
119 case OGT: | |
120 case ONE: | |
121 case OCMPSTR: | |
122 nprec = 4; | |
123 break; | |
124 | |
125 case OSEND: | |
126 nprec = 3; | |
127 break; | |
128 | |
129 case OANDAND: | |
130 nprec = 2; | |
131 break; | |
132 | |
133 case OOROR: | |
134 nprec = 1; | |
135 break; | |
136 ········ | |
137 case OTYPE: | |
138 if(n->sym != S) | |
139 nprec = 7; | |
140 break; | |
141 } | |
142 | |
143 if(prec > nprec) | |
144 fmtprint(f, "("); | |
145 | |
146 switch(n->op) { | |
147 default: | |
148 bad: | |
149 fmtprint(f, "(node %O)", n->op); | |
150 break; | |
151 | |
152 case OPAREN: | |
153 fmtprint(f, "(%#N)", n->left); | |
154 break; | |
155 | |
156 case ODDDARG: | |
157 fmtprint(f, "... argument"); | |
158 break; | |
159 | |
160 case OREGISTER: | |
161 fmtprint(f, "%R", n->val.u.reg); | |
162 break; | |
163 | |
164 case OLITERAL: | |
165 if(n->sym != S) { | |
166 fmtprint(f, "%S", n->sym); | |
167 break; | |
168 } | |
169 switch(n->val.ctype) { | |
170 default: | |
171 goto bad; | |
172 case CTINT: | |
173 fmtprint(f, "%B", n->val.u.xval); | |
174 break; | |
175 case CTBOOL: | |
176 if(n->val.u.bval) | |
177 fmtprint(f, "true"); | |
178 else | |
179 fmtprint(f, "false"); | |
180 break; | |
181 case CTCPLX: | |
182 fmtprint(f, "%.17g+%.17gi", | |
183 mpgetflt(&n->val.u.cval->real), | |
184 mpgetflt(&n->val.u.cval->imag)); | |
185 break; | |
186 case CTFLT: | |
187 fmtprint(f, "%.17g", mpgetflt(n->val.u.fval)); | |
188 break; | |
189 case CTSTR: | |
190 fmtprint(f, "\"%Z\"", n->val.u.sval); | |
191 break; | |
192 case CTNIL: | |
193 fmtprint(f, "nil"); | |
194 break; | |
195 } | |
196 break; | |
197 | |
198 case ONAME: | |
199 case OPACK: | |
200 case ONONAME: | |
201 fmtprint(f, "%S", n->sym); | |
202 break; | |
203 | |
204 case OTYPE: | |
205 if(n->type == T && n->sym != S) { | |
206 fmtprint(f, "%S", n->sym); | |
207 break; | |
208 } | |
209 fmtprint(f, "%T", n->type); | |
210 break; | |
211 | |
212 case OTARRAY: | |
213 fmtprint(f, "[]"); | |
214 exprfmt(f, n->left, PFIXME); | |
215 break; | |
216 ········ | |
217 case OTPAREN: | |
218 fmtprint(f, "("); | |
219 exprfmt(f, n->left, 0); | |
220 fmtprint(f, ")"); | |
221 break; | |
222 | |
223 case OTMAP: | |
224 fmtprint(f, "map["); | |
225 exprfmt(f, n->left, 0); | |
226 fmtprint(f, "] "); | |
227 exprfmt(f, n->right, 0); | |
228 break; | |
229 | |
230 case OTCHAN: | |
231 if(n->etype == Crecv) | |
232 fmtprint(f, "<-"); | |
233 fmtprint(f, "chan"); | |
234 if(n->etype == Csend) { | |
235 fmtprint(f, "<- "); | |
236 exprfmt(f, n->left, 0); | |
237 } else { | |
238 fmtprint(f, " "); | |
239 if(n->left->op == OTCHAN && n->left->sym == S && n->left
->etype == Crecv) { | |
240 fmtprint(f, "("); | |
241 exprfmt(f, n->left, 0); | |
242 fmtprint(f, ")"); | |
243 } else | |
244 exprfmt(f, n->left, 0); | |
245 } | |
246 break; | |
247 | |
248 case OTSTRUCT: | |
249 fmtprint(f, "<struct>"); | |
250 break; | |
251 | |
252 case OTINTER: | |
253 fmtprint(f, "<inter>"); | |
254 break; | |
255 | |
256 case OTFUNC: | |
257 fmtprint(f, "<func>"); | |
258 break; | |
259 | |
260 case OAS: | |
261 exprfmt(f, n->left, 0); | |
262 fmtprint(f, " = "); | |
263 exprfmt(f, n->right, 0); | |
264 break; | |
265 | |
266 case OASOP: | |
267 exprfmt(f, n->left, 0); | |
268 fmtprint(f, " %#O= ", n->etype); | |
269 exprfmt(f, n->right, 0); | |
270 break; | |
271 | |
272 case OAS2: | |
273 case OAS2DOTTYPE: | |
274 case OAS2FUNC: | |
275 case OAS2MAPR: | |
276 case OAS2MAPW: | |
277 case OAS2RECV: | |
278 exprlistfmt(f, n->list); | |
279 fmtprint(f, " = "); | |
280 exprlistfmt(f, n->rlist); | |
281 break; | |
282 | |
283 case OADD: | |
284 case OADDSTR: | |
285 case OAND: | |
286 case OANDAND: | |
287 case OANDNOT: | |
288 case ODIV: | |
289 case OEQ: | |
290 case OGE: | |
291 case OGT: | |
292 case OLE: | |
293 case OLT: | |
294 case OLSH: | |
295 case OMOD: | |
296 case OMUL: | |
297 case ONE: | |
298 case OOR: | |
299 case OOROR: | |
300 case ORSH: | |
301 case OSEND: | |
302 case OSUB: | |
303 case OXOR: | |
304 exprfmt(f, n->left, nprec); | |
305 fmtprint(f, " %#O ", n->op); | |
306 exprfmt(f, n->right, nprec+1); | |
307 break; | |
308 | |
309 case OCMPSTR: | |
310 exprfmt(f, n->left, nprec); | |
311 fmtprint(f, " %#O ", n->etype); | |
312 exprfmt(f, n->right, nprec+1); | |
313 break; | |
314 | |
315 case OADDR: | |
316 case OCOM: | |
317 case OIND: | |
318 case OMINUS: | |
319 case ONOT: | |
320 case OPLUS: | |
321 case ORECV: | |
322 fmtprint(f, "%#O", n->op); | |
323 if((n->op == OMINUS || n->op == OPLUS) && n->left->op == n->op) | |
324 fmtprint(f, " "); | |
325 exprfmt(f, n->left, 0); | |
326 break; | |
327 | |
328 case OCLOSURE: | |
329 if(f->flags & FmtShort) { | |
330 fmtprint(f, "func literal", n->type); | |
331 } else { | |
332 fmtprint(f, "func %hhT {", n->type); | |
333 stmtlistfmt(f, n->nbody); | |
334 fmtprint(f, " }"); | |
335 } | |
336 break; | |
337 | |
338 case OCOMPLIT: | |
339 fmtprint(f, "composite literal"); | |
340 break; | |
341 ········ | |
342 case OARRAYLIT: | |
343 case OMAPLIT: | |
344 case OSTRUCTLIT: | |
345 if(f->flags & FmtShort) { | |
346 fmtprint(f, "%#hhT literal", n->type); | |
347 } else { | |
348 fmtprint(f, "%#hhT{", n->type); | |
349 for (l=n->list; l; l=l->next) { | |
350 fmtprint(f, " %#N:%#N", l->n->left, l->n->right)
; | |
351 if (l->next) fmtprint(f, ","); | |
352 } | |
353 fmtprint(f, " }"); | |
354 } | |
355 break; | |
356 | |
357 case OXDOT: | |
358 case ODOT: | |
359 case ODOTPTR: | |
360 case ODOTINTER: | |
361 case ODOTMETH: | |
362 exprfmt(f, n->left, 7); | |
363 if(n->right == N || n->right->sym == S) | |
364 fmtprint(f, ".<nil>"); | |
365 else { | |
366 // skip leading type· in method name | |
367 p = utfrrune(n->right->sym->name, 0xb7); | |
368 if(p) | |
369 p+=2; | |
370 else | |
371 p = n->right->sym->name; | |
372 fmtprint(f, ".%s", p); | |
373 } | |
374 break; | |
375 | |
376 case ODOTTYPE: | |
377 case ODOTTYPE2: | |
378 exprfmt(f, n->left, 7); | |
379 fmtprint(f, ".("); | |
380 if(n->right != N) | |
381 exprfmt(f, n->right, 0); | |
382 else | |
383 fmtprint(f, "%T", n->type); | |
384 fmtprint(f, ")"); | |
385 break; | |
386 | |
387 case OINDEX: | |
388 case OINDEXMAP: | |
389 exprfmt(f, n->left, 7); | |
390 fmtprint(f, "["); | |
391 exprfmt(f, n->right, 0); | |
392 fmtprint(f, "]"); | |
393 break; | |
394 | |
395 case OSLICE: | |
396 case OSLICESTR: | |
397 case OSLICEARR: | |
398 exprfmt(f, n->left, 7); | |
399 fmtprint(f, "["); | |
400 if(n->right->left != N) | |
401 exprfmt(f, n->right->left, 0); | |
402 fmtprint(f, ":"); | |
403 if(n->right->right != N) | |
404 exprfmt(f, n->right->right, 0); | |
405 fmtprint(f, "]"); | |
406 break; | |
407 | |
408 case OCALL: | |
409 case OCALLFUNC: | |
410 case OCALLINTER: | |
411 case OCALLMETH: | |
412 exprfmt(f, n->left, 7); | |
413 fmtprint(f, "("); | |
414 exprlistfmt(f, n->list); | |
415 if(n->isddd) | |
416 fmtprint(f, "..."); | |
417 fmtprint(f, ")"); | |
418 break; | |
419 | |
420 case OCOMPLEX: | |
421 fmtprint(f, "complex("); | |
422 exprfmt(f, n->left, 0); | |
423 fmtprint(f, ", "); | |
424 exprfmt(f, n->right, 0); | |
425 fmtprint(f, ")"); | |
426 break; | |
427 | |
428 case OREAL: | |
429 fmtprint(f, "real("); | |
430 exprfmt(f, n->left, 0); | |
431 fmtprint(f, ")"); | |
432 break; | |
433 | |
434 case OIMAG: | |
435 fmtprint(f, "imag("); | |
436 exprfmt(f, n->left, 0); | |
437 fmtprint(f, ")"); | |
438 break; | |
439 | |
440 case OCONV: | |
441 case OCONVIFACE: | |
442 case OCONVNOP: | |
443 case OARRAYBYTESTR: | |
444 case OSTRARRAYBYTE: | |
445 case ORUNESTR: | |
446 if(n->type == T || n->type->sym == S) | |
447 fmtprint(f, "(%T)(", n->type); | |
448 else | |
449 fmtprint(f, "%T(", n->type); | |
450 if(n->left == N) | |
451 exprlistfmt(f, n->list); | |
452 else | |
453 exprfmt(f, n->left, 0); | |
454 fmtprint(f, ")"); | |
455 break; | |
456 | |
457 case OAPPEND: | |
458 case OCAP: | |
459 case OCLOSE: | |
460 case OLEN: | |
461 case OCOPY: | |
462 case OMAKE: | |
463 case ONEW: | |
464 case OPANIC: | |
465 case OPRINT: | |
466 case OPRINTN: | |
467 fmtprint(f, "%#O(", n->op); | |
468 if(n->left) | |
469 exprfmt(f, n->left, 0); | |
470 else | |
471 exprlistfmt(f, n->list); | |
472 fmtprint(f, ")"); | |
473 break; | |
474 | |
475 case OMAKESLICE: | |
476 fmtprint(f, "make(%#T, ", n->type); | |
477 exprfmt(f, n->left, 0); | |
478 if(count(n->list) > 2) { | |
479 fmtprint(f, ", "); | |
480 exprfmt(f, n->right, 0); | |
481 } | |
482 fmtprint(f, ")"); | |
483 break; | |
484 | |
485 case OMAKEMAP: | |
486 case OMAKECHAN: | |
487 fmtprint(f, "make(%#T)", n->type); | |
488 break; | |
489 | |
490 // Some statements | |
491 | |
492 case ODCL: | |
493 fmtprint(f, "var %S %#T", n->left->sym, n->left->type); | |
494 break; | |
495 | |
496 case ORETURN: | |
497 fmtprint(f, "return "); | |
498 exprlistfmt(f, n->list); | |
499 break; | |
500 | |
501 case OPROC: | |
502 fmtprint(f, "go %#N", n->left); | |
503 break; | |
504 | |
505 case ODEFER: | |
506 fmtprint(f, "defer %#N", n->left); | |
507 break; | |
508 | |
509 case OIF: | |
510 if (n->ninit && n->ninit->next) { | |
511 fmtprint(f, "{"); | |
512 stmtlistfmt(f, n->ninit); | |
513 fmtprint(f, "; "); | |
514 } | |
515 fmtstrcpy(f, "if "); | |
516 if (n->ninit && !n->ninit->next) | |
517 fmtprint(f, "%#N; ", n->ninit->n); | |
518 fmtprint(f, "%#N {", n->ntest); | |
519 stmtlistfmt(f, n->nbody); | |
520 if (n->nelse) { | |
521 fmtprint(f, "} else {"); | |
522 stmtlistfmt(f, n->nelse); | |
523 } | |
524 fmtprint(f, "}"); | |
525 if (n->ninit && n->ninit->next) | |
526 fmtprint(f, "}"); | |
527 break; | |
528 | |
529 case OFOR: | |
530 if (n->ninit && n->ninit->next) { | |
531 fmtprint(f, "{"); | |
532 stmtlistfmt(f, n->ninit); | |
533 fmtprint(f, "; "); | |
534 } | |
535 fmtstrcpy(f, "for"); | |
536 if (n->ninit && !n->ninit->next) | |
537 fmtprint(f, " %#N;", n->ninit->n); | |
538 else if (n->ntest || n->nincr) | |
539 fmtstrcpy(f, " ;"); | |
540 if (n->ntest) | |
541 fmtprint(f, "%#N", n->ntest); | |
542 if (n->nincr) | |
543 fmtprint(f, "; %#N", n->nincr); | |
544 else if (n->ninit && !n->ninit->next) | |
545 fmtstrcpy(f, " ;"); | |
546 fmtstrcpy(f, " {"); | |
547 stmtlistfmt(f, n->nbody); | |
548 fmtprint(f, "}"); | |
549 if (n->ninit && n->ninit->next) | |
550 fmtprint(f, "}"); | |
551 break; | |
552 ········ | |
553 case ORANGE: | |
554 if (n->ninit) { | |
555 fmtprint(f, "{"); | |
556 stmtlistfmt(f, n->ninit); | |
557 fmtprint(f, "; "); | |
558 } | |
559 fmtprint(f, "for "); | |
560 exprlistfmt(f, n->list); | |
561 fmtprint(f, " = range %#N {", n->right); | |
562 stmtlistfmt(f, n->nbody); | |
563 fmtprint(f, "}"); | |
564 if (n->ninit) | |
565 fmtprint(f, "}"); | |
566 break; | |
567 | |
568 case OSWITCH: | |
569 if (n->ninit && n->ninit->next) { | |
570 fmtprint(f, "{"); | |
571 stmtlistfmt(f, n->ninit); | |
572 fmtprint(f, "; "); | |
573 } | |
574 fmtstrcpy(f, "select"); | |
575 if (n->ninit && !n->ninit->next) | |
576 fmtprint(f, " %#N;", n->ninit->n); | |
577 if (n->ntest) | |
578 fmtprint(f, "%#N", n->ntest); | |
579 fmtstrcpy(f, " {"); | |
580 for(l=n->list; l; l=l->next) { | |
581 if (l->n->list) { | |
582 fmtprint(f, " case "); | |
583 exprlistfmt(f, l->n->list); | |
584 } else { | |
585 fmtprint(f, " default"); | |
586 } | |
587 fmtstrcpy(f, ":"); | |
588 stmtlistfmt(f, l->n->nbody); | |
589 if (l->next) | |
590 fmtprint(f, ";"); | |
591 } | |
592 fmtprint(f, " }"); | |
593 if (n->ninit) | |
594 fmtprint(f, "}"); | |
595 break; | |
596 | |
597 | |
598 case OSELECT: | |
599 if (n->ninit) { | |
600 fmtprint(f, "{"); | |
601 stmtlistfmt(f, n->ninit); | |
602 fmtprint(f, "; "); | |
603 } | |
604 fmtstrcpy(f, "select {"); | |
605 for(l=n->list; l; l=l->next) { | |
606 if (l->n->list) { | |
607 fmtprint(f, " case "); | |
608 exprlistfmt(f, l->n->list); | |
609 } else { | |
610 fmtprint(f, " default"); | |
611 } | |
612 fmtstrcpy(f, ":"); | |
613 stmtlistfmt(f, l->n->nbody); | |
614 if (l->next) | |
615 fmtprint(f, ";"); | |
616 } | |
617 fmtprint(f, " }"); | |
618 if (n->ninit) | |
619 fmtprint(f, "}"); | |
620 break; | |
621 } | |
622 | |
623 if(prec > nprec) | |
624 fmtprint(f, ")"); | |
625 } | |
LEFT | RIGHT |