2016-12-17 10:19:18 -05:00
|
|
|
package main;
|
|
|
|
|
2017-03-23 12:14:44 -04:00
|
|
|
import static com.googlecode.lanterna.terminal.IOSafeTerminalAdapter.createRuntimeExceptionConvertingAdapter;
|
2018-01-20 08:34:31 -05:00
|
|
|
import static java.text.MessageFormat.format;
|
2017-03-19 12:54:35 -04:00
|
|
|
import static terminal.LispTerminal.END_OF_SEGMENT;
|
|
|
|
|
2017-11-12 09:42:25 -05:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.PipedInputStream;
|
|
|
|
import java.io.PipedOutputStream;
|
|
|
|
import java.io.PrintStream;
|
2017-02-11 13:33:34 -05:00
|
|
|
import java.util.function.Function;
|
|
|
|
|
2017-11-12 09:42:25 -05:00
|
|
|
import com.googlecode.lanterna.terminal.DefaultTerminalFactory;
|
|
|
|
import com.googlecode.lanterna.terminal.IOSafeTerminal;
|
|
|
|
import com.googlecode.lanterna.terminal.Terminal;
|
2017-03-19 12:54:35 -04:00
|
|
|
|
2017-11-12 09:42:25 -05:00
|
|
|
import interpreter.LispInterpreter;
|
|
|
|
import interpreter.LispInterpreterBuilder;
|
|
|
|
import interpreter.LispInterpreterBuilderImpl;
|
2017-03-23 16:14:26 -04:00
|
|
|
import stream.UncheckedIOException;
|
2017-11-12 09:42:25 -05:00
|
|
|
import terminal.LispTerminal;
|
|
|
|
import terminal.TerminalConfiguration;
|
2016-12-17 10:19:18 -05:00
|
|
|
|
|
|
|
public class LispMain {
|
|
|
|
|
2018-01-20 08:34:31 -05:00
|
|
|
public static final String GREETING = "Transcendental Lisp - Version {0}";
|
2017-03-22 14:08:22 -04:00
|
|
|
|
2017-03-23 16:14:26 -04:00
|
|
|
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";
|
2017-03-21 12:07:22 -04:00
|
|
|
|
2018-01-21 10:32:55 -05:00
|
|
|
public static final String[] LANGUAGE_FILE_NAMES = new String[] { "functions.lisp", "dlambda.lisp" };
|
|
|
|
|
2017-03-22 14:08:22 -04:00
|
|
|
public static void main(String[] arguments) {
|
2017-03-21 12:07:22 -04:00
|
|
|
LispMain lispMain = new LispMain();
|
|
|
|
|
2017-03-22 14:08:22 -04:00
|
|
|
if (arguments.length == 0)
|
2017-03-21 12:07:22 -04:00
|
|
|
lispMain.runInteractive();
|
|
|
|
else
|
2017-03-22 14:08:22 -04:00
|
|
|
lispMain.runWithFile(arguments[0]);
|
2017-03-21 12:07:22 -04:00
|
|
|
}
|
|
|
|
|
2017-03-23 12:14:44 -04:00
|
|
|
private LispInterpreterBuilder builder;
|
2017-03-18 16:49:46 -04:00
|
|
|
private PipedInputStream inputReader;
|
2017-03-23 12:14:44 -04:00
|
|
|
private PrintStream output;
|
2017-03-19 12:54:35 -04:00
|
|
|
private LispTerminal lispTerminal;
|
2017-03-23 18:48:37 -04:00
|
|
|
private TerminalConfiguration configuration;
|
2017-02-11 13:33:34 -05:00
|
|
|
|
2017-03-23 12:14:44 -04:00
|
|
|
public LispMain() {
|
|
|
|
this.builder = LispInterpreterBuilderImpl.getInstance();
|
2017-03-21 15:03:16 -04:00
|
|
|
}
|
|
|
|
|
2017-03-23 12:14:44 -04:00
|
|
|
public LispMain(LispInterpreterBuilder builder, TerminalConfiguration configuration) {
|
|
|
|
this.builder = builder;
|
2017-03-23 18:48:37 -04:00
|
|
|
this.configuration = configuration;
|
2017-03-21 15:03:16 -04:00
|
|
|
}
|
|
|
|
|
2017-03-23 12:14:44 -04:00
|
|
|
public void runInteractive() {
|
2017-03-23 18:48:37 -04:00
|
|
|
initializeTerminal();
|
2017-03-23 12:14:44 -04:00
|
|
|
printGreeting();
|
|
|
|
lispTerminal.start();
|
|
|
|
buildInteractiveInterpreter().interpret();
|
|
|
|
shutdownTerminal();
|
2017-03-18 16:49:46 -04:00
|
|
|
}
|
2017-03-17 16:07:25 -04:00
|
|
|
|
2017-03-24 09:29:19 -04:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-21 15:03:16 -04:00
|
|
|
private void printGreeting() {
|
2018-01-20 08:34:31 -05:00
|
|
|
output.println(format(GREETING, getVersion()));
|
2017-03-23 12:14:44 -04:00
|
|
|
output.println();
|
2016-12-17 10:19:18 -05:00
|
|
|
}
|
|
|
|
|
2018-01-20 08:34:31 -05:00
|
|
|
private String getVersion() {
|
|
|
|
return getClass().getPackage().getImplementationVersion();
|
|
|
|
}
|
|
|
|
|
2017-03-21 12:07:22 -04:00
|
|
|
private LispInterpreter buildInteractiveInterpreter() {
|
|
|
|
builder.setInput(inputReader, "terminal");
|
2017-03-23 12:14:44 -04:00
|
|
|
builder.setOutput(output);
|
|
|
|
builder.setErrorOutput(output);
|
|
|
|
builder.setTerminationFunction(this::shutdownTerminal);
|
|
|
|
builder.setErrorTerminationFunction(this::shutdownTerminal);
|
2018-01-21 10:32:55 -05:00
|
|
|
builder.setLanguageFileNames(LANGUAGE_FILE_NAMES);
|
2017-03-22 11:26:53 -04:00
|
|
|
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));
|
2016-12-17 10:19:18 -05:00
|
|
|
|
2017-02-09 11:00:23 -05:00
|
|
|
return builder.build();
|
|
|
|
}
|
|
|
|
|
2017-03-23 12:14:44 -04:00
|
|
|
private void shutdownTerminal() {
|
|
|
|
output.print(END_OF_SEGMENT);
|
2017-03-21 12:07:22 -04:00
|
|
|
lispTerminal.stop();
|
2017-03-23 12:14:44 -04:00
|
|
|
output.close();
|
2017-03-18 16:49:46 -04:00
|
|
|
}
|
|
|
|
|
2017-03-22 14:08:22 -04:00
|
|
|
private Function<String, String> makeColorDecorator(String color) {
|
|
|
|
return new Function<String, String>() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String apply(String s) {
|
|
|
|
return color + s + ANSI_RESET;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-03-23 12:14:44 -04:00
|
|
|
public void runWithFile(String fileName) {
|
2017-03-21 12:07:22 -04:00
|
|
|
buildFileInterpreter(fileName).interpret();
|
2016-12-17 10:19:18 -05:00
|
|
|
}
|
|
|
|
|
2017-03-21 12:07:22 -04:00
|
|
|
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));
|
2018-01-21 10:32:55 -05:00
|
|
|
builder.setLanguageFileNames(LANGUAGE_FILE_NAMES);
|
2017-03-21 12:07:22 -04:00
|
|
|
builder.setValueOutputDecorator(makeColorDecorator(ANSI_GREEN));
|
|
|
|
builder.setWarningOutputDecorator(makeColorDecorator(ANSI_YELLOW));
|
|
|
|
builder.setErrorOutputDecorator(makeColorDecorator(ANSI_RED));
|
|
|
|
builder.setCriticalOutputDecorator(makeColorDecorator(ANSI_PURPLE));
|
2017-02-11 13:33:34 -05:00
|
|
|
|
2017-03-21 12:07:22 -04:00
|
|
|
return builder.build();
|
2017-02-11 13:33:34 -05:00
|
|
|
}
|
2017-03-23 12:14:44 -04:00
|
|
|
|
2016-12-17 10:19:18 -05:00
|
|
|
}
|