/// <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 + "'"); }
/// <summary> /// This static method recursively processes /// OpenLisp.NET forms and tokenizes them. /// </summary> /// <param name="reader"></param> /// <returns></returns> public static OpenLispVal ReadForm(TokensReader reader) { string token = reader.Peek(); if (token == null) { throw new OpenLispContinue(); } OpenLispVal form = null; switch (token) { case "'": reader.Next(); return(new OpenLispList(new OpenLispSymbol("quote"), ReadForm(reader))); case "`": reader.Next(); return(new OpenLispList(new OpenLispSymbol("quasiquote"), ReadForm(reader))); case "~": reader.Next(); return(new OpenLispList(new OpenLispSymbol("unquote"), ReadForm(reader))); case "~@": reader.Next(); return(new OpenLispList(new OpenLispSymbol("splice-unquote"), ReadForm(reader))); case "^": reader.Next(); OpenLispVal meta = ReadForm(reader); return(new OpenLispList(new OpenLispSymbol("with-meta"), ReadForm(reader), meta)); case "@": reader.Next(); return(new OpenLispList(new OpenLispSymbol("deref"), ReadForm(reader))); case "(": form = ReadList(reader, new OpenLispList(), '(', ')'); break; case ")": throw new ParseError("unexpected ')'"); case "[": form = ReadList(reader, new OpenLispVector(), '[', ']'); break; case "]": throw new ParseError("unexpected ']'"); case "{": form = ReadHashMap(reader); break; case "}": throw new ParseError("unexpected '}'"); default: form = ReadAtom(reader); break; } return(form); }