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

📄 statementast.cs

📁 charp compiler
💻 CS
📖 第 1 页 / 共 4 页
字号:
//-----------------------------------------------------------------------------
// File: StatementAST.cs
//
// Description: All Statement nodes in the AST
// See AST.cs for details
//-----------------------------------------------------------------------------

using System;
using System.Diagnostics;
using System.Xml;

using CodeGen = Blue.CodeGen;
using Utilities = Blue.Utilities;

using Blue.Public;
using SymbolEngine;

namespace AST
{
//-----------------------------------------------------------------------------
// Statement base class
//-----------------------------------------------------------------------------

/// <summary>
/// Abstract base class for all statements.
/// </summary>
public abstract class Statement : Node
{

    // Semantic resolution
    public abstract void ResolveStatement(ISemanticResolver s);
    public virtual void ResolveStatement2(ISemanticResolver s) { }

    // Code generation
    public abstract void Generate(CodeGen.EmitCodeGen gen);
}

#region Empty Statement
//-----------------------------------------------------------------------------        
// Empty statement
//-----------------------------------------------------------------------------        
public class EmptyStatement : Statement
{
    public EmptyStatement() 
    {
    }
    
    public override void ResolveStatement(ISemanticResolver s)
    {
    }
    
    public override void Generate(CodeGen.EmitCodeGen gen)
    {
        // @todo - should we emit a nop?
    }    
    
#region Checks    
    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {
        sb.WriteLine("; // empty");
    }
    public override void Dump(XmlWriter o)
    {        
    }
    
    public override void DebugCheck(ISemanticResolver s)
    {
    }
#endregion    

}
#endregion

#region BlockStatement
//-----------------------------------------------------------------------------        
// Block statement
// Statements inside '{' .... '}'
// Can have their own statements & optionally their own little scope
//-----------------------------------------------------------------------------        
public class BlockStatement : Statement
{
#region Construction
    public BlockStatement(
        LocalVarDecl[] arLocals, // can be null if we have no locals
        Statement[] arStatements // never null
    )
    {
        // If we have any locals in this block statement, then we
        // also need to have a scope to hold them.
        if (arLocals == null)
        {
            m_arLocals = new LocalVarDecl[0];
        } else {
            m_arLocals = arLocals;
            // @todo - decorate name w/ filerange?
            //m_scopeLocals = new Scope("block_scope", null);
        }
        
        // May have an empty statement block, so arStatements.Length could be 0
        // but at least expect an array.
        Debug.Assert(arStatements != null);
        m_arStatements = arStatements;
        
        // @todo - fix this
        if (arStatements.Length == 0)
            this.m_filerange = new FileRange();
        else 
            this.m_filerange = arStatements[0].Location;
    }
#endregion

    // Inject a statement at the beginning
    // Must resolve after doing this.
    public void InjectStatementAtHead(Statement sNew)
    {   
        Statement[] ar2 = new Statement[this.Statements.Length + 1];
        ar2[0] = sNew;
        for(int i = 0; i < Statements.Length; i++)        
            ar2[i + 1] = Statements[i];
        
        this.m_arStatements = ar2;
    }
    
    public void InjectLocalVar(LocalVarDecl l)
    {
        //m_scopeLocals = new Scope("block_scope", null);
        LocalVarDecl[] ar2 = new LocalVarDecl[Locals.Length + 1];
        ar2[0] = l;
        for(int i = 0; i < Locals.Length; i++)        
            ar2[i + 1] = Locals[i];
        m_arLocals = ar2;
    }

#region Checks
    //-----------------------------------------------------------------------------
    // Debugging check
    //-----------------------------------------------------------------------------
    public override void DebugCheck(ISemanticResolver s)
    {
        Debug.Assert(m_arLocals != null);
        Debug.Assert(m_arStatements != null);
        
        foreach(LocalVarDecl v in m_arLocals)
        {
            v.DebugCheck(s);
        }
        
        foreach(Statement st in m_arStatements)
        {
            st.DebugCheck(s);        
        }
    }

    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {
        sb.WriteLine('{');
        sb.Indent++;
                
        foreach(LocalVarDecl v in Locals)
        {
            v.ToSource(sb);
            sb.WriteLine();
        }
        foreach(Statement s in Statements)
        {
            s.ToSource(sb); // these should already add '\n'            
        }
        sb.Indent--;
        sb.WriteLine('}');
        
    }

    // Dump as XML
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("BlockStatement");
        
        
        foreach(LocalVarDecl v in Locals)
        {
            v.Dump(o);
        }
                
        foreach(Statement s in Statements)
        {
            s.Dump(o);
        }
                    
        o.WriteEndElement();
    }
#endregion
    
#region Properties & Data
    Scope m_scopeLocals;

    protected LocalVarDecl [] m_arLocals;
    protected Statement[] m_arStatements;
    
    public LocalVarDecl [] Locals
    {
        get { return m_arLocals; }
    }
    
    public Statement[] Statements
    {
        get { return m_arStatements; }
    }
#endregion


#region Resolution   
    // Semantic resolution
    public override void ResolveStatement(ISemanticResolver s)
    {        
        Scope prev = null;
        if (this.m_arLocals.Length != 0)
        {
            //s.PushScope(m_scopeLocals);
            m_scopeLocals = new Scope("block_scope", null, s.GetCurrentContext());
            prev = s.SetCurrentContext(m_scopeLocals);
        }
            
        foreach(LocalVarDecl v in Locals)
        {
            v.ResolveVarDecl(s);
        }
                
        foreach(Statement stmt in Statements)
        {
            stmt.ResolveStatement(s);
        }

        if (m_scopeLocals != null)
            //s.PopScope(m_scopeLocals);
            s.RestoreContext(prev);
            
    }

    public override void ResolveStatement2(ISemanticResolver s)
    {
        Scope prev = null;
        if (m_scopeLocals != null)
            //s.PushScope(m_scopeLocals);
            prev = s.SetCurrentContext(m_scopeLocals);

        foreach(Statement stmt in Statements)
        {
            stmt.ResolveStatement2(s);
        }

        if (m_scopeLocals != null)
            //s.PopScope(m_scopeLocals);
            s.RestoreContext(prev);
    }
#endregion

    // Code generation
    public override void Generate(CodeGen.EmitCodeGen gen)
    {
        foreach(Statement stmt in Statements)
        {
            stmt.Generate(gen);
        }
    }
}
#endregion

#region EH statements    
//-----------------------------------------------------------------------------        
// Catch-handler, used in try block
//-----------------------------------------------------------------------------        
public class CatchHandler
{    
    public CatchHandler(
        TypeSig type,           // type we're catching (must derived from System.Exception)
        Identifier idName,       // optional (can be null) name for local var to store exception
        BlockStatement stmtBody // handler body (non-null)
    ) 
    {         
        Debug.Assert(stmtBody != null);
        
        // General catch blocks just becomes a System.Exception
        if (type == null)
        {        
            m_type = new SimpleTypeSig(new DotObjExp(
                new SimpleObjExp(new Identifier("System", null)),
                new Identifier("Exception", null)
                ));
        
            
        } else {     
            m_type = type;
        }
        m_idVarName = idName;
        m_body = stmtBody;
    }
    
#region Properties & Data    
    TypeSig m_type;
    public TypeEntry CatchType
    {
        get { return m_type.BlueType; }
    }
    
    Identifier m_idVarName;
    public Identifier IdVarName
    {
        get { return m_idVarName; }
    }
    
    LocalVarDecl m_var;
    public LocalVarDecl CatchVarDecl
    {
        get {return m_var; }
    }
    
        
    BlockStatement m_body;
    public BlockStatement Body
    {
        get { return m_body; }
    }       
#endregion

#region Checks    
    public void Dump(XmlWriter o)
    {
        o.WriteStartElement("Catch");
        if (IdVarName != null)
            o.WriteAttributeString("varname", IdVarName.Text);
            
        if (m_type != null)
            this.m_type.Dump(o);
        Body.Dump(o);        
        o.WriteEndElement();
    }
    
    public void DebugCheck(ISemanticResolver s)
    {
        CatchType.DebugCheck(s);
        Body.DebugCheck(s);
    }
#endregion
   
#region Resolution    
    public void ResolveHandler2(ISemanticResolver s)
    {
        m_body.ResolveStatement2(s);
    }
    
    public void ResolveHandler(ISemanticResolver s)
    {           
        // Catch blocks can declare an identifier        
        if (IdVarName != null)
        {
            m_var = new LocalVarDecl(IdVarName, m_type);
            Body.InjectLocalVar(m_var);
        }
        
        this.m_type.ResolveType(s);
        Body.ResolveStatement(s);
        
        // Catch type must be of type System.Exception
        if (m_var != null)
        {
            s.EnsureAssignable(m_var.Symbol.m_type.CLRType, typeof(System.Exception), IdVarName.Location);
        }
        
        // Catch type must be of type System.Exception
        //TypeEntry tSystem_Exception =s.ResolveCLRTypeToBlueType(typeof(System.Exception));
        //s.EnsureDerivedType(tSystem_Exception, m_type.TypeRec, new FileRange());
        
    }
#endregion    
}

//-----------------------------------------------------------------------------        
// Try-Catch-Finally
// -> 'try' block 'finally' block
// -> 'try' block <'catch' '(' TypeSig id ')' block>+ ['finally' block]?
//-----------------------------------------------------------------------------      
public class TryStatement : Statement
{
// Must have a finally or at least one Catch (or both)
    public TryStatement(
        BlockStatement stmtTry,     // never null
        CatchHandler [] arCatch,    // can be null
        BlockStatement stmtFinally  // can be null        
    )
    {
        Debug.Assert(stmtTry != null); // always have a try block        
        Debug.Assert((arCatch != null && arCatch.Length > 0) || stmtFinally != null);
                
        m_stmtTry = stmtTry;
        m_arCatchHandlers = (arCatch == null) ? new CatchHandler[0] : arCatch;        
        m_stmtFinally = stmtFinally;
        
        // @todo - this is wrong
        m_filerange = stmtTry.Location;
    }

#region Properties & Data    
    protected BlockStatement m_stmtTry;
    public BlockStatement TryStmt
    {
        get { return m_stmtTry; }
    }
    
    protected CatchHandler [] m_arCatchHandlers;
    public CatchHandler [] CatchHandlers
    {
        get { return m_arCatchHandlers; }
    }
    
    
    protected BlockStatement m_stmtFinally;
    public BlockStatement FinallyStmt
    {
        get { return m_stmtFinally; }
    }
#endregion

#region Checks    
    // Dump as XML
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("TryStatement");
        
        o.WriteStartElement("try_block");
        m_stmtTry.Dump(o);
        o.WriteEndElement();
        
        
        o.WriteStartElement("catch_handlers");
        foreach(CatchHandler c in m_arCatchHandlers)
        {
            c.Dump(o);
        }
        o.WriteEndElement();
                
        if (m_stmtFinally != null)
        {
            o.WriteStartElement("finally_block");
            m_stmtFinally.Dump(o);
            o.WriteEndElement();
        }
        
        o.WriteEndElement();        
    }
        
    //-----------------------------------------------------------------------------
    // Debugging check
    //-----------------------------------------------------------------------------
    public override void DebugCheck(ISemanticResolver s)
    {
        m_stmtTry.DebugCheck(s);
        
        if (m_stmtFinally != null)
            m_stmtFinally.DebugCheck(s);
            
        foreach(CatchHandler c in CatchHandlers)
        {
            c.DebugCheck(s);
        }
    }
#endregion

#region Resolution
    
    // Semantic resolution
    public override void ResolveStatement(ISemanticResolver s)
    {
        m_stmtTry.ResolveStatement(s);
        
        for(int i = 0; i < CatchHandlers.Length; i++)
        {        
            CatchHandler c = CatchHandlers[i];
            c.ResolveHandler(s);

⌨️ 快捷键说明

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