/// <summary> /// Update a value in the symbol table. /// If the symbol is not defined, return false. /// Cache the symbol location if not already done. /// </summary> /// <param name="symbol">The symbol to update.</param> /// <param name="val">The new value.</param> /// <param name="level">The number of levels to travel to find the definition</param> /// <returns>The new value, null if not found.</returns> internal SchemeObject Update(Symbol symbol, SchemeObject val, int level) { var entry = new NameValuePair(symbol.SymbolName, val); lock (this.lockObj) { if (symbol.Located) { if (level != symbol.Level) { return null; } this.entries[symbol.Pos] = entry; return val; } var index = this.FindSymbol(symbol); if (!SymbolFound(index)) { return null; } this.entries[index] = entry; symbol.SetLocation(index, level); return val; } }
/// <summary> /// Add a symbol and its value to the environment. /// If the symbol is not defined in the environment, add it. /// If the symbol is already defined in the envhronment, update its value. /// The caller is responsible for locking. /// </summary> /// <param name="symbol">The symbol name.</param> /// <param name="val">The value.</param> private void AddUnlocked(Symbol symbol, SchemeObject val) { var index = this.FindSymbol(symbol); if (!SymbolFound(index)) { this.entries.Add(new NameValuePair(symbol.SymbolName, val)); index = this.entries.Count - 1; } else { this.entries[index] = new NameValuePair(symbol.SymbolName, val); } symbol.SetLocation(index, 0); }
/// <summary> /// Look up a symbol given its name. /// If the symbol is not found at this level, then return null and we will continue to search /// through the parent environment chain. /// </summary> /// <param name="symbol">The symbol to look up.</param> /// <param name="level">The number of levels to travel to find the definition. Cached in the symbol the /// first time it is looked up.</param> /// <returns>The value of the object looked up, null if not found.</returns> internal SchemeObject Lookup(Symbol symbol, int level) { lock (this.lockObj) { if (symbol.Located) { Debug.Assert(level == symbol.Level, "SymbolTable:Lookup level -- symbol.Level"); return this.entries[symbol.Pos].Value; } var index = this.FindSymbol(symbol); if (!SymbolFound(index)) { return null; } symbol.SetLocation(index, level); return this.entries[index].Value; } }