Convert sexpressions to kotlin
This commit is contained in:
parent
4c8342a9f7
commit
16118a9a78
|
@ -4,6 +4,7 @@ import error.LispException;
|
||||||
import recursion.TailCall;
|
import recursion.TailCall;
|
||||||
import recursion.TailCalls;
|
import recursion.TailCalls;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
import sexpression.Symbol;
|
import sexpression.Symbol;
|
||||||
import table.ExecutionContext;
|
import table.ExecutionContext;
|
||||||
|
@ -14,7 +15,6 @@ import java.util.ArrayList;
|
||||||
import static function.builtin.EVAL.eval;
|
import static function.builtin.EVAL.eval;
|
||||||
import static java.text.MessageFormat.format;
|
import static java.text.MessageFormat.format;
|
||||||
import static recursion.TailCalls.done;
|
import static recursion.TailCalls.done;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
|
|
||||||
public class UserDefinedFunction extends LispFunction {
|
public class UserDefinedFunction extends LispFunction {
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ public class UserDefinedFunction extends LispFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
private SExpression evaluateBody() {
|
private SExpression evaluateBody() {
|
||||||
SExpression lastEvaluation = NIL;
|
SExpression lastEvaluation = Nil.INSTANCE;
|
||||||
|
|
||||||
for (Cons expression = body; expression.isCons(); expression = (Cons) expression.getRest())
|
for (Cons expression = body; expression.isCons(); expression = (Cons) expression.getRest())
|
||||||
lastEvaluation = eval(expression.getFirst());
|
lastEvaluation = eval(expression.getFirst());
|
||||||
|
|
|
@ -6,10 +6,10 @@ import sexpression.AtSignExpression;
|
||||||
import sexpression.BackquoteExpression;
|
import sexpression.BackquoteExpression;
|
||||||
import sexpression.CommaExpression;
|
import sexpression.CommaExpression;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
|
||||||
import static function.builtin.EVAL.eval;
|
import static function.builtin.EVAL.eval;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
|
|
||||||
class BackquoteEvaluator {
|
class BackquoteEvaluator {
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ class BackquoteEvaluator {
|
||||||
this.listValidator = new ArgumentValidator("`|list|");
|
this.listValidator = new ArgumentValidator("`|list|");
|
||||||
this.atSignValidator = new ArgumentValidator("@|list|");
|
this.atSignValidator = new ArgumentValidator("@|list|");
|
||||||
this.backTick = backTick;
|
this.backTick = backTick;
|
||||||
this.resolvedList = new Cons(NIL, NIL);
|
this.resolvedList = new Cons(Nil.INSTANCE, Nil.INSTANCE);
|
||||||
this.leader = resolvedList;
|
this.leader = resolvedList;
|
||||||
this.follower = resolvedList;
|
this.follower = resolvedList;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ class BackquoteEvaluator {
|
||||||
for (; list.isCons(); list = (Cons) list.getRest())
|
for (; list.isCons(); list = (Cons) list.getRest())
|
||||||
resolveExpression(list.getFirst());
|
resolveExpression(list.getFirst());
|
||||||
|
|
||||||
follower.setRest(NIL);
|
follower.setRest(Nil.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolveExpression(SExpression expression) {
|
private void resolveExpression(SExpression expression) {
|
||||||
|
@ -123,7 +123,7 @@ class BackquoteEvaluator {
|
||||||
|
|
||||||
private void addResolvedExpression(SExpression expression) {
|
private void addResolvedExpression(SExpression expression) {
|
||||||
leader.setFirst(expression);
|
leader.setFirst(expression);
|
||||||
leader.setRest(new Cons(NIL, NIL));
|
leader.setRest(new Cons(Nil.INSTANCE, Nil.INSTANCE));
|
||||||
follower = leader;
|
follower = leader;
|
||||||
leader = (Cons) leader.getRest();
|
leader = (Cons) leader.getRest();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import function.builtin.special.RECUR.RecurNotInTailPositionException;
|
||||||
import sexpression.BackquoteExpression;
|
import sexpression.BackquoteExpression;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
import sexpression.LambdaExpression;
|
import sexpression.LambdaExpression;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
import sexpression.Symbol;
|
import sexpression.Symbol;
|
||||||
import table.ExecutionContext;
|
import table.ExecutionContext;
|
||||||
|
@ -16,8 +17,6 @@ import table.FunctionTable;
|
||||||
import static function.builtin.cons.LIST.makeList;
|
import static function.builtin.cons.LIST.makeList;
|
||||||
import static function.builtin.special.Lambda.Lambda;
|
import static function.builtin.special.Lambda.Lambda;
|
||||||
import static java.text.MessageFormat.format;
|
import static java.text.MessageFormat.format;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static sexpression.Symbol.T;
|
|
||||||
|
|
||||||
@FunctionNames({ "EVAL" })
|
@FunctionNames({ "EVAL" })
|
||||||
public class EVAL extends LispFunction {
|
public class EVAL extends LispFunction {
|
||||||
|
@ -67,9 +66,9 @@ public class EVAL extends LispFunction {
|
||||||
|
|
||||||
public static SExpression lookupSymbol(String symbolName) {
|
public static SExpression lookupSymbol(String symbolName) {
|
||||||
if (symbolName.equals("NIL"))
|
if (symbolName.equals("NIL"))
|
||||||
return NIL;
|
return Nil.INSTANCE;
|
||||||
else if (symbolName.equals("T"))
|
else if (symbolName.equals("T"))
|
||||||
return T;
|
return Symbol.Companion.getT();
|
||||||
else if (symbolName.startsWith(":"))
|
else if (symbolName.startsWith(":"))
|
||||||
return new Symbol(symbolName);
|
return new Symbol(symbolName);
|
||||||
|
|
||||||
|
@ -155,7 +154,7 @@ public class EVAL extends LispFunction {
|
||||||
|
|
||||||
private Cons evaluateArgumentList(Cons arguments) {
|
private Cons evaluateArgumentList(Cons arguments) {
|
||||||
if (arguments.isNull())
|
if (arguments.isNull())
|
||||||
return NIL;
|
return Nil.INSTANCE;
|
||||||
|
|
||||||
SExpression first = eval(arguments.getFirst());
|
SExpression first = eval(arguments.getFirst());
|
||||||
SExpression rest = arguments.getRest();
|
SExpression rest = arguments.getRest();
|
||||||
|
|
|
@ -5,7 +5,7 @@ import function.ArgumentValidator
|
||||||
import function.FunctionNames
|
import function.FunctionNames
|
||||||
import function.LispFunction
|
import function.LispFunction
|
||||||
import sexpression.Cons
|
import sexpression.Cons
|
||||||
import sexpression.Nil.NIL
|
import sexpression.Nil
|
||||||
import sexpression.SExpression
|
import sexpression.SExpression
|
||||||
|
|
||||||
@FunctionNames("EXIT")
|
@FunctionNames("EXIT")
|
||||||
|
@ -21,6 +21,6 @@ class Exit(name: String) : LispFunction() {
|
||||||
argumentValidator.validate(argumentList)
|
argumentValidator.validate(argumentList)
|
||||||
RuntimeEnvironment.terminateSuccessfully()
|
RuntimeEnvironment.terminateSuccessfully()
|
||||||
|
|
||||||
return NIL
|
return Nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,9 @@ import function.LispFunction;
|
||||||
import parser.LispParser;
|
import parser.LispParser;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
import sexpression.LispString;
|
import sexpression.LispString;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
import sexpression.Symbol;
|
||||||
import util.Path;
|
import util.Path;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
@ -18,8 +20,6 @@ import java.util.Stack;
|
||||||
|
|
||||||
import static function.builtin.EVAL.eval;
|
import static function.builtin.EVAL.eval;
|
||||||
import static java.text.MessageFormat.format;
|
import static java.text.MessageFormat.format;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static sexpression.Symbol.T;
|
|
||||||
|
|
||||||
@FunctionNames({ "LOAD" })
|
@FunctionNames({ "LOAD" })
|
||||||
public class LOAD extends LispFunction {
|
public class LOAD extends LispFunction {
|
||||||
|
@ -57,7 +57,7 @@ public class LOAD extends LispFunction {
|
||||||
if (parser != null)
|
if (parser != null)
|
||||||
isSuccessful = isSuccessfulEvaluationWithPathPrefix(prefixedFileName, parser);
|
isSuccessful = isSuccessfulEvaluationWithPathPrefix(prefixedFileName, parser);
|
||||||
|
|
||||||
return isSuccessful ? T : NIL;
|
return isSuccessful ? Symbol.Companion.getT() : Nil.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String prefixFileNameIfNecessary(String fileName) {
|
private String prefixFileNameIfNecessary(String fileName) {
|
||||||
|
|
|
@ -4,10 +4,9 @@ import function.ArgumentValidator;
|
||||||
import function.FunctionNames;
|
import function.FunctionNames;
|
||||||
import function.LispFunction;
|
import function.LispFunction;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
|
import sexpression.Nil;
|
||||||
import table.FunctionTable;
|
import table.FunctionTable;
|
||||||
|
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
|
|
||||||
@FunctionNames({ "APPEND" })
|
@FunctionNames({ "APPEND" })
|
||||||
public class APPEND extends LispFunction {
|
public class APPEND extends LispFunction {
|
||||||
|
|
||||||
|
@ -53,11 +52,11 @@ public class APPEND extends LispFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Cons copy(Cons list) {
|
private Cons copy(Cons list) {
|
||||||
Cons newList = new Cons(list.getFirst(), NIL);
|
Cons newList = new Cons(list.getFirst(), Nil.INSTANCE);
|
||||||
Cons builder = newList;
|
Cons builder = newList;
|
||||||
|
|
||||||
for (Cons iterator = (Cons) list.getRest(); iterator.isCons(); iterator = (Cons) iterator.getRest()) {
|
for (Cons iterator = (Cons) list.getRest(); iterator.isCons(); iterator = (Cons) iterator.getRest()) {
|
||||||
builder.setRest(new Cons(iterator.getFirst(), NIL));
|
builder.setRest(new Cons(iterator.getFirst(), Nil.INSTANCE));
|
||||||
builder = (Cons) builder.getRest();
|
builder = (Cons) builder.getRest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,15 +4,14 @@ import function.ArgumentValidator;
|
||||||
import function.FunctionNames;
|
import function.FunctionNames;
|
||||||
import function.LispFunction;
|
import function.LispFunction;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
|
|
||||||
@FunctionNames({ "LIST" })
|
@FunctionNames({ "LIST" })
|
||||||
public class LIST extends LispFunction {
|
public class LIST extends LispFunction {
|
||||||
|
|
||||||
public static Cons makeList(SExpression sexpr) {
|
public static Cons makeList(SExpression sexpr) {
|
||||||
return new Cons(sexpr, NIL);
|
return new Cons(sexpr, Nil.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArgumentValidator argumentValidator;
|
private ArgumentValidator argumentValidator;
|
||||||
|
|
|
@ -6,8 +6,6 @@ import function.LispFunction;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
import sexpression.LispNumber;
|
import sexpression.LispNumber;
|
||||||
|
|
||||||
import static sexpression.LispNumber.ONE;
|
|
||||||
|
|
||||||
@FunctionNames({ "*" })
|
@FunctionNames({ "*" })
|
||||||
public class MULTIPLY extends LispFunction {
|
public class MULTIPLY extends LispFunction {
|
||||||
|
|
||||||
|
@ -24,7 +22,7 @@ public class MULTIPLY extends LispFunction {
|
||||||
public LispNumber call(Cons argumentList) {
|
public LispNumber call(Cons argumentList) {
|
||||||
argumentValidator.validate(argumentList);
|
argumentValidator.validate(argumentList);
|
||||||
|
|
||||||
return mathFunction.callTailRecursive(new Cons(ONE, argumentList)).invoke();
|
return mathFunction.callTailRecursive(new Cons(LispNumber.Companion.getONE(), argumentList)).invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
private LispNumber multiply(LispNumber number1, LispNumber number2) {
|
private LispNumber multiply(LispNumber number1, LispNumber number2) {
|
||||||
|
|
|
@ -6,8 +6,6 @@ import function.LispFunction;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
import sexpression.LispNumber;
|
import sexpression.LispNumber;
|
||||||
|
|
||||||
import static sexpression.LispNumber.ZERO;
|
|
||||||
|
|
||||||
@FunctionNames({ "+" })
|
@FunctionNames({ "+" })
|
||||||
public class PLUS extends LispFunction {
|
public class PLUS extends LispFunction {
|
||||||
|
|
||||||
|
@ -24,7 +22,7 @@ public class PLUS extends LispFunction {
|
||||||
public LispNumber call(Cons argumentList) {
|
public LispNumber call(Cons argumentList) {
|
||||||
argumentValidator.validate(argumentList);
|
argumentValidator.validate(argumentList);
|
||||||
|
|
||||||
return mathFunction.callTailRecursive(new Cons(ZERO, argumentList)).invoke();
|
return mathFunction.callTailRecursive(new Cons(LispNumber.Companion.getZERO(), argumentList)).invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
private LispNumber add(LispNumber number1, LispNumber number2) {
|
private LispNumber add(LispNumber number1, LispNumber number2) {
|
||||||
|
|
|
@ -4,10 +4,9 @@ import function.ArgumentValidator;
|
||||||
import function.FunctionNames;
|
import function.FunctionNames;
|
||||||
import function.LispFunction;
|
import function.LispFunction;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
import sexpression.Symbol;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static sexpression.Symbol.T;
|
|
||||||
|
|
||||||
@FunctionNames({ "ATOM", "ATOM?" })
|
@FunctionNames({ "ATOM", "ATOM?" })
|
||||||
public class ATOM extends LispFunction {
|
public class ATOM extends LispFunction {
|
||||||
|
@ -24,6 +23,6 @@ public class ATOM extends LispFunction {
|
||||||
argumentValidator.validate(argumentList);
|
argumentValidator.validate(argumentList);
|
||||||
SExpression argument = argumentList.getFirst();
|
SExpression argument = argumentList.getFirst();
|
||||||
|
|
||||||
return argument.isAtom() ? T : NIL;
|
return argument.isAtom() ? Symbol.Companion.getT() : Nil.INSTANCE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,9 @@ import function.ArgumentValidator;
|
||||||
import function.FunctionNames;
|
import function.FunctionNames;
|
||||||
import function.LispFunction;
|
import function.LispFunction;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
import sexpression.Symbol;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static sexpression.Symbol.T;
|
|
||||||
|
|
||||||
@FunctionNames({ "EQ", "EQ?" })
|
@FunctionNames({ "EQ", "EQ?" })
|
||||||
public class EQ extends LispFunction {
|
public class EQ extends LispFunction {
|
||||||
|
@ -42,7 +41,7 @@ public class EQ extends LispFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
private SExpression atomEq(SExpression firstArgument, SExpression secondArgument) {
|
private SExpression atomEq(SExpression firstArgument, SExpression secondArgument) {
|
||||||
return isEq(firstArgument, secondArgument) ? T : NIL;
|
return isEq(firstArgument, secondArgument) ? Symbol.Companion.getT() : Nil.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEq(SExpression firstArgument, SExpression secondArgument) {
|
private boolean isEq(SExpression firstArgument, SExpression secondArgument) {
|
||||||
|
@ -50,6 +49,6 @@ public class EQ extends LispFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
private SExpression listEq(SExpression firstArgument, SExpression secondArgument) {
|
private SExpression listEq(SExpression firstArgument, SExpression secondArgument) {
|
||||||
return (firstArgument == secondArgument) ? T : NIL;
|
return (firstArgument == secondArgument) ? Symbol.Companion.getT() : Nil.INSTANCE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,9 @@ import function.ArgumentValidator;
|
||||||
import function.FunctionNames;
|
import function.FunctionNames;
|
||||||
import function.LispFunction;
|
import function.LispFunction;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
import sexpression.Symbol;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static sexpression.Symbol.T;
|
|
||||||
|
|
||||||
@FunctionNames({ "EQUAL", "EQUAL?" })
|
@FunctionNames({ "EQUAL", "EQUAL?" })
|
||||||
public class EQUAL extends LispFunction {
|
public class EQUAL extends LispFunction {
|
||||||
|
@ -35,6 +34,6 @@ public class EQUAL extends LispFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
private SExpression equal(SExpression firstArgument, SExpression secondArgument) {
|
private SExpression equal(SExpression firstArgument, SExpression secondArgument) {
|
||||||
return isEqual(firstArgument, secondArgument) ? T : NIL;
|
return isEqual(firstArgument, secondArgument) ? Symbol.Companion.getT() : Nil.INSTANCE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,9 @@ import function.ArgumentValidator;
|
||||||
import function.FunctionNames;
|
import function.FunctionNames;
|
||||||
import function.LispFunction;
|
import function.LispFunction;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
import sexpression.Symbol;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -13,8 +15,6 @@ import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static function.builtin.GENSYM.GENSYM_PREFIX;
|
import static function.builtin.GENSYM.GENSYM_PREFIX;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static sexpression.Symbol.T;
|
|
||||||
|
|
||||||
@FunctionNames({ "GENSYM-EQUAL", "GENSYM-EQUAL?" })
|
@FunctionNames({ "GENSYM-EQUAL", "GENSYM-EQUAL?" })
|
||||||
public class GENSYM_EQUAL extends LispFunction {
|
public class GENSYM_EQUAL extends LispFunction {
|
||||||
|
@ -41,7 +41,7 @@ public class GENSYM_EQUAL extends LispFunction {
|
||||||
String firstEqualized = equalizeGensyms(firstArgument);
|
String firstEqualized = equalizeGensyms(firstArgument);
|
||||||
String secondEqualized = equalizeGensyms(secondArgument);
|
String secondEqualized = equalizeGensyms(secondArgument);
|
||||||
|
|
||||||
return firstEqualized.equals(secondEqualized) ? T : NIL;
|
return firstEqualized.equals(secondEqualized) ? Symbol.Companion.getT() : Nil.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String equalizeGensyms(SExpression expression) {
|
private String equalizeGensyms(SExpression expression) {
|
||||||
|
|
|
@ -4,10 +4,9 @@ import function.ArgumentValidator;
|
||||||
import function.FunctionNames;
|
import function.FunctionNames;
|
||||||
import function.LispFunction;
|
import function.LispFunction;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
import sexpression.Symbol;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static sexpression.Symbol.T;
|
|
||||||
|
|
||||||
@FunctionNames({ "LISTP", "LIST?" })
|
@FunctionNames({ "LISTP", "LIST?" })
|
||||||
public class LISTP extends LispFunction {
|
public class LISTP extends LispFunction {
|
||||||
|
@ -23,6 +22,6 @@ public class LISTP extends LispFunction {
|
||||||
public SExpression call(Cons argumentList) {
|
public SExpression call(Cons argumentList) {
|
||||||
argumentValidator.validate(argumentList);
|
argumentValidator.validate(argumentList);
|
||||||
|
|
||||||
return argumentList.getFirst().isList() ? T : NIL;
|
return argumentList.getFirst().isList() ? Symbol.Companion.getT() : Nil.INSTANCE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,9 @@ import function.ArgumentValidator;
|
||||||
import function.FunctionNames;
|
import function.FunctionNames;
|
||||||
import function.LispFunction;
|
import function.LispFunction;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
import sexpression.Symbol;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static sexpression.Symbol.T;
|
|
||||||
|
|
||||||
@FunctionNames({ "NULL", "NULL?" })
|
@FunctionNames({ "NULL", "NULL?" })
|
||||||
public class NULL extends LispFunction {
|
public class NULL extends LispFunction {
|
||||||
|
@ -23,6 +22,6 @@ public class NULL extends LispFunction {
|
||||||
public SExpression call(Cons argumentList) {
|
public SExpression call(Cons argumentList) {
|
||||||
argumentValidator.validate(argumentList);
|
argumentValidator.validate(argumentList);
|
||||||
|
|
||||||
return argumentList.getFirst().isNull() ? T : NIL;
|
return argumentList.getFirst().isNull() ? Symbol.Companion.getT() : Nil.INSTANCE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,12 @@ import function.LispFunction;
|
||||||
import recursion.TailCall;
|
import recursion.TailCall;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
import sexpression.LispNumber;
|
import sexpression.LispNumber;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
import sexpression.Symbol;
|
||||||
|
|
||||||
import static recursion.TailCalls.done;
|
import static recursion.TailCalls.done;
|
||||||
import static recursion.TailCalls.tailCall;
|
import static recursion.TailCalls.tailCall;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static sexpression.Symbol.T;
|
|
||||||
|
|
||||||
@FunctionNames({ ">" })
|
@FunctionNames({ ">" })
|
||||||
public class NUMERIC_GREATER extends LispFunction {
|
public class NUMERIC_GREATER extends LispFunction {
|
||||||
|
@ -35,7 +35,7 @@ public class NUMERIC_GREATER extends LispFunction {
|
||||||
Cons remainingArguments = (Cons) argumentList.getRest();
|
Cons remainingArguments = (Cons) argumentList.getRest();
|
||||||
|
|
||||||
if (remainingArguments.isNull())
|
if (remainingArguments.isNull())
|
||||||
return done(T);
|
return done(Symbol.Companion.getT());
|
||||||
|
|
||||||
SExpression firstArgument = argumentList.getFirst();
|
SExpression firstArgument = argumentList.getFirst();
|
||||||
SExpression secondArgument = remainingArguments.getFirst();
|
SExpression secondArgument = remainingArguments.getFirst();
|
||||||
|
@ -43,7 +43,7 @@ public class NUMERIC_GREATER extends LispFunction {
|
||||||
LispNumber number2 = (LispNumber) secondArgument;
|
LispNumber number2 = (LispNumber) secondArgument;
|
||||||
|
|
||||||
if (!isFirstGreater(number1, number2))
|
if (!isFirstGreater(number1, number2))
|
||||||
return done(NIL);
|
return done(Nil.INSTANCE);
|
||||||
|
|
||||||
return tailCall(() -> callTailRecursive(remainingArguments));
|
return tailCall(() -> callTailRecursive(remainingArguments));
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,12 @@ import function.LispFunction;
|
||||||
import recursion.TailCall;
|
import recursion.TailCall;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
import sexpression.LispNumber;
|
import sexpression.LispNumber;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
import sexpression.Symbol;
|
||||||
|
|
||||||
import static recursion.TailCalls.done;
|
import static recursion.TailCalls.done;
|
||||||
import static recursion.TailCalls.tailCall;
|
import static recursion.TailCalls.tailCall;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static sexpression.Symbol.T;
|
|
||||||
|
|
||||||
@FunctionNames({ "<" })
|
@FunctionNames({ "<" })
|
||||||
public class NUMERIC_LESS extends LispFunction {
|
public class NUMERIC_LESS extends LispFunction {
|
||||||
|
@ -35,7 +35,7 @@ public class NUMERIC_LESS extends LispFunction {
|
||||||
Cons remainingArguments = (Cons) argumentList.getRest();
|
Cons remainingArguments = (Cons) argumentList.getRest();
|
||||||
|
|
||||||
if (remainingArguments.isNull())
|
if (remainingArguments.isNull())
|
||||||
return done(T);
|
return done(Symbol.Companion.getT());
|
||||||
|
|
||||||
SExpression firstArgument = argumentList.getFirst();
|
SExpression firstArgument = argumentList.getFirst();
|
||||||
SExpression secondArgument = remainingArguments.getFirst();
|
SExpression secondArgument = remainingArguments.getFirst();
|
||||||
|
@ -43,7 +43,7 @@ public class NUMERIC_LESS extends LispFunction {
|
||||||
LispNumber number2 = (LispNumber) secondArgument;
|
LispNumber number2 = (LispNumber) secondArgument;
|
||||||
|
|
||||||
if (!isFirstLesser(number1, number2))
|
if (!isFirstLesser(number1, number2))
|
||||||
return done(NIL);
|
return done(Nil.INSTANCE);
|
||||||
|
|
||||||
return tailCall(() -> callTailRecursive(remainingArguments));
|
return tailCall(() -> callTailRecursive(remainingArguments));
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@ import function.FunctionNames
|
||||||
import function.LispFunction
|
import function.LispFunction
|
||||||
import sexpression.Cons
|
import sexpression.Cons
|
||||||
import sexpression.LispNumber
|
import sexpression.LispNumber
|
||||||
import sexpression.Nil.NIL
|
import sexpression.Nil
|
||||||
import sexpression.SExpression
|
import sexpression.SExpression
|
||||||
import sexpression.Symbol.T
|
import sexpression.Symbol.Companion.T
|
||||||
|
|
||||||
@FunctionNames("=")
|
@FunctionNames("=")
|
||||||
class NumericEqual(name: String) : LispFunction() {
|
class NumericEqual(name: String) : LispFunction() {
|
||||||
|
@ -34,6 +34,6 @@ class NumericEqual(name: String) : LispFunction() {
|
||||||
val number1 = argumentList.first as LispNumber
|
val number1 = argumentList.first as LispNumber
|
||||||
val number2 = remainingArguments.first as LispNumber
|
val number2 = remainingArguments.first as LispNumber
|
||||||
|
|
||||||
return if (number1.value != number2.value) NIL else callTailRecursive(remainingArguments)
|
return if (number1.value != number2.value) Nil else callTailRecursive(remainingArguments)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,11 @@ import function.LispSpecialFunction;
|
||||||
import recursion.TailCall;
|
import recursion.TailCall;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
import sexpression.Symbol;
|
||||||
|
|
||||||
import static function.builtin.EVAL.eval;
|
import static function.builtin.EVAL.eval;
|
||||||
import static recursion.TailCalls.done;
|
import static recursion.TailCalls.done;
|
||||||
import static recursion.TailCalls.tailCall;
|
import static recursion.TailCalls.tailCall;
|
||||||
import static sexpression.Symbol.T;
|
|
||||||
|
|
||||||
@FunctionNames({ "AND" })
|
@FunctionNames({ "AND" })
|
||||||
public class AND extends LispSpecialFunction {
|
public class AND extends LispSpecialFunction {
|
||||||
|
@ -25,7 +25,7 @@ public class AND extends LispSpecialFunction {
|
||||||
public SExpression call(Cons argumentList) {
|
public SExpression call(Cons argumentList) {
|
||||||
argumentValidator.validate(argumentList);
|
argumentValidator.validate(argumentList);
|
||||||
|
|
||||||
return callTailRecursive(argumentList, T).invoke();
|
return callTailRecursive(argumentList, Symbol.Companion.getT()).invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
private TailCall<SExpression> callTailRecursive(Cons argumentList, SExpression lastValue) {
|
private TailCall<SExpression> callTailRecursive(Cons argumentList, SExpression lastValue) {
|
||||||
|
|
|
@ -7,13 +7,12 @@ import recursion.TailCall;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
import sexpression.Nil;
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
import sexpression.Symbol;
|
||||||
|
|
||||||
import static function.builtin.EVAL.eval;
|
import static function.builtin.EVAL.eval;
|
||||||
import static function.builtin.predicate.EQUAL.isEqual;
|
import static function.builtin.predicate.EQUAL.isEqual;
|
||||||
import static recursion.TailCalls.done;
|
import static recursion.TailCalls.done;
|
||||||
import static recursion.TailCalls.tailCall;
|
import static recursion.TailCalls.tailCall;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static sexpression.Symbol.T;
|
|
||||||
|
|
||||||
@FunctionNames({ "CASE" })
|
@FunctionNames({ "CASE" })
|
||||||
public class CASE extends LispSpecialFunction {
|
public class CASE extends LispSpecialFunction {
|
||||||
|
@ -37,7 +36,7 @@ public class CASE extends LispSpecialFunction {
|
||||||
|
|
||||||
private TailCall<SExpression> callTailRecursive(SExpression key, Cons argumentList) {
|
private TailCall<SExpression> callTailRecursive(SExpression key, Cons argumentList) {
|
||||||
if (argumentList.isNull())
|
if (argumentList.isNull())
|
||||||
return done(NIL);
|
return done(Nil.INSTANCE);
|
||||||
|
|
||||||
Cons clause = (Cons) argumentList.getFirst();
|
Cons clause = (Cons) argumentList.getFirst();
|
||||||
Cons remainingClauses = (Cons) argumentList.getRest();
|
Cons remainingClauses = (Cons) argumentList.getRest();
|
||||||
|
@ -55,7 +54,7 @@ public class CASE extends LispSpecialFunction {
|
||||||
else if (keyList.isCons())
|
else if (keyList.isCons())
|
||||||
return containsMatch(key, keyList);
|
return containsMatch(key, keyList);
|
||||||
|
|
||||||
return isEqual(key, keyList) || isEqual(T, keyList);
|
return isEqual(key, keyList) || isEqual(Symbol.Companion.getT(), keyList);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean containsMatch(SExpression key, SExpression keyList) {
|
private boolean containsMatch(SExpression key, SExpression keyList) {
|
||||||
|
@ -75,7 +74,7 @@ public class CASE extends LispSpecialFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
private SExpression evaluateConsequents(SExpression consequentList) {
|
private SExpression evaluateConsequents(SExpression consequentList) {
|
||||||
SExpression lastConsequentValue = NIL;
|
SExpression lastConsequentValue = Nil.INSTANCE;
|
||||||
|
|
||||||
for (; consequentList.isCons(); consequentList = advanceCons(consequentList))
|
for (; consequentList.isCons(); consequentList = advanceCons(consequentList))
|
||||||
lastConsequentValue = eval(getFirst(consequentList));
|
lastConsequentValue = eval(getFirst(consequentList));
|
||||||
|
|
|
@ -11,7 +11,6 @@ import sexpression.SExpression;
|
||||||
import static function.builtin.EVAL.eval;
|
import static function.builtin.EVAL.eval;
|
||||||
import static recursion.TailCalls.done;
|
import static recursion.TailCalls.done;
|
||||||
import static recursion.TailCalls.tailCall;
|
import static recursion.TailCalls.tailCall;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
|
|
||||||
@FunctionNames({ "COND" })
|
@FunctionNames({ "COND" })
|
||||||
public class COND extends LispSpecialFunction {
|
public class COND extends LispSpecialFunction {
|
||||||
|
@ -33,7 +32,7 @@ public class COND extends LispSpecialFunction {
|
||||||
|
|
||||||
private TailCall<SExpression> callTailRecursive(Cons argumentList) {
|
private TailCall<SExpression> callTailRecursive(Cons argumentList) {
|
||||||
if (argumentList.isNull())
|
if (argumentList.isNull())
|
||||||
return done(NIL);
|
return done(Nil.INSTANCE);
|
||||||
|
|
||||||
Cons clause = (Cons) argumentList.getFirst();
|
Cons clause = (Cons) argumentList.getFirst();
|
||||||
Cons remainingClauses = (Cons) argumentList.getRest();
|
Cons remainingClauses = (Cons) argumentList.getRest();
|
||||||
|
@ -46,7 +45,7 @@ public class COND extends LispSpecialFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isTestSuccessful(SExpression test) {
|
private boolean isTestSuccessful(SExpression test) {
|
||||||
return test != NIL;
|
return test != Nil.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SExpression evaluateConsequents(SExpression consequentList, SExpression test) {
|
private SExpression evaluateConsequents(SExpression consequentList, SExpression test) {
|
||||||
|
|
|
@ -4,13 +4,13 @@ import function.ArgumentValidator;
|
||||||
import function.FunctionNames;
|
import function.FunctionNames;
|
||||||
import function.LispSpecialFunction;
|
import function.LispSpecialFunction;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
import sexpression.Symbol;
|
import sexpression.Symbol;
|
||||||
import table.ExecutionContext;
|
import table.ExecutionContext;
|
||||||
import table.SymbolTable;
|
import table.SymbolTable;
|
||||||
|
|
||||||
import static function.builtin.EVAL.eval;
|
import static function.builtin.EVAL.eval;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
|
|
||||||
@FunctionNames({ "LET" })
|
@FunctionNames({ "LET" })
|
||||||
public class LET extends LispSpecialFunction {
|
public class LET extends LispSpecialFunction {
|
||||||
|
@ -79,7 +79,7 @@ public class LET extends LispSpecialFunction {
|
||||||
}
|
}
|
||||||
|
|
||||||
private SExpression evaluateBody(Cons body) {
|
private SExpression evaluateBody(Cons body) {
|
||||||
SExpression lastEvaluation = NIL;
|
SExpression lastEvaluation = Nil.INSTANCE;
|
||||||
|
|
||||||
for (; body.isCons(); body = (Cons) body.getRest())
|
for (; body.isCons(); body = (Cons) body.getRest())
|
||||||
lastEvaluation = eval(body.getFirst());
|
lastEvaluation = eval(body.getFirst());
|
||||||
|
|
|
@ -5,12 +5,12 @@ import function.FunctionNames;
|
||||||
import function.LispSpecialFunction;
|
import function.LispSpecialFunction;
|
||||||
import recursion.TailCall;
|
import recursion.TailCall;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
|
||||||
import static function.builtin.EVAL.eval;
|
import static function.builtin.EVAL.eval;
|
||||||
import static recursion.TailCalls.done;
|
import static recursion.TailCalls.done;
|
||||||
import static recursion.TailCalls.tailCall;
|
import static recursion.TailCalls.tailCall;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
|
|
||||||
@FunctionNames({ "PROGN", "BEGIN" })
|
@FunctionNames({ "PROGN", "BEGIN" })
|
||||||
public class PROGN extends LispSpecialFunction {
|
public class PROGN extends LispSpecialFunction {
|
||||||
|
@ -25,7 +25,7 @@ public class PROGN extends LispSpecialFunction {
|
||||||
public SExpression call(Cons argumentList) {
|
public SExpression call(Cons argumentList) {
|
||||||
argumentValidator.validate(argumentList);
|
argumentValidator.validate(argumentList);
|
||||||
|
|
||||||
return callTailRecursive(argumentList, NIL).invoke();
|
return callTailRecursive(argumentList, Nil.INSTANCE).invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
private TailCall<SExpression> callTailRecursive(Cons argumentList, SExpression lastValue) {
|
private TailCall<SExpression> callTailRecursive(Cons argumentList, SExpression lastValue) {
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
package sexpression;
|
|
||||||
|
|
||||||
public class AtSignExpression extends SExpression {
|
|
||||||
|
|
||||||
private SExpression expression;
|
|
||||||
|
|
||||||
public AtSignExpression(SExpression expression) {
|
|
||||||
this.expression = expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SExpression getExpression() {
|
|
||||||
return expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAtSign() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "@" + expression;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package sexpression
|
||||||
|
|
||||||
|
class AtSignExpression(val expression: SExpression) : SExpression() {
|
||||||
|
|
||||||
|
override val isAtSign: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override fun toString() = "@$expression"
|
||||||
|
}
|
|
@ -1,21 +0,0 @@
|
||||||
package sexpression;
|
|
||||||
|
|
||||||
@DisplayName("atom")
|
|
||||||
public abstract class Atom extends SExpression {
|
|
||||||
|
|
||||||
private String text;
|
|
||||||
|
|
||||||
public Atom(String text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAtom() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package sexpression
|
||||||
|
|
||||||
|
@DisplayName("atom")
|
||||||
|
abstract class Atom(private val text: String) : SExpression() {
|
||||||
|
|
||||||
|
override val isAtom: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override fun toString() = text
|
||||||
|
}
|
|
@ -1,24 +0,0 @@
|
||||||
package sexpression;
|
|
||||||
|
|
||||||
public class BackquoteExpression extends SExpression {
|
|
||||||
|
|
||||||
private SExpression expression;
|
|
||||||
|
|
||||||
public BackquoteExpression(SExpression expression) {
|
|
||||||
this.expression = expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SExpression getExpression() {
|
|
||||||
return expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isBackquote() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "`" + expression;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package sexpression
|
||||||
|
|
||||||
|
class BackquoteExpression(val expression: SExpression) : SExpression() {
|
||||||
|
|
||||||
|
override val isBackquote: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override fun toString() = "`$expression"
|
||||||
|
}
|
|
@ -1,24 +0,0 @@
|
||||||
package sexpression;
|
|
||||||
|
|
||||||
public class CommaExpression extends SExpression {
|
|
||||||
|
|
||||||
private SExpression expression;
|
|
||||||
|
|
||||||
public CommaExpression(SExpression expression) {
|
|
||||||
this.expression = expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SExpression getExpression() {
|
|
||||||
return expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isComma() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "," + expression;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package sexpression
|
||||||
|
|
||||||
|
class CommaExpression(val expression: SExpression) : SExpression() {
|
||||||
|
|
||||||
|
override val isComma: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override fun toString() = ",$expression"
|
||||||
|
}
|
|
@ -1,56 +0,0 @@
|
||||||
package sexpression;
|
|
||||||
|
|
||||||
import recursion.TailCall;
|
|
||||||
|
|
||||||
import static recursion.TailCalls.done;
|
|
||||||
import static recursion.TailCalls.tailCall;
|
|
||||||
|
|
||||||
@DisplayName("list")
|
|
||||||
public class Cons extends SExpression {
|
|
||||||
|
|
||||||
private SExpression first;
|
|
||||||
private SExpression rest;
|
|
||||||
|
|
||||||
public Cons(SExpression first, SExpression rest) {
|
|
||||||
this.first = first;
|
|
||||||
this.rest = rest;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SExpression getFirst() {
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SExpression getRest() {
|
|
||||||
return rest;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFirst(SExpression first) {
|
|
||||||
this.first = first;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRest(SExpression rest) {
|
|
||||||
this.rest = rest;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCons() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return toStringTailRecursive(new StringBuilder("(")).invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
private TailCall<String> toStringTailRecursive(StringBuilder leadingString) {
|
|
||||||
leadingString.append(first.toString());
|
|
||||||
|
|
||||||
if (rest.isNull())
|
|
||||||
return done(leadingString.append(")").toString());
|
|
||||||
else if (rest.isCons()) {
|
|
||||||
return tailCall(() -> ((Cons) rest).toStringTailRecursive(leadingString.append(" ")));
|
|
||||||
}
|
|
||||||
|
|
||||||
return done(leadingString.append(" . " + rest.toString() + ")").toString());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package sexpression
|
||||||
|
|
||||||
|
import recursion.TailCall
|
||||||
|
|
||||||
|
import recursion.TailCalls.done
|
||||||
|
import recursion.TailCalls.tailCall
|
||||||
|
|
||||||
|
@DisplayName("list")
|
||||||
|
open class Cons(open var first: SExpression, open var rest: SExpression) : SExpression() {
|
||||||
|
|
||||||
|
override val isCons: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return toStringTailRecursive(StringBuilder("(")).invoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toStringTailRecursive(leadingString: StringBuilder): TailCall<String> {
|
||||||
|
leadingString.append(first.toString())
|
||||||
|
|
||||||
|
if (rest.isNull)
|
||||||
|
return done(leadingString.append(")").toString())
|
||||||
|
else if (rest.isCons) {
|
||||||
|
return tailCall { (rest as Cons).toStringTailRecursive(leadingString.append(" ")) }
|
||||||
|
}
|
||||||
|
|
||||||
|
return done(leadingString.append(" . " + rest.toString() + ")").toString())
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +0,0 @@
|
||||||
package sexpression;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
public @interface DisplayName {
|
|
||||||
|
|
||||||
String value();
|
|
||||||
}
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package sexpression
|
||||||
|
|
||||||
|
import kotlin.annotation.AnnotationRetention.RUNTIME
|
||||||
|
import kotlin.annotation.AnnotationTarget.CLASS
|
||||||
|
import kotlin.annotation.AnnotationTarget.FILE
|
||||||
|
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
@Target(CLASS, FILE)
|
||||||
|
annotation class DisplayName(val value: String)
|
|
@ -1,33 +0,0 @@
|
||||||
package sexpression;
|
|
||||||
|
|
||||||
import function.UserDefinedFunction;
|
|
||||||
|
|
||||||
@DisplayName("lambda-expression")
|
|
||||||
public class LambdaExpression extends SExpression {
|
|
||||||
|
|
||||||
private Cons lambdaExpression;
|
|
||||||
private UserDefinedFunction function;
|
|
||||||
|
|
||||||
public LambdaExpression(Cons lambdaExpression, UserDefinedFunction function) {
|
|
||||||
this.lambdaExpression = lambdaExpression;
|
|
||||||
this.function = function;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFunction() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Cons getLambdaExpression() {
|
|
||||||
return lambdaExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserDefinedFunction getFunction() {
|
|
||||||
return function;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return lambdaExpression.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package sexpression
|
||||||
|
|
||||||
|
import function.UserDefinedFunction
|
||||||
|
|
||||||
|
@DisplayName("lambda-expression")
|
||||||
|
class LambdaExpression(val lambdaExpression: Cons, val function: UserDefinedFunction) : SExpression() {
|
||||||
|
|
||||||
|
override val isFunction: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override fun toString() = lambdaExpression.toString()
|
||||||
|
}
|
|
@ -1,56 +0,0 @@
|
||||||
package sexpression;
|
|
||||||
|
|
||||||
import error.LispException;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
import static java.text.MessageFormat.format;
|
|
||||||
|
|
||||||
@DisplayName("number")
|
|
||||||
public class LispNumber extends Atom {
|
|
||||||
|
|
||||||
public static final LispNumber ZERO = new LispNumber(BigInteger.ZERO);
|
|
||||||
public static final LispNumber ONE = new LispNumber(BigInteger.ONE);
|
|
||||||
|
|
||||||
private BigInteger value;
|
|
||||||
|
|
||||||
public LispNumber(String text) {
|
|
||||||
super(text.replaceFirst("^0+(?!$)", ""));
|
|
||||||
|
|
||||||
try {
|
|
||||||
this.value = new BigInteger(text);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
throw new InvalidNumberException(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public LispNumber(BigInteger value) {
|
|
||||||
super(value.toString());
|
|
||||||
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isNumber() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BigInteger getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class InvalidNumberException extends LispException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
private String text;
|
|
||||||
|
|
||||||
public InvalidNumberException(String text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMessage() {
|
|
||||||
return format("{0} is not a valid integer", text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package sexpression
|
||||||
|
|
||||||
|
import error.LispException
|
||||||
|
|
||||||
|
import java.math.BigInteger
|
||||||
|
|
||||||
|
import java.text.MessageFormat.format
|
||||||
|
|
||||||
|
@DisplayName("number")
|
||||||
|
class LispNumber : Atom {
|
||||||
|
|
||||||
|
var value: BigInteger? = null
|
||||||
|
private set
|
||||||
|
|
||||||
|
override val isNumber: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
constructor(text: String) : super(text.replaceFirst("^0+(?!$)".toRegex(), "")) {
|
||||||
|
try {
|
||||||
|
this.value = BigInteger(text)
|
||||||
|
} catch (e: NumberFormatException) {
|
||||||
|
throw InvalidNumberException(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(value: BigInteger) : super(value.toString()) {
|
||||||
|
this.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class InvalidNumberException(private val text: String) : LispException() {
|
||||||
|
override val message: String
|
||||||
|
get() = format("{0} is not a valid integer", text)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val ZERO = LispNumber(BigInteger.ZERO)
|
||||||
|
val ONE = LispNumber(BigInteger.ONE)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +0,0 @@
|
||||||
package sexpression;
|
|
||||||
|
|
||||||
@DisplayName("string")
|
|
||||||
public class LispString extends Atom {
|
|
||||||
|
|
||||||
public LispString(String text) {
|
|
||||||
super(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isString() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package sexpression
|
||||||
|
|
||||||
|
@DisplayName("string")
|
||||||
|
class LispString(text: String) : Atom(text) {
|
||||||
|
|
||||||
|
override val isString: Boolean
|
||||||
|
get() = true
|
||||||
|
}
|
|
@ -1,51 +0,0 @@
|
||||||
package sexpression;
|
|
||||||
|
|
||||||
@DisplayName("nil")
|
|
||||||
public class Nil extends Cons {
|
|
||||||
|
|
||||||
public static final Nil NIL = new Nil();
|
|
||||||
|
|
||||||
private Nil() {
|
|
||||||
super(null, null);
|
|
||||||
|
|
||||||
super.setFirst(this);
|
|
||||||
super.setRest(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isNull() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAtom() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCons() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSymbol() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The first of NIL can not be changed.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setFirst(SExpression first) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The rest of NIL can not be changed.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setRest(SExpression rest) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "NIL";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package sexpression
|
||||||
|
|
||||||
|
import sexpression.Symbol.Companion.T
|
||||||
|
|
||||||
|
@DisplayName("nil")
|
||||||
|
object Nil : Cons(T, T) {
|
||||||
|
|
||||||
|
override var first: SExpression = this
|
||||||
|
set(_) {}
|
||||||
|
|
||||||
|
override var rest: SExpression = this
|
||||||
|
set(_) {}
|
||||||
|
|
||||||
|
override val isNull: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override val isAtom: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override val isCons: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
|
override val isSymbol: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override fun toString() = "NIL"
|
||||||
|
}
|
|
@ -1,49 +0,0 @@
|
||||||
package sexpression;
|
|
||||||
|
|
||||||
@DisplayName("s-expression")
|
|
||||||
public abstract class SExpression {
|
|
||||||
|
|
||||||
public boolean isNull() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAtom() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCons() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isList() {
|
|
||||||
return (isCons() || isNull());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNumber() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSymbol() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFunction() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isString() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isBackquote() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isComma() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAtSign() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package sexpression
|
||||||
|
|
||||||
|
@DisplayName("s-expression")
|
||||||
|
abstract class SExpression {
|
||||||
|
|
||||||
|
open val isNull: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
|
open val isAtom: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
|
open val isCons: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
|
open val isList: Boolean
|
||||||
|
get() = isCons || isNull
|
||||||
|
|
||||||
|
open val isNumber: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
|
open val isSymbol: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
|
open val isFunction: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
|
open val isString: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
|
open val isBackquote: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
|
open val isComma: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
|
open val isAtSign: Boolean
|
||||||
|
get() = false
|
||||||
|
}
|
|
@ -1,22 +0,0 @@
|
||||||
package sexpression;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
@DisplayName("symbol")
|
|
||||||
public class Symbol extends Atom {
|
|
||||||
|
|
||||||
public static final Symbol T = new Symbol("T");
|
|
||||||
|
|
||||||
public static Symbol createQuote() {
|
|
||||||
return new Symbol("QUOTE");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Symbol(String text) {
|
|
||||||
super(text.toUpperCase(Locale.ROOT));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSymbol() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package sexpression
|
||||||
|
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
@DisplayName("symbol")
|
||||||
|
open class Symbol(text: String) : Atom(text.toUpperCase(Locale.ROOT)) {
|
||||||
|
|
||||||
|
override val isSymbol: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val T = Symbol("T")
|
||||||
|
|
||||||
|
fun createQuote() = Symbol("QUOTE")
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ package table
|
||||||
|
|
||||||
import function.LispFunction
|
import function.LispFunction
|
||||||
import sexpression.Cons
|
import sexpression.Cons
|
||||||
import sexpression.Nil.NIL
|
import sexpression.Nil
|
||||||
import sexpression.SExpression
|
import sexpression.SExpression
|
||||||
import table.SymbolTable.NullSymbolTable
|
import table.SymbolTable.NullSymbolTable
|
||||||
import java.util.Stack
|
import java.util.Stack
|
||||||
|
@ -39,7 +39,7 @@ object ExecutionContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toList(): Cons {
|
fun toList(): Cons {
|
||||||
var symbols: Cons = NIL
|
var symbols: Cons = Nil
|
||||||
|
|
||||||
for (table in scope)
|
for (table in scope)
|
||||||
symbols = Cons(table.toList(), symbols)
|
symbols = Cons(table.toList(), symbols)
|
||||||
|
|
|
@ -3,14 +3,14 @@ package table
|
||||||
import function.builtin.cons.APPEND.append
|
import function.builtin.cons.APPEND.append
|
||||||
import function.builtin.cons.LIST.makeList
|
import function.builtin.cons.LIST.makeList
|
||||||
import sexpression.Cons
|
import sexpression.Cons
|
||||||
import sexpression.Nil.NIL
|
import sexpression.Nil
|
||||||
import sexpression.SExpression
|
import sexpression.SExpression
|
||||||
import sexpression.Symbol
|
import sexpression.Symbol
|
||||||
import kotlin.collections.Map.Entry
|
import kotlin.collections.Map.Entry
|
||||||
|
|
||||||
open class SymbolTable @JvmOverloads constructor(open val parent: SymbolTable? = NullSymbolTable) : Iterable<SymbolTable> {
|
open class SymbolTable @JvmOverloads constructor(open val parent: SymbolTable? = NullSymbolTable) : Iterable<SymbolTable> {
|
||||||
|
|
||||||
private val table = mutableMapOf<String, SExpression>()
|
private val table = mutableMapOf<String, SExpression>()
|
||||||
|
|
||||||
override fun iterator(): Iterator<SymbolTable> = SymbolTableIterator(this)
|
override fun iterator(): Iterator<SymbolTable> = SymbolTableIterator(this)
|
||||||
operator fun contains(symbolName: String) = symbolName in table
|
operator fun contains(symbolName: String) = symbolName in table
|
||||||
|
@ -23,7 +23,7 @@ open class SymbolTable @JvmOverloads constructor(open val parent: SymbolTable? =
|
||||||
fun isGlobal() = parent === NullSymbolTable
|
fun isGlobal() = parent === NullSymbolTable
|
||||||
|
|
||||||
fun toList(): Cons {
|
fun toList(): Cons {
|
||||||
var context: Cons = NIL
|
var context: Cons = Nil
|
||||||
|
|
||||||
for (binding in table.toSortedMap().entries)
|
for (binding in table.toSortedMap().entries)
|
||||||
context = append(context, makeList(makeSymbolValuePair(binding)))
|
context = append(context, makeList(makeSymbolValuePair(binding)))
|
||||||
|
|
|
@ -2,7 +2,7 @@ package token
|
||||||
|
|
||||||
import file.FilePosition
|
import file.FilePosition
|
||||||
import sexpression.Cons
|
import sexpression.Cons
|
||||||
import sexpression.Nil.NIL
|
import sexpression.Nil
|
||||||
import sexpression.SExpression
|
import sexpression.SExpression
|
||||||
import sexpression.Symbol
|
import sexpression.Symbol
|
||||||
|
|
||||||
|
@ -12,6 +12,6 @@ class QuoteMark(text: String, position: FilePosition) : Token(text, position) {
|
||||||
val nextToken = getNextToken()
|
val nextToken = getNextToken()
|
||||||
val argument = nextToken.parseSExpression(getNextToken)
|
val argument = nextToken.parseSExpression(getNextToken)
|
||||||
|
|
||||||
return Cons(Symbol.createQuote(), Cons(argument, NIL))
|
return Cons(Symbol.createQuote(), Cons(argument, Nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import file.FilePosition
|
||||||
import recursion.TailCall
|
import recursion.TailCall
|
||||||
import recursion.TailCalls.done
|
import recursion.TailCalls.done
|
||||||
import sexpression.Cons
|
import sexpression.Cons
|
||||||
import sexpression.Nil.NIL
|
import sexpression.Nil
|
||||||
import sexpression.SExpression
|
import sexpression.SExpression
|
||||||
|
|
||||||
class RightParenthesis(text: String, position: FilePosition) : Token(text, position) {
|
class RightParenthesis(text: String, position: FilePosition) : Token(text, position) {
|
||||||
|
@ -15,7 +15,7 @@ class RightParenthesis(text: String, position: FilePosition) : Token(text, posit
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun parseListTail(getNextToken: () -> Token): TailCall<Cons> {
|
override fun parseListTail(getNextToken: () -> Token): TailCall<Cons> {
|
||||||
return done(NIL)
|
return done(Nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun parseListTailRecursive(start: Cons, end: Cons, getNextToken: () -> Token): TailCall<Cons> {
|
override fun parseListTailRecursive(start: Cons, end: Cons, getNextToken: () -> Token): TailCall<Cons> {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import file.FilePosition
|
||||||
import recursion.TailCall
|
import recursion.TailCall
|
||||||
import recursion.TailCalls.tailCall
|
import recursion.TailCalls.tailCall
|
||||||
import sexpression.Cons
|
import sexpression.Cons
|
||||||
import sexpression.Nil.NIL
|
import sexpression.Nil
|
||||||
import sexpression.SExpression
|
import sexpression.SExpression
|
||||||
|
|
||||||
abstract class Token(val text: String, val position: FilePosition) {
|
abstract class Token(val text: String, val position: FilePosition) {
|
||||||
|
@ -20,14 +20,14 @@ abstract class Token(val text: String, val position: FilePosition) {
|
||||||
abstract fun parseSExpression(getNextToken: () -> Token): SExpression
|
abstract fun parseSExpression(getNextToken: () -> Token): SExpression
|
||||||
|
|
||||||
open fun parseListTail(getNextToken: () -> Token): TailCall<Cons> {
|
open fun parseListTail(getNextToken: () -> Token): TailCall<Cons> {
|
||||||
val firstCons = Cons(parseSExpression(getNextToken), NIL)
|
val firstCons = Cons(parseSExpression(getNextToken), Nil)
|
||||||
val next = getNextToken()
|
val next = getNextToken()
|
||||||
|
|
||||||
return tailCall { next.parseListTailRecursive(firstCons, firstCons, getNextToken) }
|
return tailCall { next.parseListTailRecursive(firstCons, firstCons, getNextToken) }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun parseListTailRecursive(start: Cons, end: Cons, getNextToken: () -> Token): TailCall<Cons> {
|
protected open fun parseListTailRecursive(start: Cons, end: Cons, getNextToken: () -> Token): TailCall<Cons> {
|
||||||
val newEnd = Cons(parseSExpression(getNextToken), NIL)
|
val newEnd = Cons(parseSExpression(getNextToken), Nil)
|
||||||
val next = getNextToken()
|
val next = getNextToken()
|
||||||
end.rest = newEnd
|
end.rest = newEnd
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,11 @@
|
||||||
(defmacro dlambda (&rest methods)
|
(defmacro dlambda (&rest methods)
|
||||||
(let ((arguments (gensym)))
|
(let ((arguments (gensym)))
|
||||||
|
|
||||||
`(lambda (&rest ,arguments)
|
`(lambda (&rest, arguments)
|
||||||
(case (first ,arguments)
|
(case (first, arguments), @(mapcar
|
||||||
,@(mapcar
|
(lambda (method))
|
||||||
(lambda (method)
|
`(, (first method))
|
||||||
`(,(first method)
|
(apply (lambda, @(rest method)), (if (equal t (first method)))
|
||||||
(apply (lambda ,@(rest method))
|
arguments
|
||||||
,(if (equal t (first method))
|
`(rest, arguments))
|
||||||
arguments
|
methods)))))
|
||||||
`(rest ,arguments)))))
|
|
||||||
methods)))))
|
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
|
|
||||||
(defun maplist (function-name the-list)
|
(defun maplist (function-name the-list)
|
||||||
(cond
|
(cond
|
||||||
((null the-list) nil)
|
((null the-list) nil)
|
||||||
(t (cons (funcall function-name the-list)
|
(t (cons (funcall function-name the-list)
|
||||||
(maplist function-name (rest the-list))))))
|
(maplist function-name (rest the-list))))))
|
||||||
|
|
||||||
(defun map (function the-list)
|
(defun map (function the-list)
|
||||||
(reverse (map-tail function the-list nil)))
|
(reverse (map-tail function the-list nil)))
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
(defun reverse-tail (accumulator the-list)
|
(defun reverse-tail (accumulator the-list)
|
||||||
(if (null the-list) accumulator
|
(if (null the-list) accumulator
|
||||||
(recur (cons (first the-list) accumulator) (rest the-list))))
|
(recur (cons (first the-list) accumulator) (rest the-list))))
|
||||||
|
|
||||||
(defun deep-reverse (the-list)
|
(defun deep-reverse (the-list)
|
||||||
(if the-list
|
(if the-list
|
||||||
|
@ -55,9 +55,9 @@
|
||||||
|
|
||||||
(defun nth (n listA)
|
(defun nth (n listA)
|
||||||
(cond
|
(cond
|
||||||
((equal 0 n) (first listA))
|
((equal 0 n) (first listA))
|
||||||
(t (nth (- n 1) (rest listA)))))
|
(t (nth (- n 1) (rest listA)))))
|
||||||
|
|
||||||
(eval
|
(eval
|
||||||
(let ((expr (gensym)))
|
(let ((expr (gensym)))
|
||||||
`(defun global-eval (,expr) (eval ,expr))))
|
`(defun global-eval (, expr) (eval, expr))))
|
||||||
|
|
|
@ -16,18 +16,16 @@ import static error.Severity.ERROR;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static sexpression.Symbol.T;
|
|
||||||
|
|
||||||
public class ArgumentValidatorTest {
|
public class ArgumentValidatorTest {
|
||||||
|
|
||||||
private ArgumentValidator validator;
|
private ArgumentValidator validator;
|
||||||
|
|
||||||
private Cons makeArgumentListOfSize(int size) {
|
private Cons makeArgumentListOfSize(int size) {
|
||||||
Cons argumentList = NIL;
|
Cons argumentList = Nil.INSTANCE;
|
||||||
|
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
argumentList = new Cons(NIL, argumentList);
|
argumentList = new Cons(Nil.INSTANCE, argumentList);
|
||||||
|
|
||||||
return argumentList;
|
return argumentList;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +82,7 @@ public class ArgumentValidatorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void tooManyArgumentsException_HasCorrectAttributes() {
|
public void tooManyArgumentsException_HasCorrectAttributes() {
|
||||||
TooManyArgumentsException e = new TooManyArgumentsException("TEST", NIL);
|
TooManyArgumentsException e = new TooManyArgumentsException("TEST", Nil.INSTANCE);
|
||||||
|
|
||||||
assertEquals(ERROR, e.getSeverity());
|
assertEquals(ERROR, e.getSeverity());
|
||||||
assertNotNull(e.getMessage());
|
assertNotNull(e.getMessage());
|
||||||
|
@ -93,7 +91,7 @@ public class ArgumentValidatorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void tooFewArgumentsException_HasCorrectAttributes() {
|
public void tooFewArgumentsException_HasCorrectAttributes() {
|
||||||
TooFewArgumentsException e = new TooFewArgumentsException("TEST", NIL);
|
TooFewArgumentsException e = new TooFewArgumentsException("TEST", Nil.INSTANCE);
|
||||||
|
|
||||||
assertEquals(ERROR, e.getSeverity());
|
assertEquals(ERROR, e.getSeverity());
|
||||||
assertNotNull(e.getMessage());
|
assertNotNull(e.getMessage());
|
||||||
|
@ -102,7 +100,7 @@ public class ArgumentValidatorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void badArgumentTypeException_HasCorrectAttributes() {
|
public void badArgumentTypeException_HasCorrectAttributes() {
|
||||||
BadArgumentTypeException e = new BadArgumentTypeException("TEST", NIL, SExpression.class);
|
BadArgumentTypeException e = new BadArgumentTypeException("TEST", Nil.INSTANCE, SExpression.class);
|
||||||
|
|
||||||
assertEquals(ERROR, e.getSeverity());
|
assertEquals(ERROR, e.getSeverity());
|
||||||
assertNotNull(e.getMessage());
|
assertNotNull(e.getMessage());
|
||||||
|
@ -123,7 +121,7 @@ public class ArgumentValidatorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void correctFirstAndRestArgumentTypes_DoesNotThrowException() {
|
public void correctFirstAndRestArgumentTypes_DoesNotThrowException() {
|
||||||
Cons argumentList = new Cons(T, new Cons(NIL, NIL));
|
Cons argumentList = new Cons(Symbol.Companion.getT(), new Cons(Nil.INSTANCE, Nil.INSTANCE));
|
||||||
|
|
||||||
validator.setFirstArgumentExpectedType(Symbol.class);
|
validator.setFirstArgumentExpectedType(Symbol.class);
|
||||||
validator.setTrailingArgumentExpectedType(Cons.class);
|
validator.setTrailingArgumentExpectedType(Cons.class);
|
||||||
|
@ -132,7 +130,7 @@ public class ArgumentValidatorTest {
|
||||||
|
|
||||||
@Test(expected = BadArgumentTypeException.class)
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
public void badFirstArgumentType_ThrowsException() {
|
public void badFirstArgumentType_ThrowsException() {
|
||||||
Cons argumentList = new Cons(T, new Cons(NIL, NIL));
|
Cons argumentList = new Cons(Symbol.Companion.getT(), new Cons(Nil.INSTANCE, Nil.INSTANCE));
|
||||||
|
|
||||||
validator.setFirstArgumentExpectedType(Cons.class);
|
validator.setFirstArgumentExpectedType(Cons.class);
|
||||||
validator.setTrailingArgumentExpectedType(Cons.class);
|
validator.setTrailingArgumentExpectedType(Cons.class);
|
||||||
|
@ -141,7 +139,7 @@ public class ArgumentValidatorTest {
|
||||||
|
|
||||||
@Test(expected = BadArgumentTypeException.class)
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
public void badTrailingArgumentType_ThrowsException() {
|
public void badTrailingArgumentType_ThrowsException() {
|
||||||
Cons argumentList = new Cons(T, new Cons(NIL, NIL));
|
Cons argumentList = new Cons(Symbol.Companion.getT(), new Cons(Nil.INSTANCE, Nil.INSTANCE));
|
||||||
|
|
||||||
validator.setFirstArgumentExpectedType(Symbol.class);
|
validator.setFirstArgumentExpectedType(Symbol.class);
|
||||||
validator.setTrailingArgumentExpectedType(Symbol.class);
|
validator.setTrailingArgumentExpectedType(Symbol.class);
|
||||||
|
@ -150,7 +148,7 @@ public class ArgumentValidatorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void expectedTypeWithNoDisplayName_DoesNotCauseNPE() {
|
public void expectedTypeWithNoDisplayName_DoesNotCauseNPE() {
|
||||||
Cons argumentList = new Cons(T, new Cons(NIL, NIL));
|
Cons argumentList = new Cons(Symbol.Companion.getT(), new Cons(Nil.INSTANCE, Nil.INSTANCE));
|
||||||
SExpression withoutDisplayName = new SExpression() {};
|
SExpression withoutDisplayName = new SExpression() {};
|
||||||
|
|
||||||
validator.setEveryArgumentExpectedType(withoutDisplayName.getClass());
|
validator.setEveryArgumentExpectedType(withoutDisplayName.getClass());
|
||||||
|
@ -165,21 +163,22 @@ public class ArgumentValidatorTest {
|
||||||
|
|
||||||
@Test(expected = DottedArgumentListException.class)
|
@Test(expected = DottedArgumentListException.class)
|
||||||
public void givenDottedArgumentList_ThrowsException() {
|
public void givenDottedArgumentList_ThrowsException() {
|
||||||
Cons argumentList = new Cons(T, T);
|
Cons argumentList = new Cons(Symbol.Companion.getT(), Symbol.Companion.getT());
|
||||||
|
|
||||||
validator.validate(argumentList);
|
validator.validate(argumentList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = DottedArgumentListException.class)
|
@Test(expected = DottedArgumentListException.class)
|
||||||
public void givenLargeDottedArgumentList_ThrowsException() {
|
public void givenLargeDottedArgumentList_ThrowsException() {
|
||||||
Cons argumentList = new Cons(T, new Cons(T, T));
|
Cons argumentList =
|
||||||
|
new Cons(Symbol.Companion.getT(), new Cons(Symbol.Companion.getT(), Symbol.Companion.getT()));
|
||||||
|
|
||||||
validator.validate(argumentList);
|
validator.validate(argumentList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void dottedArgumentListException_HasCorrectAttributes() {
|
public void dottedArgumentListException_HasCorrectAttributes() {
|
||||||
DottedArgumentListException e = new DottedArgumentListException("TEST", NIL);
|
DottedArgumentListException e = new DottedArgumentListException("TEST", Nil.INSTANCE);
|
||||||
|
|
||||||
assertEquals(ERROR, e.getSeverity());
|
assertEquals(ERROR, e.getSeverity());
|
||||||
assertNotNull(e.getMessage());
|
assertNotNull(e.getMessage());
|
||||||
|
@ -189,36 +188,36 @@ public class ArgumentValidatorTest {
|
||||||
@Test
|
@Test
|
||||||
public void excludedFirstArgumentType_DoesNotAffectTrailingArguments() {
|
public void excludedFirstArgumentType_DoesNotAffectTrailingArguments() {
|
||||||
validator.setFirstArgumentExcludedType(Nil.class);
|
validator.setFirstArgumentExcludedType(Nil.class);
|
||||||
validator.validate(new Cons(T, new Cons(NIL, NIL)));
|
validator.validate(new Cons(Symbol.Companion.getT(), new Cons(Nil.INSTANCE, Nil.INSTANCE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void excludedTrailingArgumentType_DoesNotAffectFirstArgument() {
|
public void excludedTrailingArgumentType_DoesNotAffectFirstArgument() {
|
||||||
validator.setTrailingArgumentExcludedType(Nil.class);
|
validator.setTrailingArgumentExcludedType(Nil.class);
|
||||||
validator.validate(new Cons(NIL, new Cons(T, NIL)));
|
validator.validate(new Cons(Nil.INSTANCE, new Cons(Symbol.Companion.getT(), Nil.INSTANCE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = BadArgumentTypeException.class)
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
public void excludedFirstArgumentType_ThrowsException() {
|
public void excludedFirstArgumentType_ThrowsException() {
|
||||||
validator.setFirstArgumentExcludedType(Nil.class);
|
validator.setFirstArgumentExcludedType(Nil.class);
|
||||||
validator.validate(new Cons(NIL, new Cons(T, NIL)));
|
validator.validate(new Cons(Nil.INSTANCE, new Cons(Symbol.Companion.getT(), Nil.INSTANCE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = BadArgumentTypeException.class)
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
public void excludedTrailingArgumentType_ThrowsException() {
|
public void excludedTrailingArgumentType_ThrowsException() {
|
||||||
validator.setTrailingArgumentExcludedType(Nil.class);
|
validator.setTrailingArgumentExcludedType(Nil.class);
|
||||||
validator.validate(new Cons(T, new Cons(NIL, NIL)));
|
validator.validate(new Cons(Symbol.Companion.getT(), new Cons(Nil.INSTANCE, Nil.INSTANCE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = BadArgumentTypeException.class)
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
public void excludedArgumentType_ThrowsExceptionOnFirstArgument() {
|
public void excludedArgumentType_ThrowsExceptionOnFirstArgument() {
|
||||||
validator.setEveryArgumentExcludedType(Nil.class);
|
validator.setEveryArgumentExcludedType(Nil.class);
|
||||||
validator.validate(new Cons(NIL, new Cons(T, NIL)));
|
validator.validate(new Cons(Nil.INSTANCE, new Cons(Symbol.Companion.getT(), Nil.INSTANCE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = BadArgumentTypeException.class)
|
@Test(expected = BadArgumentTypeException.class)
|
||||||
public void excludedArgumentType_ThrowsExceptionOnTrailingArgument() {
|
public void excludedArgumentType_ThrowsExceptionOnTrailingArgument() {
|
||||||
validator.setEveryArgumentExcludedType(Nil.class);
|
validator.setEveryArgumentExcludedType(Nil.class);
|
||||||
validator.validate(new Cons(T, new Cons(NIL, NIL)));
|
validator.validate(new Cons(Symbol.Companion.getT(), new Cons(Nil.INSTANCE, Nil.INSTANCE)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,13 @@ import function.UserDefinedFunction.IllegalKeywordRestPositionException;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
import sexpression.LispNumber;
|
import sexpression.LispNumber;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
import sexpression.Symbol;
|
import sexpression.Symbol;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static testutil.TestUtilities.assertSExpressionsMatch;
|
import static testutil.TestUtilities.assertSExpressionsMatch;
|
||||||
|
|
||||||
public class UserDefinedFunctionTest {
|
public class UserDefinedFunctionTest {
|
||||||
|
@ -21,24 +21,27 @@ public class UserDefinedFunctionTest {
|
||||||
private static final String FUNCTION_NAME = "TEST";
|
private static final String FUNCTION_NAME = "TEST";
|
||||||
|
|
||||||
private UserDefinedFunction createNoArgumentFunctionThatReturnsNil() {
|
private UserDefinedFunction createNoArgumentFunctionThatReturnsNil() {
|
||||||
return new UserDefinedFunction(FUNCTION_NAME, NIL, new Cons(NIL, NIL));
|
return new UserDefinedFunction(FUNCTION_NAME,
|
||||||
|
Nil.INSTANCE, new Cons(Nil.INSTANCE, Nil.INSTANCE));
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserDefinedFunction createOneArgumentFunctionThatReturnsArgument() {
|
private UserDefinedFunction createOneArgumentFunctionThatReturnsArgument() {
|
||||||
return new UserDefinedFunction(FUNCTION_NAME, new Cons(new Symbol("X"), NIL), new Cons(new Symbol("X"), NIL));
|
return new UserDefinedFunction(FUNCTION_NAME, new Cons(new Symbol("X"), Nil.INSTANCE), new Cons(new Symbol("X"),
|
||||||
|
Nil.INSTANCE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void nilFunctionCall() {
|
public void nilFunctionCall() {
|
||||||
UserDefinedFunction function = createNoArgumentFunctionThatReturnsNil();
|
UserDefinedFunction function = createNoArgumentFunctionThatReturnsNil();
|
||||||
|
|
||||||
assertEquals(NIL, function.call(NIL));
|
assertEquals(Nil.INSTANCE, function.call(Nil.INSTANCE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void nilFunctionToString() {
|
public void nilFunctionToString() {
|
||||||
UserDefinedFunction function = createNoArgumentFunctionThatReturnsNil();
|
UserDefinedFunction function = createNoArgumentFunctionThatReturnsNil();
|
||||||
Cons expected = new Cons(new Symbol(FUNCTION_NAME), new Cons(NIL, new Cons(NIL, NIL)));
|
Cons expected = new Cons(new Symbol(FUNCTION_NAME), new Cons(Nil.INSTANCE, new Cons(Nil.INSTANCE,
|
||||||
|
Nil.INSTANCE)));
|
||||||
|
|
||||||
assertSExpressionsMatch(expected, function.getLambdaExpression());
|
assertSExpressionsMatch(expected, function.getLambdaExpression());
|
||||||
}
|
}
|
||||||
|
@ -47,7 +50,7 @@ public class UserDefinedFunctionTest {
|
||||||
public void oneArgumentFunction_ReturnsCorrectValue() {
|
public void oneArgumentFunction_ReturnsCorrectValue() {
|
||||||
UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument();
|
UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument();
|
||||||
SExpression argument = new LispNumber("23");
|
SExpression argument = new LispNumber("23");
|
||||||
Cons argumentList = new Cons(argument, NIL);
|
Cons argumentList = new Cons(argument, Nil.INSTANCE);
|
||||||
|
|
||||||
assertSExpressionsMatch(argument, function.call(argumentList));
|
assertSExpressionsMatch(argument, function.call(argumentList));
|
||||||
}
|
}
|
||||||
|
@ -56,7 +59,7 @@ public class UserDefinedFunctionTest {
|
||||||
public void oneArgumentFunction_ThrowsExceptionWithTooManyArguments() {
|
public void oneArgumentFunction_ThrowsExceptionWithTooManyArguments() {
|
||||||
UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument();
|
UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument();
|
||||||
SExpression argument = new LispNumber("23");
|
SExpression argument = new LispNumber("23");
|
||||||
Cons argumentList = new Cons(argument, new Cons(argument, NIL));
|
Cons argumentList = new Cons(argument, new Cons(argument, Nil.INSTANCE));
|
||||||
|
|
||||||
function.call(argumentList);
|
function.call(argumentList);
|
||||||
}
|
}
|
||||||
|
@ -65,12 +68,13 @@ public class UserDefinedFunctionTest {
|
||||||
public void oneArgumentFunction_ThrowsExceptionWithTooFewArguments() {
|
public void oneArgumentFunction_ThrowsExceptionWithTooFewArguments() {
|
||||||
UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument();
|
UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument();
|
||||||
|
|
||||||
function.call(NIL);
|
function.call(Nil.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void illegalKeywordRestPositionException_HasCorrectAttributes() {
|
public void illegalKeywordRestPositionException_HasCorrectAttributes() {
|
||||||
IllegalKeywordRestPositionException e = new IllegalKeywordRestPositionException(FUNCTION_NAME, NIL);
|
IllegalKeywordRestPositionException e = new IllegalKeywordRestPositionException(FUNCTION_NAME,
|
||||||
|
Nil.INSTANCE);
|
||||||
|
|
||||||
assertNotNull(e.getMessage());
|
assertNotNull(e.getMessage());
|
||||||
assertTrue(e.getMessage().length() > 0);
|
assertTrue(e.getMessage().length() > 0);
|
||||||
|
|
|
@ -12,11 +12,10 @@ import sexpression.CommaExpression;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
import sexpression.LispNumber;
|
import sexpression.LispNumber;
|
||||||
import sexpression.LispString;
|
import sexpression.LispString;
|
||||||
|
import sexpression.Nil;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
import sexpression.Symbol;
|
import sexpression.Symbol;
|
||||||
|
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static sexpression.Symbol.T;
|
|
||||||
import static testutil.TestUtilities.assertIsErrorWithMessage;
|
import static testutil.TestUtilities.assertIsErrorWithMessage;
|
||||||
import static testutil.TestUtilities.assertSExpressionsMatch;
|
import static testutil.TestUtilities.assertSExpressionsMatch;
|
||||||
import static testutil.TestUtilities.makeList;
|
import static testutil.TestUtilities.makeList;
|
||||||
|
@ -29,9 +28,9 @@ public class BackquoteEvaluatorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void evaluateNil() {
|
public void evaluateNil() {
|
||||||
BackquoteEvaluator evaluator = createBackquoteEvaluator(NIL);
|
BackquoteEvaluator evaluator = createBackquoteEvaluator(Nil.INSTANCE);
|
||||||
|
|
||||||
assertSExpressionsMatch(NIL, evaluator.evaluate());
|
assertSExpressionsMatch(Nil.INSTANCE, evaluator.evaluate());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -155,14 +154,17 @@ public class BackquoteEvaluatorTest {
|
||||||
|
|
||||||
@Test(expected = DottedArgumentListException.class)
|
@Test(expected = DottedArgumentListException.class)
|
||||||
public void evaluateDottedList() {
|
public void evaluateDottedList() {
|
||||||
BackquoteEvaluator evaluator = createBackquoteEvaluator(new Cons(T, T));
|
BackquoteEvaluator evaluator =
|
||||||
|
createBackquoteEvaluator(new Cons(Symbol.Companion.getT(), Symbol.Companion.getT()));
|
||||||
|
|
||||||
evaluator.evaluate();
|
evaluator.evaluate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = DottedArgumentListException.class)
|
@Test(expected = DottedArgumentListException.class)
|
||||||
public void atSignWithDottedList() {
|
public void atSignWithDottedList() {
|
||||||
SExpression input = makeList(new CommaExpression(new AtSignExpression(makeList(new Symbol("CONS"), T, T))));
|
SExpression input = makeList(new CommaExpression(new AtSignExpression(makeList(new Symbol("CONS"),
|
||||||
|
Symbol.Companion.getT(),
|
||||||
|
Symbol.Companion.getT()))));
|
||||||
BackquoteEvaluator evaluator = createBackquoteEvaluator(input);
|
BackquoteEvaluator evaluator = createBackquoteEvaluator(input);
|
||||||
|
|
||||||
evaluator.evaluate();
|
evaluator.evaluate();
|
||||||
|
|
|
@ -10,12 +10,12 @@ import function.builtin.EVAL.UnmatchedAtSignException;
|
||||||
import function.builtin.EVAL.UnmatchedCommaException;
|
import function.builtin.EVAL.UnmatchedCommaException;
|
||||||
import function.builtin.special.RECUR.RecurNotInTailPositionException;
|
import function.builtin.special.RECUR.RecurNotInTailPositionException;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import sexpression.Nil;
|
||||||
import testutil.SymbolAndFunctionCleaner;
|
import testutil.SymbolAndFunctionCleaner;
|
||||||
|
|
||||||
import static function.builtin.EVAL.lookupSymbol;
|
import static function.builtin.EVAL.lookupSymbol;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static testutil.TestUtilities.assertIsErrorWithMessage;
|
import static testutil.TestUtilities.assertIsErrorWithMessage;
|
||||||
import static testutil.TestUtilities.assertSExpressionsMatch;
|
import static testutil.TestUtilities.assertSExpressionsMatch;
|
||||||
import static testutil.TestUtilities.evaluateString;
|
import static testutil.TestUtilities.evaluateString;
|
||||||
|
@ -100,12 +100,12 @@ public class EVALTest extends SymbolAndFunctionCleaner {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void undefinedFunctionException_HasCorrectAttributes() {
|
public void undefinedFunctionException_HasCorrectAttributes() {
|
||||||
assertIsErrorWithMessage(new UndefinedFunctionException(NIL));
|
assertIsErrorWithMessage(new UndefinedFunctionException(Nil.INSTANCE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void undefinedSymbolException_HasCorrectAttributes() {
|
public void undefinedSymbolException_HasCorrectAttributes() {
|
||||||
assertIsErrorWithMessage(new UndefinedSymbolException(NIL));
|
assertIsErrorWithMessage(new UndefinedSymbolException(Nil.INSTANCE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = UnmatchedCommaException.class)
|
@Test(expected = UnmatchedCommaException.class)
|
||||||
|
|
|
@ -5,13 +5,13 @@ import function.ArgumentValidator.TooFewArgumentsException;
|
||||||
import function.ArgumentValidator.TooManyArgumentsException;
|
import function.ArgumentValidator.TooManyArgumentsException;
|
||||||
import function.builtin.SYMBOL_FUNCTION.UndefinedSymbolFunctionException;
|
import function.builtin.SYMBOL_FUNCTION.UndefinedSymbolFunctionException;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import sexpression.Nil;
|
||||||
import testutil.SymbolAndFunctionCleaner;
|
import testutil.SymbolAndFunctionCleaner;
|
||||||
|
|
||||||
import static error.Severity.ERROR;
|
import static error.Severity.ERROR;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static testutil.TestUtilities.evaluateString;
|
import static testutil.TestUtilities.evaluateString;
|
||||||
|
|
||||||
public class SYMBOL_FUNCTIONTest extends SymbolAndFunctionCleaner {
|
public class SYMBOL_FUNCTIONTest extends SymbolAndFunctionCleaner {
|
||||||
|
@ -63,7 +63,7 @@ public class SYMBOL_FUNCTIONTest extends SymbolAndFunctionCleaner {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void undefinedSymbolFunctionException_HasCorrectAttributes() {
|
public void undefinedSymbolFunctionException_HasCorrectAttributes() {
|
||||||
UndefinedSymbolFunctionException e = new UndefinedSymbolFunctionException(NIL);
|
UndefinedSymbolFunctionException e = new UndefinedSymbolFunctionException(Nil.INSTANCE);
|
||||||
|
|
||||||
assertEquals(ERROR, e.getSeverity());
|
assertEquals(ERROR, e.getSeverity());
|
||||||
assertNotNull(e.getMessage());
|
assertNotNull(e.getMessage());
|
||||||
|
|
|
@ -8,9 +8,9 @@ import function.builtin.EVAL.UndefinedSymbolException;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
import sexpression.LispNumber;
|
import sexpression.LispNumber;
|
||||||
|
import sexpression.Nil;
|
||||||
import testutil.SymbolAndFunctionCleaner;
|
import testutil.SymbolAndFunctionCleaner;
|
||||||
|
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static testutil.TestUtilities.assertSExpressionsMatch;
|
import static testutil.TestUtilities.assertSExpressionsMatch;
|
||||||
import static testutil.TestUtilities.evaluateString;
|
import static testutil.TestUtilities.evaluateString;
|
||||||
|
|
||||||
|
@ -27,14 +27,14 @@ public class LETTest extends SymbolAndFunctionCleaner {
|
||||||
public void emptyLet_ReturnsNil() {
|
public void emptyLet_ReturnsNil() {
|
||||||
String input = "(let ())";
|
String input = "(let ())";
|
||||||
|
|
||||||
assertSExpressionsMatch(NIL, evaluateString(input));
|
assertSExpressionsMatch(Nil.INSTANCE, evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void letWithSymbolsOnly_SetsValuesToNil() {
|
public void letWithSymbolsOnly_SetsValuesToNil() {
|
||||||
String input = "(let ((x) (y)) (list x y))";
|
String input = "(let ((x) (y)) (list x y))";
|
||||||
|
|
||||||
assertSExpressionsMatch(new Cons(NIL, new Cons(NIL, NIL)), evaluateString(input));
|
assertSExpressionsMatch(new Cons(Nil.INSTANCE, new Cons(Nil.INSTANCE, Nil.INSTANCE)), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -8,9 +8,9 @@ import function.builtin.EVAL.UndefinedSymbolException;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import sexpression.Cons;
|
import sexpression.Cons;
|
||||||
import sexpression.LispNumber;
|
import sexpression.LispNumber;
|
||||||
|
import sexpression.Nil;
|
||||||
import testutil.SymbolAndFunctionCleaner;
|
import testutil.SymbolAndFunctionCleaner;
|
||||||
|
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static testutil.TestUtilities.assertSExpressionsMatch;
|
import static testutil.TestUtilities.assertSExpressionsMatch;
|
||||||
import static testutil.TestUtilities.evaluateString;
|
import static testutil.TestUtilities.evaluateString;
|
||||||
|
|
||||||
|
@ -27,14 +27,14 @@ public class LET_STARTest extends SymbolAndFunctionCleaner {
|
||||||
public void emptyLet_ReturnsNil() {
|
public void emptyLet_ReturnsNil() {
|
||||||
String input = "(let* ())";
|
String input = "(let* ())";
|
||||||
|
|
||||||
assertSExpressionsMatch(NIL, evaluateString(input));
|
assertSExpressionsMatch(Nil.INSTANCE, evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void letStarWithSymbolsOnly_SetsValuesToNil() {
|
public void letStarWithSymbolsOnly_SetsValuesToNil() {
|
||||||
String input = "(let* ((x) (y)) (list x y))";
|
String input = "(let* ((x) (y)) (list x y))";
|
||||||
|
|
||||||
assertSExpressionsMatch(new Cons(NIL, new Cons(NIL, NIL)), evaluateString(input));
|
assertSExpressionsMatch(new Cons(Nil.INSTANCE, new Cons(Nil.INSTANCE, Nil.INSTANCE)), evaluateString(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -12,10 +12,10 @@ import org.junit.jupiter.api.Assertions.assertThrows
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import sexpression.Cons
|
import sexpression.Cons
|
||||||
import sexpression.LispNumber
|
import sexpression.LispNumber
|
||||||
import sexpression.LispNumber.ONE
|
import sexpression.LispNumber.Companion.ONE
|
||||||
import sexpression.Nil.NIL
|
import sexpression.Nil
|
||||||
import sexpression.Symbol
|
import sexpression.Symbol
|
||||||
import sexpression.Symbol.T
|
import sexpression.Symbol.Companion.T
|
||||||
import testutil.SymbolAndFunctionCleaner
|
import testutil.SymbolAndFunctionCleaner
|
||||||
import testutil.TestUtilities.assertSExpressionsMatch
|
import testutil.TestUtilities.assertSExpressionsMatch
|
||||||
import testutil.TestUtilities.evaluateString
|
import testutil.TestUtilities.evaluateString
|
||||||
|
@ -46,7 +46,7 @@ class LambdaTest : SymbolAndFunctionCleaner() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `lambda expression is a lambda expression`() {
|
fun `lambda expression is a lambda expression`() {
|
||||||
val lambdaExpression = Cons(Symbol("LAMBDA"), Cons(NIL, Cons(NIL, NIL)))
|
val lambdaExpression = Cons(Symbol("LAMBDA"), Cons(Nil, Cons(Nil, Nil)))
|
||||||
|
|
||||||
assertThat(isLambdaExpression(lambdaExpression)).isTrue()
|
assertThat(isLambdaExpression(lambdaExpression)).isTrue()
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ class LambdaTest : SymbolAndFunctionCleaner() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `create lambda expression`() {
|
fun `create lambda expression`() {
|
||||||
val lambdaExpression = Cons(Symbol("LAMBDA"), Cons(NIL, Cons(NIL, NIL)))
|
val lambdaExpression = Cons(Symbol("LAMBDA"), Cons(Nil, Cons(Nil, Nil)))
|
||||||
|
|
||||||
assertSExpressionsMatch(parseString("(:LAMBDA () ())"), createFunction(lambdaExpression).lambdaExpression)
|
assertSExpressionsMatch(parseString("(:LAMBDA () ())"), createFunction(lambdaExpression).lambdaExpression)
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ class LambdaTest : SymbolAndFunctionCleaner() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `create function with dotted argument list`() {
|
fun `create function with dotted argument list`() {
|
||||||
val lambdaExpression = Cons(Symbol("LAMBDA"), Cons(NIL, ONE))
|
val lambdaExpression = Cons(Symbol("LAMBDA"), Cons(Nil, ONE))
|
||||||
|
|
||||||
assertThrows(DottedArgumentListException::class.java) { createFunction(lambdaExpression) }
|
assertThrows(DottedArgumentListException::class.java) { createFunction(lambdaExpression) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import static error.Severity.ERROR;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static sexpression.Nil.NIL;
|
|
||||||
import static testutil.TestUtilities.assertSExpressionsMatch;
|
import static testutil.TestUtilities.assertSExpressionsMatch;
|
||||||
import static testutil.TestUtilities.makeList;
|
import static testutil.TestUtilities.makeList;
|
||||||
|
|
||||||
|
@ -25,7 +24,7 @@ public class SExpressionTest {
|
||||||
public void nil_ToString() {
|
public void nil_ToString() {
|
||||||
String input = "NIL";
|
String input = "NIL";
|
||||||
|
|
||||||
assertSExpressionMatchesString(input, NIL);
|
assertSExpressionMatchesString(input, Nil.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -83,7 +82,8 @@ public class SExpressionTest {
|
||||||
@Test
|
@Test
|
||||||
public void lambdaExpression_ToString() {
|
public void lambdaExpression_ToString() {
|
||||||
String expected = "(LAMBDA)";
|
String expected = "(LAMBDA)";
|
||||||
LambdaExpression lambda = new LambdaExpression(makeList(new Symbol("lambda")), null);
|
LambdaExpression lambda = new LambdaExpression(makeList(new Symbol("lambda")),
|
||||||
|
new UserDefinedFunction("", Nil.INSTANCE, Nil.INSTANCE));
|
||||||
|
|
||||||
assertSExpressionMatchesString(expected, lambda);
|
assertSExpressionMatchesString(expected, lambda);
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,8 @@ public class SExpressionTest {
|
||||||
@Test
|
@Test
|
||||||
public void lambdaExpression_GetLambdaExpression() {
|
public void lambdaExpression_GetLambdaExpression() {
|
||||||
String expected = "(LAMBDA)";
|
String expected = "(LAMBDA)";
|
||||||
LambdaExpression lambda = new LambdaExpression(makeList(new Symbol("lambda")), null);
|
LambdaExpression lambda = new LambdaExpression(makeList(new Symbol("lambda")),
|
||||||
|
new UserDefinedFunction("", Nil.INSTANCE, Nil.INSTANCE));
|
||||||
|
|
||||||
assertSExpressionMatchesString(expected, lambda.getLambdaExpression());
|
assertSExpressionMatchesString(expected, lambda.getLambdaExpression());
|
||||||
}
|
}
|
||||||
|
@ -99,7 +100,7 @@ public class SExpressionTest {
|
||||||
@Test
|
@Test
|
||||||
public void lambdaExpression_GetFunction() {
|
public void lambdaExpression_GetFunction() {
|
||||||
String expected = "(LAMBDA)";
|
String expected = "(LAMBDA)";
|
||||||
UserDefinedFunction function = new UserDefinedFunction(expected, NIL, NIL);
|
UserDefinedFunction function = new UserDefinedFunction(expected, Nil.INSTANCE, Nil.INSTANCE);
|
||||||
LambdaExpression lambda = new LambdaExpression(makeList(new Symbol("lambda")), function);
|
LambdaExpression lambda = new LambdaExpression(makeList(new Symbol("lambda")), function);
|
||||||
|
|
||||||
assertEquals(function, lambda.getFunction());
|
assertEquals(function, lambda.getFunction());
|
||||||
|
@ -107,28 +108,28 @@ public class SExpressionTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void firstOfNilIsNil() {
|
public void firstOfNilIsNil() {
|
||||||
assertEquals(NIL, NIL.getFirst());
|
assertEquals(Nil.INSTANCE, Nil.INSTANCE.getFirst());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void restOfNilIsNil() {
|
public void restOfNilIsNil() {
|
||||||
assertEquals(NIL, NIL.getRest());
|
assertEquals(Nil.INSTANCE, Nil.INSTANCE.getRest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void afterSettingFirstOfNil_ShouldStillBeNil() {
|
public void afterSettingFirstOfNil_ShouldStillBeNil() {
|
||||||
Cons nil = NIL;
|
Cons nil = Nil.INSTANCE;
|
||||||
nil.setFirst(new LispNumber("2"));
|
nil.setFirst(new LispNumber("2"));
|
||||||
|
|
||||||
assertEquals(NIL, nil.getFirst());
|
assertEquals(Nil.INSTANCE, nil.getFirst());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void afterSettingRestOfNil_ShouldStillBeNil() {
|
public void afterSettingRestOfNil_ShouldStillBeNil() {
|
||||||
Cons nil = NIL;
|
Cons nil = Nil.INSTANCE;
|
||||||
nil.setRest(new LispNumber("2"));
|
nil.setRest(new LispNumber("2"));
|
||||||
|
|
||||||
assertEquals(NIL, nil.getRest());
|
assertEquals(Nil.INSTANCE, nil.getRest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -159,8 +160,8 @@ public class SExpressionTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void lispNumberConstants() {
|
public void lispNumberConstants() {
|
||||||
assertEquals(BigInteger.ZERO, LispNumber.ZERO.getValue());
|
assertEquals(BigInteger.ZERO, LispNumber.Companion.getZERO().getValue());
|
||||||
assertEquals(BigInteger.ONE, LispNumber.ONE.getValue());
|
assertEquals(BigInteger.ONE, LispNumber.Companion.getONE().getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -6,8 +6,8 @@ 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 sexpression.Nil.NIL
|
import sexpression.Nil
|
||||||
import sexpression.Symbol.T
|
import sexpression.Symbol.Companion.T
|
||||||
import table.SymbolTable.NullSymbolTable
|
import table.SymbolTable.NullSymbolTable
|
||||||
|
|
||||||
@TestInstance(PER_CLASS)
|
@TestInstance(PER_CLASS)
|
||||||
|
@ -75,11 +75,11 @@ class ExecutionContextTest {
|
||||||
fun `lookup a shadowed variable`() {
|
fun `lookup a shadowed variable`() {
|
||||||
val scope = SymbolTable(ExecutionContext.scope)
|
val scope = SymbolTable(ExecutionContext.scope)
|
||||||
|
|
||||||
scope["shadowed"] = NIL
|
scope["shadowed"] = Nil
|
||||||
ExecutionContext.scope["shadowed"] = T
|
ExecutionContext.scope["shadowed"] = T
|
||||||
ExecutionContext.scope = scope
|
ExecutionContext.scope = scope
|
||||||
|
|
||||||
assertThat(ExecutionContext.lookupSymbolValue("shadowed")).isEqualTo(NIL)
|
assertThat(ExecutionContext.lookupSymbolValue("shadowed")).isEqualTo(Nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -13,8 +13,7 @@ import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
|
||||||
import sexpression.Cons
|
import sexpression.Cons
|
||||||
import sexpression.LispString
|
import sexpression.LispString
|
||||||
import sexpression.Nil
|
import sexpression.Nil
|
||||||
import sexpression.Nil.NIL
|
import sexpression.Symbol.Companion.T
|
||||||
import sexpression.Symbol.T
|
|
||||||
import table.FunctionTable.LispFunctionInstantiationException
|
import table.FunctionTable.LispFunctionInstantiationException
|
||||||
import table.FunctionTable.defineFunction
|
import table.FunctionTable.defineFunction
|
||||||
import table.FunctionTable.isAlreadyDefined
|
import table.FunctionTable.isAlreadyDefined
|
||||||
|
@ -31,11 +30,11 @@ class FunctionTableTest {
|
||||||
|
|
||||||
@FunctionNames("BAD")
|
@FunctionNames("BAD")
|
||||||
class BadFunction : LispFunction() {
|
class BadFunction : LispFunction() {
|
||||||
override fun call(argumentList: Cons): Nil = NIL
|
override fun call(argumentList: Cons): Nil = Nil
|
||||||
}
|
}
|
||||||
|
|
||||||
class UglyFunction : LispFunction() {
|
class UglyFunction : LispFunction() {
|
||||||
override fun call(argumentList: Cons): Nil = NIL
|
override fun call(argumentList: Cons): Nil = Nil
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createLispFunction() = object : LispFunction() {
|
private fun createLispFunction() = object : LispFunction() {
|
||||||
|
|
|
@ -5,8 +5,8 @@ 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 sexpression.Nil.NIL
|
import sexpression.Nil
|
||||||
import sexpression.Symbol.T
|
import sexpression.Symbol.Companion.T
|
||||||
|
|
||||||
@TestInstance(PER_CLASS)
|
@TestInstance(PER_CLASS)
|
||||||
class SymbolTableTest {
|
class SymbolTableTest {
|
||||||
|
@ -40,9 +40,9 @@ class SymbolTableTest {
|
||||||
@Test
|
@Test
|
||||||
fun `redefine the value of a symbol`() {
|
fun `redefine the value of a symbol`() {
|
||||||
symbolTable["symbol"] = T
|
symbolTable["symbol"] = T
|
||||||
symbolTable["symbol"] = NIL
|
symbolTable["symbol"] = Nil
|
||||||
|
|
||||||
assertThat(symbolTable["symbol"]).isEqualTo(NIL)
|
assertThat(symbolTable["symbol"]).isEqualTo(Nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -6,7 +6,7 @@ import function.builtin.EVAL.eval
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import parser.LispParser
|
import parser.LispParser
|
||||||
import sexpression.Cons
|
import sexpression.Cons
|
||||||
import sexpression.Nil.NIL
|
import sexpression.Nil
|
||||||
import sexpression.SExpression
|
import sexpression.SExpression
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
@ -64,7 +64,7 @@ object TestUtilities {
|
||||||
@JvmStatic()
|
@JvmStatic()
|
||||||
fun makeList(vararg expressionList: SExpression): Cons {
|
fun makeList(vararg expressionList: SExpression): Cons {
|
||||||
if (expressionList.isEmpty())
|
if (expressionList.isEmpty())
|
||||||
return NIL
|
return Nil
|
||||||
|
|
||||||
val rest = makeList(*Arrays.copyOfRange(expressionList, 1, expressionList.size))
|
val rest = makeList(*Arrays.copyOfRange(expressionList, 1, expressionList.size))
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package testutil
|
package testutil
|
||||||
|
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import sexpression.Nil.NIL
|
import sexpression.Nil
|
||||||
import sexpression.SExpression
|
import sexpression.SExpression
|
||||||
import sexpression.Symbol.T
|
import sexpression.Symbol.Companion.T
|
||||||
|
|
||||||
object TypeAssertions {
|
object TypeAssertions {
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ object TypeAssertions {
|
||||||
|
|
||||||
@JvmStatic()
|
@JvmStatic()
|
||||||
fun assertNil(sExpression: SExpression) {
|
fun assertNil(sExpression: SExpression) {
|
||||||
assertThat(sExpression).isEqualTo(NIL)
|
assertThat(sExpression).isEqualTo(Nil)
|
||||||
|
|
||||||
assertThat(sExpression.isAtom).isTrue()
|
assertThat(sExpression.isAtom).isTrue()
|
||||||
assertThat(sExpression.isCons).isFalse()
|
assertThat(sExpression.isCons).isFalse()
|
||||||
|
|
Loading…
Reference in New Issue