1 // cs-treedump.cs: Dumps the parsed tree to standard output
3 // Author: Miguel de Icaza (miguel@gnu.org)
5 // Licensed under the terms of the GNU GPL
7 // (C) 2001 Ximian, Inc. (http://www.ximian.com)
10 // Variable declarations
11 // Fix precedence rules to lower the number of parenthesis.
16 using System
.Collections
;
21 public class TreeDump
: CIR
.ITreeDump
{
30 output (new String (' ', indent
* 8));
34 void output (string s
)
46 void output_newline (string s
)
52 void ioutput (string s
)
58 string GetParameter (Parameter par
)
60 Parameter
.Modifier f
= par
.ModFlags
;
64 case Parameter
.Modifier
.REF
:
66 case Parameter
.Modifier
.OUT
:
68 case Parameter
.Modifier
.PARAMS
:
69 mod
= "params "; break;
70 case Parameter
.Modifier
.NONE
:
73 return mod
+ par
.Type
+ " " + par
.Name
;
76 string GetUnary (Unary u
, int paren_level
)
80 string s
= "0_ERROR>";
84 case Unary
.Operator
.UnaryPlus
:
89 case Unary
.Operator
.UnaryNegation
:
94 case Unary
.Operator
.LogicalNot
:
99 case Unary
.Operator
.OnesComplement
:
104 case Unary
.Operator
.Indirection
:
109 case Unary
.Operator
.AddressOf
:
114 case Unary
.Operator
.PreIncrement
:
119 case Unary
.Operator
.PreDecrement
:
124 case Unary
.Operator
.PostDecrement
:
130 case Unary
.Operator
.PostIncrement
:
137 e
= GetExpression (u
.Expr
, prec
);
143 if (prec
< paren_level
)
144 return "(" + e
+ ")";
149 string GetBinary (Binary b
, int paren_level
)
153 bool assoc_left
= true;
157 case Binary
.Operator
.Multiply
:
161 case Binary
.Operator
.Division
:
165 case Binary
.Operator
.Modulus
:
169 case Binary
.Operator
.Addition
:
173 case Binary
.Operator
.Subtraction
:
177 case Binary
.Operator
.LeftShift
:
181 case Binary
.Operator
.RightShift
:
185 case Binary
.Operator
.LessThan
:
189 case Binary
.Operator
.GreaterThan
:
193 case Binary
.Operator
.LessThanOrEqual
:
197 case Binary
.Operator
.GreaterThanOrEqual
:
201 case Binary
.Operator
.Equality
:
205 case Binary
.Operator
.Inequality
:
209 case Binary
.Operator
.BitwiseAnd
:
213 case Binary
.Operator
.BitwiseOr
:
217 case Binary
.Operator
.LogicalAnd
:
221 case Binary
.Operator
.LogicalOr
:
225 case Binary
.Operator
.ExclusiveOr
:
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
+ ")";
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
)
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
:
269 case Argument
.AType
.Out
:
272 r
+= GetExpression (arg
.Expr
, 0);
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 */ . " : ".") +
309 string GetSimpleName (SimpleName n
)
313 if (s
.StartsWith ("0_"))
319 string GetProbe (Probe p
)
321 string s
= GetExpression (p
.Expr
, 6);
323 if (p
.Oper
== CIR
.Probe
.Operator
.Is
)
325 else if (p
.Oper
== CIR
.Probe
.Operator
.As
)
335 string GetLocalVariableReference (LocalVariableReference l
)
338 return "/* local var: */" + l
.Name
;
343 string GetParameterReference (ParameterReference r
)
346 return "/* par: */ " + r
.Name
;
351 string GetExpression (Expression e
, int paren_level
)
354 return "<NULL EXPRESSION>";
358 return GetUnary ((Unary
) e
, paren_level
);
359 else if (e
is Binary
)
360 return GetBinary ((Binary
) e
, paren_level
);
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
);
378 return GetNew ((New
) e
);
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
);
388 return GetProbe ((Probe
) e
);
390 return "WARNING {" + e.ToString () + "} WARNING";
393 void GenerateParameters (Parameters pars
)
398 pfixed
= pars
.FixedParameters
;
401 for (int i
= 0; i
< pfixed
.Length
; i
++){
402 output (GetParameter (pfixed
[i
]));
403 if (i
+1 != pfixed
.Length
)
408 parray
= pars
.ArrayParameter
;
410 output (GetParameter (parray
));
414 void GenerateIf (If s
)
418 output ("if (" + GetExpression (s
.Expr
, 0) + ") ");
419 do_indent
= !(s
.TrueStatement
is Block
);
422 GenerateStatement (s
.TrueStatement
, true, false, false);
425 if (s
.FalseStatement
!= null){
428 GenerateStatement (s
.FalseStatement
, false, true, false);
432 void GenerateDo (Do s
)
434 output ("do"); newline ();
436 GenerateStatement (s
.EmbeddedStatement
, false, false, false);
438 output (" while (" + GetExpression (s
.Expr
, 0) + ");");
442 void GenerateWhile (While s
)
444 output ("while (" + GetExpression (s
.Expr
, 0) + ")");
445 GenerateStatement (s
.Statement
, true, true, false);
448 void GenerateFor (For s
)
451 if (! (s
.InitStatement
== EmptyStatement
.Value
))
452 GenerateStatement (s
.InitStatement
, true, true, true);
454 output (GetExpression (s
.Test
, 0));
456 if (! (s
.Increment
== EmptyStatement
.Value
))
457 GenerateStatement (s
.Increment
, true, true, true);
459 GenerateStatement (s
.Statement
, true, true, false);
462 void GenerateReturn (Return s
)
466 GetExpression (s
.Expr
, 0) : "" + ";") +
471 void GenerateGoto (Goto s
)
473 output ("goto " + s
.Target
+ ";");
477 void GenerateThrow (Throw s
)
481 void GenerateStatementExpression (StatementExpression s
)
483 output (GetExpression (s
.Expr
, 0) + ";");
487 void GenerateSwitchLabels (ArrayList labels
)
489 foreach (SwitchLabel sl
in labels
){
490 Expression lab
= sl
.Label
;
493 ioutput ("default:");
496 ioutput ("case " + GetExpression (lab
, 0) + ":");
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
)
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
){
530 output ("(" + c
.Type
+
531 (c
.Name
!= null ? " " + c
.Name
: "") + ")");
533 GenerateBlock (c
.Block
, false, false);
537 void GenerateTry (Try t
)
540 GenerateBlock (t
.Block
, false, false);
542 if (t
.Specific
!= null){
543 GenerateCatchClauses (t
.Specific
);
546 if (t
.General
!= null){
549 GenerateBlock (t
.Block
, false, false);
553 GenerateBlock (t
.Fini
, false, false);
557 void GenerateStatement (Statement s
, bool doPlacement
, bool blockFlushesLine
, bool embedded
)
560 output ("WARNING: got a null Statement");
567 GenerateBlock ((Block
) s
, doPlacement
, embedded
);
579 GenerateWhile ((While
) s
);
581 GenerateFor ((For
) s
);
582 else if (s
is Return
)
583 GenerateReturn ((Return
) s
);
585 GenerateGoto ((Goto
) s
);
587 GenerateThrow ((Throw
) s
);
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 */;");
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
);
605 GenerateTry ((Try
) s
);
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
617 void GenerateBlock (Block b
, bool doPlacement
, bool embedded
)
620 output (b
.Label
+ ":");
632 if (b
.Variables
!= null){
633 foreach (DictionaryEntry entry
in b
.Variables
){
634 VariableInfo vi
= (VariableInfo
) entry
.Value
;
639 (string) entry
.Key
+ ";");
644 foreach (Statement s
in b
.Statements
){
645 GenerateStatement (s
, false, true, false);
656 void GenerateMethod (Method m
)
658 ioutput (GetModifiers (m
.ModFlags
) +
661 GenerateParameters (m
.Parameters
);
662 output_newline (")");
665 GenerateBlock (m
.Block
, false, false);
669 void GenerateInterfaceMethod (InterfaceMethod imethod
)
672 output (imethod
.IsNew
? "new " : "");
673 output (imethod
.ReturnType
+ " " + imethod
.Name
+ " (");
674 GenerateParameters (imethod
.Parameters
);
679 void GenerateInterfaceProperty (InterfaceProperty iprop
)
682 output (iprop
.IsNew
? "new " : "");
683 output (iprop
.Type
+ " " + iprop
.Name
+ " { ");
684 if (iprop
.HasGet
) output ("get; ");
685 if (iprop
.HasSet
) output ("set; ");
690 void GenerateInterfaceEvent (InterfaceEvent ievent
)
693 output ((ievent
.IsNew
? "new " : "") + "event ");
694 output (ievent
.Type
+ " " + ievent
.Name
+ ";");
698 void GenerateInterfaceIndexer (InterfaceIndexer iindexer
)
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; ");
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
) + " {");
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
);
755 void GenerateField (Field f
)
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));
764 output ("ADD SUPPORT FOR ARRAYS");
770 void GenerateConstructor (Constructor c
)
772 ConstructorInitializer init
= c
.Initializer
;
775 output (GetModifiers (c
.ModFlags
) + c
.Name
+ " (");
776 GenerateParameters (c
.Parameters
);
780 if (init
is ConstructorThisInitializer
)
784 output (GetArguments (init
.Arguments
));
788 GenerateBlock (c
.Block
, false, false);
791 void GenerateProperty (Property prop
)
794 output (GetModifiers (prop
.ModFlags
) + prop
.Type
+
795 " " + prop
.Name
+ " {");
798 if (prop
.Get
!= null){
801 GenerateBlock (prop
.Get
, false, false);
805 if (prop
.Set
!= null){
808 GenerateBlock (prop
.Set
, false, false);
816 void GenerateEnum (CIR
.Enum e
)
819 output ("enum " + e
.Name
+ " {");
823 foreach (string name
in e
.ValueNames
){
824 Expression expr
= e
[name
];
830 output (" = " + GetExpression (expr
, 0));
837 output_newline ("}");
840 void GenerateTypeContainerData (TypeContainer tc
)
842 if (tc
.Constants
!= null){
843 foreach (Constant c
in tc
.Constants
){
846 output ("const " + c
.ConstantType
+ " " + c
.Name
+ " = " +
847 GetExpression (c
.Expr
, 0) + ";");
853 if (tc
.Enums
!= null){
854 foreach (CIR
.Enum e
in tc
.Enums
)
858 if (tc
.Fields
!= null){
859 foreach (Field f
in tc
.Fields
)
864 if (tc
.Constructors
!= null){
865 foreach (Constructor c
in tc
.Constructors
)
866 GenerateConstructor (c
);
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
){
886 string GetModifiers (int mod_flags
)
890 for (int i
= 1; i
<= (int) CIR
.Modifiers
.TOP
; i
<<= 1){
891 if ((mod_flags
& i
) != 0)
892 s
+= Modifiers
.Name (i
) + " ";
898 string ClassName (string name
)
901 //return name.Substring (1 + name.LastIndexOf ('.'));
904 string GenBases (ArrayList bases
)
910 int top
= bases
.Count
;
911 for (int i
= 0; i
< bases
.Count
; i
++){
912 Type t
= (Type
) bases
[i
];
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
) + " {");
933 GenerateTypeContainerData (c
);
941 void GenerateFromStruct (Struct s
)
943 GenerateTypeContainerData (s
);
946 void GenerateFromTypes (TypeContainer types
)
948 if (types
.Types
== null)
951 foreach (DictionaryEntry de
in types
.Types
){
952 TypeContainer type
= (TypeContainer
) de
.Value
;
955 GenerateFromClass ((Class
) type
);
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
)
975 GenerateFromTypes (tree
.Types
);
980 public void ParseOptions (string options
)
982 if (options
== "tag")