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

📄 scope.cs

📁 charp compiler
💻 CS
📖 第 1 页 / 共 2 页
字号:
        // for finializing scopes after we've resolved a symbol.
        // Locking is also a useful flag to implement lazy evaluation because
        // it lets us check if a scope has been finished.
        bool m_fIsLocked;
        internal void LockScope()
        {
            m_fIsLocked = true;
        }
        internal bool IsLocked
        {
            get { return m_fIsLocked; }
        }
#endregion

    
#region Add & Lookup operations
        /// <summary>
        /// Add a symbol to this scope. (SymEntry contains the string name)        
        /// <seealso cref="AddAliasSymbol"/>
        /// </summary>
        /// <remarks>
        /// Adds the given Symbol to this scope, and indexes it by the symbol's name.        
        /// </remarks>
        /// <param name="s">The symbol to add</param>
        
        public void AddSymbol(SymEntry s) 
        {
            Debug.Assert(!m_fIsLocked, "Can't add to a locked scope");
            Debug.Assert(s != null);
            Debug.Assert(s.Name != null);
            
            // If we try to add the symbol and it's already there, we have a Symbol-Redefinition
            // error. Hashtable.Add() will throw an exception, we catch that, and then throw our
            // own version. 
            // We choose to catch, rather than to check first, because we optimize for the 
            // non-error case.
            try
            {            
                m_table.Add(s.Name, s); // this already throws
            }
            catch(ArgumentException)
            {
                // @todo - How should we handle this error?
                Debug.Assert(false, "@todo - symbol already defined");   
            }
        }
    
        /// <summary>
        /// Add a symbol under an aliased name.
        /// </summary>
        /// <remarks>
        /// Add an existing symbol entry, but indexed under a new name
        /// <para><example>
        /// [globalscope].AddAliasSymbol("int", [SymEntry for System.Int32]);
        /// </example></para>
        /// <seealso cref="AddSymbol"/>
        /// </remarks>
        /// <param name="stAliasName">Aliased name of the symbol</param>
        /// <param name="s">Symbol to add</param>                
        public void AddAliasSymbol(string stAliasName, SymEntry s)
        {                   
            Debug.Assert(!m_fIsLocked, "Can't add to a locked scope");
            m_table.Add(stAliasName, s);
        }
        
        /// <summary>
        /// Do a deep lookup in this scope. This includes super scopes but not lexical parents.
        /// </summary>
        /// <remarks>
        /// <para>If this scope does not have an ILookupController, this is equivalent to 
        /// just calling <see cref="LookupSymbolInThisScopeOnly"/> </para>
        /// <para>else this calls <see cref="ILookupController.SmartLookup"/></para>
        /// </remarks>
        /// <param name="strName">String name to search for</param>
        /// <returns>A symbol added under this name. Null if not found.</returns>
        public SymEntry LookupSymbol(string strName)
        {
            // @todo - we do this when looking for namespaces during import.
            // If it's not there, we add it. 
            // It would be nice to enable this assert though...
            //Debug.Assert(m_fIsLocked, "Don't lookup a symbol in an unlocked scope");
            if (m_pController == null)
                return this.LookupSymbolInThisScopeOnly(strName);
            else
                return m_pController.SmartLookup(strName, this);
        }
        
        /// <summary>
        /// Lookup a SymEntry only in this scope. Don't search super scopes or lexical parents. 
        /// </summary>
        /// <remarks>This is a shallow lookup that does not invoke the ILookupController</remarks>
        /// <param name="strName">String name to search for.</param>
        /// <returns>A symbol added under this name. Null if not found.</returns>
        public SymEntry LookupSymbolInThisScopeOnly(string strName)
        {        
            return (SymEntry) m_table[strName];
        }
        
        // If we don't know the string name and we need to do a more elaborate
        // match (ex, say on parameters), then we have to provide access to our
        // values.
        // So expose an enumerator for the all the SymEntry in this scope.
        public System.Collections.IEnumerator GetEnumerator()
        {
            return this.m_table.Values.GetEnumerator();
        }

#endregion
        
#region Checks    
        #if DEBUG
        // Dump a tree view of the scope tree that this is a root for.
        // Includes the super scopes & lexical parents.
        public void DumpTree()
        {
            Console.WriteLine("** Debug print of current context **");
            Scope s = this;
            int i = 0;
            while (s != null)
            {
                Console.Write("{0}:#{1},{2}", i, s.m_id, s.m_szDebugName);
                
                if (s.m_pController != null)
                {
                    object o = s.m_pController;
                    Console.Write("({0})", o.GetType().Name);
                    s.m_pController.DumpScope(s);
                }
                
                Console.WriteLine();
                i++;
                s = s.LexicalParent;
            }
        }
        
        // Dump all the raw entries
        public void DumpKeys()
        {
            Console.WriteLine("*** Debug dump of keys in scope #{0},{1} [", this.m_id, this.m_szDebugName);
            
            System.Collections.IDictionaryEnumerator e = m_table.GetEnumerator();            
            while (e.MoveNext())
            {
                string str = (string) e.Key;
                SymEntry sym = (SymEntry) e.Value;
                
                Console.WriteLine("{0} is a {1}", str, sym.ToString()); 
            }
            Console.WriteLine("] End dump");
        }
        #endif

        // Verify integrity of all symbol elements in this scope
        public void DebugCheck(ISemanticResolver s)
        {
            System.Collections.IDictionaryEnumerator e = m_table.GetEnumerator();            
            while (e.MoveNext())
            {
                string str = (string) e.Key;
                SymEntry sym = (SymEntry) e.Value;
                
                sym.DebugCheck(s);
            }
        }
        
        // Dump the scope to an xml file
        public void Dump(XmlWriter o, bool fRecursive)
        {   
            o.WriteStartElement("scope");
            o.WriteAttributeString("name", m_szDebugName);

            ILookupController p = this.m_pController;            
            o.WriteAttributeString("controller", (p == null) ? "none" : ((object) p).GetType().Name);
            /*
            if (m_SuperScope != null) 
            {
                o.WriteAttributeString("super", m_SuperScope.m_szDebugName);
            }
            */
            
            System.Collections.IDictionaryEnumerator e = m_table.GetEnumerator();            
            while (e.MoveNext())
            {
                string str = (string) e.Key;
                SymEntry sym = (SymEntry) e.Value;
                
                sym.Dump(o, fRecursive);
            }
        
            o.WriteEndElement(); // scope
        }     
        
        // Debug function
        public void DebugConsoleDump()
        {
            XmlWriter o = new XmlTextWriter(Console.Out);
            bool f = true;
            if (f)
                Dump(o, true);
            else 
                Dump(o, false);
            o.Close();
        }
#endregion        
    } // end class scope

}

⌨️ 快捷键说明

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