/// <summary> /// Reads an S-expression from the input source /// </summary> public static object Read(InPort port) { Func <object, object> readAhead = null; readAhead = token => { Symbol quote; if (object.Equals(token, Symbol.EOF)) { throw new SyntaxError("unexpected EOF"); } else if (token is string) { string tokenStr = (string)token; if (tokenStr == "(") { var L = new List <object>(); while (true) { token = port.NextToken(); if (token is string && (string)token == ")") { return(L); } else { L.Add(readAhead(token)); } } } else if (tokenStr == ")") { throw new SyntaxError("unexpected )"); } else if (Symbol.QuotesMap.TryGetValue(tokenStr, out quote)) { object quoted = Read(port); return(new List <object> { quote, quoted }); } else { return(ParseAtom(tokenStr)); } } else { throw new SyntaxError("unexpected token: " + token); } }; var token1 = port.NextToken(); return(Symbol.EOF.Equals(token1) ? Symbol.EOF : readAhead(token1)); }