SYMTBL
                    class SYMTBL
                
                using Microsoft.CSharp.RuntimeBinder.Syntax;
using System.Collections.Generic;
namespace Microsoft.CSharp.RuntimeBinder.Semantics
{
    internal class SYMTBL
    {
        private sealed class Key
        {
            private readonly Name _name;
            private readonly ParentSymbol _parent;
            public Key(Name name, ParentSymbol parent)
            {
                _name = name;
                _parent = parent;
            }
            public override bool Equals(object obj)
            {
                Key key = obj as Key;
                if (key != null && _name.Equals(key._name))
                    return _parent.Equals(key._parent);
                return false;
            }
            public override int GetHashCode()
            {
                return _name.GetHashCode() ^ _parent.GetHashCode();
            }
        }
        private Dictionary<Key, Symbol> _dictionary;
        public SYMTBL()
        {
            _dictionary = new Dictionary<Key, Symbol>();
        }
        public Symbol LookupSym(Name name, ParentSymbol parent, symbmask_t kindmask)
        {
            Key key = new Key(name, parent);
            if (_dictionary.TryGetValue(key, out Symbol value))
                return FindCorrectKind(value, kindmask);
            return null;
        }
        public void InsertChild(ParentSymbol parent, Symbol child)
        {
            child.parent = parent;
            InsertChildNoGrow(child);
        }
        private void InsertChildNoGrow(Symbol child)
        {
            Key key = new Key(child.name, child.parent);
            if (_dictionary.TryGetValue(key, out Symbol value)) {
                while (value != null && value.nextSameName != null) {
                    value = value.nextSameName;
                }
                value.nextSameName = child;
            } else
                _dictionary.Add(key, child);
        }
        private static Symbol FindCorrectKind(Symbol sym, symbmask_t kindmask)
        {
            do {
                if ((kindmask & sym.mask()) != (symbmask_t)0)
                    return sym;
                sym = sym.nextSameName;
            } while (sym != null);
            return null;
        }
    }
}