Convert ExecutionContext to kotlin
This commit is contained in:
parent
04a4164c1b
commit
91c4070b53
|
@ -34,7 +34,7 @@ public class UserDefinedFunction extends LispFunction {
|
|||
this.name = name;
|
||||
this.body = body;
|
||||
this.lambdaExpression = new Cons(new Symbol(name), new Cons(lambdaList, body));
|
||||
this.executionContext = ExecutionContext.getInstance();
|
||||
this.executionContext = ExecutionContext.INSTANCE;
|
||||
this.functionScope = executionContext.getScope();
|
||||
this.keywordRestParameter = null;
|
||||
this.isKeywordRestPresent = false;
|
||||
|
|
|
@ -14,6 +14,7 @@ import sexpression.Symbol;
|
|||
import table.ExecutionContext;
|
||||
|
||||
import static function.builtin.cons.LIST.makeList;
|
||||
import static function.builtin.special.LAMBDA.Lambda;
|
||||
import static java.text.MessageFormat.format;
|
||||
import static sexpression.Nil.NIL;
|
||||
import static sexpression.Symbol.T;
|
||||
|
@ -22,7 +23,7 @@ import static table.FunctionTable.lookupFunction;
|
|||
@FunctionNames({ "EVAL" })
|
||||
public class EVAL extends LispFunction {
|
||||
|
||||
private static ExecutionContext executionContext = ExecutionContext.getInstance();
|
||||
private static ExecutionContext executionContext = ExecutionContext.INSTANCE;
|
||||
|
||||
public static SExpression eval(SExpression sExpression) {
|
||||
Cons argumentList = makeList(sExpression);
|
||||
|
@ -59,8 +60,8 @@ public class EVAL extends LispFunction {
|
|||
private static LispFunction createLambdaFunction(SExpression lambdaExpression) {
|
||||
if (lambdaExpression.isFunction())
|
||||
return ((LambdaExpression) lambdaExpression).getFunction();
|
||||
else if (LAMBDA.Companion.isLambdaExpression(lambdaExpression))
|
||||
return LAMBDA.Companion.createFunction((Cons) lambdaExpression);
|
||||
else if (Lambda.isLambdaExpression(lambdaExpression))
|
||||
return Lambda.createFunction((Cons) lambdaExpression);
|
||||
else
|
||||
throw new UndefinedFunctionException(lambdaExpression);
|
||||
}
|
||||
|
@ -73,7 +74,7 @@ public class EVAL extends LispFunction {
|
|||
else if (symbolName.startsWith(":"))
|
||||
return new Symbol(symbolName);
|
||||
|
||||
return ExecutionContext.getInstance().lookupSymbolValue(symbolName);
|
||||
return ExecutionContext.INSTANCE.lookupSymbolValue(symbolName);
|
||||
}
|
||||
|
||||
private ArgumentValidator argumentValidator;
|
||||
|
|
|
@ -25,7 +25,7 @@ public class SET extends LispFunction {
|
|||
this.argumentValidator = new ArgumentValidator(name);
|
||||
this.argumentValidator.setExactNumberOfArguments(2);
|
||||
this.argumentValidator.setFirstArgumentExpectedType(Symbol.class);
|
||||
this.executionContext = ExecutionContext.getInstance();
|
||||
this.executionContext = ExecutionContext.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,7 +16,7 @@ public class SYMBOLS extends LispFunction {
|
|||
public SYMBOLS(String name) {
|
||||
this.argumentValidator = new ArgumentValidator(name);
|
||||
this.argumentValidator.setExactNumberOfArguments(0);
|
||||
this.executionContext = ExecutionContext.getInstance();
|
||||
this.executionContext = ExecutionContext.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -40,7 +40,7 @@ class LAMBDA(name: String) : LispSpecialFunction() {
|
|||
return Cons(Symbol("LAMBDA"), argumentList)
|
||||
}
|
||||
|
||||
companion object {
|
||||
companion object Lambda {
|
||||
|
||||
fun isLambdaExpression(sexpr: SExpression): Boolean {
|
||||
if (sexpr.isCons) {
|
||||
|
|
|
@ -33,7 +33,7 @@ public class LET extends LispSpecialFunction {
|
|||
this.pairValidator.setMaximumNumberOfArguments(2);
|
||||
this.pairValidator.setFirstArgumentExpectedType(Symbol.class);
|
||||
|
||||
this.executionContext = ExecutionContext.getInstance();
|
||||
this.executionContext = ExecutionContext.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -18,7 +18,7 @@ public class RECUR extends LispSpecialFunction {
|
|||
|
||||
public RECUR(String name) {
|
||||
this.argumentValidator = new ArgumentValidator(name);
|
||||
this.executionContext = ExecutionContext.getInstance();
|
||||
this.executionContext = ExecutionContext.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,129 +0,0 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package table
|
||||
|
||||
import function.LispFunction
|
||||
import sexpression.Cons
|
||||
import sexpression.SExpression
|
||||
|
||||
import java.util.Stack
|
||||
|
||||
import sexpression.Nil.NIL
|
||||
|
||||
object ExecutionContext {
|
||||
|
||||
private val functionCalls: Stack<LispFunctionRecurInfo> = Stack()
|
||||
|
||||
var scope: SymbolTable = SymbolTable(NullSymbolTable)
|
||||
var isRecur: Boolean = false
|
||||
private set
|
||||
|
||||
val isInFunctionCall: Boolean
|
||||
get() = !functionCalls.empty()
|
||||
|
||||
val currentFunction: LispFunction
|
||||
get() = functionCalls.peek().lispFunction
|
||||
|
||||
val isRecurInitializing: Boolean
|
||||
get() = functionCalls.peek().isRecurInitializing
|
||||
|
||||
fun clearContext() {
|
||||
scope = SymbolTable(NullSymbolTable)
|
||||
functionCalls.clear()
|
||||
clearRecur()
|
||||
}
|
||||
|
||||
fun restoreGlobalScope() {
|
||||
while (!scope.isGlobal)
|
||||
scope = scope.parent
|
||||
}
|
||||
|
||||
fun lookupSymbolValue(symbolName: String): SExpression? {
|
||||
var t = scope
|
||||
while (t !== NullSymbolTable) {
|
||||
if (t.contains(symbolName))
|
||||
return t.get(symbolName)
|
||||
|
||||
t = t.parent
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun toList(): Cons {
|
||||
var symbols: Cons = NIL
|
||||
|
||||
var t = scope
|
||||
while (t !== NullSymbolTable) {
|
||||
symbols = Cons(t.toList(), symbols)
|
||||
t = t.parent
|
||||
}
|
||||
|
||||
return symbols
|
||||
}
|
||||
|
||||
fun pushFunctionCall(function: LispFunction) {
|
||||
functionCalls.push(LispFunctionRecurInfo(function))
|
||||
}
|
||||
|
||||
fun popFunctionCall() {
|
||||
functionCalls.pop()
|
||||
}
|
||||
|
||||
fun setRecur() {
|
||||
isRecur = true
|
||||
}
|
||||
|
||||
fun clearRecur() {
|
||||
isRecur = false
|
||||
}
|
||||
|
||||
fun setRecurInitializing() {
|
||||
functionCalls.peek().setRecurInitializing()
|
||||
}
|
||||
|
||||
fun clearRecurInitializing() {
|
||||
functionCalls.peek().clearRecurInitializing()
|
||||
}
|
||||
|
||||
class LispFunctionRecurInfo(val lispFunction: LispFunction) {
|
||||
var isRecurInitializing: Boolean = false
|
||||
private set
|
||||
|
||||
fun setRecurInitializing() {
|
||||
isRecurInitializing = true
|
||||
}
|
||||
|
||||
fun clearRecurInitializing() {
|
||||
isRecurInitializing = false
|
||||
}
|
||||
}
|
||||
|
||||
object NullSymbolTable : SymbolTable()
|
||||
}
|
|
@ -3,6 +3,7 @@ package table;
|
|||
import sexpression.Cons;
|
||||
import sexpression.SExpression;
|
||||
import sexpression.Symbol;
|
||||
import table.ExecutionContext.NullSymbolTable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
@ -19,7 +20,7 @@ public class SymbolTable {
|
|||
private SymbolTable parent;
|
||||
|
||||
public SymbolTable() {
|
||||
this(null);
|
||||
this(NullSymbolTable.INSTANCE);
|
||||
}
|
||||
|
||||
public SymbolTable(SymbolTable parent) {
|
||||
|
@ -44,7 +45,7 @@ public class SymbolTable {
|
|||
}
|
||||
|
||||
public boolean isGlobal() {
|
||||
return parent == null;
|
||||
return parent == NullSymbolTable.INSTANCE;
|
||||
}
|
||||
|
||||
public Cons toList() {
|
||||
|
|
|
@ -19,7 +19,7 @@ import static util.Path.getPathPrefix;
|
|||
public class LispInterpreterFixture {
|
||||
|
||||
private static ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
private static ExecutionContext executionContext = ExecutionContext.getInstance();
|
||||
private static ExecutionContext executionContext = ExecutionContext.INSTANCE;
|
||||
private static RuntimeEnvironment environment = RuntimeEnvironment.getInstance();
|
||||
private static LispInterpreter interpreter = null;
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import sexpression.LispNumber;
|
|||
import sexpression.Symbol;
|
||||
import testutil.SymbolAndFunctionCleaner;
|
||||
|
||||
import static function.builtin.special.LAMBDA.Lambda;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static sexpression.LispNumber.ONE;
|
||||
|
@ -47,12 +48,12 @@ public class LAMBDATest extends SymbolAndFunctionCleaner {
|
|||
public void lambdaExpressionIsLambdaExpression() {
|
||||
Cons lambdaExpression = new Cons(new Symbol("LAMBDA"), new Cons(NIL, new Cons(NIL, NIL)));
|
||||
|
||||
assertTrue(LAMBDA.Companion.isLambdaExpression(lambdaExpression));
|
||||
assertTrue(Lambda.isLambdaExpression(lambdaExpression));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void somethingElseIsNotLambdaExpression() {
|
||||
assertFalse(LAMBDA.Companion.isLambdaExpression(T));
|
||||
assertFalse(Lambda.isLambdaExpression(T));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -60,7 +61,7 @@ public class LAMBDATest extends SymbolAndFunctionCleaner {
|
|||
Cons lambdaExpression = new Cons(new Symbol("LAMBDA"), new Cons(NIL, new Cons(NIL, NIL)));
|
||||
|
||||
assertSExpressionsMatch(parseString("(:LAMBDA () ())"),
|
||||
LAMBDA.Companion.createFunction(lambdaExpression).getLambdaExpression());
|
||||
Lambda.createFunction(lambdaExpression).getLambdaExpression());
|
||||
}
|
||||
|
||||
@Test(expected = DottedArgumentListException.class)
|
||||
|
@ -81,14 +82,14 @@ public class LAMBDATest extends SymbolAndFunctionCleaner {
|
|||
public void createFunctionWithDottedArgumentList() {
|
||||
Cons lambdaExpression = new Cons(new Symbol("LAMBDA"), new Cons(NIL, ONE));
|
||||
|
||||
LAMBDA.Companion.createFunction(lambdaExpression);
|
||||
Lambda.createFunction(lambdaExpression);
|
||||
}
|
||||
|
||||
@Test(expected = BadArgumentTypeException.class)
|
||||
public void createFunctionWithNonList() {
|
||||
Cons lambdaExpression = new Cons(new Symbol("LAMBDA"), ONE);
|
||||
|
||||
LAMBDA.Companion.createFunction(lambdaExpression);
|
||||
Lambda.createFunction(lambdaExpression);
|
||||
}
|
||||
|
||||
@Test(expected = BadArgumentTypeException.class)
|
||||
|
|
|
@ -8,11 +8,12 @@ import org.junit.jupiter.api.TestInstance
|
|||
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
|
||||
import sexpression.Nil.NIL
|
||||
import sexpression.Symbol.T
|
||||
import table.ExecutionContext.NullSymbolTable
|
||||
|
||||
@TestInstance(PER_CLASS)
|
||||
class ExecutionContextTest {
|
||||
|
||||
private val executionContext: ExecutionContext = ExecutionContext.getInstance()
|
||||
private val executionContext: ExecutionContext = ExecutionContext
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
|
@ -40,7 +41,7 @@ class ExecutionContextTest {
|
|||
assertThat(executionContext.scope).isEqualTo(scope)
|
||||
executionContext.clearContext()
|
||||
assertThat(executionContext.scope).isNotEqualTo(scope)
|
||||
assertThat(executionContext.scope.parent).isNull()
|
||||
assertThat(executionContext.scope.parent).isEqualTo(NullSymbolTable)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -11,7 +11,7 @@ public abstract class SymbolAndFunctionCleaner {
|
|||
protected ExecutionContext executionContext;
|
||||
|
||||
public SymbolAndFunctionCleaner() {
|
||||
this.executionContext = ExecutionContext.getInstance();
|
||||
this.executionContext = ExecutionContext.INSTANCE;
|
||||
}
|
||||
|
||||
@Before
|
||||
|
|
Loading…
Reference in New Issue