GCC Rust: Parsing in floats now
[official-gcc.git] / gcc / rust / rdot-pretty-print.cc
blob51330e318abd958b5f85650d9187e844135950d5
1 /* This file is part of GCC.
3 GCC is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 3, or (at your option)
6 any later version.
8 GCC is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with GCC; see the file COPYING3. If not see
15 <http://www.gnu.org/licenses/>. */
17 #include "rust.h"
19 static bool _no_infer = false;
20 static bool first = true;
22 #define RDOT_PREFIX_PRE ".pre-rdot"
23 #define RDOT_PREFIX_POST ".pst-rdot"
25 static const char * typeStrings [] = {
26 "bool",
27 "int",
28 "float",
29 "unsigned_int",
30 "__infer_me",
31 "__user_struct",
32 "void"
35 static char *
36 typeStringNode (const rdot node)
38 char buffer [128];
39 size_t offset = 0;
40 if (RDOT_MEM_MODIFIER (node))
42 std::vector<ALLOCA_>::iterator it;
43 for (it = RDOT_MEM_MODIFIER (node)->begin ();
44 it != RDOT_MEM_MODIFIER (node)->end (); ++it )
46 switch (*it)
48 case ALLOC_HEAP:
50 buffer [offset] = '~';
51 offset++;
53 break;
54 case ALLOC_REF:
56 buffer [offset] = '&';
57 offset++;
59 break;
60 case ALLOC_DEREF:
62 buffer [offset] = '*';
63 offset++;
65 break;
69 if (node != NULL_DOT)
71 switch (RDOT_TYPE (node))
73 case RTYPE_BOOL:
74 strcpy (buffer+offset, typeStrings [0]);
75 break;
77 case RTYPE_INT:
78 strcpy (buffer+offset, typeStrings [1]);
79 break;
81 case RTYPE_FLOAT:
82 strcpy (buffer+offset, typeStrings [2]);
83 break;
85 case RTYPE_UINT:
86 strcpy (buffer+offset, typeStrings [3]);
87 break;
89 case RTYPE_INFER:
91 if (_no_infer)
92 fatal_error ("gcc-rust has failed to infer a type and cannot continue");
93 else
94 strcpy (buffer+offset, typeStrings [4]);
96 break;
98 case RTYPE_USER_STRUCT:
99 strcpy (buffer+offset, RDOT_IDENTIFIER_POINTER (RDOT_lhs_TT (node)));
100 break;
102 default:
103 fatal_error ("unhandled type [%s]", RDOT_OPCODE_STR (node));
104 break;
107 return xstrdup (buffer);
110 static void dot_pass_dump_node (FILE *, rdot, size_t);
111 static void dot_pass_dump_method (FILE *, rdot, size_t);
112 static void dot_pass_dump_struct (FILE *, rdot, size_t);
114 static void dot_pass_dumpPrimitive (FILE *, rdot);
115 static void dot_pass_dumpExprNode (FILE *, rdot);
116 static void dot_pass_dump_expr (FILE *, rdot);
118 static
119 void dot_pass_dump_struct (FILE * fd, rdot node, size_t indents)
121 size_t i;
122 for (i = 0; i < indents; ++i)
123 fprintf (fd, " ");
125 rdot ident = RDOT_lhs_TT (node);
126 rdot layout = RDOT_rhs_TT (node);
128 fprintf (fd, "struct %s {\n", RDOT_IDENTIFIER_POINTER (ident));
129 rdot next;
130 for (next = layout; next != NULL_DOT; next = RDOT_CHAIN (next))
132 gcc_assert (RDOT_TYPE (next) = D_PARAMETER);
133 const char * id = RDOT_IDENTIFIER_POINTER (RDOT_lhs_TT (next));
134 const char * typestr = typeStringNode (RDOT_rhs_TT (next));
136 for (i = 0; i < (indents + 1); ++i)
137 fprintf (fd, " ");
138 fprintf (fd, "%s %s;\n", typestr, id);
140 for (i = 0; i < indents; ++i)
141 fprintf (fd, " ");
142 fprintf (fd, "}\n");
145 static
146 void dot_pass_dump_method (FILE * fd, rdot node, size_t indents)
148 size_t i;
149 for (i = 0; i < indents; ++i)
150 fprintf (fd, " ");
152 const char * method_id = RDOT_IDENTIFIER_POINTER (RDOT_FIELD (node));
153 char * rtype = NULL;
154 if (RDOT_FIELD2 (node))
155 rtype = typeStringNode (RDOT_FIELD2 (node));
156 else
157 rtype = xstrdup ("void");
158 rdot parameters = RDOT_lhs_TT (node);
160 if (DOT_RETVAL (node))
161 fprintf (fd, "pub fn %s ( ", method_id);
162 else
163 fprintf (fd, "fn %s ( ", method_id);
165 if (parameters == NULL_DOT)
166 fprintf (fd, "void");
167 else
169 rdot next;
170 for (next = parameters; next != NULL_DOT; next = RDOT_CHAIN (next))
172 gcc_assert (RDOT_TYPE (next) = D_PARAMETER);
173 bool iself = false;
174 bool muta = RDOT_qual (next);
175 const char * id = RDOT_IDENTIFIER_POINTER (RDOT_lhs_TT (next));
177 if (strcmp (id, "self") == 0)
178 iself = true;
180 const char *smuta;
181 if (muta) {
182 smuta = "mut";
184 else {
185 smuta = "final";
188 if (iself)
189 fprintf (fd, "[%s] _self_", smuta);
190 else
192 const char * typestr = typeStringNode (RDOT_rhs_TT (next));
193 fprintf (fd, "[%s] %s:%s", smuta, typestr, id);
195 if (RDOT_CHAIN (next) != NULL_DOT)
196 fprintf (fd, ", ");
199 fprintf (fd, " ) -> %s {\n", rtype);
200 free (rtype);
202 rdot suite;
203 for (suite = RDOT_rhs_TT (node); suite != NULL_DOT; suite = RDOT_CHAIN (suite))
205 dot_pass_dump_node (fd, suite, indents + 1);
206 fprintf (fd, "\n");
209 for (i = 0; i < indents; ++i)
210 fprintf (fd, " ");
211 fprintf (fd, "}\n");
214 static
215 void dot_pass_dumpPrimitive (FILE * fd, rdot node)
217 /* Handle other primitive literal types here ... */
218 switch (RDOT_lhs_TC (node).T)
220 case D_T_INTEGER:
221 fprintf (fd, "%i", RDOT_lhs_TC (node).o.integer);
222 break;
224 case D_T_FLOAT:
225 fprintf (fd, "%f", RDOT_lhs_TC (node).o.ffloat);
226 break;
228 case D_T_STRING:
229 fprintf (fd, "\"%s\"", RDOT_lhs_TC (node).o.string);
230 break;
232 default:
233 fatal_error ("Unable to dump primitive [%s]",
234 rdot_getOpString_T (RDOT_lhs_TC (node).T));
235 break;
239 static
240 void dot_pass_dumpExprNode (FILE * fd, rdot node)
242 if (RDOT_MEM_MODIFIER (node))
244 std::vector<ALLOCA_>::iterator it;
245 for (it = RDOT_MEM_MODIFIER (node)->begin ();
246 it != RDOT_MEM_MODIFIER (node)->end (); ++it )
248 switch (*it)
250 case ALLOC_DEREF:
251 fprintf (fd, "*");
252 break;
253 case ALLOC_HEAP:
254 fprintf (fd, "~");
255 break;
256 case ALLOC_REF:
257 fprintf (fd, "&");
258 break;
262 switch (RDOT_TYPE (node))
264 case D_PRIMITIVE:
265 dot_pass_dumpPrimitive (fd, node);
266 break;
268 case D_IDENTIFIER:
269 fprintf (fd, "%s", RDOT_IDENTIFIER_POINTER (node));
270 break;
272 case D_BOOLEAN:
274 bool val = RDOT_BOOLEAN_VAL (node);
275 if (val)
276 fprintf (fd, "true");
277 else
278 fprintf (fd, "false");
280 break;
282 case D_CALL_EXPR:
284 rdot id = RDOT_lhs_TT (node);
285 dot_pass_dump_expr (fd, id);
286 fprintf (fd, " (");
288 rdot p;
289 for (p = RDOT_rhs_TT (node); p != NULL_DOT; p = RDOT_CHAIN (p))
291 dot_pass_dump_expr (fd, p);
292 if (RDOT_CHAIN (p) != NULL_DOT)
293 fprintf (fd, ", ");
295 fprintf (fd, ")");
297 break;
299 case D_VAR_DECL:
301 const char * mut;
302 if (RDOT_qual (node))
303 mut = "_final_";
304 else
305 mut = "_mut_";
307 fprintf (fd, "let [%s] ", mut);
308 dot_pass_dumpExprNode (fd, RDOT_lhs_TT (node));
309 fprintf (fd, " -> [%s]", typeStringNode (RDOT_rhs_TT (node)));
311 break;
313 case D_STRUCT_INIT:
315 rdot ident = RDOT_lhs_TT (node);
316 rdot init = RDOT_rhs_TT (node);
318 fprintf (fd, "%s { ", RDOT_IDENTIFIER_POINTER (ident));
319 rdot next;
320 for (next = init; next != NULL_DOT; next = RDOT_CHAIN (next))
322 gcc_assert (RDOT_TYPE (next) == D_STRUCT_PARAM);
323 const char * name = RDOT_IDENTIFIER_POINTER (RDOT_lhs_TT (next));
325 fprintf (fd, "%s:(", name);
326 dot_pass_dump_expr (fd, RDOT_rhs_TT (next));
327 fprintf (fd, ")");
328 if (RDOT_CHAIN (next) != NULL_DOT)
329 fprintf (fd, ", ");
331 fprintf (fd, " }");
333 break;
335 default:
336 error ("unhandled dumpExprNode [%s]\n", RDOT_OPCODE_STR (node));
337 break;
341 static
342 void dot_pass_dump_expr (FILE * fd, rdot node)
344 if (DOT_RETVAL (node)) {
345 fprintf (fd, "[_rust_retval]: ");
348 switch (RDOT_TYPE (node))
350 case D_PRIMITIVE:
351 case D_IDENTIFIER:
352 case D_CALL_EXPR:
353 case D_BOOLEAN:
354 case D_VAR_DECL:
355 case D_STRUCT_INIT:
356 dot_pass_dumpExprNode (fd, node);
357 break;
359 default:
361 /* print expr tree ... */
362 rdot lhs = RDOT_lhs_TT (node);
363 rdot rhs = RDOT_rhs_TT (node);
365 dot_pass_dump_expr (fd, lhs);
366 switch (RDOT_TYPE (node))
368 case D_MODIFY_EXPR:
369 fprintf (fd, " = ");
370 break;
372 case D_ADD_EXPR:
373 fprintf (fd, " + ");
374 break;
376 case D_MINUS_EXPR:
377 fprintf (fd, " - ");
378 break;
380 case D_MULT_EXPR:
381 fprintf (fd, " * ");
382 break;
384 case D_LESS_EXPR:
385 fprintf (fd, " < ");
386 break;
388 case D_LESS_EQ_EXPR:
389 fprintf (fd, " <= ");
390 break;
392 case D_GREATER_EXPR:
393 fprintf (fd, " > ");
394 break;
396 case D_GREATER_EQ_EXPR:
397 fprintf (fd, " >= ");
398 break;
400 case D_EQ_EQ_EXPR:
401 fprintf (fd, " == ");
402 break;
404 case D_NOT_EQ_EXPR:
405 fprintf (fd, " != ");
406 break;
408 case D_ATTRIB_REF:
409 fprintf (fd, ".");
410 break;
412 case D_ACC_EXPR:
413 fprintf (fd, "::");
414 break;
416 default:
417 fatal_error ("unhandled dump [%s]!\n", RDOT_OPCODE_STR (node));
418 break;
420 dot_pass_dump_expr (fd, rhs);
422 break;
426 static
427 void dot_pass_dump_enum (FILE * fd, rdot node, size_t indents)
429 rdot enum_id = RDOT_lhs_TT (node);
430 rdot enum_layout = RDOT_rhs_TT (node);
432 size_t i;
433 for (i = 0; i < indents; ++i)
434 fprintf (fd, " ");
435 const char * id = RDOT_IDENTIFIER_POINTER (enum_id);
436 fprintf (fd, "enum %s {\n", id);
438 indents++;
439 rdot next;
440 for (next = enum_layout; next != NULL_DOT; next = RDOT_CHAIN (next))
442 for (i = 0; i < indents; ++i)
443 fprintf (fd, " ");
444 const char *enumit = RDOT_IDENTIFIER_POINTER (next);
445 fprintf (fd, "[%s],\n", enumit);
447 indents--;
449 for (i = 0; i < indents; ++i)
450 fprintf (fd, " ");
451 fprintf (fd, "}\n");
454 static
455 void dot_pass_dump_cond (FILE * fd, rdot node, size_t indents)
457 size_t i;
458 rdot ifb = RDOT_lhs_TT (node);
459 rdot elb = RDOT_rhs_TT (node);
461 gcc_assert (RDOT_TYPE (ifb) == D_STRUCT_IF);
463 for (i = 0; i < indents; ++i)
464 fprintf (fd, " ");
466 fprintf (fd, "if (");
467 dot_pass_dump_expr (fd, RDOT_lhs_TT (ifb));
468 fprintf (fd, ") {\n");
470 rdot next;
471 for (next = RDOT_rhs_TT (ifb) ; next != NULL_DOT; next = RDOT_CHAIN (next))
473 dot_pass_dump_node (fd, next, indents + 1);
474 fprintf (fd, "\n");
477 for (i = 0; i < indents; ++i)
478 fprintf (fd, " ");
479 fprintf (fd, "}");
481 if (elb != NULL_DOT)
483 fprintf (fd, " else {\n");
484 for (next = RDOT_lhs_TT (elb); next != NULL_DOT; next = RDOT_CHAIN (next))
486 dot_pass_dump_node (fd, next, indents + 1);
487 fprintf (fd, "\n");
489 for (i = 0; i < indents; ++i)
490 fprintf (fd, " ");
491 fprintf (fd, "}\n");
495 static
496 void dot_pass_dump_break (FILE * fd, const rdot node, size_t indents)
498 size_t i;
499 for (i = 0; i < indents; ++i)
500 fprintf (fd, " ");
501 fprintf (fd, "break;");
504 static
505 void dot_pass_dump_loop (FILE * fd, const rdot node, size_t indents)
507 const rdot suite = RDOT_lhs_TT (node);
508 size_t i;
509 for (i = 0; i < indents; ++i)
510 fprintf (fd, " ");
511 fprintf (fd, "loop {\n");
513 rdot next;
514 for (next = suite; next != NULL_DOT; next = RDOT_CHAIN (next))
516 dot_pass_dump_node (fd, next, indents + 1);
517 fprintf (fd, "\n");
520 for (i = 0; i < indents; ++i)
521 fprintf (fd, " ");
522 fprintf (fd, "}\n");
525 static
526 void dot_pass_dump_while (FILE * fd, const rdot node, size_t indents)
528 size_t i;
529 rdot expr = RDOT_lhs_TT (node);
530 rdot suite = RDOT_rhs_TT (node);
532 for (i = 0; i < indents; ++i)
533 fprintf (fd, " ");
534 fprintf (fd, "while (");
535 dot_pass_dump_expr (fd, expr);
536 fprintf (fd, ") {\n");
538 rdot next;
539 for (next = suite; next != NULL_DOT; next = RDOT_CHAIN (next))
541 dot_pass_dump_node (fd, next, indents + 1);
542 fprintf (fd, "\n");
545 for (i = 0; i < indents; ++i)
546 fprintf (fd, " ");
547 fprintf (fd, "}");
550 static
551 void dot_pass_dump_impl (FILE * fd, rdot node, size_t indents)
553 const char * implid = RDOT_IDENTIFIER_POINTER (RDOT_lhs_TT (node));
554 fprintf (fd, "impl %s {\n", implid);
556 rdot next;
557 for (next = RDOT_rhs_TT (node); next != NULL_DOT; next = RDOT_CHAIN (next))
559 dot_pass_dump_node (fd, next, indents + 1);
560 fprintf (fd, "\n");
563 fprintf (fd, "}\n");
566 static
567 void dot_pass_dump_node (FILE * fd, rdot node, size_t indents)
569 if (RDOT_T_FIELD (node) == D_D_EXPR)
571 size_t i;
572 for (i = 0; i < indents; ++i)
573 fprintf (fd, " ");
574 dot_pass_dump_expr (fd, node);
575 fprintf (fd, ";");
577 else
579 switch (RDOT_TYPE (node))
581 case D_PRIMITIVE:
582 dot_pass_dump_expr (fd, node);
583 break;
585 case D_STRUCT_IMPL:
586 dot_pass_dump_impl (fd, node, indents);
587 break;
589 case D_STRUCT_METHOD:
590 dot_pass_dump_method (fd, node, indents);
591 break;
593 case D_STRUCT_TYPE:
594 dot_pass_dump_struct (fd, node, indents);
595 break;
597 case D_STRUCT_ENUM:
598 dot_pass_dump_enum (fd, node, indents);
599 break;
601 case D_STRUCT_IF:
602 dot_pass_dump_cond (fd, node, indents);
603 break;
605 case D_STRUCT_WHILE:
606 dot_pass_dump_while (fd, node, indents);
607 break;
609 case D_STRUCT_LOOP:
610 dot_pass_dump_loop (fd, node, indents);
611 break;
613 case C_BREAK_STMT:
614 dot_pass_dump_break (fd, node, indents);
615 break;
617 default:
618 error ("unhandled node [%s]\n", RDOT_OPCODE_STR (node));
619 break;
624 vec<rdot,va_gc> * dot_pass_PrettyPrint (vec<rdot,va_gc> * decls)
626 if (GRS_OPT_dump_dot)
628 size_t bsize = 128;
629 char * outfile = (char *) alloca (bsize);
630 gcc_assert (outfile);
631 memset (outfile, 0, bsize);
633 strncpy (outfile, GRS_current_infile, strlen (GRS_current_infile));
634 if (first == true)
636 strncat (outfile, RDOT_PREFIX_PRE, sizeof (RDOT_PREFIX_PRE));
637 first = false;
639 else
641 strncat (outfile, RDOT_PREFIX_POST, sizeof (RDOT_PREFIX_POST));
642 _no_infer = true;
645 FILE * fd = fopen (outfile, "w");
646 if (!fd)
648 error ("Unable to open %s for write\n", outfile);
649 goto exit;
652 rdot idtx = NULL_DOT;
653 size_t i;
654 for (i = 0; decls->iterate (i, &idtx); ++i)
656 dot_pass_dump_node (fd, idtx, 0);
657 fprintf (fd, "\n");
660 fclose (fd);
662 exit:
663 return decls;