Exemple #1
0
        /// <summary>
        /// Looks up the specified symbol by scanning the scoped symbol table, starting from the current scope.
        /// </summary>
        /// <param name="symbol">Symbol to look up in the scope symbol table.</param>
        /// <param name="value">Indexed value matching the specified symbol. The outer index represents the scope relative to the current scope, with a value of -1 representing the global scope. The inner index represents the index in the declaring symbol table.</param>
        /// <returns>true if the symbol was found; otherwise, false.</returns>
        public bool TryLookup(TSymbol symbol, out Indexed <Indexed <TValue> > value)
        {
            var level = 0;

            Indexed <TValue> res;

            foreach (var table in _environment)
            {
                if (table.TryGetValue(symbol, out res))
                {
                    value = new Indexed <Indexed <TValue> >(res, level);
                    return(true);
                }

                level++;
            }

            if (GlobalScope.TryGetValue(symbol, out res))
            {
                value = new Indexed <Indexed <TValue> >(res, -1);
                return(true);
            }

            value = default;
            return(false);
        }
Exemple #2
0
        /// <summary>
        /// Gets the symbol table entry associated with the specified symbol.
        /// </summary>
        /// <param name="symbol">Symbol to look up in the symbol table.</param>
        /// <param name="value">Indexed value matching the specified symbol.</param>
        /// <returns>true if the symbol was found; otherwise, false.</returns>
        public bool TryGetValue(TSymbol symbol, out Indexed <TValue> value)
        {
            if (_table.TryGetValue(symbol, out Indexed <TValue> state))
            {
                value = state;
                return(true);
            }

            value = default;
            return(false);
        }
Exemple #3
0
        /// <summary>
        /// Adds an entry to the symbol table.
        /// </summary>
        /// <param name="symbol">Symbol to add to the table.</param>
        /// <param name="value">Value to associate to the symbol.</param>
        /// <returns>Indexed entry in the symbol table.</returns>
        public Indexed <KeyValuePair <TSymbol, TValue> > Add(TSymbol symbol, TValue value)
        {
            if (_table.ContainsKey(symbol))
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Symbol table already contains symbol '{0}'.", symbol));
            }

            var res = new Indexed <TValue>(value, _table.Count);

            _table[symbol] = res;

            var entry = new KeyValuePair <TSymbol, TValue>(symbol, value);

            _ordered.Add(entry);

            return(new Indexed <KeyValuePair <TSymbol, TValue> >(entry, res.Index));
        }
Exemple #4
0
        /// <summary>
        /// Looks up the specified symbol by following the symbol table's parent chain.
        /// </summary>
        /// <param name="symbol">Symbol to look up in the symbol table and its parents.</param>
        /// <param name="value">Indexed value matching the specified symbol. The outer index represents the scope relative to the current table. The inner index represents the index in the declaring symbol table.</param>
        /// <returns>true if the symbol was found; otherwise, false.</returns>
        public bool TryLookup(TSymbol symbol, out Indexed <Indexed <TValue> > value)
        {
            var level = 0;

            var table = this;

            while (table != null)
            {
                if (table.TryGetValue(symbol, out Indexed <TValue> res))
                {
                    value = new Indexed <Indexed <TValue> >(res, level);
                    return(true);
                }

                table = table.Parent;
                level++;
            }

            value = default;
            return(false);
        }
Exemple #5
0
 /// <summary>
 /// Determines whether this value equals to the specified indexed value.
 /// Two indexed values matches if both their index and object are equal.
 /// </summary>
 /// <param name="other">Other indexed value to compare this value to.</param>
 /// <returns>true if both indexed values are equal; otherwise, false.</returns>
 public bool Equals(Indexed <T> other) => Index == other.Index && EqualityComparer <T> .Default.Equals(Value, other.Value);