⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 statementast.cs

📁 charp compiler
💻 CS
📖 第 1 页 / 共 4 页
字号:

        // Test to make sure that break & continue are in a loop
    static int m_loopcount = 0;
    public static bool IsInsideLoop()  
    {
        return m_loopcount != 0;
    }

    protected Exp m_expTest;
    public Exp TestExp
    {
        get { return m_expTest; }
    }

    protected Statement m_stmtBody;        
    public Statement BodyStmt
    {
        get { return m_stmtBody; }
    }


    // Debug checking
    public override void DebugCheck(ISemanticResolver s)
    {
        TestExp.DebugCheck(s);
        BodyStmt.DebugCheck(s);
    }

    // Semantic resolution
    public override void ResolveStatement(ISemanticResolver s)
    {        
        Exp.ResolveExpAsRight(ref this.m_expTest, s);

        m_loopcount++;
        BodyStmt.ResolveStatement(s);
        m_loopcount--;

        //s.EnsureDerivedType(s.ResolveCLRTypeToBlueType(typeof(bool)), TestExp);
        s.EnsureAssignable(TestExp, typeof(bool));
    }

    public override void ResolveStatement2(ISemanticResolver s)
    {
        m_loopcount++;
        BodyStmt.ResolveStatement2(s);
        m_loopcount--;
    }
} // end LoopStatement

//-----------------------------------------------------------------------------
// Do Statement 
//-----------------------------------------------------------------------------
public class DoStatement : LoopStatement
{
    public DoStatement(
        Exp expTest,
        Statement stmtBody
    ) 
        : base(expTest, stmtBody)
    {        
    }
        
    // Dump
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("do");
        TestExp.Dump(o);
        BodyStmt.Dump(o);
        o.WriteEndElement();
    }
    
    // Code generation
    public override void Generate(CodeGen.EmitCodeGen gen)
    {   
        gen.Generate(this);
    }
}

//-----------------------------------------------------------------------------
// For statement. Has 2 flavors - variable initialed & no var initialized
//-----------------------------------------------------------------------------
public class ForStatement : LoopStatement
{
#region Construction
    public ForStatement(
        StatementExp eInit,
        Exp expTest,
        StatementExp eNext,
        Statement stmtBody)
    : base(expTest, stmtBody)        
    {
        m_sexpInit = eInit;        
        m_sexpNext = eNext;
    }
#endregion

#region Properties & Data
    StatementExp m_sexpInit;
    public StatementExp InitExp
    {   
        get { return m_sexpInit; }
    }
    
    StatementExp m_sexpNext;
    public StatementExp NextExp
    {
        get { return m_sexpNext; }
    }    
#endregion    

#region Checks
    // Dump
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("for");
        InitExp.Dump(o);
        TestExp.Dump(o);
        NextExp.Dump(o);
        BodyStmt.Dump(o);
        o.WriteEndElement();
    }
    
    // Debug checking
    public override void DebugCheck(ISemanticResolver s)
    {
        InitExp.DebugCheck(s);
        NextExp.DebugCheck(s);
        
        // Call to Loop.DebugCheck();
        base.DebugCheck(s);
    }
#endregion
    
#region Resolution    
    // Semantic resolution
    public override void ResolveStatement(ISemanticResolver s)
    {        
        Exp e = m_sexpInit;
        Exp.ResolveExpAsRight(ref e, s);
        Debug.Assert(e == m_sexpInit); // @todo - fix this
        
        e = m_sexpNext;
        Exp.ResolveExpAsRight(ref e, s);
        Debug.Assert(e == m_sexpNext); // @todo -fix this
        
        base.ResolveStatement(s);
    }    
#endregion     
    
    // Code generation
    public override void Generate(CodeGen.EmitCodeGen gen)
    {   
        gen.Generate(this);
    }
}

//-----------------------------------------------------------------------------
// Foreach statement
// foreach (Type t in Exp) Body
// Resolves to either a For statement or a while statement
//-----------------------------------------------------------------------------
public class ForeachStatement : Statement
{
    public ForeachStatement(
        LocalVarDecl var,
        Exp expCollection,
        Statement body
    )
    {
        Debug.Assert(var != null);
        Debug.Assert(expCollection != null);
        
        m_var = var;
        m_expCollection = expCollection;
        m_stmtBody = body;
    }
    
#region Properties & Data
    Statement m_stmtResolved;
    public Statement ResolvedStmt
    {
        get { return m_stmtResolved; }
    }
    
    LocalVarDecl m_var;
    Exp m_expCollection;
    Statement m_stmtBody;

#endregion

#region Checks
    // Dump
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("foreach");
        m_var.Dump(o);
        m_expCollection.Dump(o);
        m_stmtBody.Dump(o);
        if (m_stmtResolved != null)
        {
            o.WriteStartElement("ResolvedStatement");
            m_stmtResolved.Dump(o);
            o.WriteEndElement();
        }
        o.WriteEndElement();
    }      
    
    public override void DebugCheck(ISemanticResolver s)
    {
        Debug.Assert(m_stmtResolved != null);
        m_stmtResolved.DebugCheck(s);
        
    /*
        m_var.DebugCheck(s);
        m_expCollection.DebugCheck(s);
        m_stmtBody.DebugCheck(s);
    */        
    }
    
    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {
        sb.Write("foreach(");
        this.m_var.ToSource(sb);
        sb.Write(" in ");
        this.m_expCollection.ToSource(sb);
        sb.WriteLine(')');
        this.m_stmtBody.ToSource(sb);
        
    }
#endregion

    // Code generation, just pass on to our resolved statement
    public override void Generate(CodeGen.EmitCodeGen gen)
    {           
        m_stmtResolved.Generate(gen);
    }

#region Resolution
    // Semantic resolution
    public override void ResolveStatement(ISemanticResolver s)
    {
        // If collection is an array, then we resolve to a for-loop around the array
        Exp.ResolveExpAsRight(ref m_expCollection, s);
                
        if (m_expCollection.CLRType.IsArray)
        {
            ResolveAsArray(s);
        } else {
            ResolveAsIEnumerator(s);
        }
        
        Debug.Assert(m_stmtResolved != null);
        m_stmtResolved.ResolveStatement(s);
    }
    
    public override void ResolveStatement2(ISemanticResolver s)
    {
        // By now, we have the resolved statement, so just go through
        // to it on the 2nd pass.
        m_stmtResolved.ResolveStatement2(s);
    }

    // We expect to resolve this as an array. If The collection is an 
    // array type, we should be able to do that without any problems.           
    void ResolveAsArray(ISemanticResolver s)
    {
#if false
// foreach(T t in C) [Body];
// Array resolves as:
{
    int i;
    T t;    
    for(i = 0; i < C.Length; i++)
    {
        t = A[i];
        [Body]
    }        
}
#endif
        Identifier idI = new Identifier(".temp", this.Location);
        SimpleObjExp expI = new SimpleObjExp(idI);
        
        Identifier idT = new Identifier(this.m_var.Name, Location);
        
        // Build an AST for the resolved statement
        m_stmtResolved = new BlockStatement(
            new LocalVarDecl[] { 
                new LocalVarDecl(
                    idI, 
                    //new TypeSig(new SimpleObjExp(new Identifier("int", Location)))
                    new ResolvedTypeSig(typeof(int), s)
                ),
                this.m_var
            },
            new Statement[] {
                new ForStatement(
                    new AssignStmtExp(
                        expI,
                        new IntExp(0, this.Location)
                    ),
                    new BinaryExp(
                        expI,
                        new DotObjExp(
                            m_expCollection,
                            new Identifier("Length", Location)
                        ),
                        BinaryExp.BinaryOp.cLT
                    ),
                    new PrePostIncDecStmtExp(expI, false, true),
                    new BlockStatement(
                        null,
                        new Statement[] {
                            new ExpStatement(
                                new AssignStmtExp(
                                    new SimpleObjExp(idT),
                                    new ArrayAccessExp(m_expCollection, expI)
                                )
                            ),
                            this.m_stmtBody
                        }
                    )
                )
            }                        
        ); // end BlockStatement
            
    } // End resolve as array
    
    // We expect to resolve using IEnumerator. This has several conditions,
    // and so we have to do some error checking.
    void ResolveAsIEnumerator(ISemanticResolver s)
    {
#if false
// foreach(T t in C) [Body];
// Enumeration resolves as:
{
    E e;
    T t;
    
    e = C.GetEnumerator();
    while(e.MoveNext())
    {
        t = (T) e.Current;
        [Body]
    }
}
#endif
        // First must find the GetEnumerator() method
        bool dummy;
        MethodExpEntry mGetEnumerator = 
            s.ResolveCLRTypeToBlueType(m_expCollection.CLRType).
            LookupMethod(s, new Identifier("GetEnumerator"), new Type[0], out dummy);

        Identifier idEnum = new Identifier(".Temp", Location);
        SimpleObjExp expEnum = new SimpleObjExp(idEnum);
        
        Identifier idT = new Identifier(this.m_var.Name, Location);
        
        // Build an AST for the resolved statement
        m_stmtResolved = new BlockStatement(
            new LocalVarDecl[] {
                new LocalVarDecl(
                    idEnum,
                    new ResolvedTypeSig(mGetEnumerator.RetType)
                ),
                this.m_var
            },
            new Statement[] {
                new ExpStatement(
                    new AssignStmtExp(
                        expEnum,
                        new MethodCallExp(m_expCollection, new Identifier("GetEnumerator", Location), new ArgExp[0])
                    )
                ),
                new WhileStatement(
                    new MethodCallExp(
                        expEnum,
                        new Identifier("MoveNext", Location),
                        new ArgExp[0]
                    ),
                    new BlockStatement(
                        null,
                        new Statement[]
                        {
                            new ExpStatement(
                                new AssignStmtExp(
                                    new SimpleObjExp(idT),
                                    new AST.CastObjExp(
                                        this.m_var.Sig,
                                        new DotObjExp(expEnum, new Identifier("Current", Location))
                                    )
                                )
                            ),                                
                            this.m_stmtBody
                        }
                    )
                ) // end while
            } // end Statement[]
        );            
    
    
    } // end resolve as Enumerator

#endregion    
        
}

//-----------------------------------------------------------------------------
// While Statement 
//-----------------------------------------------------------------------------
public class WhileStatement : LoopStatement
{
    public WhileStatement(
        Exp expTest,
        Statement stmtBody
    ) : base(expTest, stmtBody)    
    {        
    }
        
    // Dump
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("while");
        TestExp.Dump(o);
        BodyStmt.Dump(o);
        o.WriteEndElement();
    }
    
    // Code generation
    public override void Generate(CodeGen.EmitCodeGen gen)
    {   
        gen.Generate(this);
    }
}
#endregion Loop Statements

#region Jump statements    
//-----------------------------------------------------------------------------
// Statement 
//-----------------------------------------------------------------------------
public class LabelStatement : Statement
{
    public LabelStatement(Identifier label)
    {
        Debug.Assert(label != null);
        m_label = label;
    }

    protected Identifier m_label;
    public Identifier LabelId
    {
        get { return m_label; }
    }

    protected LabelEntry m_symbol;
    public LabelEntry Symbol
    {
        get { return m_symbol; }
    }
    
    // Debug checking
    public override void DebugCheck(ISemanticResolver s)
    {
        Debug.Assert(m_symbol != null);
    }

    // Dump
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("LabelStatement");
        o.WriteAttributeString("name", m_label.Text);
        o.WriteEndElement();
    }

    // Semantic resolution
    public override void ResolveStatement(ISemanticResolver s)
    {
    // Label must have not been defined.
        m_symbol = (LabelEntry) s.LookupSymbol(s.GetCurrentContext(), m_label, false);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -