public INode Get(string key) { if (Parent == null) { return(GetShallow(key)); } return(GetShallow(key) ?? Parent.Get(key)); }
private INode VisitSymbolNode(SymbolNode node, Environment env) { while (true) { var nullable = env.Get(node.Value); if (nullable == null) { return(node); } if (nullable.GetType() != typeof(SymbolNode)) { return(nullable); } node = (SymbolNode)nullable; } }
private INode BuiltinSet(List <INode> args, Environment env) { var first = (QuotedExpressionNode)args[0]; var second = (IntegerNode)args[1]; var third = args[2]; if (first.Children.Count != 1) { return(new ErrorNode("expected singleton array")); } var child = first.Children[0]; if (child.GetType() != typeof(SymbolNode)) { return(new ErrorNode("expected singleton array to contain a symbol")); } var definition = env.Get(((SymbolNode)child).Value); if (definition?.GetType() != typeof(QuotedExpressionNode)) { return(new ErrorNode("symbol must be bound to an array")); } var array = (QuotedExpressionNode)definition; var index = second.Value; var replacement = third; if (index < 0 || index >= array.Children.Count) { return(new ErrorNode("index is out of bounds")); } array.Children[index] = replacement; return(Null); }