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

📄 semanticchecker.cs

📁 charp compiler
💻 CS
📖 第 1 页 / 共 3 页
字号:
        // the string names. Unfortunately, the defualt Type.Equals() doesn't
        // do it like that.           
        int iExpected = (objA.ToString() == objB.ToString()) ? 0 : 1;
        Debug.Assert(iExpected == iActual);
#endif
        return iActual;
#else
            // Another emit bug:
            // We have a Type problem. If we go from 1) T --> 2) T[] --> 3) T
            // the T in 1 & 3 may be different, but we expect them to be the same.
    
            int iExpected = (objA.ToString() == objB.ToString()) ? 0 : 1;
            //Debug.Assert(iExpected == iActual);
                
            return iExpected;
#endif
        }
    
        // Fast comparison
        // This is nice, but won't work due to silly bugs in the frameworks (see above).
        int CompareFast(object objA, object objB)
        {
            Type tA = (Type) objA;
            Type tB = (Type) objB;
        
            if (tA.IsEnum && !tB.IsEnum)
                return 1;
            if (!tA.IsEnum && tB.IsEnum)
                return 1;
            
            if (tA.IsEnum && tB.IsEnum)
                return (tA.FullName == tB.FullName) ? 0 : 1;
            
            return (tA == tB) ? 0 : 1;
        }
    } 
    
    protected Hashtable m_hashClrType = new Hashtable (1000, new TypeHashProvider(), new TypeHashProvider());
#endregion
        
    ICLRtypeProvider m_provider;
    
#region Main checking routine     
//-----------------------------------------------------------------------------        
// Main checking routine
// Return true if successful, else false
//-----------------------------------------------------------------------------
    public bool DoCheck(
        AST.ProgramDecl p,
        ICLRtypeProvider provider,
        Assembly [] refs
    )
    {   
        Debug.Assert(provider != null);
        Debug.Assert(p != null);
    
        m_provider = provider;
        
        string stSubPhase = "";
        try
        {   
            m_scopeGlobal = new Scope("Global", null, null);
            
                
                            
            // Import symbols            
            stSubPhase = "importing assemblies";            
            ImportAssembly(GetMscorlib());
            AddDefaultTypes(m_scopeGlobal);
            foreach(Assembly a in refs)
            {
                ImportAssembly(a);
            }
            
            // Pass 1 - Resolve the namespaces and stub the types.
            // This will stub all scopes and create a lexical-scope tree.            
            stSubPhase = "resolving namespaces";            
            p.ResolveNamespace(this, m_scopeGlobal);
            
            
            // Pass 2 - Resolve Types (to both CLR & Blue)             
            stSubPhase = "resolving to clr types";            
            p.ResolveTypes(this, provider);
                		    		    		
            // Pass 3 - resolve class member declarations (Methods & fields)
            stSubPhase = "resolving member declarations";            
            p.ResolveMemberDecls(this, provider);
                		    		
            // Pass 4 - resolve method bodies
            stSubPhase = "resolving member bodies";            
            p.ResolveBodies(this);
                        
            // Final Debug verify before codegen
            stSubPhase = "final debug check";
            p.DebugCheck(this);
            m_scopeGlobal.DebugCheck(this);
            
            p.NotifyResolutionDone();
            
            return true;
        }
        
        // Strip away SymbolErrors; we've already reported them when we first threw them.
        catch (SymbolError.SymbolErrorException)
        {            
            return false;
        }
        catch(System.Exception e)
        {
            Blue.Driver.PrintError_InternalError(e, "Symbol Resolution(" + stSubPhase + ")");
            return false;
        }
    }
#endregion

#region Manage the scope stack       
/*
    // AST call back on this to push / pop / query scopes
    // Can only push a scope once before popping it
    public void PushScope(Scope scope)
    {        
        Debug.Assert(scope != null);
        Debug.Assert(scope.m_parent == null);
            
        Scope t = m_top;
        m_top = scope;
        scope.m_parent = t;
    }
        
    protected Scope m_top; // top of stack
        
    // Pops off the top scope. If top scope doesn't match scope,
    // then scope stack is corrupted and we throw an exception
    public void PopScope(Scope scope) 
    { 
        Scope t= m_top;
        Debug.Assert(m_top == scope);
            
        m_top = m_top.m_parent;
        t.m_parent = null;
    }
        
    // Get the current scope. Used to add symbols
    public Scope GetCurrentScope() 
    {
        return m_top;
    }
*/    
    //-----------------------------------------------------------------------------        
    // Set the current class that we're processing
    //-----------------------------------------------------------------------------
    protected TypeEntry m_curClass;        
    public void SetCurrentClass(TypeEntry type)
    {
        m_curClass = type;
    }
    
    public TypeEntry GetCurrentClass()
    {
        return m_curClass;
    }


    protected MethodExpEntry m_curMethod;
    public void SetCurrentMethod(MethodExpEntry m)
    {
        m_curMethod = m;
    }

    public MethodExpEntry GetCurrentMethod()
    {
        return m_curMethod;
    }    
#endregion    
    
#region Hookup to Provider
    // Given a symbol for an array type, get the corresponding CLR type.
    public System.Type GetArrayType(ArrayTypeEntry sym)
    {
        System.Type t = m_provider.CreateCLRArrayType(sym);
        Debug.Assert(t != null);
        return t;
    }
    
    // get a reference type
    public System.Type GetRefToType(System.Type tElem)
    {
        System.Type t = m_provider.CreateCLRReferenceType(tElem);
        Debug.Assert(t != null);
        return t;
    }
#endregion    
    
#region Lookup functions    
    
    // We only need Lookup() during the resolve phase (because that's the only time
    // we need to convert text into symbols)
    // After that, we can just use the symbols directly    
    
    // Lookup an entry in a specific scope
    // If it doesn't exist, then return null if !fMustExist and throw if fMustExist
    public SymEntry LookupSymbol(Scope scope, Identifier id, bool fMustExist)
    {
        SymEntry  s = scope.LookupSymbol(id.Text);
        if (fMustExist && s == null)
        {
            ThrowError(SymbolError.UndefinedSymbol(id));
        }
        return s;
    }
    
    
    // Get rid of this function
    public SymEntry LookupSymbol(Scope scope, string st, bool fMustExist)
    {
        SymEntry s = scope.LookupSymbol(st);        
        bool f= false;
        if (f) {
            System.Xml.XmlWriter o = new System.Xml.XmlTextWriter(new System.IO.StreamWriter("dump.xml"));
            scope.Dump(o, true);
            o.Close();
        }
        
        if (fMustExist && s == null)
        {
            FileRange range = new FileRange();
            range.Filename = "<not specified>";
            
            Identifier id = new Identifier(st, range);
            //ThrowError_UndefinedSymbol(id);
            ThrowError(SymbolError.UndefinedSymbol(id));
        }
        return s;
    }
    
    // Lookup a system type
    // Context-free
    public TypeEntry LookupSystemType(string st)
    {        
        NamespaceEntry nsSystem = (NamespaceEntry) LookupSymbol(m_scopeGlobal, "System", true);
        Scope scopeSystem = nsSystem.ChildScope;
        
        
        SymEntry s = LookupSymbol(scopeSystem, st, true);        
        
        // An end-user program can't lookup system types, so this assert should be fine.        
        Debug.Assert(s is TypeEntry, "Expected '" + st + "' is a type");
        
        return s as TypeEntry;
    }
    
    // Sets the current context that we lookup symbols against.
    // Returns the previous current context, which should be
    // passed to RestoreContext()
    public virtual Scope SetCurrentContext(Scope scopeNewContext)
    {
        Scope prev = m_CurrentContext;
        m_CurrentContext = scopeNewContext;
        return prev;
    }
    
    public virtual void RestoreContext(Scope scopePreviousContext)
    {
        m_CurrentContext = scopePreviousContext;
    }
    
    public virtual Scope GetCurrentContext()
    {
        return m_CurrentContext;
    }
    
    Scope m_CurrentContext;
        
    // Lookup a symbol in the current context.
    // The context includes the lexical scope stack, super scopes, 
    // and using directives        
    // If it doesn't exist, then return null if !fMustExist and throw exception if fMustExist
    public virtual SymEntry LookupSymbolWithContext(Identifier id, bool fMustExist)
    {   
        string strName = id.Text;
    
        // Search through stack of lexical scopes
        SymEntry sym = null;
        Scope t = m_CurrentContext;
        while(t != null)
        {
            sym = LookupSymbol(t, id, false); // <-- smart lookup, go through ILookupController
            if (sym != null) 
                return sym;
            t = t.m_LexicalParent;            
        }

        // Don't need this any more with ILookupControllers
        #if false
        // Check using directives if not found in the current scope stack
        // Do this by traversing the scope stack and looking for UserNamespaceEntry
        // (we can never be in an imported namespace, so that's ok)
        t = m_CurrentContext;
        while (t != null)
        {            
            AST.NamespaceDecl node = t.Node as AST.NamespaceDecl;            
            if (node != null)
            {
                sym = node.LookupSymbolInUsingDirectives(this, id);
                if (sym != null)
                    return sym;
            }

            t = t.m_LexicalParent;
        }
        #endif

            
        // Symbol  not found
        if (fMustExist) 
        {            
            //ThrowError_UndefinedSymbol(id);
            ThrowError(SymbolError.UndefinedSymbol(id));
        }
        return null;
    }
#endregion        

#if DEBUG
#region Debugging    
    // Debugging helper to print the current context
    public virtual void Dump()
    {    
        Console.WriteLine("*** Dump of current SemanticChecker state [");
        m_CurrentContext.DumpTree();
        m_CurrentContext.DumpKeys();
        Console.WriteLine("Current class:{0}", 
            (m_curClass == null) ? "null" : m_curClass.ToString());
        Console.WriteLine("Current method:{0}", 
            (m_curMethod == null) ? "null" : m_curMethod.PrettyDecoratedName);
        Console.WriteLine("]");        
    }
#endregion
#endif

} // end class SemanticChecker

} // end namespace

⌨️ 快捷键说明

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