// Return the value of a target symbol in this or an outer scope. public MalVal Get(MalSym keySymbol) { Env e = Find(keySymbol); if (e == null) { switch (keySymbol.ToString(true)) { // Some symbols are only valid when used in a particular context. case "unquote": throw new MalEvalError("'unquote' used incorrectly (missing macro?)"); case "quasiquote": throw new MalEvalError("'quasiquote' used incorrectly (missing macro?)"); case "splice-unquote": throw new MalEvalError("'splice-unquote' used incorrectly (missing macro?)"); } //// If here the symbol simply hasn't been defined or is mis-spelt. throw new MalLookupError("Get - Symbol not found '" + keySymbol.ToString(true) + "'"); } else { if (e.data.TryGetValue(keySymbol.getName(), out MalVal value)) { return(value); } else { throw new MalInternalError("Get - Find successful but symbol retrieval failed '" + keySymbol.ToString(true) + "'"); } } }
public void Set(MalSym keySymbol, MalVal value) { // Takes a symbol key and a mal value and adds them to the environment. if (!data.TryAdd(keySymbol.getName(), value)) { // Symbol can shadow an equivalent in an outer scope but cannot be duped. throw new MalEvalError("Attempt to redefine '" + keySymbol.ToString(true) + "'"); } }
// Return the value of a target symbol in this or an outer scope. public MalVal Get(MalSym keySymbol) { Env e = Find(keySymbol); if (e != null && e.data.TryGetValue(keySymbol.getName(), out MalVal value)) { return(value); } throw new MalEvalError("Symbol not found '" + keySymbol.ToString(true) + "'"); }
// Search for and return the environment (scope) that contains a target symbol. public Env Find(MalSym keySymbol) { if (data.ContainsKey(keySymbol.getName())) { // Symbol exists in the current scope. return(this); } else if (outer != null) { // Recurse to search for the symbol in an outer scope. return(outer.Find(keySymbol)); } else { // Symbol is not defined. return(null); } }
// Return the value of a target symbol in this or an outer scope. public MalVal Get(MalSym keySymbol) { Env e = Find(keySymbol); if (e != null && e.data.TryGetValue(keySymbol.getName(), out MalVal value)) { return(value); } switch (keySymbol.ToString(true)) { case "quote": throw new MalEvalError("'quote' used where expression expected"); case "quasiquote": throw new MalEvalError("'quasiquote' used where expression expected"); case "splice-unquote": throw new MalEvalError("'splice-unquote' used where expression expected"); default: throw new MalEvalError("Symbol not found '" + keySymbol.ToString(true) + "'"); } }