// The guts of the REPL. It extendsthe C#-Mal reference REPL // to handle (1) multi-line forms and (2) multi-form lines. public void RunREPL() { while (true) { try { // Read standard input. string line = ReadLine.Readline("JKL> "); // Exit if EOF or ctrl-Z. if (line == null) { break; } // Go round again if empty line (user hit return). if (line == "") { continue; } // Tokenise the input and load the tokens into a Reader object. MalReader.Reader rdr = new MalReader.Reader(MalReader.Tokenizer(line)); // Loop until all tokens on the line have been consumed. This handles lines // like (a b) (c d) - where Mal REPL would silently ignore (c d) while (rdr.Peek() != null) { // Parse input to create a Mal abstract syntax tree. The parser // attempts to reload the reader if it runs out of tokens mid form. MalVal ast = READMULTILINE(rdr); // Evaluate the ast and print the result. Console.WriteLine(PRINT(EVAL(ast, myEnv))); } } catch (MalParseError e) { Console.WriteLine(e.Message); } catch (MalEvalError e) { Console.WriteLine(e.Message); } catch (MalInternalError e) { Console.WriteLine(e.Message); } } }
// Handle multi-lines. static MalVal READMULTILINE(MalReader.Reader rdr) { return(MalReader.read_str_multiline(rdr)); }