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

📄 expast.cs

📁 charp compiler
💻 CS
📖 第 1 页 / 共 5 页
字号:
#endregion

#region Checks
    public override void DebugCheck(ISemanticResolver s)
    {        
    }

    // Dump as XML
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("DeclareLocalStmtExp");
                
        o.WriteEndElement();
    }
    
    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {   
        sb.Write("<TempLocal>{0}", this.m_exp.Symbol.Name);   
    }
#endregion
    
#region Resolution
    // There's nothing to resolve here. No real action happens until
    // codegen...
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {           
        return this;
    }
    static int m_count = 0;
#endregion   

#region Generate
    // We should only do this as a Statement (since it produces side-effects)
    public override void GenerateAsStatement(CodeGen.EmitCodeGen gen)
    {
        gen.GenerateAsStatement(this);
    }
#endregion
}

//-----------------------------------------------------------------------------
// Compound expressions
// useful in code transformations.
// Has a list of statement expressions that get generated. And then generates
// the last expression and uses that value.
//-----------------------------------------------------------------------------
public class CompoundStmtExp : StatementExp
{
    // <e0, e1, e2 .... en>
    // e_0 .. e_n-1 are StatementExp, that generate as Statements (to produce side effects)
    // e_n is a normal expression, generated as an expression, to produce a value
    public CompoundStmtExp(
        StatementExp [] eList,
        Exp eLast
    )
    {
        Debug.Assert(eList != null);
        Debug.Assert(eLast != null);
        
        m_eList = eList;
        m_eLast = eLast;
    }        
#region Properties & Data
    StatementExp [] m_eList;
    Exp m_eLast;
#endregion

#region Resolution
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {
        for(int i = 0; i < m_eList.Length; i++)
            StatementExp.ResolveExpAsRight(ref m_eList[i], s);

        Exp.ResolveExpAsRight(ref m_eLast, s);
            
        CalcCLRType(s);
                    
        return this;
    }
    
    // Type of an assignment is the type of the Right Side    
    protected override Type CalcCLRTypeHelper(ISemanticResolver s)
    {
        return m_eLast.CLRType;
    }
#endregion

#region Checks
    public override void DebugCheck(ISemanticResolver s)
    {
        foreach(Exp e in m_eList)
            e.DebugCheck(s);
        m_eLast.DebugCheck(s);
    }

    // Dump as XML
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("CompoundStmtExp");
    
        o.WriteStartElement("Statements");
        foreach(Exp e in m_eList)
            e.Dump(o);
        o.WriteEndElement();
        
        m_eLast.Dump(o);
                
        o.WriteEndElement();
    }
    
    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {
        sb.Write('[');
        foreach(StatementExp e in m_eList)
        {
            e.ToSource(sb);
            sb.Write(',');
        }
        m_eLast.ToSource(sb);
        sb.Write(']');
    }
#endregion

#region CodeGen
    // For all CodeGen variations on a CompoundStatement, we want to 
    // first generate the StmtExp list to get the sideffects, and
    // then fall through to the last expression and use that
    // as the real CodeGen target.

    // Code generation as an expression
    public override void GenerateAsRight(CodeGen.EmitCodeGen gen)
    {
        // Generate the StmtExp to get their sideffects
        foreach(StatementExp e in m_eList)
            e.GenerateAsStatement(gen);
                    
        m_eLast.GenerateAsRight(gen);
    }
    
    // We can only generate as a Statement if the last thing is also
    // a StatementeExp
    public override void GenerateAsStatement(CodeGen.EmitCodeGen gen)
    {
        // Generate the StmtExp to get their sideffects
        foreach(StatementExp e in m_eList)
            e.GenerateAsStatement(gen);
            
        Debug.Assert(m_eLast is StatementExp);
        StatementExp se = (StatementExp) m_eLast;
                            
        se.GenerateAsStatement(gen);
    }
    
    // Generate the address
    public override void GenerateAddrOf(CodeGen.EmitCodeGen gen)
    {        
        // Still generate all the StmtExp normally because we 
        // need their side-effects
        foreach(StatementExp e in m_eList)
            e.GenerateAsStatement(gen);
            
        // Use the address of the last expression.            
        m_eLast.GenerateAddrOf(gen);
    }
    
#endregion

}
#endif


#if false
//-----------------------------------------------------------------------------
// OpEqual exoressions: +=, *=, /=, -=, %=
//-----------------------------------------------------------------------------
public class OpEqualStmtExp : StatementExp
{
#region Construction
    public OpEqualStmtExp(Exp expLeft, Exp expRight, BinaryExp.BinaryOp op)
    {   
        Debug.Assert(false, "OpEqualStmtExp is obsolete"); //
        m_op = op;
        m_eLeft = expLeft;
        m_expRight = expRight;        
    }
#endregion    

#region Checks
    public override void DebugCheck(ISemanticResolver s)
    {
        Debug.Assert(Left != null);
        Debug.Assert(Right != null);
    
        Left.DebugCheck(s);
        Right.DebugCheck(s);            
    }

    // Dump as XML
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("OpEqualStmtExp");
    
        Left.Dump(o);
        Right.Dump(o);
                
        o.WriteEndElement();
    }
#endregion

#region Properties & Data
    BinaryExp.BinaryOp m_op;
    public BinaryExp.BinaryOp Op
    {
        get { return m_op; }
    }

    protected Exp m_eLeft;
    public Exp Left
    {
        get { return m_eLeft; }
    }
    
    protected Exp m_expRight;
    public Exp Right
    {
        get { return m_expRight; }
    }
#endregion

#region Resolution
    // Semantic resolution
    // "a X= b" is semantically equivalent to "a = a X b"
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {
        // Note that the left side ("a") of "a X= b" is both a 
        // Left & Right side value
        ResolveExpAsLeft(ref this.m_eLeft, s);
        ResolveExpAsRight(ref this.m_expRight, s);
       
        
        CalcCLRType(s);
    
        // Ensure type match
        s.EnsureAssignable(m_expRight, Left.CLRType);
        
        return this;
    }
    
    // Type of an assignment is the type of the Right Side    
    protected override Type CalcCLRTypeHelper(ISemanticResolver s)
    {
        return Left.CLRType;
    }
#endregion

    // Code generation as an expression
    public override void GenerateAsRight(CodeGen.EmitCodeGen gen)
    {
        gen.Generate(this);
    }
    
    public override void GenerateAsStatement(CodeGen.EmitCodeGen gen)
    {
        gen.GenerateAsStatement(this);
    }
}

#endif

//-----------------------------------------------------------------------------    
// Assignment statement
//-----------------------------------------------------------------------------    
public class AssignStmtExp : StatementExp
{
#region Construction
    public AssignStmtExp(Exp expLeft, Exp expRight)
    {
        Debug.Assert(expLeft != null);
        Debug.Assert(expRight != null);
    
        m_oeLeft = expLeft;
        m_expRight = expRight;
    
        //m_filerange = FileRange.Merge(expLeft.Location, expRight.Location);
    }
#endregion

#region Checks
    //-----------------------------------------------------------------------------
    // Debugging check
    //-----------------------------------------------------------------------------
    public override void DebugCheck(ISemanticResolver s)
    {
        Debug.Assert(m_oeLeft != null);
        Debug.Assert(m_expRight != null);
    
        m_oeLeft.DebugCheck(s);
        m_expRight.DebugCheck(s);
            
    }

    // Dump as XML
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("AssignStmtExp");
    
        m_oeLeft.Dump(o);
        m_expRight.Dump(o);
                
        o.WriteEndElement();
    }
    
    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {
        m_oeLeft.ToSource(sb);
        sb.Write("=");
        m_expRight.ToSource(sb);
    }
#endregion

#region Resolution
    
    // Semantic resolution.
    // This is where we check for Set-Property transformations (where an
    // assignment gets changed into a methodcall)
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {
        // Resolve the leftside of the operator                
        Exp.ResolveExpAsLeft(ref m_oeLeft, s);
        
        
        // Event transform  actually occurs in the assignment node.
        // A.e = A.e + d --> A.add_e(d)            
        // We have to do this before we resolve the RHS of the operator (Since we
        // can't resolve events as a RHS).
        if (m_oeLeft is EventExp)
        {   
            EventExp nodeEvent = (EventExp)m_oeLeft;
            EventExpEntry e = nodeEvent.Symbol;         
            
            // Here we just do some asserts.
            BinaryExp b = this.m_expRight as BinaryExp;
            Debug.Assert(b != null, "bad formed event +=,-=");  
         
            // By now, we know we have something of the form A = B + C   
            // Make sure that A=B. Since we resolved A as left, must resolve B as left too.
            Exp eTempLeft = b.Left;
            Exp.ResolveExpAsLeft(ref eTempLeft, s);
            Debug.Assert(eTempLeft is EventExp);
            Debug.Assert(Object.ReferenceEquals(((EventExp) eTempLeft).Symbol, e)); // symbols should be exact references
            
            // Resolve C (the delegate that we're adding to the event)
            Exp eTempRight = b.Right;
            Exp.ResolveExpAsRight(ref eTempRight, s);            
            Debug.Assert(AST.DelegateDecl.IsDelegate(eTempRight.CLRType), "Event only ops w/ delegates"); // @todo -legit/            
            
            Debug.Assert(b.Op == BinaryExp.BinaryOp.cAdd || b.Op == BinaryExp.BinaryOp.cSub);
                
            
            MethodExpEntry m2 = (b.Op == BinaryExp.BinaryOp.cAdd) ? e.AddMethod : e.RemoveMethod;
                
            Exp e2 = new MethodCallExp(
                nodeEvent.InstanceExp,
                m2,
                new ArgExp[] {
                    new ArgExp(EArgFlow.cIn, eTempRight)
                },
                s
            );
                    
            Exp.ResolveExpAsRight(ref e2, s);
            return e2;            
        }
        
        Exp.ResolveExpAsRight(ref m_expRight, s);
                        
        
        // Check for calling add_, remove on events
        // a.E += X 
        // a.E = a.E + X (parser transforms)
        // if E is a delegate, and RHS is structured like E + X
        // then transform to a.add_E(X) or a.remove_E(x)
        
        // @todo - use the EventInfo to get exact add / remove functions
        if (DelegateDecl.IsDelegate(m_oeLeft.CLRType))
        {   
            // Events can only exist on a class
            AST.FieldExp f = m_oeLeft as FieldExp;
            if (f == null)
                goto NotAnEvent;
                
            Exp eInstance = f.InstanceExp; // ok if static                
            
            BinaryExp rhs = m_expRight as BinaryExp;
            if (rhs == null)
                goto NotAnEvent;            
            
            // Check if RHS is a.E + X
            if ((rhs.Left != m_oeLeft) || (rhs.Right.CLRType != rhs.Left.CLRType))
                goto NotAnEvent;
            
                        
            string stEventName = f.Symbol.Name;
            string stOpName;
            if (rhs.Op == BinaryExp.BinaryOp.cAdd)
                stOpName = "add_" + stEventName;
            else if (rhs.Op == BinaryExp.BinaryOp.cSub)
                stOpName = "remove_" + stEventName;                        
            else
                goto NotAnEvent;                
             
            // a.add_E(X);    
            Exp e = new MethodCallExp(
                eInstance,
                new Identifier(stOpName),
                new ArgExp[] {
                    new ArgExp(EArgFlow.cIn, rhs.Right)
                }
            );            
            
            Exp.ResolveExpAsRight(ref e, s);
            e.SetLocation(this.Location);    
            return e;
                        
            
        NotAnEvent:
            ;            
        }
        
        // Check for set-indexer
        if (m_oeLeft is ArrayAccessExp)
        {
            ArrayAccessExp a = m_oeLeft as ArrayAccessExp;
            if (a.IsIndexer) 
            {

⌨️ 快捷键说明

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