transcendental-lisp/src/main/java/table/ExecutionContext.java

130 lines
2.9 KiB
Java

package table;
import function.LispFunction;
import sexpression.Cons;
import sexpression.SExpression;
import java.util.Stack;
import static sexpression.Nil.NIL;
public class ExecutionContext {
private static ExecutionContext uniqueInstance = new ExecutionContext();
public static ExecutionContext getInstance() {
return uniqueInstance;
}
private SymbolTable scope;
private Stack<LispFunctionRecurInfo> functionCalls;
private boolean recur;
private ExecutionContext() {
clearContext();
}
public void clearContext() {
this.scope = new SymbolTable();
this.functionCalls = new Stack<>();
this.clearRecur();
}
public SymbolTable getScope() {
return scope;
}
public void setScope(SymbolTable scope) {
this.scope = scope;
}
public void restoreGlobalScope() {
while (!scope.isGlobal())
scope = scope.getParent();
}
public SExpression lookupSymbolValue(String symbolName) {
for (SymbolTable t = scope; t != null; t = t.getParent())
if (t.contains(symbolName))
return t.get(symbolName);
return null;
}
public Cons toList() {
Cons symbols = NIL;
for (SymbolTable t = scope; t != null; t = t.getParent())
symbols = new Cons(t.toList(), symbols);
return symbols;
}
public void pushFunctionCall(LispFunction function) {
functionCalls.push(new LispFunctionRecurInfo(function));
}
public void popFunctionCall() {
functionCalls.pop();
}
public boolean isInFunctionCall() {
return !functionCalls.empty();
}
public LispFunction getCurrentFunction() {
return functionCalls.peek().getLispFunction();
}
public boolean isRecur() {
return recur;
}
public void setRecur() {
recur = true;
}
public void clearRecur() {
recur = false;
}
public boolean isRecurInitializing() {
return functionCalls.peek().isRecurInitializing();
}
public void setRecurInitializing() {
functionCalls.peek().setRecurInitializing();
}
public void clearRecurInitializing() {
functionCalls.peek().clearRecurInitializing();
}
public static class LispFunctionRecurInfo {
private LispFunction lispFunction;
private boolean recurInitializing;
public LispFunctionRecurInfo(LispFunction lispFunction) {
this.lispFunction = lispFunction;
this.clearRecurInitializing();
}
public boolean isRecurInitializing() {
return recurInitializing;
}
public void setRecurInitializing() {
this.recurInitializing = true;
}
public void clearRecurInitializing() {
this.recurInitializing = false;
}
public LispFunction getLispFunction() {
return lispFunction;
}
}
}