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

📄 expast.cs

📁 charp compiler
💻 CS
📖 第 1 页 / 共 5 页
字号:
                // Leftside: get_Item(idx, value);
                System.Type [] alParams = new Type [] {
                    a.ExpIndex.CLRType,
                    m_expRight.CLRType
                };
            
                TypeEntry t = s.ResolveCLRTypeToBlueType(a.Left.CLRType);            
                MethodExpEntry m = t.LookupIndexer(a.Left.Location, s, alParams, true);
                
                Exp e = new MethodCallExp(
                    a.Left,
                    m,
                    new ArgExp[] { 
                        new ArgExp(EArgFlow.cIn, a.ExpIndex),
                        new ArgExp(EArgFlow.cIn, m_expRight) 
                    },
                    s);
                
                Exp.ResolveExpAsRight(ref e, s);
                e.SetLocation(this.Location);    
                return e;
            }        
        }
        
        // Check for transforming properties into MethodCalls
        if (m_oeLeft is PropertyExp)
        {
            PropertyExp p = (PropertyExp) m_oeLeft;
            
            Exp e = new MethodCallExp(
                p.InstanceExp, 
                p.Symbol.SymbolSet, 
                new ArgExp[] { 
                    new ArgExp(EArgFlow.cIn, m_expRight) 
                },
                s);
                
            Exp.ResolveExpAsRight(ref e, s);
            e.SetLocation(this.Location);
            return e;
        }
        
        CalcCLRType(s);
    
        // Ensure type match        
        s.EnsureAssignable(m_expRight, m_oeLeft.CLRType);        
        
        return this;
    }
    
    // Type of an assignment is the type of the Right Side    
    protected override Type CalcCLRTypeHelper(ISemanticResolver s)
    {
        return m_oeLeft.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);
    }
    
#region Properties & Data
    protected Exp m_oeLeft;
    public Exp Left
    {
        get { return m_oeLeft; }
    }
    
    protected Exp m_expRight;
    public Exp Right
    {
        get { return m_expRight; }
    }
#endregion    
}

//-----------------------------------------------------------------------------    
// Pre & Post inc / dec
//-----------------------------------------------------------------------------    
public class PrePostIncDecStmtExp : StatementExp
{
#region Construction
    public PrePostIncDecStmtExp(
        Exp e,
        bool fPre, bool fInc)
    {
        m_exp = e;
        m_fPre = fPre;
        m_fInc = fInc;
    }
#endregion    

#region Properties & Data
    Exp m_exp;
    public Exp Arg
    {
        get  { return m_exp; }
    }
    
    bool m_fPre;
    bool m_fInc;
    
    public bool IsPre
    {
        get { return m_fPre; }
    }
    
    public bool IsInc
    {
        get { return m_fInc; }
    }
#endregion

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

    // Dump as XML
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("PrePostIncDecStmtExp");
        o.WriteAttributeString("IsPre", IsPre.ToString());
        o.WriteAttributeString("IsInc", IsInc.ToString());
    
        Arg.Dump(o);       
                
        o.WriteEndElement();
    }
    
    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {
        string stOp = (IsInc) ? "++" : "--";
        if (IsPre)
            sb.Write(stOp);
        Arg.ToSource(sb);
        if (!IsPre)
            sb.Write(stOp);            
    }
    
#endregion

#region Resolution
    // Semantic resolution
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {
        // We have a problem. If our arg is a property, then we need to 
        // transform this x++ --> x = x + 1
        // But we can't always transform since we can overload the ++, -- operators.
        // So resolve our arg, see if it's a property, and then transform if it is.
        
        // Since we update the Arg, we must resolve it as a left value
        Exp.ResolveExpAsLeft(ref this.m_exp, s);
        
        // First check if we have an overload
        
        
        // Check if we're a property
        if (m_exp is PropertyExp)
        {
            Exp e = null;
            int iDelta = IsInc ? 1 : -1;
            
            e = new AssignStmtExp(
                m_exp, 
                new BinaryExp(
                    m_exp,
                    new IntExp(iDelta, this.m_filerange),
                    BinaryExp.BinaryOp.cAdd
                )
            );
            
            Exp.ResolveExpAsRight(ref e, s);
            return e;
        }
                
        CalcCLRType(s);
    
        // Ensure type match, unless we have an overload.
        s.EnsureAssignable(Arg, typeof(int));
        
        return this;
    }
    
    // Type of an assignment is the type of the Right Side    
    protected override Type CalcCLRTypeHelper(ISemanticResolver s)
    {
        return Arg.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);
    }
}

#endregion // Statement Exp

#region ?: operator
//-----------------------------------------------------------------------------    
// Conditional Expression
//-----------------------------------------------------------------------------    
public class IfExp : Exp
{
#region Construction
    public IfExp(
        Exp expTest,
        Exp expTrue,
        Exp expFalse
    )
    {
        Debug.Assert(expTest != null);
        Debug.Assert(expTrue != null);
        Debug.Assert(expFalse != null);
        
        m_expTest = expTest;
        m_expTrue = expTrue;
        m_expFalse = expFalse;
    }
#endregion

#region Properties & Data
    Exp m_expTest;
    Exp m_expTrue;
    Exp m_expFalse;
    
    public Exp TestExp
    {
        get { return m_expTest;}
    }
    
    public Exp TrueExp
    {
        get { return m_expTrue; }
    }
    
    public Exp FalseExp
    {
        get { return m_expFalse; }
    }
#endregion

#region Checks
    public override void DebugCheck(ISemanticResolver s)
    {
        m_expTest.DebugCheck(s);
        m_expTrue.DebugCheck(s);
        m_expFalse.DebugCheck(s);
    }

    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {
        sb.Write('(');
        this.m_expTest.ToSource(sb);
        sb.Write('?');
        this.m_expTrue.ToSource(sb);
        sb.Write(':');
        this.m_expFalse.ToSource(sb);
        sb.Write(')');
    }

    // Dump as XML
    public override void Dump(XmlWriter o)
    {    
        o.WriteStartElement("IFExp");
        
        o.WriteStartElement("Test Expression");
        m_expTest.Dump(o);
        o.WriteEndElement();
        
        o.WriteStartElement("True Expression");
        m_expTrue.Dump(o);
        o.WriteEndElement();
        
        o.WriteStartElement("False Expression");
        m_expFalse.Dump(o);
        o.WriteEndElement();
        
        o.WriteEndElement();
    }
#endregion
    // Semantic resolution
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {
        ResolveExpAsRight(ref this.m_expTest, s);
        ResolveExpAsRight(ref this.m_expTrue, s);
        ResolveExpAsRight(ref this.m_expFalse, s);
        
        s.EnsureAssignable(m_expTest, typeof(bool));
                
        CalcCLRType(s);
        return this;
    }

    // Code generation
    public override void GenerateAsRight(CodeGen.EmitCodeGen gen)
    {
        gen.Generate(this);
    }
    
    public override void GenerateAddrOf(CodeGen.EmitCodeGen gen)
    {
        gen.GenerateAddrOf(this);
    }
    
    // typeof ?: operator.
    // Rules for determining type: Say you have (b ? t : f) where
    // t is type T, f is type F.
    // - If T ==F, type is T
    // - if implicit convert T -> F, then type is F
    // - if implicit convert F -> T, then type is T
    // - else error
    protected override Type CalcCLRTypeHelper(ISemanticResolver s)
    {
        Type t = m_expTrue.CLRType;
        Type f = m_expFalse.CLRType;
        
        // If both ops are null, then we'll be null too 
        if (t == null && f == null)
            return null;
  
        // If these are compound types, may not have reference equality,
        // but the IsAssignable tests will still pass and so we're ok.
        if (t == f)
            return t;
            
        if (TypeEntry.IsAssignable(t, f))
            return f;
            
        if (TypeEntry.IsAssignable(f, t))
            return t;
            
        // Else we have error
        //ThrowError_BadTypeIfExp(s, this); // won't return
        ThrowError(SymbolError.BadTypeIfExp(this));
             
        return null;
    }
}


#endregion

#region Operator Expressions (binary, unary)
//-----------------------------------------------------------------------------    
// Is boolean operator
//-----------------------------------------------------------------------------
public class IsExp : Exp
{
#region Construction
    public IsExp(
        Exp expTest,
        TypeSig tTarget
    )
    {
        Debug.Assert(expTest != null);
        Debug.Assert(tTarget != null);

        m_expTest = expTest;
        m_tTarget = tTarget;

        //m_filerange = FileRange.Merge(expTest.Location, tTarget.Location);
    }
#endregion

#region Properties & Data
    Exp m_expTest;
    public Exp Left
    {
        get { return m_expTest; }
    }

    TypeSig m_tTarget;
    public TypeEntry TargetType
    {
        get { return m_tTarget.BlueType; }
    }

    public override void DebugCheck(ISemanticResolver s)
    {
        m_expTest.DebugCheck(s);
        m_tTarget.DebugCheck(s);
    }
#endregion

#region Checks
    // Dump as XML
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("IsExp");
        m_expTest.Dump(o);
        m_tTarget.Dump(o);
        o.WriteEndElement();
    }
    
    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {
        sb.Write('(');
        m_expTest.ToSource(sb);
        sb.Write(" is ");
        m_tTarget.ToSource(sb);
        sb.Write(')');
    }
#endregion    

#region Resolution
    // Semantic resolution
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {
        ResolveExpAsRight(ref m_expTest, s);
        m_tTarget.ResolveType(s);
        
        CalcCLRType(s);
        
        return this;
    }
        
    // 'Is' operator is always boolean

⌨️ 快捷键说明

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