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

📄 objexpast.cs

📁 charp compiler
💻 CS
📖 第 1 页 / 共 5 页
字号:
        CalcCLRType(s);
        return this; 
    }
#endregion

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

//-----------------------------------------------------------------------------
// For events
// This is only a temporary node (like properties) and should be transformed
// into method calls.
//-----------------------------------------------------------------------------
public class EventExp : Exp
{
    public EventExp(
        EventExpEntry symbol,
        Exp expInstance // null for statics
        )
    {
        Debug.Assert(symbol != null);
        m_symbol        = symbol;
        m_expInstance   = expInstance;
    }
    
    EventExpEntry m_symbol;
    public EventExpEntry Symbol
    {
        get { return m_symbol; }
    }
    
    Exp m_expInstance;
    public Exp InstanceExp
    {
        get { return m_expInstance; }
    }
    
#region Checks
    public override void DebugCheck(ISemanticResolver s)
    {
        Debug.Assert(false, "EventExp node should be replaced by end of resolution");
        Debug.Assert(m_symbol != null);        
    }
    
    public override void Dump(XmlWriter o)
    {
    
    }
    
    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {
        sb.Write("<E>{0}", m_symbol.Name);
    }
#endregion    
    
#region Resolution
    protected override Type CalcCLRTypeHelper(ISemanticResolver s)
    {
        return m_symbol.EventType.CLRType;
    }
    
    // Ok to resolve as a LS thing (really only in += and -=).    
    // This node will get replaced with a method call anyways..
    protected override Exp ResolveExpAsLeft(ISemanticResolver s)
    {
        CalcCLRType(s);
        return this; 
    }
    
    // See section 10.7 of the C# spec.
    // Outside of our class, we can only use an event as the LS in += and -=
    // However, within our class, we can use an event on the RS, like a delegate.
    // This is a little goofy. 
    // We can actually never use an event on the RS. When try to, we're actually
    // using a compiler generated delegate (that has the exact same name) instead.
    // However, we can't put both an event & a delegate in the same scope (because
    // the names would conflict). So the delegate has a different name than the event.
    // When the user tries to access an event as a RHS, we switch it to the delegate here.
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {
        FieldExpEntry f = m_symbol.Field;
        if (f == null)
        {   
            // Events aren't allowed as RHS expressions.
            ThrowError(SymbolError.NoEventOnRHS(this));
        }
        Exp e = new FieldExp(f, this.InstanceExp);
        Exp.ResolveExpAsRight(ref e, s);
        return e;
        
    }
#endregion    

}

//-----------------------------------------------------------------------------
// For fields
//-----------------------------------------------------------------------------
public class FieldExp : Exp
{
    public FieldExp(
        FieldExpEntry symbol,
        Exp expInstance // null for statics
    )
    {
        Debug.Assert(symbol != null);
        m_symbol = symbol;
        m_expInstance = expInstance;
    }
    
#region Properties & Data
    SymbolEngine.FieldExpEntry m_symbol;
    public FieldExpEntry Symbol
    {
        get { return m_symbol; }
    }
    
    Exp m_expInstance;
    public Exp InstanceExp
    {
        get { return m_expInstance; }    
    }
    
    public bool IsStatic
    {
        get { return m_expInstance == null; }
    }
#endregion

#region Checks
    public override void DebugCheck(ISemanticResolver s)
    {
        Debug.Assert(m_symbol != null);
        Debug.Assert(m_symbol.IsStatic == IsStatic);
    }
    
    public override void Dump(XmlWriter o)
    {
    
    }
    
    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {
        if (m_expInstance == null)
            //sb.Write("[static]");
            sb.Write(m_symbol.SymbolClass.FullName);
        else
            m_expInstance.ToSource(sb);
                                
        sb.Write(".<field>{0}", m_symbol.Name);   
    }
#endregion

#region Resolution
    protected override Type CalcCLRTypeHelper(ISemanticResolver s)
    {
        return m_symbol.CLRType;
    }
    
    protected override Exp ResolveExpAsLeft(ISemanticResolver s)
    {
        CalcCLRType(s);
        return this; 
    }
    
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {
        CalcCLRType(s);
        return this; 
    }
    
#endregion

#region Generate
    public override void GenerateAsLeftPre(CodeGen.EmitCodeGen gen)
    {
        gen.GenerateAsLeftPre(this);
    }    
    public override void GenerateAsRight(CodeGen.EmitCodeGen gen)
    {
        gen.Generate(this);
    }
    public override void GenerateAsLeftPost(CodeGen.EmitCodeGen gen)
    {
        gen.GenerateAsLeftPost(this);
    }
        
    public override void GenerateAddrOf(CodeGen.EmitCodeGen gen)
    {
        gen.GenerateAddrOf(this);
    }
#endregion

}



#endregion



//-----------------------------------------------------------------------------    
// ObjExp -> id
// Resolve to another, more-specific, Node
//-----------------------------------------------------------------------------
public class SimpleObjExp : Exp
{
    public SimpleObjExp(Identifier id)
    {
        m_filerange = id.Location;
        m_strId = id;
    }
    
    public SimpleObjExp(string st)
    {
        m_filerange = null;
        m_strId = new Identifier(st, m_filerange);
    }
    
#region Properties & Data        
    Identifier m_strId;
    public Identifier Name
    {
        get { return m_strId; }
    }

    
#endregion
    
#region Checks        
    public override void DebugCheck(ISemanticResolver s)
    {
        Debug.Assert(false, "Temporary node still in Final pass");
    }

    // Dump as XML
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("SimpleObjExp");
        o.WriteAttributeString("id", m_strId.Text);        
        o.WriteEndElement();
    }
    
    public override string ToString()
    {
        return this.m_strId.Text;
    }
    
    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {        
        sb.Write("'{0}'", this.Name.Text);   
    }
#endregion    
    // m_type is only null if we're a namespace, in which case we have an ancestor
    // DotObjExp which will have the type
    
    // Resolve as a LHS
    protected override Exp ResolveExpAsLeft(ISemanticResolver s)
    {
        Exp e = GetResolvedNode(s, false);        
        Debug.Assert(e != this);
        Exp.ResolveExpAsLeft(ref e, s); 
        e.SetLocation(this.Location);       
        return e;
    }
    
    // Resolve as a RHS
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {           
        Exp e = GetResolvedNode(s, true);        
        if (e != this)
            Exp.ResolveExpAsRight(ref e, s);
        e.SetLocation(this.Location);                    
        return e;
    }
    
    
    // An ObjExp is just a temporary node. But that's the best a Context-Free parse can
    // do. So now that we're building a symbol table, we can do a Context-Sensitive resolution
    // and figure out what type of node this really is.
    public Exp GetResolvedNode(ISemanticResolver s, bool fRight)
    {   
        Exp eResolved = null;
        
        // Lookup the symbol and determine what we are
        //SymEntry sym = s.LookupSymbol(this.m_strId, true);
        string stName = this.m_strId.Text;
        SymEntry sym = s.LookupSymbolWithContext(this.m_strId, false); // allow methods
        
        // Namespace
        if (sym is NamespaceEntry)
        {
            eResolved = new NamespaceExp(sym as NamespaceEntry);
        }
        
        // Local Variable
        else if (sym is LocalVarExpEntry)
        {
            eResolved = new LocalExp(sym as LocalVarExpEntry);
        }
        
        // Parameter
        else if (sym is ParamVarExpEntry)
        {
            eResolved = new ParamExp(sym as ParamVarExpEntry);   
        }
        
        // A type name
        else if (sym is TypeEntry)
        {
            eResolved = new TypeExp(sym as TypeEntry);
        }
        
        // A field (w/ an implied 'this' pointer)
        else if (sym is FieldExpEntry)
        {
            // When a single identifier resolves to a field, it can be either
            // an instance field with an implied 'this' ref, or a static field of this class.
            FieldExpEntry f = sym as FieldExpEntry;
            Exp expInstance = null;
            if (!f.IsStatic)
            {
                expInstance = new SimpleObjExp("this");
                Exp.ResolveExpAsRight(ref expInstance, s);
            }
            eResolved = new FieldExp(f, expInstance);
        }
        
        // An event (w/ an implied 'this' ptr)
        else if (sym is EventExpEntry)
        {
            EventExpEntry e = (EventExpEntry) sym;
            Exp expInstance = null;
            if (!e.Mods.IsStatic)
            {
                expInstance = new SimpleObjExp("this");
                Exp.ResolveExpAsRight(ref expInstance, s);
            }
            eResolved = new EventExp(e, expInstance);            
        }
        
        // A property (w/ an implied 'this' ptr).
        // Properties will eventually be converted into method calls.
        else if (sym is PropertyExpEntry)
        {
            PropertyExpEntry p = (PropertyExpEntry) sym;
            
            Exp expInstance = null;
            if (!p.IsStatic)            
            {
                expInstance = new SimpleObjExp("this");
                Exp.ResolveExpAsRight(ref expInstance, s);
            }
            
            eResolved = new PropertyExp(p, expInstance);
        }
        
        // Not recognized.
        else {
            if (stName == "this") // check a common error case...            
                Debug.Assert(false, "Can't access 'this'. Are we in a static?");
            
            if (sym == null)
            {
                MethodHeaderEntry h = s.GetCurrentClass().LookupMethodHeader(this.m_strId.Text);
                if (h != null)
                {                    
                    return this;
                }
                
                ThrowError(SymbolError.UndefinedSymbol(m_strId));
                //Debug.Assert(false, "Unknown name in SimpleObjExp:" + stName);
            }
            Debug.Assert(false, "Unknown symbol type:" + ((sym == null) ? "null" : sym.ToString()));
        }
        
        
        Debug.Assert(eResolved != null);        
        return eResolved;
    }
  
}

//-----------------------------------------------------------------------------    
// DotObjExp -> ObjExp '.' id
//-----------------------------------------------------------------------------    
public class DotObjExp : Exp
{
#region Construction
    public DotObjExp(Exp left, Identifier id)
    {
        m_left = left;
        m_strId = id;
        
        m_filerange = id.Location;
    }
#endregion

#region Properties & Data
    Exp m_left;
    public Exp LeftExp
    {
        get { return m_left; }
    }

    readonly Identifier m_strId;
    public Identifier Id
    { 
        get { return m_strId; }
    }        
    
#endregion    

#region Resolution
    // Resolve as a LHS
    protected override Exp ResolveExpAsLeft(ISemanticResolver s)
    {
        Exp.ResolveExpAsRight(ref m_left, s);
        Exp e = GetResolvedNode(s);        
        Exp.ResolveExpAsLeft(ref e, s);
        e.SetLocation(this.Location);
        return e;
    }
    
    // Resolve as a RHS
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {           
        // E.i
        // First resolve the exp on the left of the dot.
        Exp.ResolveExpAsRight(ref m_left, s);
        
        // Now we can figure out what we ought to be.
        Exp e = GetResolvedNode(s);
        

⌨️ 快捷键说明

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