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

📄 objexpast.cs

📁 charp compiler
💻 CS
📖 第 1 页 / 共 5 页
字号:
                m_objExp = new TypeExp(tCur);
            } else {
                m_objExp = new SimpleObjExp("this");
            }
        }
        
        // Need to Lookup m_strName in m_objExp's scope (inherited scope)
        Exp.ResolveExpAsRight(ref m_objExp, s);
                    
                
        // Get type of of left side object
        // This call can either be a field on a variable
        // or a static method on a class
        
        bool fIsStaticMember = false;
        
        // If we don't yet know what TypeEntry this methodcall is on, then figure
        // it out based off the expression
        if (tLeft == null)
        {
            if (m_objExp is TypeExp)
            {
                fIsStaticMember = true;
                tLeft = ((TypeExp) m_objExp).Symbol;
            } else {
                fIsStaticMember = false;
                tLeft = s.ResolveCLRTypeToBlueType(m_objExp.CLRType);
            }
        }
        
        // Here's the big lookup. This will jump through all sorts of hoops to match
        // parameters, search base classes, do implied conversions, varargs, 
        // deal with abstract, etc.
        bool fIsVarArg;
        m_symbol = tLeft.LookupMethod(s, m_idName, alParamTypes, out fIsVarArg);
        Debug.Assert(m_symbol != null);
        
        if (m_fIsNotPolymorphic)
        {
            // of the form 'base.X(....)'
            if (m_symbol.IsStatic)
                ThrowError(SymbolError.BaseAccessCantBeStatic(this.Location, m_symbol)); // @todo - PrintError?
        } else {
            // normal method call
            /*
            if (fIsStaticMember && !m_symbol.IsStatic)
                ThrowError(SymbolError.ExpectInstanceMember(this.Location)); // @todo - PrintError?
            else if (!fIsStaticMember && m_symbol.IsStatic)                
                ThrowError(SymbolError.ExpectStaticMember(this.Location)); // @todo - PrintError?
            */
            Debug.Assert(fIsStaticMember == m_symbol.IsStatic, "@todo - user error. Mismatch between static & instance members on line.");
        }
        
        
        // If we have a vararg, then transform it 
        if (fIsVarArg)
        {
        // Create the array
            int cDecl = m_symbol.ParamCount;
            int cCall = this.ParamExps.Length;
            
            ArrayTypeSig tSig = new ArrayTypeSig(m_symbol.ParamCLRType(cDecl - 1), s);
            
            Node [] list = new Node[cCall - cDecl + 1];
            for(int i = 0; i < list.Length; i++)
            {
                list[i] = this.ParamExps[i + cDecl - 1];
            }
            
            Exp eArray = new NewArrayObjExp(
                tSig,
                new ArrayInitializer(
                    list
                )
            );
            
            Exp.ResolveExpAsRight(ref eArray, s);
            
        // Change the parameters to use the array    
            ArgExp [] arParams = new ArgExp[cDecl];
            for(int i = 0; i < cDecl - 1; i++)
                arParams[i] = m_arParams[i];
            arParams[cDecl - 1] = new ArgExp(EArgFlow.cIn, eArray);
            
            m_arParams = arParams;                            
        } // end vararg transformation
                
        this.CalcCLRType(s);
   
        return this;
    }
#endregion
    
    public override void GenerateAsRight(CodeGen.EmitCodeGen gen)
    {        
        gen.Generate(this);      
    }
    
    public override void GenerateAsStatement(CodeGen.EmitCodeGen gen)
    {        
        // Default impl generates as a RHS exp and just pops the value off    
        gen.GenerateAsStatement(this);
    }
}

#region Cast Expressions (TypeCasting & As operator)
//-----------------------------------------------------------------------------
// Type Cast any expression into a specific type
// TypeCast -> '(' Type ')' Exp                           
// AsExp -> Exp as Type
//-----------------------------------------------------------------------------

public class AsExp : BaseCastObjExp
{
    public AsExp(
        TypeSig tTargetType,
        Exp expSource
        ) 
        : base(tTargetType, expSource)
    {
    }
    
    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {
        sb.Write('(');
        this.m_expSource.ToSource(sb);
        sb.Write(" as {0}", this.m_tTargetType.ToString());
        sb.Write(')');
    }

    // Resolve
    // The 'as' operator can only be used on a Reference type (not a struct)
    // So let the base class resolve, and then just add the error check here
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {
        Exp e = base.ResolveExpAsRight(s);
                
        if (this.SourceExp.CLRType.IsValueType)            
            ThrowError(SymbolError.AsOpOnlyOnRefTypes(this.Location));
        
        return e;
    }

    // Do codegen
    public override void GenerateAsRight(CodeGen.EmitCodeGen gen)
    {        
        gen.Generate(this);
    }
}

public class CastObjExp : BaseCastObjExp
{
    public CastObjExp(
        TypeSig tTargetType,
        Exp expSource
        ) 
        : base(tTargetType, expSource)
    {
    }


    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {
        sb.Write("(({0}) ", m_tTargetType.ToString());        
        this.m_expSource.ToSource(sb);                
        sb.Write(')');
    }
    
    // Do codegen
    public override void GenerateAsRight(CodeGen.EmitCodeGen gen)
    {        
        gen.Generate(this);
    }
}
    
// Base class for both TypeCasting & As operator
public abstract class BaseCastObjExp : Exp
{
    public BaseCastObjExp(
        TypeSig tTargetType,
        Exp expSource
        )
    {
        m_tTargetType = tTargetType;
        m_expSource = expSource;
        
        Debug.Assert(m_tTargetType != null);
        Debug.Assert(m_expSource != null);
        
        // @todo - have parser resolve this
        //m_filerange = FileRange.Merge(expSource.Location, m_tTargetType.Location);
    }
    
    //-----------------------------------------------------------------------------
    // Debugging check
    //-----------------------------------------------------------------------------
    public override void DebugCheck(ISemanticResolver s)
    {
        Debug.Assert(m_tTargetType != null);
        m_tTargetType.DebugCheck(s);
        
        Debug.Assert(m_expSource != null);
        m_expSource.DebugCheck(s);    
                
        //Debug.Assert(m_tTargetType.TypeRec == base.TypeRec);
    }
    
    // Get the type that we want to cast too
    protected TypeSig m_tTargetType;
    public TypeSig TargetType
    {   
        get { return m_tTargetType; }
    }
    
    // The source expression whos type will get converted
    protected Exp m_expSource;
    public Exp SourceExp
    {
        get { return m_expSource; }
    }
    
    // Dump as XML
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement(this.GetType().ToString());
        o.WriteAttributeString("targettype", TargetType.ToString());
    
        m_expSource.Dump(o);
                
        o.WriteEndElement();
    } 
        
    // Resolve
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {
        ResolveExpAsRight(ref m_expSource, s);
        m_tTargetType.ResolveType(s);
        
        // Optimizing Check - if we're casting to the type of the source exp,
        // then remove the cast. ex: '(T) t --> t'
        if (m_tTargetType.CLRType == m_expSource.CLRType)
        {
            return m_expSource;
        }
        
        
        //ResolveAsExpEntry(m_tTargetType.TypeRec, s);
        CalcCLRType(s);   
        return this;
    }
    
    protected override Type CalcCLRTypeHelper(ISemanticResolver s)
    {
        return m_tTargetType.BlueType.CLRType;
    }
} // end cast expression

#endregion

#region New Expressions
//-----------------------------------------------------------------------------
// Allocate an object and invoke the proper constructor
// NewObjExp -> 'new' type '(' exp_list ')'
//-----------------------------------------------------------------------------
public class NewObjExp : Exp
{
    public NewObjExp(
        TypeSig tType,
        Exp [] arParams
    )
    {
        Debug.Assert(tType != null);
        Debug.Assert(arParams != null);
        
        m_tType = tType;
        m_arParams = arParams;
        
        // @todo- this is wrong
        m_filerange = tType.Location;                
    }
    
#region Checks    
    //-----------------------------------------------------------------------------
    // Debugging check
    //-----------------------------------------------------------------------------
    public override void DebugCheck(ISemanticResolver s)
    {
    /*
        Debug.Assert(m_tType != null);
        m_tType.DebugCheck(s);
        
        Debug.Assert(m_tType.TypeRec == TypeRec);
        
        Debug.Assert(m_arParams != null);
        foreach(Exp e in m_arParams)
        {
            e.DebugCheck(s);
        }
        
        if (m_tType.TypeRec.IsStruct && (m_arParams.Length == 0))
        {
            // structs can't have a parameterless ctor
        } else {
            Debug.Assert(SymbolCtor != null);
            Debug.Assert(SymbolCtor.IsCtor || 
                (SymbolCtor.SymbolClass.IsStruct && (SymbolCtor.RetType.CLRType == typeof(void)))
            );
            
            Debug.Assert(!SymbolCtor.IsStatic); // new can't call a static ctor
        
            // Name of ctor must match name of the type we're creating
            Debug.Assert(SymbolCtor.Name == m_tType.TypeRec.Name);
        }
    */   
        
    }
    
    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {   
        sb.Write("new {0}", this.ElemType.ToString());
    }
    
    // Dump as XML
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("NewObjExp");
        o.WriteAttributeString("targettype", ElemType.ToString());
        if (SymbolCtor != null)
            o.WriteAttributeString("ctor", SymbolCtor.ToString());
    
    
        o.WriteStartElement("parameters");            
        foreach(Exp e in Params)
        {
            e.Dump(o);
        }
        o.WriteEndElement();
                
        o.WriteEndElement();
    } 
#endregion

#region Properties & Data    
    // The type of object that we're allocating
    protected TypeSig m_tType;
    public TypeSig ElemType
    {
        get { return m_tType; }
    }
    
    // The parameter list for the constructor call
    protected Exp[] m_arParams;
    public Exp[] Params
    {
        get { return m_arParams; }
    }
    
    // To make codegen's like easier, semantic checking
    // figures out what constructor operator new should
    // invoke
    protected MethodExpEntry m_symCtor;
    public MethodExpEntry SymbolCtor
    {
        get { return m_symCtor; }
    }
#endregion
    
    // Do codegen
    public override void GenerateAsRight(CodeGen.EmitCodeGen gen)
    {
        gen.Generate(this);
    }
    
#region Resolution    
    // Resolve
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {
        // Resolve the type we're allocating        
        m_tType.ResolveType(s);
                               
        // One major exception for creating a new delegate, of the form:
        // new T(E.i)
        //if (m_tType.CLRType.BaseType == typeof(System.MulticastDelegate))
        if (DelegateDecl.IsDelegate(m_tType.CLRType))
        {
            //Debug.Assert(false, "@todo - Impl Delegates in New");
            if (Params.Length != 1)
            {
                // When this is resolved, we actually have 2 params (not just one).
                // Make sure we've already resolved this. 
                return this;           
            }        
            
            Exp.ResolveExpAsRight(ref m_arParams[0], s);
            DotObjExp e = m_arParams[0] as DotObjExp;
            Debug.Assert(e != null);
            
            Exp expInstance = null;
            TypeEntry tLeft = null;
            
            if (e.LeftExp is TypeExp)
            {
                // Static
                expInstance = new NullExp(Location);
                tLeft = ((TypeExp) e.LeftExp).Symbol;
            } else {
                // Instance
                expInstance = e.LeftExp;
                tLeft = s.ResolveCLRTypeToBlueType(e.LeftExp.CLRType);
            }
            
            // Use the parameter list off the delegate type to discern for overloads.            
            System.Type [] alDelegateParams = DelegateDecl.GetParams(m_tType.BlueType);
            
            // Lookup what function we're passing to the delegate.
            
            bool fIsOut;
            MethodExpEntry m = tLeft.LookupMethod(s, e.Id, alDelegateParams, out fIsOut);
            Debug.Assert(!fIsOut, "@todo - can't have a delegate reference a vararg function");
            
            // Change parameters
            m_arParams = new Exp [] {
                expInstance,
                new MethodPtrExp(m)
            };
        }
        
        // Resolve all parameters                
        System.Type [] alParamTypes = new Type[Params.Length];
        for(int i = 0; i < this.m_arParams.Length; i++)
        {
            Exp.ResolveExpAsRight(ref m_arParams[i], s);
            
            alParamTypes[i] = m_arParams[i].CLRType;
            //Debug.Assert(alParamTypes[i] != null);            
        }
        

⌨️ 快捷键说明

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