2 // statement.cs: Statement representation for the IL tree.
5 // Miguel de Icaza (miguel@ximian.com)
7 // (C) 2001 Ximian, Inc.
11 using System.Reflection;
12 using System.Reflection.Emit;
16 using System.Collections;
18 public abstract class Statement {
21 public class EmptyStatement : Statement {
24 public class If : Statement {
26 Statement trueStatement;
27 Statement falseStatement;
29 public If (Expression expr, Statement trueStatement)
32 this.trueStatement = trueStatement;
35 public If (Expression expr,
36 Statement trueStatement,
37 Statement falseStatement)
40 this.trueStatement = trueStatement;
41 this.falseStatement = falseStatement;
44 public Statement TrueStatement {
50 public Statement FalseStatement {
52 return falseStatement;
56 public Expression Expr {
63 public class Do : Statement {
67 public Do (Statement statement, Expression boolExpr)
69 this.boolExpr = boolExpr;
70 this.statement = statement;
73 public Statement EmbeddedStatement {
79 public Expression Expr {
86 public class While : Statement {
90 public While (Expression boolExpr, Statement statement)
92 this.boolExpr = boolExpr;
93 this.statement = statement;
96 public Statement Statement {
102 public Expression Expr {
109 public class For : Statement {
110 Statement initStatement;
115 public For (Statement initStatement,
120 this.initStatement = initStatement;
122 this.increment = increment;
123 this.statement = statement;
126 public Statement InitStatement {
128 return initStatement;
132 public Expression Test {
138 public Statement Increment {
144 public Statement Statement {
152 public class StatementExpression : Statement {
155 public StatementExpression (Expression expr)
160 public Expression Expr {
167 public class Return : Statement {
170 public Return (Expression expr)
175 public Expression Expr {
182 public class Goto : Statement {
185 public Goto (string label)
190 public string Target {
197 public class Throw : Statement {
200 public Throw (Expression expr)
206 public class Break : Statement {
212 public class Continue : Statement {
218 public class VariableInfo {
219 public readonly string Type;
220 public LocalBuilder LocalBuilder;
221 public Type VariableType;
225 public VariableInfo (string type)
245 // Used for Label management
248 public class Block : Statement {
249 public readonly Block Parent;
250 public readonly bool Implicit;
251 public readonly string Label;
254 // The statements in this block
256 StatementCollection statements;
259 // An array of Blocks
264 // Labels. (label, block) pairs.
269 // Keeps track of (name, type) pairs
274 // Maps variable names to ILGenerator.LocalBuilders
276 Hashtable local_builders;
280 public Block (Block parent)
283 parent.AddChild (this);
285 this.Parent = parent;
286 this.Implicit = false;
289 public Block (Block parent, bool implicit_block)
292 parent.AddChild (this);
294 this.Parent = parent;
295 this.Implicit = true;
298 public Block (Block parent, string labeled)
301 parent.AddChild (this);
303 this.Parent = parent;
304 this.Implicit = true;
308 public void AddChild (Block b)
310 if (children == null)
311 children = new ArrayList ();
317 // Adds a label to the current block.
321 // false if the name already exists in this block. true
325 public bool AddLabel (string name, Block block)
328 labels = new Hashtable ();
329 if (labels.Contains (name))
332 labels.Add (name, block);
336 public bool AddVariable (string type, string name)
338 if (variables == null)
339 variables = new Hashtable ();
341 if (GetVariableType (name) != null)
344 VariableInfo vi = new VariableInfo (type);
346 variables.Add (name, vi);
350 public Hashtable Variables {
356 public VariableInfo GetVariableInfo (string name)
358 if (variables != null) {
360 temp = variables [name];
361 return (VariableInfo) temp;
365 return Parent.GetVariableInfo (name);
371 public string GetVariableType (string name)
373 VariableInfo vi = GetVariableInfo (name);
382 // True if the variable named @name has been defined
385 public bool IsVariableDefined (string name)
387 return GetVariableType (name) != null;
391 // Use to fetch the statement associated with this label
393 public Statement this [string name] {
395 return (Statement) labels [name];
400 // A list of labels that were not used within this block
402 public string [] GetUnreferenced ()
404 // FIXME: Implement me
408 public StatementCollection Statements {
410 if (statements == null)
411 statements = new StatementCollection ();
417 public void AddStatement (Statement s)
419 if (statements == null)
420 statements = new StatementCollection ();
433 // Creates a compiler-internal identifier, this is
434 // used to create temporary variables that should not
435 // be seen by the application
437 int internal_id_serial;
438 public string MakeInternalID () {
439 string ret = internal_id_serial.ToString ();
441 internal_id_serial++;
446 // Emits the variable declarations and labels.
449 // tc: is our typecontainer (to resolve type references)
450 // ig: is the code generator:
451 // toplevel: the toplevel block. This is used for checking
452 // that no two labels with the same name are used.
454 public void EmitMeta (TypeContainer tc, ILGenerator ig, Block toplevel)
457 // Process this block variables
459 if (variables != null){
460 local_builders = new Hashtable ();
463 foreach (DictionaryEntry de in variables){
464 string name = (string) de.Key;
465 VariableInfo vi = (VariableInfo) de.Value;
468 t = tc.LookupType (vi.Type, false);
473 vi.LocalBuilder = ig.DeclareLocal (t);
479 // Now, handle the children
481 if (children != null){
482 foreach (Block b in children)
483 b.EmitMeta (tc, ig, toplevel);
488 public class SwitchLabel {
492 // if expr == null, then it is the default case.
494 public SwitchLabel (Expression expr)
499 public Expression Label {
506 public class SwitchSection {
507 // An array of SwitchLabels.
511 public SwitchSection (ArrayList labels, Block block)
513 this.labels = labels;
523 public ArrayList Labels {
530 public class Switch : Statement {
534 public Switch (Expression expr, ArrayList sections)
537 this.sections = sections;
540 public Expression Expr {
546 public ArrayList Sections {
553 public class Lock : Statement {
557 public Lock (Expression expr, Statement stmt)
563 public Statement Statement {
569 public Expression Expr {
577 public class Unchecked : Statement {
580 public Unchecked (Block b)
592 public class Checked : Statement {
595 public Checked (Block b)
607 public class Try : Statement {
613 // specific, general and fini might all be null.
615 public Try (Block block, ArrayList specific, Catch general, Block fini)
617 if (specific == null && general == null){
618 Console.WriteLine ("CIR.Try: Either specific or general have to be non-null");
622 this.specific = specific;
623 this.general = general;
633 public ArrayList Specific {
639 public Catch General {
657 public Catch (string type, string name, Block block)