package main; import static terminal.LispTerminal.END_OF_SEGMENT; import java.io.*; import java.util.function.Function; import com.googlecode.lanterna.terminal.*; import interpreter.*; import terminal.LispTerminal; public class LispMain { private static final String ANSI_RESET = "\u001B[0m"; private static final String ANSI_RED = "\u001B[31m"; private static final String ANSI_GREEN = "\u001B[32m"; private static final String ANSI_YELLOW = "\u001B[33m"; private static final String ANSI_PURPLE = "\u001B[35m"; private PipedInputStream inputReader; private PipedOutputStream inputWriter; private PipedInputStream outputReader; private PipedOutputStream outputWriter; private LispTerminal lispTerminal; private LispMain() throws IOException { inputReader = new PipedInputStream(); inputWriter = new PipedOutputStream(inputReader); outputReader = new PipedInputStream(); outputWriter = new PipedOutputStream(outputReader); lispTerminal = new LispTerminal(createIOSafeTerminal(), inputWriter, outputReader); } private IOSafeTerminal createIOSafeTerminal() throws IOException { return IOSafeTerminalAdapter.createRuntimeExceptionConvertingAdapter(new DefaultTerminalFactory().createTerminal()); } public static void main(String[] args) throws IOException { new LispMain().run(args); } private void run(String[] args) { if (args.length == 0) lispTerminal.run(); LispInterpreter interpreter = buildInterpreter(args); interpreter.interpret(); } private LispInterpreter buildInterpreter(String[] args) { LispInterpreterBuilder builder = LispInterpreterBuilderImpl.getInstance(); configureInput(args, builder); configureOutput(args, builder); configureTerminatingFunctions(args, builder); configureDecorators(args, builder); return builder.build(); } private void configureTerminatingFunctions(String[] args, LispInterpreterBuilder builder) { if (args.length > 0) { builder.setTerminationFunction(() -> System.exit(0)); builder.setErrorTerminationFunction(() -> System.exit(1)); } else { builder.setTerminationFunction(this::shutdown); builder.setErrorTerminationFunction(this::shutdown); } } private void configureDecorators(String[] args, LispInterpreterBuilder builder) { if (args.length > 0) { builder.setOutputDecorator(makeColorDecorator(ANSI_GREEN)); builder.setValueOutputDecorator(makeColorDecorator(ANSI_GREEN)); builder.setWarningOutputDecorator(makeColorDecorator(ANSI_YELLOW)); builder.setErrorOutputDecorator(makeColorDecorator(ANSI_RED)); builder.setCriticalOutputDecorator(makeColorDecorator(ANSI_PURPLE)); } else { builder.setOutputDecorator(makeInteractiveDecorator(ANSI_GREEN)); builder.setValueOutputDecorator(makeInteractiveDecorator(ANSI_GREEN)); builder.setWarningOutputDecorator(makeInteractiveDecorator(ANSI_YELLOW)); builder.setErrorOutputDecorator(makeInteractiveDecorator(ANSI_RED)); builder.setCriticalOutputDecorator(makeInteractiveDecorator(ANSI_PURPLE)); } } private void shutdown() { try { lispTerminal.finish(); outputWriter.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void configureOutput(String[] args, LispInterpreterBuilder builder) { if (args.length > 0) { builder.setOutput(System.out); builder.setErrorOutput(System.err); } else { PrintStream outputStream = new PrintStream(outputWriter); builder.setOutput(outputStream); builder.setErrorOutput(outputStream); } } private void configureInput(String[] args, LispInterpreterBuilder builder) { if (args.length > 0) builder.useFile(args[0]); else builder.setInput(inputReader, "stdin"); } private static Function makeColorDecorator(String color) { return new Function() { @Override public String apply(String s) { return color + s + ANSI_RESET; } }; } private static Function makeInteractiveDecorator(String color) { return new Function() { @Override public String apply(String s) { return s + END_OF_SEGMENT; } }; } }