transcendental-lisp/src/main/LispMain.java

157 lines
5.3 KiB
Java

package main;
import static com.googlecode.lanterna.terminal.IOSafeTerminalAdapter.createRuntimeExceptionConvertingAdapter;
import static java.text.MessageFormat.format;
import static terminal.LispTerminal.END_OF_SEGMENT;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.util.function.Function;
import com.googlecode.lanterna.terminal.DefaultTerminalFactory;
import com.googlecode.lanterna.terminal.IOSafeTerminal;
import com.googlecode.lanterna.terminal.Terminal;
import interpreter.LispInterpreter;
import interpreter.LispInterpreterBuilder;
import interpreter.LispInterpreterBuilderImpl;
import stream.UncheckedIOException;
import terminal.LispTerminal;
import terminal.TerminalConfiguration;
public class LispMain {
public static final String GREETING = "Transcendental Lisp - Version {0}";
public static final String ANSI_RESET = "\u001B[0m";
public static final String ANSI_RED = "\u001B[31m";
public static final String ANSI_GREEN = "\u001B[32m";
public static final String ANSI_YELLOW = "\u001B[33m";
public static final String ANSI_PURPLE = "\u001B[35m";
public static final String[] LANGUAGE_FILE_NAMES = new String[] { "functions.lisp", "dlambda.lisp" };
public static void main(String[] arguments) {
LispMain lispMain = new LispMain();
if (arguments.length == 0)
lispMain.runInteractive();
else
lispMain.runWithFile(arguments[0]);
}
private LispInterpreterBuilder builder;
private PipedInputStream inputReader;
private PrintStream output;
private LispTerminal lispTerminal;
private TerminalConfiguration configuration;
public LispMain() {
this.builder = LispInterpreterBuilderImpl.getInstance();
}
public LispMain(LispInterpreterBuilder builder, TerminalConfiguration configuration) {
this.builder = builder;
this.configuration = configuration;
}
public void runInteractive() {
initializeTerminal();
printGreeting();
lispTerminal.start();
buildInteractiveInterpreter().interpret();
shutdownTerminal();
}
private void initializeTerminal() {
createTerminalConfiguration();
inputReader = configuration.getInputReader();
output = new PrintStream(configuration.getOutputWriter());
lispTerminal = new LispTerminal(configuration);
}
private void createTerminalConfiguration() {
if (configuration == null) {
configuration = new TerminalConfiguration();
configuration.setInputPair(new PipedOutputStream(), new PipedInputStream());
configuration.setOutputPair(new PipedOutputStream(), new PipedInputStream());
configuration.setTerminal(createIOSafeTerminal());
}
}
private IOSafeTerminal createIOSafeTerminal() {
return createRuntimeExceptionConvertingAdapter(createDefaultTerminal());
}
private Terminal createDefaultTerminal() {
try {
return new DefaultTerminalFactory().createTerminal();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
private void printGreeting() {
output.println(format(GREETING, getVersion()));
output.println();
}
private String getVersion() {
return getClass().getPackage().getImplementationVersion();
}
private LispInterpreter buildInteractiveInterpreter() {
builder.setInput(inputReader, "terminal");
builder.setOutput(output);
builder.setErrorOutput(output);
builder.setTerminationFunction(this::shutdownTerminal);
builder.setErrorTerminationFunction(this::shutdownTerminal);
builder.setLanguageFileNames(LANGUAGE_FILE_NAMES);
builder.setPromptDecorator(s -> s + END_OF_SEGMENT);
builder.setValueOutputDecorator(makeColorDecorator(ANSI_GREEN));
builder.setWarningOutputDecorator(makeColorDecorator(ANSI_YELLOW));
builder.setErrorOutputDecorator(makeColorDecorator(ANSI_RED));
builder.setCriticalOutputDecorator(makeColorDecorator(ANSI_PURPLE));
return builder.build();
}
private void shutdownTerminal() {
output.print(END_OF_SEGMENT);
lispTerminal.stop();
output.close();
}
private Function<String, String> makeColorDecorator(String color) {
return new Function<String, String>() {
@Override
public String apply(String s) {
return color + s + ANSI_RESET;
}
};
}
public void runWithFile(String fileName) {
buildFileInterpreter(fileName).interpret();
}
private LispInterpreter buildFileInterpreter(String fileName) {
builder.useFile(fileName);
builder.setOutput(System.out);
builder.setErrorOutput(System.err);
builder.setTerminationFunction(() -> System.exit(0));
builder.setErrorTerminationFunction(() -> System.exit(1));
builder.setLanguageFileNames(LANGUAGE_FILE_NAMES);
builder.setValueOutputDecorator(makeColorDecorator(ANSI_GREEN));
builder.setWarningOutputDecorator(makeColorDecorator(ANSI_YELLOW));
builder.setErrorOutputDecorator(makeColorDecorator(ANSI_RED));
builder.setCriticalOutputDecorator(makeColorDecorator(ANSI_PURPLE));
return builder.build();
}
}