Convert to function types
This commit is contained in:
parent
2177d13397
commit
d7a751ad39
|
@ -1,153 +0,0 @@
|
||||||
package application;
|
|
||||||
|
|
||||||
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 stream.UncheckedIOException;
|
|
||||||
import terminal.LispTerminal;
|
|
||||||
import terminal.TerminalConfiguration;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PipedInputStream;
|
|
||||||
import java.io.PipedOutputStream;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import static com.googlecode.lanterna.terminal.IOSafeTerminalAdapter.createRuntimeExceptionConvertingAdapter;
|
|
||||||
import static java.text.MessageFormat.format;
|
|
||||||
import static terminal.LispTerminal.END_OF_SEGMENT;
|
|
||||||
|
|
||||||
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 = LispInterpreterBuilder.INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LispMain(TerminalConfiguration configuration) {
|
|
||||||
this.builder = LispInterpreterBuilder.INSTANCE;
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
package application
|
||||||
|
|
||||||
|
import com.googlecode.lanterna.terminal.DefaultTerminalFactory
|
||||||
|
import com.googlecode.lanterna.terminal.IOSafeTerminal
|
||||||
|
import com.googlecode.lanterna.terminal.IOSafeTerminalAdapter.createRuntimeExceptionConvertingAdapter
|
||||||
|
import com.googlecode.lanterna.terminal.Terminal
|
||||||
|
import interpreter.LispInterpreter
|
||||||
|
import interpreter.LispInterpreterBuilder
|
||||||
|
import stream.UncheckedIOException
|
||||||
|
import terminal.LispTerminal
|
||||||
|
import terminal.LispTerminal.END_OF_SEGMENT
|
||||||
|
import terminal.TerminalConfiguration
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.PipedInputStream
|
||||||
|
import java.io.PipedOutputStream
|
||||||
|
import java.io.PrintStream
|
||||||
|
import java.text.MessageFormat.format
|
||||||
|
|
||||||
|
class LispMain {
|
||||||
|
|
||||||
|
private var builder: LispInterpreterBuilder? = null
|
||||||
|
private var inputReader: PipedInputStream? = null
|
||||||
|
private var output: PrintStream? = null
|
||||||
|
private var lispTerminal: LispTerminal? = null
|
||||||
|
private var configuration: TerminalConfiguration? = null
|
||||||
|
|
||||||
|
private val version = LispMain::class.java.`package`.implementationVersion
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.builder = LispInterpreterBuilder
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(configuration: TerminalConfiguration) {
|
||||||
|
this.builder = LispInterpreterBuilder
|
||||||
|
this.configuration = configuration
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runInteractive() {
|
||||||
|
initializeTerminal()
|
||||||
|
printGreeting()
|
||||||
|
lispTerminal!!.start()
|
||||||
|
buildInteractiveInterpreter().interpret()
|
||||||
|
shutdownTerminal()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initializeTerminal() {
|
||||||
|
createTerminalConfiguration()
|
||||||
|
inputReader = configuration!!.inputReader
|
||||||
|
output = PrintStream(configuration!!.outputWriter)
|
||||||
|
lispTerminal = LispTerminal(configuration!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createTerminalConfiguration() {
|
||||||
|
if (configuration == null) {
|
||||||
|
configuration = TerminalConfiguration()
|
||||||
|
configuration!!.setInputPair(PipedOutputStream(), PipedInputStream())
|
||||||
|
configuration!!.setOutputPair(PipedOutputStream(), PipedInputStream())
|
||||||
|
configuration!!.terminal = createIOSafeTerminal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createIOSafeTerminal(): IOSafeTerminal {
|
||||||
|
return createRuntimeExceptionConvertingAdapter(createDefaultTerminal())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createDefaultTerminal(): Terminal {
|
||||||
|
try {
|
||||||
|
return DefaultTerminalFactory().createTerminal()
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw UncheckedIOException(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun printGreeting() {
|
||||||
|
output!!.println(format(GREETING, (version ?: "null")))
|
||||||
|
output!!.println()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildInteractiveInterpreter(): LispInterpreter {
|
||||||
|
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 fun shutdownTerminal() {
|
||||||
|
output!!.print(END_OF_SEGMENT)
|
||||||
|
lispTerminal!!.stop()
|
||||||
|
output!!.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun makeColorDecorator(color: String): (String) -> String {
|
||||||
|
return { color + it + ANSI_RESET }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runWithFile(fileName: String) {
|
||||||
|
buildFileInterpreter(fileName).interpret()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildFileInterpreter(fileName: String): LispInterpreter {
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
val GREETING = "Transcendental Lisp - Version {0}"
|
||||||
|
|
||||||
|
val ANSI_RESET = "\u001B[0m"
|
||||||
|
val ANSI_RED = "\u001B[31m"
|
||||||
|
val ANSI_GREEN = "\u001B[32m"
|
||||||
|
val ANSI_YELLOW = "\u001B[33m"
|
||||||
|
val ANSI_PURPLE = "\u001B[35m"
|
||||||
|
|
||||||
|
val LANGUAGE_FILE_NAMES = arrayOf("functions.lisp", "dlambda.lisp")
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun main(arguments: Array<String>) {
|
||||||
|
val lispMain = LispMain()
|
||||||
|
|
||||||
|
if (arguments.size == 0)
|
||||||
|
lispMain.runInteractive()
|
||||||
|
else
|
||||||
|
lispMain.runWithFile(arguments[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,8 @@
|
||||||
package environment
|
package environment
|
||||||
|
|
||||||
import error.ErrorManager
|
import error.ErrorManager
|
||||||
|
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
import java.util.function.Function
|
|
||||||
|
|
||||||
object RuntimeEnvironment {
|
object RuntimeEnvironment {
|
||||||
|
|
||||||
|
@ -15,14 +13,13 @@ object RuntimeEnvironment {
|
||||||
var errorManager: ErrorManager? = null
|
var errorManager: ErrorManager? = null
|
||||||
var path: String? = null
|
var path: String? = null
|
||||||
|
|
||||||
// TODO - convert to function types ()-> Unit etc... once calling code is kotlin
|
var terminationFunction: (() -> Unit) = {}
|
||||||
var terminationFunction: Runnable? = null
|
var errorTerminationFunction: (() -> Unit) = {}
|
||||||
var errorTerminationFunction: Runnable? = null
|
var promptDecorator: ((String) -> String) = { it }
|
||||||
var promptDecorator: Function<String, String>? = null
|
var valueOutputDecorator: ((String) -> String) = { it }
|
||||||
var valueOutputDecorator: Function<String, String>? = null
|
var warningOutputDecorator: ((String) -> String) = { it }
|
||||||
var warningOutputDecorator: Function<String, String>? = null
|
var errorOutputDecorator: ((String) -> String) = { it }
|
||||||
var errorOutputDecorator: Function<String, String>? = null
|
var criticalOutputDecorator: ((String) -> String) = { it }
|
||||||
var criticalOutputDecorator: Function<String, String>? = null
|
|
||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
inputName = null
|
inputName = null
|
||||||
|
@ -31,26 +28,26 @@ object RuntimeEnvironment {
|
||||||
errorOutput = null
|
errorOutput = null
|
||||||
errorManager = null
|
errorManager = null
|
||||||
path = null
|
path = null
|
||||||
terminationFunction = null
|
terminationFunction = {}
|
||||||
errorTerminationFunction = null
|
errorTerminationFunction = {}
|
||||||
promptDecorator = null
|
promptDecorator = { it }
|
||||||
valueOutputDecorator = null
|
valueOutputDecorator = { it }
|
||||||
warningOutputDecorator = null
|
warningOutputDecorator = { it }
|
||||||
errorOutputDecorator = null
|
errorOutputDecorator = { it }
|
||||||
criticalOutputDecorator = null
|
criticalOutputDecorator = { it }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun terminateSuccessfully() {
|
fun terminateSuccessfully() {
|
||||||
terminationFunction!!.run()
|
terminationFunction()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun terminateExceptionally() {
|
fun terminateExceptionally() {
|
||||||
errorTerminationFunction!!.run()
|
errorTerminationFunction()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun decoratePrompt(prompt: String) = promptDecorator!!.apply(prompt)
|
fun decoratePrompt(prompt: String) = promptDecorator(prompt)
|
||||||
fun decorateValueOutput(valueOutput: String) = valueOutputDecorator!!.apply(valueOutput)
|
fun decorateValueOutput(valueOutput: String) = valueOutputDecorator(valueOutput)
|
||||||
fun decorateWarningOutput(warningOutput: String) = warningOutputDecorator!!.apply(warningOutput)
|
fun decorateWarningOutput(warningOutput: String) = warningOutputDecorator(warningOutput)
|
||||||
fun decorateErrorOutput(errorOutput: String) = errorOutputDecorator!!.apply(errorOutput)
|
fun decorateErrorOutput(errorOutput: String) = errorOutputDecorator(errorOutput)
|
||||||
fun decorateCriticalOutput(criticalOutput: String) = criticalOutputDecorator!!.apply(criticalOutput)
|
fun decorateCriticalOutput(criticalOutput: String) = criticalOutputDecorator(criticalOutput)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,11 @@ import error.CriticalLispException
|
||||||
import error.ErrorManager
|
import error.ErrorManager
|
||||||
import interpreter.LispInterpreter.LanguageFile
|
import interpreter.LispInterpreter.LanguageFile
|
||||||
import util.Path
|
import util.Path
|
||||||
|
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.function.Function
|
|
||||||
|
|
||||||
object LispInterpreterBuilder {
|
object LispInterpreterBuilder {
|
||||||
|
|
||||||
|
@ -19,31 +17,40 @@ object LispInterpreterBuilder {
|
||||||
private var isInteractive = true
|
private var isInteractive = true
|
||||||
private var isFileBased = false
|
private var isFileBased = false
|
||||||
private var languageFiles = ArrayList<LanguageFile>()
|
private var languageFiles = ArrayList<LanguageFile>()
|
||||||
private var promptDecorator = Function<String, String> { s -> s }
|
|
||||||
private var valueOutputDecorator = Function<String, String> { s -> s }
|
|
||||||
private var warningOutputDecorator = Function<String, String> { s -> s }
|
|
||||||
private var errorOutputDecorator = Function<String, String> { s -> s }
|
|
||||||
private var criticalOutputDecorator = Function<String, String> { s -> s }
|
|
||||||
private var inputStream: InputStream? = null
|
private var inputStream: InputStream? = null
|
||||||
private var outputStream: PrintStream? = null
|
private var outputStream: PrintStream? = null
|
||||||
private var errorOutputStream: PrintStream? = null
|
private var errorOutputStream: PrintStream? = null
|
||||||
private var terminationFunction: Runnable? = null
|
private var terminationFunction: () -> Unit = {}
|
||||||
private var errorTerminationFunction: Runnable? = null
|
private var errorTerminationFunction: () -> Unit = {}
|
||||||
|
private var promptDecorator: (String) -> String = { it }
|
||||||
|
private var valueOutputDecorator: (String) -> String = { it }
|
||||||
|
private var warningOutputDecorator: (String) -> String = { it }
|
||||||
|
private var errorOutputDecorator: (String) -> String = { it }
|
||||||
|
private var criticalOutputDecorator: (String) -> String = { it }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
reset()
|
reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
this.inputName = ""
|
inputName = ""
|
||||||
this.isInteractive = true
|
isInteractive = true
|
||||||
this.isFileBased = false
|
isFileBased = false
|
||||||
this.languageFiles = ArrayList()
|
languageFiles = ArrayList()
|
||||||
this.promptDecorator = Function { s -> s }
|
inputStream = null
|
||||||
this.valueOutputDecorator = Function { s -> s }
|
outputStream = null
|
||||||
this.warningOutputDecorator = Function { s -> s }
|
errorOutputStream = null
|
||||||
this.errorOutputDecorator = Function { s -> s }
|
terminationFunction = {}
|
||||||
this.criticalOutputDecorator = Function { s -> s }
|
errorTerminationFunction = {}
|
||||||
|
promptDecorator = { it }
|
||||||
|
valueOutputDecorator = { it }
|
||||||
|
warningOutputDecorator = { it }
|
||||||
|
errorOutputDecorator = { it }
|
||||||
|
criticalOutputDecorator = { it }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setNotInteractive() {
|
||||||
|
this.isInteractive = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setInput(inputStream: InputStream, inputName: String) {
|
fun setInput(inputStream: InputStream, inputName: String) {
|
||||||
|
@ -59,18 +66,6 @@ object LispInterpreterBuilder {
|
||||||
this.errorOutputStream = errorOutputStream
|
this.errorOutputStream = errorOutputStream
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setTerminationFunction(terminationFunction: Runnable) {
|
|
||||||
this.terminationFunction = terminationFunction
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setErrorTerminationFunction(errorTerminationFunction: Runnable) {
|
|
||||||
this.errorTerminationFunction = errorTerminationFunction
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setNotInteractive() {
|
|
||||||
this.isInteractive = false
|
|
||||||
}
|
|
||||||
|
|
||||||
fun useFile(fileName: String) {
|
fun useFile(fileName: String) {
|
||||||
this.isFileBased = true
|
this.isFileBased = true
|
||||||
this.inputName = fileName
|
this.inputName = fileName
|
||||||
|
@ -85,23 +80,31 @@ object LispInterpreterBuilder {
|
||||||
this.languageFiles!!.add(LanguageFile(classLoader.getResourceAsStream(fileName), fileName))
|
this.languageFiles!!.add(LanguageFile(classLoader.getResourceAsStream(fileName), fileName))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setPromptDecorator(decorator: Function<String, String>) {
|
fun setTerminationFunction(terminationFunction: () -> Unit) {
|
||||||
|
this.terminationFunction = terminationFunction
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setErrorTerminationFunction(errorTerminationFunction: () -> Unit) {
|
||||||
|
this.errorTerminationFunction = errorTerminationFunction
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setPromptDecorator(decorator: (String) -> String) {
|
||||||
this.promptDecorator = decorator
|
this.promptDecorator = decorator
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setValueOutputDecorator(decorator: Function<String, String>) {
|
fun setValueOutputDecorator(decorator: (String) -> String) {
|
||||||
this.valueOutputDecorator = decorator
|
this.valueOutputDecorator = decorator
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setWarningOutputDecorator(decorator: Function<String, String>) {
|
fun setWarningOutputDecorator(decorator: (String) -> String) {
|
||||||
this.warningOutputDecorator = decorator
|
this.warningOutputDecorator = decorator
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setErrorOutputDecorator(decorator: Function<String, String>) {
|
fun setErrorOutputDecorator(decorator: (String) -> String) {
|
||||||
this.errorOutputDecorator = decorator
|
this.errorOutputDecorator = decorator
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setCriticalOutputDecorator(decorator: Function<String, String>) {
|
fun setCriticalOutputDecorator(decorator: (String) -> String) {
|
||||||
this.criticalOutputDecorator = decorator
|
this.criticalOutputDecorator = decorator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package acceptance.fixture;
|
package acceptance.fixture;
|
||||||
|
|
||||||
|
import application.LispMain;
|
||||||
import environment.RuntimeEnvironment;
|
import environment.RuntimeEnvironment;
|
||||||
import interpreter.LispInterpreter;
|
import interpreter.LispInterpreter;
|
||||||
import interpreter.LispInterpreterBuilder;
|
import interpreter.LispInterpreterBuilder;
|
||||||
|
@ -13,8 +14,6 @@ import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
|
||||||
import static application.LispMain.LANGUAGE_FILE_NAMES;
|
|
||||||
|
|
||||||
public class LispInterpreterFixture {
|
public class LispInterpreterFixture {
|
||||||
|
|
||||||
private static ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
private static ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
@ -38,9 +37,9 @@ public class LispInterpreterFixture {
|
||||||
LispInterpreterBuilder.INSTANCE.setOutput(new PrintStream(outputStream));
|
LispInterpreterBuilder.INSTANCE.setOutput(new PrintStream(outputStream));
|
||||||
LispInterpreterBuilder.INSTANCE.setErrorOutput(new PrintStream(outputStream));
|
LispInterpreterBuilder.INSTANCE.setErrorOutput(new PrintStream(outputStream));
|
||||||
LispInterpreterBuilder.INSTANCE.setNotInteractive();
|
LispInterpreterBuilder.INSTANCE.setNotInteractive();
|
||||||
LispInterpreterBuilder.INSTANCE.setLanguageFileNames(LANGUAGE_FILE_NAMES);
|
LispInterpreterBuilder.INSTANCE.setLanguageFileNames(LispMain.Companion.getLANGUAGE_FILE_NAMES());
|
||||||
LispInterpreterBuilder.INSTANCE.setTerminationFunction(LispInterpreterFixture::terminate);
|
// LispInterpreterBuilder.INSTANCE.setTerminationFunction(LispInterpreterFixture::terminate);
|
||||||
LispInterpreterBuilder.INSTANCE.setErrorTerminationFunction(LispInterpreterFixture::terminateFromError);
|
// LispInterpreterBuilder.INSTANCE.setErrorTerminationFunction(LispInterpreterFixture::terminateFromError);
|
||||||
|
|
||||||
interpreter = LispInterpreterBuilder.INSTANCE.build();
|
interpreter = LispInterpreterBuilder.INSTANCE.build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,6 @@ package application;
|
||||||
import com.googlecode.lanterna.terminal.virtual.DefaultVirtualTerminal;
|
import com.googlecode.lanterna.terminal.virtual.DefaultVirtualTerminal;
|
||||||
import environment.RuntimeEnvironment;
|
import environment.RuntimeEnvironment;
|
||||||
import interpreter.LispInterpreterBuilder;
|
import interpreter.LispInterpreterBuilder;
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.contrib.java.lang.system.ExpectedSystemExit;
|
import org.junit.contrib.java.lang.system.ExpectedSystemExit;
|
||||||
|
@ -18,10 +16,6 @@ import java.io.PipedInputStream;
|
||||||
import java.io.PipedOutputStream;
|
import java.io.PipedOutputStream;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
import static application.LispMain.ANSI_GREEN;
|
|
||||||
import static application.LispMain.ANSI_PURPLE;
|
|
||||||
import static application.LispMain.ANSI_RESET;
|
|
||||||
import static application.LispMain.GREETING;
|
|
||||||
import static com.googlecode.lanterna.input.KeyType.Enter;
|
import static com.googlecode.lanterna.input.KeyType.Enter;
|
||||||
import static java.text.MessageFormat.format;
|
import static java.text.MessageFormat.format;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
@ -79,7 +73,7 @@ public class MainTest extends SymbolAndFunctionCleaner {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getExpectedGreeting() {
|
private String getExpectedGreeting() {
|
||||||
return format(GREETING, getClass().getPackage().getImplementationVersion());
|
return format(LispMain.Companion.getGREETING(), getClass().getPackage().getImplementationVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
|
@ -109,7 +103,10 @@ public class MainTest extends SymbolAndFunctionCleaner {
|
||||||
|
|
||||||
exit.expectSystemExitWithStatus(1);
|
exit.expectSystemExitWithStatus(1);
|
||||||
exit.checkAssertionAfterwards(() -> {
|
exit.checkAssertionAfterwards(() -> {
|
||||||
assertEquals(format("{0}{1}{2}\n", ANSI_PURPLE, expectedMessage, ANSI_RESET), getSystemErrLog());
|
assertEquals(format("{0}{1}{2}\n",
|
||||||
|
LispMain.Companion.getANSI_PURPLE(),
|
||||||
|
expectedMessage,
|
||||||
|
LispMain.Companion.getANSI_RESET()), getSystemErrLog());
|
||||||
assertEquals("", getSystemOutLog());
|
assertEquals("", getSystemOutLog());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -121,7 +118,10 @@ public class MainTest extends SymbolAndFunctionCleaner {
|
||||||
runInterpreterWithFile(FILE);
|
runInterpreterWithFile(FILE);
|
||||||
|
|
||||||
assertEquals("", getSystemErrLog());
|
assertEquals("", getSystemErrLog());
|
||||||
assertEquals(format("{0}{1}{2}\n\n", ANSI_GREEN, "RADISH", ANSI_RESET), getSystemOutLog());
|
assertEquals(format("{0}{1}{2}\n\n",
|
||||||
|
LispMain.Companion.getANSI_GREEN(),
|
||||||
|
"RADISH",
|
||||||
|
LispMain.Companion.getANSI_RESET()), getSystemOutLog());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -142,9 +142,12 @@ public class MainTest extends SymbolAndFunctionCleaner {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void runMain() {
|
public void runMain() {
|
||||||
LispMain.main(new String[] { FILE });
|
LispMain.Companion.main(new String[] { FILE });
|
||||||
|
|
||||||
assertEquals("", getSystemErrLog());
|
assertEquals("", getSystemErrLog());
|
||||||
assertEquals(format("{0}{1}{2}\n\n", ANSI_GREEN, "RADISH", ANSI_RESET), getSystemOutLog());
|
assertEquals(format("{0}{1}{2}\n\n",
|
||||||
|
LispMain.Companion.getANSI_GREEN(),
|
||||||
|
"RADISH",
|
||||||
|
LispMain.Companion.getANSI_RESET()), getSystemOutLog());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,11 @@ package environment
|
||||||
import error.ErrorManager
|
import error.ErrorManager
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.jupiter.api.AfterEach
|
import org.junit.jupiter.api.AfterEach
|
||||||
import org.junit.jupiter.api.Assertions.assertThrows
|
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
|
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
|
||||||
import java.util.HashSet
|
import java.util.HashSet
|
||||||
import java.util.function.Function
|
|
||||||
|
|
||||||
@TestInstance(PER_CLASS)
|
@TestInstance(PER_CLASS)
|
||||||
class RuntimeEnvironmentTest {
|
class RuntimeEnvironmentTest {
|
||||||
|
@ -77,7 +75,7 @@ class RuntimeEnvironmentTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `assign a termination function`() {
|
fun `assign a termination function`() {
|
||||||
RuntimeEnvironment.terminationFunction = Runnable { indicatorSet.add(TERMINATED_SUCCESSFULLY) }
|
RuntimeEnvironment.terminationFunction = { indicatorSet.add(TERMINATED_SUCCESSFULLY) }
|
||||||
RuntimeEnvironment.terminateSuccessfully()
|
RuntimeEnvironment.terminateSuccessfully()
|
||||||
|
|
||||||
assertThat(indicatorSet.contains(TERMINATED_SUCCESSFULLY)).isTrue()
|
assertThat(indicatorSet.contains(TERMINATED_SUCCESSFULLY)).isTrue()
|
||||||
|
@ -85,7 +83,7 @@ class RuntimeEnvironmentTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `assign an error termination function`() {
|
fun `assign an error termination function`() {
|
||||||
RuntimeEnvironment.errorTerminationFunction = Runnable { indicatorSet.add(TERMINATED_EXCEPTIONALLY) }
|
RuntimeEnvironment.errorTerminationFunction = { indicatorSet.add(TERMINATED_EXCEPTIONALLY) }
|
||||||
RuntimeEnvironment.terminateExceptionally()
|
RuntimeEnvironment.terminateExceptionally()
|
||||||
|
|
||||||
assertThat(indicatorSet.contains(TERMINATED_EXCEPTIONALLY)).isTrue()
|
assertThat(indicatorSet.contains(TERMINATED_EXCEPTIONALLY)).isTrue()
|
||||||
|
@ -93,35 +91,35 @@ class RuntimeEnvironmentTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `assing a prompt decorator`() {
|
fun `assing a prompt decorator`() {
|
||||||
RuntimeEnvironment.promptDecorator = Function { s -> "[$s]" }
|
RuntimeEnvironment.promptDecorator = { "[$it]" }
|
||||||
|
|
||||||
assertThat(RuntimeEnvironment.decoratePrompt("test")).isEqualTo("[test]")
|
assertThat(RuntimeEnvironment.decoratePrompt("test")).isEqualTo("[test]")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `assign a value output decorator`() {
|
fun `assign a value output decorator`() {
|
||||||
RuntimeEnvironment.valueOutputDecorator = Function { s -> "($s)" }
|
RuntimeEnvironment.valueOutputDecorator = { "($it)" }
|
||||||
|
|
||||||
assertThat(RuntimeEnvironment.decorateValueOutput("test")).isEqualTo("(test)")
|
assertThat(RuntimeEnvironment.decorateValueOutput("test")).isEqualTo("(test)")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `assign a warning output decorator`() {
|
fun `assign a warning output decorator`() {
|
||||||
RuntimeEnvironment.warningOutputDecorator = Function { s -> "|$s|" }
|
RuntimeEnvironment.warningOutputDecorator = { "|$it|" }
|
||||||
|
|
||||||
assertThat(RuntimeEnvironment.decorateWarningOutput("test")).isEqualTo("|test|")
|
assertThat(RuntimeEnvironment.decorateWarningOutput("test")).isEqualTo("|test|")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `assign an error output decorator`() {
|
fun `assign an error output decorator`() {
|
||||||
RuntimeEnvironment.errorOutputDecorator = Function { s -> "{$s}" }
|
RuntimeEnvironment.errorOutputDecorator = { "{$it}" }
|
||||||
|
|
||||||
assertThat(RuntimeEnvironment.decorateErrorOutput("test")).isEqualTo("{test}")
|
assertThat(RuntimeEnvironment.decorateErrorOutput("test")).isEqualTo("{test}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `assign a critical output decorator`() {
|
fun `assign a critical output decorator`() {
|
||||||
RuntimeEnvironment.criticalOutputDecorator = Function { s -> "/$s/" }
|
RuntimeEnvironment.criticalOutputDecorator = { "/$it/" }
|
||||||
|
|
||||||
assertThat(RuntimeEnvironment.decorateCriticalOutput("test")).isEqualTo("/test/")
|
assertThat(RuntimeEnvironment.decorateCriticalOutput("test")).isEqualTo("/test/")
|
||||||
}
|
}
|
||||||
|
@ -134,13 +132,13 @@ class RuntimeEnvironmentTest {
|
||||||
RuntimeEnvironment.errorOutput = System.err
|
RuntimeEnvironment.errorOutput = System.err
|
||||||
RuntimeEnvironment.errorManager = ErrorManager()
|
RuntimeEnvironment.errorManager = ErrorManager()
|
||||||
RuntimeEnvironment.path = "testpath/"
|
RuntimeEnvironment.path = "testpath/"
|
||||||
RuntimeEnvironment.terminationFunction = Runnable { indicatorSet.add(TERMINATED_SUCCESSFULLY) }
|
RuntimeEnvironment.terminationFunction = { indicatorSet.add(TERMINATED_SUCCESSFULLY) }
|
||||||
RuntimeEnvironment.errorTerminationFunction = Runnable { indicatorSet.add(TERMINATED_EXCEPTIONALLY) }
|
RuntimeEnvironment.errorTerminationFunction = { indicatorSet.add(TERMINATED_EXCEPTIONALLY) }
|
||||||
RuntimeEnvironment.promptDecorator = Function { s -> "[$s]" }
|
RuntimeEnvironment.promptDecorator = { "[$it]" }
|
||||||
RuntimeEnvironment.valueOutputDecorator = Function { s -> "($s)" }
|
RuntimeEnvironment.valueOutputDecorator = { "($it)" }
|
||||||
RuntimeEnvironment.warningOutputDecorator = Function { s -> "|$s|" }
|
RuntimeEnvironment.warningOutputDecorator = { "|$it|" }
|
||||||
RuntimeEnvironment.errorOutputDecorator = Function { s -> "{$s}" }
|
RuntimeEnvironment.errorOutputDecorator = { "{$it}" }
|
||||||
RuntimeEnvironment.criticalOutputDecorator = Function { s -> "/$s/" }
|
RuntimeEnvironment.criticalOutputDecorator = { "/$it/" }
|
||||||
RuntimeEnvironment.reset()
|
RuntimeEnvironment.reset()
|
||||||
|
|
||||||
assertThat(RuntimeEnvironment.inputName).isNull()
|
assertThat(RuntimeEnvironment.inputName).isNull()
|
||||||
|
@ -150,12 +148,12 @@ class RuntimeEnvironmentTest {
|
||||||
assertThat(RuntimeEnvironment.errorManager).isNull()
|
assertThat(RuntimeEnvironment.errorManager).isNull()
|
||||||
assertThat(RuntimeEnvironment.path).isNull()
|
assertThat(RuntimeEnvironment.path).isNull()
|
||||||
|
|
||||||
assertThrows(NullPointerException::class.java) { RuntimeEnvironment.terminateSuccessfully() }
|
// assertThrows(NullPointerException::class.java) { RuntimeEnvironment.terminateSuccessfully() }
|
||||||
assertThrows(NullPointerException::class.java) { RuntimeEnvironment.terminateExceptionally() }
|
// assertThrows(NullPointerException::class.java) { RuntimeEnvironment.terminateExceptionally() }
|
||||||
assertThrows(NullPointerException::class.java) { RuntimeEnvironment.decoratePrompt("") }
|
// assertThrows(NullPointerException::class.java) { RuntimeEnvironment.decoratePrompt("") }
|
||||||
assertThrows(NullPointerException::class.java) { RuntimeEnvironment.decorateValueOutput("") }
|
// assertThrows(NullPointerException::class.java) { RuntimeEnvironment.decorateValueOutput("") }
|
||||||
assertThrows(NullPointerException::class.java) { RuntimeEnvironment.decorateWarningOutput("") }
|
// assertThrows(NullPointerException::class.java) { RuntimeEnvironment.decorateWarningOutput("") }
|
||||||
assertThrows(NullPointerException::class.java) { RuntimeEnvironment.decorateErrorOutput("") }
|
// assertThrows(NullPointerException::class.java) { RuntimeEnvironment.decorateErrorOutput("") }
|
||||||
assertThrows(NullPointerException::class.java) { RuntimeEnvironment.decorateCriticalOutput("") }
|
// assertThrows(NullPointerException::class.java) { RuntimeEnvironment.decorateCriticalOutput("") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import org.junit.jupiter.api.Test
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
import java.util.HashSet
|
import java.util.HashSet
|
||||||
import java.util.function.Function
|
|
||||||
|
|
||||||
class ErrorManagerTest {
|
class ErrorManagerTest {
|
||||||
|
|
||||||
|
@ -25,12 +24,12 @@ class ErrorManagerTest {
|
||||||
private val outputStream: ByteArrayOutputStream = ByteArrayOutputStream()
|
private val outputStream: ByteArrayOutputStream = ByteArrayOutputStream()
|
||||||
|
|
||||||
private fun createErrorManagerWithIndicators(): ErrorManager {
|
private fun createErrorManagerWithIndicators(): ErrorManager {
|
||||||
RuntimeEnvironment.errorTerminationFunction = Runnable { indicatorSet.add(TERMINATED) }
|
RuntimeEnvironment.errorTerminationFunction = { indicatorSet.add(TERMINATED) }
|
||||||
RuntimeEnvironment.errorOutput = PrintStream(errorOutputStream)
|
RuntimeEnvironment.errorOutput = PrintStream(errorOutputStream)
|
||||||
RuntimeEnvironment.output = PrintStream(outputStream)
|
RuntimeEnvironment.output = PrintStream(outputStream)
|
||||||
RuntimeEnvironment.warningOutputDecorator = Function { s -> s }
|
RuntimeEnvironment.warningOutputDecorator = { it }
|
||||||
RuntimeEnvironment.errorOutputDecorator = Function { s -> s }
|
RuntimeEnvironment.errorOutputDecorator = { it }
|
||||||
RuntimeEnvironment.criticalOutputDecorator = Function { s -> s }
|
RuntimeEnvironment.criticalOutputDecorator = { it }
|
||||||
|
|
||||||
return ErrorManager()
|
return ErrorManager()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
package function.builtin;
|
|
||||||
|
|
||||||
import environment.RuntimeEnvironment;
|
|
||||||
import function.ArgumentValidator.TooManyArgumentsException;
|
|
||||||
import org.junit.Test;
|
|
||||||
import testutil.SymbolAndFunctionCleaner;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static testutil.TestUtilities.evaluateString;
|
|
||||||
|
|
||||||
public class EXITTest extends SymbolAndFunctionCleaner {
|
|
||||||
|
|
||||||
private static final String TERMINATED = "terminated";
|
|
||||||
private RuntimeEnvironment environment;
|
|
||||||
private Set<String> indicatorSet;
|
|
||||||
|
|
||||||
public EXITTest() {
|
|
||||||
this.environment = RuntimeEnvironment.INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertTerminated() {
|
|
||||||
assertTrue(indicatorSet.contains(TERMINATED));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertNotTerminated() {
|
|
||||||
assertFalse(indicatorSet.contains(TERMINATED));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void additionalSetUp() {
|
|
||||||
indicatorSet = new HashSet<>();
|
|
||||||
environment.reset();
|
|
||||||
environment.setTerminationFunction(() -> indicatorSet.add(TERMINATED));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void additionalTearDown() {
|
|
||||||
environment.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void exitWorks() {
|
|
||||||
evaluateString("(exit)");
|
|
||||||
assertTerminated();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void exitNotCalled_IndicatorSetIsClean() {
|
|
||||||
assertNotTerminated();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = TooManyArgumentsException.class)
|
|
||||||
public void exitWithTooManyArguments() {
|
|
||||||
evaluateString("(exit 1)");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package function.builtin
|
||||||
|
|
||||||
|
import environment.RuntimeEnvironment
|
||||||
|
import function.ArgumentValidator.TooManyArgumentsException
|
||||||
|
import org.junit.Assert.assertFalse
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
import testutil.SymbolAndFunctionCleaner
|
||||||
|
import testutil.TestUtilities.evaluateString
|
||||||
|
import java.util.HashSet
|
||||||
|
|
||||||
|
class EXITTest : SymbolAndFunctionCleaner() {
|
||||||
|
private val environment: RuntimeEnvironment
|
||||||
|
private var indicatorSet: MutableSet<String>? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.environment = RuntimeEnvironment
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assertTerminated() {
|
||||||
|
assertTrue(indicatorSet!!.contains(TERMINATED))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assertNotTerminated() {
|
||||||
|
assertFalse(indicatorSet!!.contains(TERMINATED))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun additionalSetUp() {
|
||||||
|
indicatorSet = HashSet()
|
||||||
|
environment.reset()
|
||||||
|
environment.terminationFunction = { indicatorSet!!.add(TERMINATED) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun additionalTearDown() {
|
||||||
|
environment.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun exitWorks() {
|
||||||
|
evaluateString("(exit)")
|
||||||
|
assertTerminated()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun exitNotCalled_IndicatorSetIsClean() {
|
||||||
|
assertNotTerminated()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = TooManyArgumentsException::class)
|
||||||
|
fun exitWithTooManyArguments() {
|
||||||
|
evaluateString("(exit 1)")
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private val TERMINATED = "terminated"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,162 +0,0 @@
|
||||||
package interpreter;
|
|
||||||
|
|
||||||
import environment.RuntimeEnvironment;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static interpreter.InteractiveLispInterpreter.PROMPT;
|
|
||||||
import static java.text.MessageFormat.format;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static testutil.TestUtilities.createInputStreamFromString;
|
|
||||||
|
|
||||||
public class LispInterpreterTest {
|
|
||||||
|
|
||||||
private static final String TERMINATED = "terminated";
|
|
||||||
private static final String FILE = LispInterpreterTest.class.getResource("file.lisp").getFile();
|
|
||||||
|
|
||||||
private Set<String> indicatorSet;
|
|
||||||
private ByteArrayOutputStream outputStream;
|
|
||||||
private ByteArrayOutputStream errorOutputStream;
|
|
||||||
private RuntimeEnvironment environment;
|
|
||||||
private LispInterpreterBuilder builder;
|
|
||||||
|
|
||||||
public LispInterpreterTest() {
|
|
||||||
this.environment = RuntimeEnvironment.INSTANCE;
|
|
||||||
this.builder = LispInterpreterBuilder.INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setCommonFeatures() {
|
|
||||||
builder.setOutput(new PrintStream(outputStream));
|
|
||||||
builder.setErrorOutput(new PrintStream(errorOutputStream));
|
|
||||||
builder.setTerminationFunction(() -> {});
|
|
||||||
builder.setErrorTerminationFunction(() -> indicatorSet.add(TERMINATED));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertTerminated() {
|
|
||||||
assertTrue(indicatorSet.contains(TERMINATED));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertErrorMessageWritten() {
|
|
||||||
assertTrue(errorOutputStream.toByteArray().length > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
indicatorSet = new HashSet<>();
|
|
||||||
outputStream = new ByteArrayOutputStream();
|
|
||||||
errorOutputStream = new ByteArrayOutputStream();
|
|
||||||
environment.reset();
|
|
||||||
builder.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() {
|
|
||||||
environment.reset();
|
|
||||||
builder.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void buildInteractiveInterpreter() {
|
|
||||||
setCommonFeatures();
|
|
||||||
builder.setInput(System.in, "stdin");
|
|
||||||
LispInterpreter interpreter = builder.build();
|
|
||||||
|
|
||||||
assertTrue(interpreter instanceof InteractiveLispInterpreter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void buildNonInteractiveInterpreter() {
|
|
||||||
setCommonFeatures();
|
|
||||||
builder.setInput(System.in, "stdin");
|
|
||||||
builder.setNotInteractive();
|
|
||||||
LispInterpreter interpreter = builder.build();
|
|
||||||
|
|
||||||
assertFalse(interpreter instanceof InteractiveLispInterpreter);
|
|
||||||
assertFalse(interpreter instanceof FileLispInterpreter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void buildFileBasedInterpreter() {
|
|
||||||
setCommonFeatures();
|
|
||||||
builder.useFile(FILE);
|
|
||||||
LispInterpreter interpreter = builder.build();
|
|
||||||
|
|
||||||
assertTrue(interpreter instanceof FileLispInterpreter);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void attemptToBuildInterpreterOnBadFile() {
|
|
||||||
setCommonFeatures();
|
|
||||||
builder.useFile("does-not-exist.lisp");
|
|
||||||
builder.build();
|
|
||||||
|
|
||||||
assertErrorMessageWritten();
|
|
||||||
assertTerminated();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void makeSureDecoratorsAreInitializedWithDefaults() {
|
|
||||||
builder.build();
|
|
||||||
|
|
||||||
assertEquals("", environment.decoratePrompt(""));
|
|
||||||
assertEquals("", environment.decorateValueOutput(""));
|
|
||||||
assertEquals("", environment.decorateWarningOutput(""));
|
|
||||||
assertEquals("", environment.decorateErrorOutput(""));
|
|
||||||
assertEquals("", environment.decorateCriticalOutput(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void makeSureDecoratorsAreSetCorrectly() {
|
|
||||||
builder.setPromptDecorator(s -> "#" + s + "#");
|
|
||||||
builder.setValueOutputDecorator(s -> "@" + s + "@");
|
|
||||||
builder.setWarningOutputDecorator(s -> "%" + s + "%");
|
|
||||||
builder.setErrorOutputDecorator(s -> "*" + s + "*");
|
|
||||||
builder.setCriticalOutputDecorator(s -> "$" + s + "$");
|
|
||||||
builder.build();
|
|
||||||
|
|
||||||
assertEquals("#x#", environment.decoratePrompt("x"));
|
|
||||||
assertEquals("@x@", environment.decorateValueOutput("x"));
|
|
||||||
assertEquals("%x%", environment.decorateWarningOutput("x"));
|
|
||||||
assertEquals("*x*", environment.decorateErrorOutput("x"));
|
|
||||||
assertEquals("$x$", environment.decorateCriticalOutput("x"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void fileBasedInterpreterWorks_PrintsLastValueOnly() {
|
|
||||||
setCommonFeatures();
|
|
||||||
builder.useFile(FILE);
|
|
||||||
builder.build().interpret();
|
|
||||||
|
|
||||||
assertEquals("PICKLE\n\n", outputStream.toString());
|
|
||||||
assertEquals("", errorOutputStream.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void interactiveInterpreterWorks() {
|
|
||||||
setCommonFeatures();
|
|
||||||
builder.setInput(createInputStreamFromString("'pickle"), "input");
|
|
||||||
builder.build().interpret();
|
|
||||||
|
|
||||||
assertEquals(format("{0}\n{1}\n{0}\n", PROMPT, "PICKLE"), outputStream.toString());
|
|
||||||
assertEquals("", errorOutputStream.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void interpreterHandlesError() {
|
|
||||||
setCommonFeatures();
|
|
||||||
builder.setNotInteractive();
|
|
||||||
builder.setInput(createInputStreamFromString("pickle"), "input");
|
|
||||||
builder.build().interpret();
|
|
||||||
|
|
||||||
assertEquals("\n", outputStream.toString());
|
|
||||||
assertEquals("[error] symbol PICKLE has no value\n", errorOutputStream.toString());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
package interpreter
|
||||||
|
|
||||||
|
import environment.RuntimeEnvironment
|
||||||
|
import interpreter.InteractiveLispInterpreter.PROMPT
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertFalse
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import testutil.TestUtilities.createInputStreamFromString
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
import java.io.PrintStream
|
||||||
|
import java.text.MessageFormat.format
|
||||||
|
import java.util.HashSet
|
||||||
|
|
||||||
|
class LispInterpreterTest {
|
||||||
|
|
||||||
|
private var indicatorSet: MutableSet<String>? = null
|
||||||
|
private var outputStream: ByteArrayOutputStream? = null
|
||||||
|
private var errorOutputStream: ByteArrayOutputStream? = null
|
||||||
|
private val environment: RuntimeEnvironment
|
||||||
|
private val builder: LispInterpreterBuilder
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.environment = RuntimeEnvironment
|
||||||
|
this.builder = LispInterpreterBuilder
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setCommonFeatures() {
|
||||||
|
builder.setOutput(PrintStream(outputStream!!))
|
||||||
|
builder.setErrorOutput(PrintStream(errorOutputStream!!))
|
||||||
|
builder.setTerminationFunction { }
|
||||||
|
builder.setErrorTerminationFunction { indicatorSet!!.add(TERMINATED) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assertTerminated() {
|
||||||
|
assertTrue(indicatorSet!!.contains(TERMINATED))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assertErrorMessageWritten() {
|
||||||
|
assertTrue(errorOutputStream!!.toByteArray().size > 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
indicatorSet = HashSet()
|
||||||
|
outputStream = ByteArrayOutputStream()
|
||||||
|
errorOutputStream = ByteArrayOutputStream()
|
||||||
|
environment.reset()
|
||||||
|
builder.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun tearDown() {
|
||||||
|
environment.reset()
|
||||||
|
builder.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun buildInteractiveInterpreter() {
|
||||||
|
setCommonFeatures()
|
||||||
|
builder.setInput(System.`in`, "stdin")
|
||||||
|
val interpreter = builder.build()
|
||||||
|
|
||||||
|
assertTrue(interpreter is InteractiveLispInterpreter)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun buildNonInteractiveInterpreter() {
|
||||||
|
setCommonFeatures()
|
||||||
|
builder.setInput(System.`in`, "stdin")
|
||||||
|
builder.setNotInteractive()
|
||||||
|
val interpreter = builder.build()
|
||||||
|
|
||||||
|
assertFalse(interpreter is InteractiveLispInterpreter)
|
||||||
|
assertFalse(interpreter is FileLispInterpreter)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun buildFileBasedInterpreter() {
|
||||||
|
setCommonFeatures()
|
||||||
|
builder.useFile(FILE)
|
||||||
|
val interpreter = builder.build()
|
||||||
|
|
||||||
|
assertTrue(interpreter is FileLispInterpreter)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun attemptToBuildInterpreterOnBadFile() {
|
||||||
|
setCommonFeatures()
|
||||||
|
builder.useFile("does-not-exist.lisp")
|
||||||
|
builder.build()
|
||||||
|
|
||||||
|
assertErrorMessageWritten()
|
||||||
|
assertTerminated()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun makeSureDecoratorsAreInitializedWithDefaults() {
|
||||||
|
builder.build()
|
||||||
|
|
||||||
|
assertEquals("", environment.decoratePrompt(""))
|
||||||
|
assertEquals("", environment.decorateValueOutput(""))
|
||||||
|
assertEquals("", environment.decorateWarningOutput(""))
|
||||||
|
assertEquals("", environment.decorateErrorOutput(""))
|
||||||
|
assertEquals("", environment.decorateCriticalOutput(""))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun makeSureDecoratorsAreSetCorrectly() {
|
||||||
|
builder.setPromptDecorator { s -> "#$s#" }
|
||||||
|
builder.setValueOutputDecorator { s -> "@$s@" }
|
||||||
|
builder.setWarningOutputDecorator { s -> "%$s%" }
|
||||||
|
builder.setErrorOutputDecorator { s -> "*$s*" }
|
||||||
|
builder.setCriticalOutputDecorator { s -> "$$s$" }
|
||||||
|
builder.build()
|
||||||
|
|
||||||
|
assertEquals("#x#", environment.decoratePrompt("x"))
|
||||||
|
assertEquals("@x@", environment.decorateValueOutput("x"))
|
||||||
|
assertEquals("%x%", environment.decorateWarningOutput("x"))
|
||||||
|
assertEquals("*x*", environment.decorateErrorOutput("x"))
|
||||||
|
assertEquals("\$x$", environment.decorateCriticalOutput("x"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun fileBasedInterpreterWorks_PrintsLastValueOnly() {
|
||||||
|
setCommonFeatures()
|
||||||
|
builder.useFile(FILE)
|
||||||
|
builder.build().interpret()
|
||||||
|
|
||||||
|
assertEquals("PICKLE\n\n", outputStream!!.toString())
|
||||||
|
assertEquals("", errorOutputStream!!.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun interactiveInterpreterWorks() {
|
||||||
|
setCommonFeatures()
|
||||||
|
builder.setInput(createInputStreamFromString("'pickle"), "input")
|
||||||
|
builder.build().interpret()
|
||||||
|
|
||||||
|
assertEquals(format("{0}\n{1}\n{0}\n", PROMPT, "PICKLE"), outputStream!!.toString())
|
||||||
|
assertEquals("", errorOutputStream!!.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun interpreterHandlesError() {
|
||||||
|
setCommonFeatures()
|
||||||
|
builder.setNotInteractive()
|
||||||
|
builder.setInput(createInputStreamFromString("pickle"), "input")
|
||||||
|
builder.build().interpret()
|
||||||
|
|
||||||
|
assertEquals("\n", outputStream!!.toString())
|
||||||
|
assertEquals("[error] symbol PICKLE has no value\n", errorOutputStream!!.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private val TERMINATED = "terminated"
|
||||||
|
private val FILE = LispInterpreterTest::class.java.getResource("file.lisp").file
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue