ConsoleReader reader = new ConsoleReader();
try {
reader.setExpandEvents(false);
reader.addCompleter(new MetaCommandCompleter());
Unit shellScope = new Unit(null, ModuleDecl.SHELL);
FunctionDecl main = new FunctionDecl("main", null);
shellScope.declare(main);
shellContext = new HashMap<String, Object>();
boolean inFunction = false;
// Used to build up multiline statement blocks (like functions)
StringBuilder block = null;
//noinspection InfiniteLoopStatement
do {
String prompt = (block != null) ? "| " : ">> ";
String rawLine = reader.readLine(prompt);
if (inFunction) {
if (rawLine == null || rawLine.trim().isEmpty()) {
inFunction = false;
// Eval the function to verify it.
printResult(Loop.evalClassOrFunction(block.toString(), shellScope));
block = null;
continue;
}
block.append(rawLine).append('\n');
continue;
}
if (rawLine == null) {
quit(reader);
}
//noinspection ConstantConditions
String line = rawLine.trim();
if (line.isEmpty())
continue;
// Add a require import.
if (line.startsWith("require ")) {
shellScope.declare(new LexprParser(new Tokenizer(line + '\n').tokenize()).require());
shellScope.loadDeps("<shell>");
continue;
}
if (line.startsWith(":q") || line.startsWith(":quit")) {
quit(reader);
}
if (line.startsWith(":h") || line.startsWith(":help")) {
printHelp();
}
if (line.startsWith(":run")) {
String[] split = line.split("[ ]+", 2);
if (split.length < 2 || !split[1].endsWith(".loop"))
System.out.println("You must specify a .loop file to run.");
Loop.run(split[1]);
continue;
}
if (line.startsWith(":r") || line.startsWith(":reset")) {
System.out.println("Context reset.");
shellScope = new Unit(null, ModuleDecl.SHELL);
main = new FunctionDecl("main", null);
shellScope.declare(main);
shellContext = new HashMap<String, Object>();
continue;
}
if (line.startsWith(":i") || line.startsWith(":imports")) {
for (RequireDecl requireDecl : shellScope.imports()) {
System.out.println(requireDecl.toSymbol());
}
System.out.println();
continue;
}
if (line.startsWith(":f") || line.startsWith(":functions")) {
for (FunctionDecl functionDecl : shellScope.functions()) {
StringBuilder args = new StringBuilder();
List<Node> children = functionDecl.arguments().children();
for (int i = 0, childrenSize = children.size(); i < childrenSize; i++) {
Node arg = children.get(i);
args.append(arg.toSymbol());