2006-04-27 Jonathan Chambers <jonathan.chambers@ansys.com>
[mcs.git] / gmcs / gen-treedump.cs
bloba4dbf328ae9e54c6c4f9060128bc341fa0ad7ce2
1 // cs-treedump.cs: Dumps the parsed tree to standard output
2 //
3 // Author: Miguel de Icaza (miguel@gnu.org)
4 //
5 // Licensed under the terms of the GNU GPL
6 //
7 // (C) 2001 Ximian, Inc. (http://www.ximian.com)
8 //
9 // TODO:
10 // Variable declarations
11 // Fix precedence rules to lower the number of parenthesis.
14 using System;
15 using System.IO;
16 using System.Collections;
17 using CIR;
19 namespace Generator {
21 public class TreeDump : CIR.ITreeDump {
22 StreamWriter o;
23 int indent;
24 bool indented;
25 bool tag_values;
27 void space ()
29 if (!indented)
30 output (new String (' ', indent * 8));
31 indented = true;
34 void output (string s)
36 Console.Write (s);
37 //o.Write (s);
40 void newline ()
42 output ("\n");
43 indented = false;
46 void output_newline (string s)
48 output (s);
49 newline ();
52 void ioutput (string s)
54 space ();
55 output (s);
58 string GetParameter (Parameter par)
60 Parameter.Modifier f = par.ModFlags;
61 string mod = "";
63 switch (f){
64 case Parameter.Modifier.REF:
65 mod = "ref "; break;
66 case Parameter.Modifier.OUT:
67 mod = "out "; break;
68 case Parameter.Modifier.PARAMS:
69 mod = "params "; break;
70 case Parameter.Modifier.NONE:
71 mod = ""; break;
73 return mod + par.Type + " " + par.Name;
76 string GetUnary (Unary u, int paren_level)
78 string e;
79 bool left = true;
80 string s = "0_ERROR>";
81 int prec = 0;
83 switch (u.Oper){
84 case Unary.Operator.UnaryPlus:
85 prec = 10;
86 s = "+";
87 break;
89 case Unary.Operator.UnaryNegation:
90 prec = 10;
91 s = "-";
92 break;
94 case Unary.Operator.LogicalNot:
95 s = "!";
96 prec = 10;
97 break;
99 case Unary.Operator.OnesComplement:
100 prec = 10;
101 s = "~";
102 break;
104 case Unary.Operator.Indirection:
105 prec = 10;
106 s = "*";
107 break;
109 case Unary.Operator.AddressOf:
110 prec = 10;
111 s = "&";
112 break;
114 case Unary.Operator.PreIncrement:
115 prec = 11;
116 s = "++";
117 break;
119 case Unary.Operator.PreDecrement:
120 prec = 11;
121 s = "--";
122 break;
124 case Unary.Operator.PostDecrement:
125 left = false;
126 prec = 12;
127 s = "--";
128 break;
130 case Unary.Operator.PostIncrement:
131 s = "++";
132 prec = 12;
133 left = false;
134 break;
137 e = GetExpression (u.Expr, prec);
138 if (left)
139 e = s + e;
140 else
141 e = e + s;
143 if (prec < paren_level)
144 return "(" + e + ")";
145 else
146 return e;
149 string GetBinary (Binary b, int paren_level)
151 string l, r;
152 string op = null;
153 bool assoc_left = true;
154 int prec = 0;
156 switch (b.Oper){
157 case Binary.Operator.Multiply:
158 prec = 9;
159 op = "*"; break;
161 case Binary.Operator.Division:
162 prec = 9;
163 op = "/"; break;
165 case Binary.Operator.Modulus:
166 prec = 9;
167 op = "%"; break;
169 case Binary.Operator.Addition:
170 prec = 8;
171 op = "+"; break;
173 case Binary.Operator.Subtraction:
174 prec = 8;
175 op = "-"; break;
177 case Binary.Operator.LeftShift:
178 prec = 7;
179 op = "<<"; break;
181 case Binary.Operator.RightShift:
182 prec = 7;
183 op = ">>"; break;
185 case Binary.Operator.LessThan:
186 prec = 6;
187 op = "<"; break;
189 case Binary.Operator.GreaterThan:
190 prec = 6;
191 op = ">"; break;
193 case Binary.Operator.LessThanOrEqual:
194 prec = 6;
195 op = "<="; break;
197 case Binary.Operator.GreaterThanOrEqual:
198 prec = 6;
199 op = ">="; break;
201 case Binary.Operator.Equality:
202 prec = 5;
203 op = "=="; break;
205 case Binary.Operator.Inequality:
206 prec = 5;
207 op = "!="; break;
209 case Binary.Operator.BitwiseAnd:
210 prec = 4;
211 op = "&"; break;
213 case Binary.Operator.BitwiseOr:
214 prec = 2;
215 op = "|"; break;
217 case Binary.Operator.LogicalAnd:
218 prec = 1;
219 op = "&&"; break;
221 case Binary.Operator.LogicalOr:
222 prec = 0;
223 op = "||"; break;
225 case Binary.Operator.ExclusiveOr:
226 prec = 3;
227 op = "^"; break;
230 l = GetExpression (b.Left, prec - (assoc_left ? 0 : 1));
231 r = GetExpression (b.Right, prec - (assoc_left ? 0 : 1));
233 if (prec <= paren_level)
234 return "(" + l + " " + op + " " + r + ")";
235 else
236 return l + " " + op + " " + r;
239 string GetCast (Cast c)
241 return "(" + c.TargetType + ") (" + GetExpression (c.Expr, 0) + ")";
244 string GetConditional (Conditional c)
246 return "(" + GetExpression (c.Expr, 0) + ") ? (" +
247 GetExpression (c.TrueExpr, 0) + ") : (" +
248 GetExpression (c.FalseExpr, 0) + ")";
251 string GetAssign (Assign a)
253 return GetExpression (a.Target, 0) + " = " + GetExpression (a.Source, 0);
256 string GetArguments (ArrayList args)
258 string r = "";
260 if (args != null){
261 int top = args.Count;
263 for (int i = 0; i < top; i++){
264 Argument arg = (Argument) args [i];
266 switch (arg.ArgType){
267 case Argument.AType.Ref:
268 r += "ref "; break;
269 case Argument.AType.Out:
270 r += "out "; break;
272 r += GetExpression (arg.Expr, 0);
274 if (i+1 != top)
275 r += ", ";
279 return "(" + r + ")";
282 string GetInvocation (Invocation i)
284 return GetExpression (i.Expr, 0) + " " + GetArguments (i.Arguments);
287 string GetNew (New n)
289 return "new " + n.RequestedType + GetArguments (n.Arguments);
292 string GetTypeOf (TypeOf t)
294 return "typeof (" + t.QueriedType + ")";
297 string GetSizeOf (SizeOf t)
299 return "sizeof (" + t.QueriedType + ")";
302 string GetMemberAccess (MemberAccess m)
304 return GetExpression (m.Expr, 0) +
305 (tag_values ? "/* member access */ . " : ".") +
306 m.Identifier;
309 string GetSimpleName (SimpleName n)
311 string s = n.Name;
313 if (s.StartsWith ("0_"))
314 return "id_" + s;
315 else
316 return s;
319 string GetProbe (Probe p)
321 string s = GetExpression (p.Expr, 6);
323 if (p.Oper == CIR.Probe.Operator.Is)
324 s += " is ";
325 else if (p.Oper == CIR.Probe.Operator.As)
326 s += " as ";
327 else
328 s += "UNHANDLED";
330 s += p.ProbeType;
332 return s;
335 string GetLocalVariableReference (LocalVariableReference l)
337 if (tag_values)
338 return "/* local var: */" + l.Name;
339 else
340 return l.Name;
343 string GetParameterReference (ParameterReference r)
345 if (tag_values)
346 return "/* par: */ " + r.Name;
347 else
348 return r.Name;
351 string GetExpression (Expression e, int paren_level)
353 if (e == null){
354 return "<NULL EXPRESSION>";
357 if (e is Unary)
358 return GetUnary ((Unary) e, paren_level);
359 else if (e is Binary)
360 return GetBinary ((Binary) e, paren_level);
361 else if (e is Cast)
362 return GetCast ((Cast) e);
363 else if (e is Conditional)
364 return GetConditional ((Conditional) e);
365 else if (e is SimpleName)
366 return GetSimpleName ((SimpleName)e);
367 else if (e is LocalVariableReference)
368 return GetLocalVariableReference ((LocalVariableReference) e);
369 else if (e is ParameterReference)
370 return GetParameterReference ((ParameterReference) e);
371 else if (e is Assign)
372 return GetAssign ((Assign) e);
373 else if (e is Literal)
374 return e.ToString ();
375 else if (e is Invocation)
376 return GetInvocation ((Invocation) e);
377 else if (e is New)
378 return GetNew ((New) e);
379 else if (e is This)
380 return "this";
381 else if (e is TypeOf)
382 return GetTypeOf ((TypeOf) e);
383 else if (e is SizeOf)
384 return GetSizeOf ((SizeOf) e);
385 else if (e is MemberAccess)
386 return GetMemberAccess ((MemberAccess) e);
387 else if (e is Probe)
388 return GetProbe ((Probe) e);
389 else
390 return "WARNING {" + e.ToString () + "} WARNING";
393 void GenerateParameters (Parameters pars)
395 Parameter [] pfixed;
396 Parameter parray;
398 pfixed = pars.FixedParameters;
400 if (pfixed != null){
401 for (int i = 0; i < pfixed.Length; i++){
402 output (GetParameter (pfixed [i]));
403 if (i+1 != pfixed.Length)
404 output (", ");
408 parray = pars.ArrayParameter;
409 if (parray != null){
410 output (GetParameter (parray));
414 void GenerateIf (If s)
416 bool do_indent;
418 output ("if (" + GetExpression (s.Expr, 0) + ") ");
419 do_indent = !(s.TrueStatement is Block);
420 if (do_indent)
421 indent++;
422 GenerateStatement (s.TrueStatement, true, false, false);
423 if (do_indent)
424 indent--;
425 if (s.FalseStatement != null){
426 ioutput ("else");
427 newline ();
428 GenerateStatement (s.FalseStatement, false, true, false);
432 void GenerateDo (Do s)
434 output ("do"); newline ();
435 indent++;
436 GenerateStatement (s.EmbeddedStatement, false, false, false);
437 indent--;
438 output (" while (" + GetExpression (s.Expr, 0) + ");");
439 newline ();
442 void GenerateWhile (While s)
444 output ("while (" + GetExpression (s.Expr, 0) + ")");
445 GenerateStatement (s.Statement, true, true, false);
448 void GenerateFor (For s)
450 output ("for (");
451 if (! (s.InitStatement == EmptyStatement.Value))
452 GenerateStatement (s.InitStatement, true, true, true);
453 output ("; ");
454 output (GetExpression (s.Test, 0));
455 output ("; ");
456 if (! (s.Increment == EmptyStatement.Value))
457 GenerateStatement (s.Increment, true, true, true);
458 output (") ");
459 GenerateStatement (s.Statement, true, true, false);
462 void GenerateReturn (Return s)
464 output ("return " +
465 (s.Expr != null ?
466 GetExpression (s.Expr, 0) : "" + ";") +
467 ";");
468 newline ();
471 void GenerateGoto (Goto s)
473 output ("goto " + s.Target + ";");
474 newline ();
477 void GenerateThrow (Throw s)
481 void GenerateStatementExpression (StatementExpression s)
483 output (GetExpression (s.Expr, 0) + ";");
484 newline ();
487 void GenerateSwitchLabels (ArrayList labels)
489 foreach (SwitchLabel sl in labels){
490 Expression lab = sl.Label;
492 if (lab == null){
493 ioutput ("default:");
494 newline ();
495 } else {
496 ioutput ("case " + GetExpression (lab, 0) + ":");
497 newline ();
502 void GenerateSwitch (Switch s)
504 output_newline ("switch (" + GetExpression (s.Expr, 0) + ")");
505 foreach (SwitchSection ss in s.Sections){
506 GenerateSwitchLabels (ss.Labels);
507 GenerateBlock (ss.Block, false, false);
511 void GenerateChecked (Checked c)
513 output ("checked ");
514 GenerateBlock (c.Block, false, false);
517 void GenerateUnchecked (Unchecked c)
519 output ("unchecked ");
520 GenerateBlock (c.Block, false, false);
523 void GenerateCatchClauses (ArrayList list)
525 foreach (Catch c in list){
526 space ();
527 output ("catch ");
529 if (c.Type != null){
530 output ("(" + c.Type +
531 (c.Name != null ? " " + c.Name : "") + ")");
533 GenerateBlock (c.Block, false, false);
537 void GenerateTry (Try t)
539 output ("try");
540 GenerateBlock (t.Block, false, false);
542 if (t.Specific != null){
543 GenerateCatchClauses (t.Specific);
546 if (t.General != null){
547 space ();
548 output ("catch");
549 GenerateBlock (t.Block, false, false);
552 if (t.Fini != null){
553 GenerateBlock (t.Fini, false, false);
557 void GenerateStatement (Statement s, bool doPlacement, bool blockFlushesLine, bool embedded)
559 if (s == null){
560 output ("WARNING: got a null Statement");
561 newline ();
562 return;
565 if (doPlacement){
566 if (s is Block){
567 GenerateBlock ((Block) s, doPlacement, embedded);
568 return;
569 } else
570 newline ();
573 space ();
574 if (s is If)
575 GenerateIf ((If) s);
576 else if (s is Do)
577 GenerateDo ((Do) s);
578 else if (s is While)
579 GenerateWhile ((While) s);
580 else if (s is For)
581 GenerateFor ((For) s);
582 else if (s is Return)
583 GenerateReturn ((Return) s);
584 else if (s is Goto)
585 GenerateGoto ((Goto) s);
586 else if (s is Throw)
587 GenerateThrow ((Throw) s);
588 else if (s is Break)
589 output_newline ("break;");
590 else if (s is Continue)
591 output_newline ("continue;");
592 else if (s == EmptyStatement.Value)
593 output_newline ("/* empty statement */;");
594 else if (s is Block)
595 GenerateBlock ((Block) s, doPlacement, embedded);
596 else if (s is StatementExpression)
597 GenerateStatementExpression ((StatementExpression) s);
598 else if (s is Switch)
599 GenerateSwitch ((Switch) s);
600 else if (s is Checked)
601 GenerateChecked ((Checked) s);
602 else if (s is Unchecked)
603 GenerateUnchecked ((Unchecked) s);
604 else if (s is Try)
605 GenerateTry ((Try) s);
606 else {
607 System.Type t = s.GetType ();
609 output ("\n*****UNKNOWN Statement:" + t.ToString ());
614 // embedded is used only for things like the For thing
615 // that has blocks but for display purposes we want to keep
616 // without newlines.
617 void GenerateBlock (Block b, bool doPlacement, bool embedded)
619 if (b.Label != null)
620 output (b.Label + ":");
622 if (!b.Implicit){
623 if (!doPlacement)
624 space ();
626 output ("{");
627 if (!embedded)
628 newline ();
629 indent++;
632 if (b.Variables != null){
633 foreach (DictionaryEntry entry in b.Variables){
634 VariableInfo vi = (VariableInfo) entry.Value;
636 space ();
637 output_newline (
638 vi.Type + " " +
639 (string) entry.Key + ";");
641 newline ();
644 foreach (Statement s in b.Statements){
645 GenerateStatement (s, false, true, false);
648 if (!b.Implicit){
649 indent--;
650 ioutput ("}");
651 if (!embedded)
652 newline ();
656 void GenerateMethod (Method m)
658 ioutput (GetModifiers (m.ModFlags) +
659 m.ReturnType + " " +
660 m.Name + " (");
661 GenerateParameters (m.Parameters);
662 output_newline (")");
665 GenerateBlock (m.Block, false, false);
666 newline ();
669 void GenerateInterfaceMethod (InterfaceMethod imethod)
671 space ();
672 output (imethod.IsNew ? "new " : "");
673 output (imethod.ReturnType + " " + imethod.Name + " (");
674 GenerateParameters (imethod.Parameters);
675 output (");");
676 newline ();
679 void GenerateInterfaceProperty (InterfaceProperty iprop)
681 space ();
682 output (iprop.IsNew ? "new " : "");
683 output (iprop.Type + " " + iprop.Name + " { ");
684 if (iprop.HasGet) output ("get; ");
685 if (iprop.HasSet) output ("set; ");
686 output ("}");
687 newline ();
690 void GenerateInterfaceEvent (InterfaceEvent ievent)
692 space ();
693 output ((ievent.IsNew ? "new " : "") + "event ");
694 output (ievent.Type + " " + ievent.Name + ";");
695 newline ();
698 void GenerateInterfaceIndexer (InterfaceIndexer iindexer)
700 space ();
701 output (iindexer.IsNew ? "new " : "");
702 output (iindexer.Type + " this [");
703 output (iindexer.Parameters + "] {");
704 if (iindexer.HasGet) output ("get; ");
705 if (iindexer.HasSet) output ("set; ");
706 output ("}");
707 newline ();
710 string GenIfaceBases (Interface iface)
712 return GenBases (iface.Bases);
715 void GenerateInterface (Interface iface)
717 ioutput (GetModifiers (iface.ModFlags) + "interface " +
718 ClassName (iface.Name) + GenIfaceBases (iface) + " {");
719 newline ();
720 indent++;
722 if (iface.InterfaceMethods != null){
723 foreach (DictionaryEntry de in iface.InterfaceMethods){
724 InterfaceMethod method = (InterfaceMethod) de.Value;
725 GenerateInterfaceMethod (method);
729 if (iface.InterfaceProperties != null){
730 foreach (DictionaryEntry de in iface.InterfaceProperties){
731 InterfaceProperty iprop = (InterfaceProperty) de.Value;
732 GenerateInterfaceProperty (iprop);
736 if (iface.InterfaceEvents != null){
737 foreach (DictionaryEntry de in iface.InterfaceEvents){
738 InterfaceEvent ievent = (InterfaceEvent) de.Value;
739 GenerateInterfaceEvent (ievent);
743 if (iface.InterfaceIndexers != null){
744 foreach (DictionaryEntry de in iface.InterfaceIndexers){
745 InterfaceIndexer iindexer = (InterfaceIndexer) de.Value;
746 GenerateInterfaceIndexer (iindexer);
749 indent--;
750 ioutput ("}");
751 newline ();
752 newline ();
755 void GenerateField (Field f)
757 space ();
758 output (GetModifiers (f.ModFlags) +
759 f.Type + " " + f.Name);
760 if (f.Initializer != null){
761 if (f.Initializer is Expression)
762 output (" = " + GetExpression ((Expression) f.Initializer, 0));
763 else
764 output ("ADD SUPPORT FOR ARRAYS");
766 output (";");
767 newline ();
770 void GenerateConstructor (Constructor c)
772 ConstructorInitializer init = c.Initializer;
774 space ();
775 output (GetModifiers (c.ModFlags) + c.Name + " (");
776 GenerateParameters (c.Parameters);
777 output (")");
779 if (init != null){
780 if (init is ConstructorThisInitializer)
781 output (": this (");
782 else
783 output (": base (");
784 output (GetArguments (init.Arguments));
785 output (")");
787 newline ();
788 GenerateBlock (c.Block, false, false);
791 void GenerateProperty (Property prop)
793 space ();
794 output (GetModifiers (prop.ModFlags) + prop.Type +
795 " " + prop.Name + " {");
796 newline ();
797 indent++;
798 if (prop.Get != null){
799 space ();
800 output ("get ");
801 GenerateBlock (prop.Get, false, false);
802 newline ();
805 if (prop.Set != null){
806 space ();
807 output ("set ");
808 GenerateBlock (prop.Set, false, false);
810 indent--;
811 space ();
812 output ("}");
813 newline ();
816 void GenerateEnum (CIR.Enum e)
818 space ();
819 output ("enum " + e.Name + " {");
820 newline ();
822 indent++;
823 foreach (string name in e.ValueNames){
824 Expression expr = e [name];
826 space ();
828 output (name);
829 if (expr != null)
830 output (" = " + GetExpression (expr, 0));
832 output (",");
833 newline ();
835 indent--;
836 space ();
837 output_newline ("}");
840 void GenerateTypeContainerData (TypeContainer tc)
842 if (tc.Constants != null){
843 foreach (Constant c in tc.Constants){
844 space ();
846 output ("const " + c.ConstantType + " " + c.Name + " = " +
847 GetExpression (c.Expr, 0) + ";");
848 newline ();
850 newline ();
853 if (tc.Enums != null){
854 foreach (CIR.Enum e in tc.Enums)
855 GenerateEnum (e);
858 if (tc.Fields != null){
859 foreach (Field f in tc.Fields)
860 GenerateField (f);
861 newline ();
864 if (tc.Constructors != null){
865 foreach (Constructor c in tc.Constructors)
866 GenerateConstructor (c);
868 newline ();
872 if (tc.Properties != null){
873 foreach (Property prop in tc.Properties)
874 GenerateProperty (prop);
877 GenerateFromTypes (tc);
879 if (tc.Methods != null){
880 foreach (Method m in tc.Methods){
881 GenerateMethod (m);
886 string GetModifiers (int mod_flags)
888 string s = "";
890 for (int i = 1; i <= (int) CIR.Modifiers.TOP; i <<= 1){
891 if ((mod_flags & i) != 0)
892 s += Modifiers.Name (i) + " ";
895 return s;
898 string ClassName (string name)
900 return name;
901 //return name.Substring (1 + name.LastIndexOf ('.'));
904 string GenBases (ArrayList bases)
906 if (bases == null)
907 return "";
909 string res = ": ";
910 int top = bases.Count;
911 for (int i = 0; i < bases.Count; i++){
912 Type t = (Type) bases [i];
914 res += t.Name;
915 if (i + 1 != top)
916 res += ", ";
918 return res;
921 string GenClassBases (Class c)
923 return GenBases (c.Bases);
926 void GenerateFromClass (Class c)
928 ioutput (GetModifiers (c.ModFlags) + "class " + ClassName (c.Name) +
929 " " + GenClassBases (c) + " {");
930 newline ();
931 indent++;
933 GenerateTypeContainerData (c);
935 indent--;
936 ioutput ("}");
937 newline ();
938 newline ();
941 void GenerateFromStruct (Struct s)
943 GenerateTypeContainerData (s);
946 void GenerateFromTypes (TypeContainer types)
948 if (types.Types == null)
949 return;
951 foreach (DictionaryEntry de in types.Types){
952 TypeContainer type = (TypeContainer) de.Value;
954 if (type is Class)
955 GenerateFromClass ((Class) type);
956 if (type is Struct)
957 GenerateFromStruct ((Struct) type);
961 if (types.Interfaces != null){
962 foreach (DictionaryEntry de in types.Interfaces){
963 Interface iface = (Interface) de.Value;
965 GenerateInterface (iface);
970 public int Dump (Tree tree, StreamWriter output)
972 this.o = output;
974 indent = 0;
975 GenerateFromTypes (tree.Types);
977 return 0;
980 public void ParseOptions (string options)
982 if (options == "tag")
983 tag_values = true;