static public MalVal read_str_multiline(Reader rdr) { return(read_form(rdr)); }
static public MalVal read_atom(Reader reader) { // "If you have a problem and you think regex is the answer, now you have two problems!" // Unlike the referenceC#-Mal, read_atom handles floats and badly-formed symbols. string tokenToRead = reader.Next(); if (tokenToRead.Length <= 0) { throw new MalInternalError("Reader has returned empty string"); } switch (tokenToRead[0]) { case '+': if (tokenToRead.Length == 1) { // Token is a solo '+', not the beginning of a number. return(new MalSym(tokenToRead)); } // Skip the sign and extract a positive number; return(ParseNumber(tokenToRead.Substring(1), true)); case '-': if (tokenToRead.Length == 1) { // Token is a solo '-', not the beginning of a number. return(new MalSym(tokenToRead)); } // Skip the sign and extract a negative number; return(ParseNumber(tokenToRead.Substring(1), false)); case '.': // An initial '.' is only allowed at the start of a number, as in '.2'. return(ParseNumber(tokenToRead, true)); case '\"': if (tokenToRead.EndsWith("\"")) { return(new MalString(tokenToRead)); } // TODO - never reaches this point. The reader regex seems to throw away '"' chars if there is only 1. throw new MalParseError("String '" + tokenToRead + "' lacks a closing thingy"); case ':': // Handle a keyword if (tokenToRead.Length == 1) { // Can't have a solo colon. throw new MalParseError("':' must be followed by a keyword"); } return(new MalKeyword(tokenToRead)); default: if (IsDigit(tokenToRead[0].ToString())) { // Token seems to be an unsigned number. return(ParseNumber(tokenToRead, true)); } else if (tokenToRead == "nil") { return(malNil); } else if (tokenToRead == "true") { return(malTrue); } else if (tokenToRead == "false") { return(malFalse); } else { // If here it is 'just' a symbol. return(new MalSym(tokenToRead)); } } throw new MalInternalError("Can't process '" + tokenToRead + "'"); }