/// <summary>
        /// Evalues an AST in the environment.
        ///
        /// TODO: refactor to move to <see cref="OpenLisp.Core.StaticClasses.CoreNameSpace"/>.
        /// </summary>
        /// <param name="abstractSyntaxTree"></param>
        /// <param name="environment"></param>
        /// <returns></returns>
        public static OpenLispVal EvalAst(OpenLispVal abstractSyntaxTree, Env environment)
        {
            var key = abstractSyntaxTree as OpenLispSymbol;

            if (key != null)
            {
                return(environment.Get(key));
            }

            var list = abstractSyntaxTree as OpenLispList;

            if (list == null)
            {
                var map = abstractSyntaxTree as OpenLispHashMap;
                if (map == null)
                {
                    return(abstractSyntaxTree);
                }
                var newDictionary =
                    map.Value.ToDictionary(
                        entry => entry.Key, entry => Eval(entry.Value, environment));
                return(new OpenLispHashMap(newDictionary));
            }

            OpenLispList oldList = list;
            OpenLispList newList = abstractSyntaxTree.ListQ() ? new OpenLispList()
                : (OpenLispList) new OpenLispVector();

            foreach (OpenLispVal movedValue in oldList.Value)
            {
                newList.Conj(Eval(movedValue, environment));
            }
            return(newList);
        }
        /// <summary>
        /// Reads an OpenLisp.NET list expression.
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="openLispList"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public static OpenLispVal ReadList(TokensReader reader, OpenLispList openLispList, char start, char end)
        {
            string token = reader.Next();

            if (token[0] == start)
            {
                while ((token = reader.Peek()) != null && token[0] != end)
                {
                    openLispList.Conj(ReadForm(reader));
                }

                if (token == null)
                {
                    throw new ParseError("expected '" + end + "', got EOF");
                }
                reader.Next();

                return(openLispList);
            }

            throw new ParseError("expected '" + start + "'");
        }