/// <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> /// Reads an OpenLisp.NET atom. /// </summary> /// <param name="reader"></param> /// <returns></returns> public static OpenLispVal ReadAtom(TokensReader reader) { string token = reader.Next(); string pattern = @"(^-?[0-9]+$)|(^-?[0-9][0-9.]*$)|(^nil$)|(^true$)|(^false$)|^("".*"")$|:(.*)|(^[^""]*$)"; Regex regex = new Regex(pattern); Match match = regex.Match(token); //Console.WriteLine("token: ^" + token + "$"); if (!match.Success) { throw new ParseError("unrecognized token '" + token + "'"); } if (match.Groups[1].Value == String.Empty) { if (match.Groups[3].Value == String.Empty) { if (match.Groups[4].Value == String.Empty) { if (match.Groups[5].Value == String.Empty) { if (match.Groups[6].Value == String.Empty) { if (match.Groups[7].Value == String.Empty) { if (match.Groups[8].Value == String.Empty) { throw new ParseError("unrecognized '" + match.Groups[0] + "'"); } return(new OpenLispSymbol(match.Groups[8].Value)); } return(new OpenLispString("\u029e" + match.Groups[7].Value)); } string str = match.Groups[6].Value; str = str.Substring(1, str.Length - 2) .Replace("\\\"", "\"") .Replace("\\n", "\n"); return(new OpenLispString(str)); } return(StaticOpenLispTypes.False); } return(StaticOpenLispTypes.True); } return(StaticOpenLispTypes.Nil); } return(new OpenLispInt(int.Parse(match.Groups[1].Value))); }
/// <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); }