transcendental-lisp/src/main/kotlin/interpreter/LispInterpreter.java

94 lines
2.4 KiB
Java

package interpreter;
import environment.RuntimeEnvironment;
import error.LispException;
import parser.LispParser;
import sexpression.SExpression;
import java.io.InputStream;
import java.util.List;
import static function.builtin.EVAL.eval;
public class LispInterpreter {
protected RuntimeEnvironment environment;
private LispParser parser;
public LispInterpreter() {
this.environment = RuntimeEnvironment.INSTANCE;
}
public void interpretLanguageFiles(List<LanguageFile> languageFiles) {
for (LanguageFile file : languageFiles) {
LispParser languageParser = new LispParser(file.getInputStream(), file.getName());
while (!languageParser.isEof())
eval(languageParser.nextSExpression());
}
}
public void interpret() {
createParser();
for (prompt(); !parser.isEof(); prompt())
evaluateAndPrintNextSExpression();
applyFinishingTouches();
}
private void createParser() {
parser = new LispParser(environment.getInput(), environment.getInputName());
}
protected void prompt() {}
protected void evaluateAndPrintNextSExpression() {
try {
evaluateAndPrintNextSExpressionWithException();
} catch (LispException e) {
environment.getErrorManager().handle(e);
}
}
private void evaluateAndPrintNextSExpressionWithException() {
printSExpression(evaluateNextSExpression());
}
protected SExpression evaluateNextSExpression() {
SExpression sExpression = parser.nextSExpression();
return eval(sExpression);
}
protected void printSExpression(SExpression sExpression) {
String result = environment.decorateValueOutput(String.valueOf(sExpression));
environment.getOutput().println(result);
environment.getOutput().flush();
}
protected void applyFinishingTouches() {
environment.getOutput().println();
environment.getOutput().flush();
}
public static class LanguageFile {
private InputStream inputStream;
private String name;
public LanguageFile(InputStream inputStream, String name) {
this.inputStream = inputStream;
this.name = "lang:" + name;
}
public InputStream getInputStream() {
return inputStream;
}
public String getName() {
return name;
}
}
}