/// <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); }
/// <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); }
/// <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)); }
/// <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); }
/// <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);