Example #1
0
    public SymEntry EnsureSymbolType(SymEntry sym, System.Type tExpected, FileRange location)
    {
        if (sym == null)
            return null;
/*
        Type tSym = sym.GetType();
        if (tSym == tExpected)
            return sym;

        if (tSym.IsSubclassOf(tExpected))
            return sym;
*/
        bool fMatch = SymbolEngine.TypeEntry.IsAssignable(sym.GetType(), tExpected);
        if (fMatch)
            return sym;

        ThrowError(SymbolError.BadSymbolType(sym, tExpected, location));
/*
        this.ThrowError(Code.cBadSymbolType,
            location,
            "Symbol '" + sym.Name + "' must be of type '" + tExpected.ToString() + "', not '" +
            sym.GetType().ToString() + "'");
*/
        return sym;
    }
Example #2
0
        // 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
        }
Example #3
0
 // 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;
 }
Example #4
0
        // 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);
            }
        }
Example #5
0
 // 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;
 }
Example #6
0
        // 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");
        }
Example #7
0
    // 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;
    }
Example #8
0
 // 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;
 }
Example #9
0
        /// <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");
            }
        }
Example #10
0
 /// <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);
 }
Example #11
0
 /// <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");   
     }
 }
Example #12
0
 //-----------------------------------------------------------------------------
 // The symbol is of the wrong type.
 //-----------------------------------------------------------------------------
 public static SymbolErrorException BadSymbolType(SymEntry sym, System.Type tExpected, FileRange location)
 {    
     return new SymbolErrorException(
         Code.cBadSymbolType,
         location,
         "Symbol '" + sym.Name + "' must be of type '" + tExpected.ToString() + "', not '" +
         sym.GetType().ToString() + "'"
     );    
 }
Example #13
0
//-----------------------------------------------------------------------------
// Create the scopes for an imported types
//-----------------------------------------------------------------------------
    Scope CreateImportedContext(System.Type tImport)
    {
        // Traverse namespaces to find scope
        Scope scope = m_scopeGlobal;
        string s = tImport.ToString();
               
        // In a type's string name, the '.' separates namespaces,
        // the '+' separates for nested classes.        
        // Valid form:
        // i.i.i+i+i+i
                        
        int iStart  = 0;
        int i       = s.IndexOf('.');            
        
        // Search past namespaces
        while(i != -1) 
        {                
            string stNamespace = s.Substring(iStart, i - iStart);
            SymEntry sym = LookupSymbol(scope, stNamespace, false);
                                               
            if (sym == null) 
            {            
                ImportedNamespaceEntry nsImported = new ImportedNamespaceEntry(
                    stNamespace, 
                    s.Substring(0, i)
                    );
                    
                scope.AddSymbol(nsImported);
                    
                scope = nsImported.ChildScope;
            } 
            else 
            {
                // If the symbol already exists, must be a namespace                    
                if (sym is NamespaceEntry) 
                {
                    scope = ((NamespaceEntry) sym).ChildScope;
                } 
                else 
                {
                    ThrowError(SymbolError.IllegalAssembly(tImport.Assembly, "Illegal type: " + s));
                }
            }
            iStart = i + 1;
            i = s.IndexOf('.', iStart);
        }
                   
        // If we're not a nested type, then we can return the scope now
        if (tImport.DeclaringType == null)                   
        {
            Debug.Assert(s.Substring(iStart) == tImport.Name);
            return scope;
        }
        
        // Containing class should have already been added.
        Debug.Assert(TryLookupCLRType(tImport.DeclaringType) != null);
                        
        // Else we have to traverse the class scopes to find out containing scope.        
        // n.n. c1+c2
        i = s.IndexOf('+', iStart);   
        while (i != -1)
        {
            string stClass = s.Substring(iStart, i - iStart);
            
            TypeEntry tBlue = (TypeEntry) LookupSymbol(scope, stClass, true);
            scope = tBlue.MemberScope;
            Debug.Assert(scope != null);
        
            iStart = i + 1;
            i = s.IndexOf('+', iStart);        
        }
        
        Debug.Assert(s.Substring(iStart) == tImport.Name);
        
        return scope;
    }
Example #14
0
 /// <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);
 }