From 16118a9a78171c287e904fb3b26cfebb29083658 Mon Sep 17 00:00:00 2001 From: Mike Cifelli Date: Sat, 11 Aug 2018 08:44:41 -0400 Subject: [PATCH] Convert sexpressions to kotlin --- .../kotlin/function/UserDefinedFunction.java | 4 +- .../function/builtin/BackquoteEvaluator.java | 8 +-- src/main/kotlin/function/builtin/EVAL.java | 9 ++- src/main/kotlin/function/builtin/Exit.kt | 4 +- src/main/kotlin/function/builtin/LOAD.java | 6 +- .../kotlin/function/builtin/cons/APPEND.java | 7 +-- .../kotlin/function/builtin/cons/LIST.java | 5 +- .../function/builtin/math/MULTIPLY.java | 4 +- .../kotlin/function/builtin/math/PLUS.java | 4 +- .../function/builtin/predicate/ATOM.java | 7 +-- .../kotlin/function/builtin/predicate/EQ.java | 9 ++- .../function/builtin/predicate/EQUAL.java | 7 +-- .../builtin/predicate/GENSYM_EQUAL.java | 6 +- .../function/builtin/predicate/LISTP.java | 7 +-- .../function/builtin/predicate/NULL.java | 7 +-- .../builtin/predicate/NUMERIC_GREATER.java | 8 +-- .../builtin/predicate/NUMERIC_LESS.java | 8 +-- .../builtin/predicate/NumericEqual.kt | 6 +- .../kotlin/function/builtin/special/AND.java | 4 +- .../kotlin/function/builtin/special/CASE.java | 9 ++- .../kotlin/function/builtin/special/COND.java | 5 +- .../kotlin/function/builtin/special/LET.java | 4 +- .../function/builtin/special/PROGN.java | 4 +- .../kotlin/sexpression/AtSignExpression.java | 24 -------- .../kotlin/sexpression/AtSignExpression.kt | 9 +++ src/main/kotlin/sexpression/Atom.java | 21 ------- src/main/kotlin/sexpression/Atom.kt | 10 ++++ .../sexpression/BackquoteExpression.java | 24 -------- .../kotlin/sexpression/BackquoteExpression.kt | 9 +++ .../kotlin/sexpression/CommaExpression.java | 24 -------- .../kotlin/sexpression/CommaExpression.kt | 9 +++ src/main/kotlin/sexpression/Cons.java | 56 ------------------- src/main/kotlin/sexpression/Cons.kt | 29 ++++++++++ src/main/kotlin/sexpression/DisplayName.java | 13 ----- src/main/kotlin/sexpression/DisplayName.kt | 9 +++ .../kotlin/sexpression/LambdaExpression.java | 33 ----------- .../kotlin/sexpression/LambdaExpression.kt | 12 ++++ src/main/kotlin/sexpression/LispNumber.java | 56 ------------------- src/main/kotlin/sexpression/LispNumber.kt | 39 +++++++++++++ src/main/kotlin/sexpression/LispString.java | 14 ----- src/main/kotlin/sexpression/LispString.kt | 8 +++ src/main/kotlin/sexpression/Nil.java | 51 ----------------- src/main/kotlin/sexpression/Nil.kt | 27 +++++++++ src/main/kotlin/sexpression/SExpression.java | 49 ---------------- src/main/kotlin/sexpression/SExpression.kt | 38 +++++++++++++ src/main/kotlin/sexpression/Symbol.java | 22 -------- src/main/kotlin/sexpression/Symbol.kt | 16 ++++++ src/main/kotlin/table/ExecutionContext.kt | 4 +- src/main/kotlin/table/SymbolTable.kt | 6 +- src/main/kotlin/token/QuoteMark.kt | 4 +- src/main/kotlin/token/RightParenthesis.kt | 4 +- src/main/kotlin/token/Token.kt | 6 +- src/main/resources/dlambda.lisp | 18 +++--- src/main/resources/functions.lisp | 14 ++--- .../function/ArgumentValidatorTest.java | 39 +++++++------ .../function/UserDefinedFunctionTest.java | 22 +++++--- .../builtin/BackquoteEvaluatorTest.java | 14 +++-- .../kotlin/function/builtin/EVALTest.java | 6 +- .../function/builtin/SYMBOL_FUNCTIONTest.java | 4 +- .../function/builtin/special/LETTest.java | 6 +- .../builtin/special/LET_STARTest.java | 6 +- .../function/builtin/special/LambdaTest.kt | 12 ++-- .../kotlin/sexpression/SExpressionTest.java | 27 ++++----- src/test/kotlin/table/ExecutionContextTest.kt | 8 +-- src/test/kotlin/table/FunctionTableTest.kt | 7 +-- src/test/kotlin/table/SymbolTableTest.kt | 8 +-- src/test/kotlin/testutil/TestUtilities.kt | 4 +- src/test/kotlin/testutil/TypeAssertions.kt | 6 +- 68 files changed, 393 insertions(+), 576 deletions(-) delete mode 100644 src/main/kotlin/sexpression/AtSignExpression.java create mode 100644 src/main/kotlin/sexpression/AtSignExpression.kt delete mode 100644 src/main/kotlin/sexpression/Atom.java create mode 100644 src/main/kotlin/sexpression/Atom.kt delete mode 100644 src/main/kotlin/sexpression/BackquoteExpression.java create mode 100644 src/main/kotlin/sexpression/BackquoteExpression.kt delete mode 100644 src/main/kotlin/sexpression/CommaExpression.java create mode 100644 src/main/kotlin/sexpression/CommaExpression.kt delete mode 100644 src/main/kotlin/sexpression/Cons.java create mode 100644 src/main/kotlin/sexpression/Cons.kt delete mode 100644 src/main/kotlin/sexpression/DisplayName.java create mode 100644 src/main/kotlin/sexpression/DisplayName.kt delete mode 100644 src/main/kotlin/sexpression/LambdaExpression.java create mode 100644 src/main/kotlin/sexpression/LambdaExpression.kt delete mode 100644 src/main/kotlin/sexpression/LispNumber.java create mode 100644 src/main/kotlin/sexpression/LispNumber.kt delete mode 100644 src/main/kotlin/sexpression/LispString.java create mode 100644 src/main/kotlin/sexpression/LispString.kt delete mode 100644 src/main/kotlin/sexpression/Nil.java create mode 100644 src/main/kotlin/sexpression/Nil.kt delete mode 100644 src/main/kotlin/sexpression/SExpression.java create mode 100644 src/main/kotlin/sexpression/SExpression.kt delete mode 100644 src/main/kotlin/sexpression/Symbol.java create mode 100644 src/main/kotlin/sexpression/Symbol.kt diff --git a/src/main/kotlin/function/UserDefinedFunction.java b/src/main/kotlin/function/UserDefinedFunction.java index cb5bcae..36a37ff 100644 --- a/src/main/kotlin/function/UserDefinedFunction.java +++ b/src/main/kotlin/function/UserDefinedFunction.java @@ -4,6 +4,7 @@ import error.LispException; import recursion.TailCall; import recursion.TailCalls; import sexpression.Cons; +import sexpression.Nil; import sexpression.SExpression; import sexpression.Symbol; import table.ExecutionContext; @@ -14,7 +15,6 @@ import java.util.ArrayList; import static function.builtin.EVAL.eval; import static java.text.MessageFormat.format; import static recursion.TailCalls.done; -import static sexpression.Nil.NIL; public class UserDefinedFunction extends LispFunction { @@ -136,7 +136,7 @@ public class UserDefinedFunction extends LispFunction { } private SExpression evaluateBody() { - SExpression lastEvaluation = NIL; + SExpression lastEvaluation = Nil.INSTANCE; for (Cons expression = body; expression.isCons(); expression = (Cons) expression.getRest()) lastEvaluation = eval(expression.getFirst()); diff --git a/src/main/kotlin/function/builtin/BackquoteEvaluator.java b/src/main/kotlin/function/builtin/BackquoteEvaluator.java index 462640b..0903b70 100644 --- a/src/main/kotlin/function/builtin/BackquoteEvaluator.java +++ b/src/main/kotlin/function/builtin/BackquoteEvaluator.java @@ -6,10 +6,10 @@ import sexpression.AtSignExpression; import sexpression.BackquoteExpression; import sexpression.CommaExpression; import sexpression.Cons; +import sexpression.Nil; import sexpression.SExpression; import static function.builtin.EVAL.eval; -import static sexpression.Nil.NIL; class BackquoteEvaluator { @@ -24,7 +24,7 @@ class BackquoteEvaluator { this.listValidator = new ArgumentValidator("`|list|"); this.atSignValidator = new ArgumentValidator("@|list|"); this.backTick = backTick; - this.resolvedList = new Cons(NIL, NIL); + this.resolvedList = new Cons(Nil.INSTANCE, Nil.INSTANCE); this.leader = resolvedList; this.follower = resolvedList; } @@ -53,7 +53,7 @@ class BackquoteEvaluator { for (; list.isCons(); list = (Cons) list.getRest()) resolveExpression(list.getFirst()); - follower.setRest(NIL); + follower.setRest(Nil.INSTANCE); } private void resolveExpression(SExpression expression) { @@ -123,7 +123,7 @@ class BackquoteEvaluator { private void addResolvedExpression(SExpression expression) { leader.setFirst(expression); - leader.setRest(new Cons(NIL, NIL)); + leader.setRest(new Cons(Nil.INSTANCE, Nil.INSTANCE)); follower = leader; leader = (Cons) leader.getRest(); } diff --git a/src/main/kotlin/function/builtin/EVAL.java b/src/main/kotlin/function/builtin/EVAL.java index 6f9ebe0..7c5813a 100644 --- a/src/main/kotlin/function/builtin/EVAL.java +++ b/src/main/kotlin/function/builtin/EVAL.java @@ -8,6 +8,7 @@ import function.builtin.special.RECUR.RecurNotInTailPositionException; import sexpression.BackquoteExpression; import sexpression.Cons; import sexpression.LambdaExpression; +import sexpression.Nil; import sexpression.SExpression; import sexpression.Symbol; import table.ExecutionContext; @@ -16,8 +17,6 @@ import table.FunctionTable; import static function.builtin.cons.LIST.makeList; import static function.builtin.special.Lambda.Lambda; import static java.text.MessageFormat.format; -import static sexpression.Nil.NIL; -import static sexpression.Symbol.T; @FunctionNames({ "EVAL" }) public class EVAL extends LispFunction { @@ -67,9 +66,9 @@ public class EVAL extends LispFunction { public static SExpression lookupSymbol(String symbolName) { if (symbolName.equals("NIL")) - return NIL; + return Nil.INSTANCE; else if (symbolName.equals("T")) - return T; + return Symbol.Companion.getT(); else if (symbolName.startsWith(":")) return new Symbol(symbolName); @@ -155,7 +154,7 @@ public class EVAL extends LispFunction { private Cons evaluateArgumentList(Cons arguments) { if (arguments.isNull()) - return NIL; + return Nil.INSTANCE; SExpression first = eval(arguments.getFirst()); SExpression rest = arguments.getRest(); diff --git a/src/main/kotlin/function/builtin/Exit.kt b/src/main/kotlin/function/builtin/Exit.kt index 9e008d3..814273d 100644 --- a/src/main/kotlin/function/builtin/Exit.kt +++ b/src/main/kotlin/function/builtin/Exit.kt @@ -5,7 +5,7 @@ import function.ArgumentValidator import function.FunctionNames import function.LispFunction import sexpression.Cons -import sexpression.Nil.NIL +import sexpression.Nil import sexpression.SExpression @FunctionNames("EXIT") @@ -21,6 +21,6 @@ class Exit(name: String) : LispFunction() { argumentValidator.validate(argumentList) RuntimeEnvironment.terminateSuccessfully() - return NIL + return Nil } } diff --git a/src/main/kotlin/function/builtin/LOAD.java b/src/main/kotlin/function/builtin/LOAD.java index c09d9bf..8c93b50 100644 --- a/src/main/kotlin/function/builtin/LOAD.java +++ b/src/main/kotlin/function/builtin/LOAD.java @@ -9,7 +9,9 @@ import function.LispFunction; import parser.LispParser; import sexpression.Cons; import sexpression.LispString; +import sexpression.Nil; import sexpression.SExpression; +import sexpression.Symbol; import util.Path; import java.io.FileInputStream; @@ -18,8 +20,6 @@ import java.util.Stack; import static function.builtin.EVAL.eval; import static java.text.MessageFormat.format; -import static sexpression.Nil.NIL; -import static sexpression.Symbol.T; @FunctionNames({ "LOAD" }) public class LOAD extends LispFunction { @@ -57,7 +57,7 @@ public class LOAD extends LispFunction { if (parser != null) isSuccessful = isSuccessfulEvaluationWithPathPrefix(prefixedFileName, parser); - return isSuccessful ? T : NIL; + return isSuccessful ? Symbol.Companion.getT() : Nil.INSTANCE; } private String prefixFileNameIfNecessary(String fileName) { diff --git a/src/main/kotlin/function/builtin/cons/APPEND.java b/src/main/kotlin/function/builtin/cons/APPEND.java index 3eecd27..d75edea 100644 --- a/src/main/kotlin/function/builtin/cons/APPEND.java +++ b/src/main/kotlin/function/builtin/cons/APPEND.java @@ -4,10 +4,9 @@ import function.ArgumentValidator; import function.FunctionNames; import function.LispFunction; import sexpression.Cons; +import sexpression.Nil; import table.FunctionTable; -import static sexpression.Nil.NIL; - @FunctionNames({ "APPEND" }) public class APPEND extends LispFunction { @@ -53,11 +52,11 @@ public class APPEND extends LispFunction { } private Cons copy(Cons list) { - Cons newList = new Cons(list.getFirst(), NIL); + Cons newList = new Cons(list.getFirst(), Nil.INSTANCE); Cons builder = newList; 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(); } diff --git a/src/main/kotlin/function/builtin/cons/LIST.java b/src/main/kotlin/function/builtin/cons/LIST.java index 8a07cb4..443d0f1 100644 --- a/src/main/kotlin/function/builtin/cons/LIST.java +++ b/src/main/kotlin/function/builtin/cons/LIST.java @@ -4,15 +4,14 @@ import function.ArgumentValidator; import function.FunctionNames; import function.LispFunction; import sexpression.Cons; +import sexpression.Nil; import sexpression.SExpression; -import static sexpression.Nil.NIL; - @FunctionNames({ "LIST" }) public class LIST extends LispFunction { public static Cons makeList(SExpression sexpr) { - return new Cons(sexpr, NIL); + return new Cons(sexpr, Nil.INSTANCE); } private ArgumentValidator argumentValidator; diff --git a/src/main/kotlin/function/builtin/math/MULTIPLY.java b/src/main/kotlin/function/builtin/math/MULTIPLY.java index 236cfa5..5420fd5 100644 --- a/src/main/kotlin/function/builtin/math/MULTIPLY.java +++ b/src/main/kotlin/function/builtin/math/MULTIPLY.java @@ -6,8 +6,6 @@ import function.LispFunction; import sexpression.Cons; import sexpression.LispNumber; -import static sexpression.LispNumber.ONE; - @FunctionNames({ "*" }) public class MULTIPLY extends LispFunction { @@ -24,7 +22,7 @@ public class MULTIPLY extends LispFunction { public LispNumber call(Cons 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) { diff --git a/src/main/kotlin/function/builtin/math/PLUS.java b/src/main/kotlin/function/builtin/math/PLUS.java index 785b8af..40a1eae 100644 --- a/src/main/kotlin/function/builtin/math/PLUS.java +++ b/src/main/kotlin/function/builtin/math/PLUS.java @@ -6,8 +6,6 @@ import function.LispFunction; import sexpression.Cons; import sexpression.LispNumber; -import static sexpression.LispNumber.ZERO; - @FunctionNames({ "+" }) public class PLUS extends LispFunction { @@ -24,7 +22,7 @@ public class PLUS extends LispFunction { public LispNumber call(Cons 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) { diff --git a/src/main/kotlin/function/builtin/predicate/ATOM.java b/src/main/kotlin/function/builtin/predicate/ATOM.java index a8301a6..022c6fc 100644 --- a/src/main/kotlin/function/builtin/predicate/ATOM.java +++ b/src/main/kotlin/function/builtin/predicate/ATOM.java @@ -4,10 +4,9 @@ import function.ArgumentValidator; import function.FunctionNames; import function.LispFunction; import sexpression.Cons; +import sexpression.Nil; import sexpression.SExpression; - -import static sexpression.Nil.NIL; -import static sexpression.Symbol.T; +import sexpression.Symbol; @FunctionNames({ "ATOM", "ATOM?" }) public class ATOM extends LispFunction { @@ -24,6 +23,6 @@ public class ATOM extends LispFunction { argumentValidator.validate(argumentList); SExpression argument = argumentList.getFirst(); - return argument.isAtom() ? T : NIL; + return argument.isAtom() ? Symbol.Companion.getT() : Nil.INSTANCE; } } diff --git a/src/main/kotlin/function/builtin/predicate/EQ.java b/src/main/kotlin/function/builtin/predicate/EQ.java index 2dac67b..cdfa72a 100644 --- a/src/main/kotlin/function/builtin/predicate/EQ.java +++ b/src/main/kotlin/function/builtin/predicate/EQ.java @@ -4,10 +4,9 @@ import function.ArgumentValidator; import function.FunctionNames; import function.LispFunction; import sexpression.Cons; +import sexpression.Nil; import sexpression.SExpression; - -import static sexpression.Nil.NIL; -import static sexpression.Symbol.T; +import sexpression.Symbol; @FunctionNames({ "EQ", "EQ?" }) public class EQ extends LispFunction { @@ -42,7 +41,7 @@ public class EQ extends LispFunction { } 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) { @@ -50,6 +49,6 @@ public class EQ extends LispFunction { } private SExpression listEq(SExpression firstArgument, SExpression secondArgument) { - return (firstArgument == secondArgument) ? T : NIL; + return (firstArgument == secondArgument) ? Symbol.Companion.getT() : Nil.INSTANCE; } } diff --git a/src/main/kotlin/function/builtin/predicate/EQUAL.java b/src/main/kotlin/function/builtin/predicate/EQUAL.java index 92e77ce..df25f15 100644 --- a/src/main/kotlin/function/builtin/predicate/EQUAL.java +++ b/src/main/kotlin/function/builtin/predicate/EQUAL.java @@ -4,10 +4,9 @@ import function.ArgumentValidator; import function.FunctionNames; import function.LispFunction; import sexpression.Cons; +import sexpression.Nil; import sexpression.SExpression; - -import static sexpression.Nil.NIL; -import static sexpression.Symbol.T; +import sexpression.Symbol; @FunctionNames({ "EQUAL", "EQUAL?" }) public class EQUAL extends LispFunction { @@ -35,6 +34,6 @@ public class EQUAL extends LispFunction { } private SExpression equal(SExpression firstArgument, SExpression secondArgument) { - return isEqual(firstArgument, secondArgument) ? T : NIL; + return isEqual(firstArgument, secondArgument) ? Symbol.Companion.getT() : Nil.INSTANCE; } } diff --git a/src/main/kotlin/function/builtin/predicate/GENSYM_EQUAL.java b/src/main/kotlin/function/builtin/predicate/GENSYM_EQUAL.java index 9964ee9..d87f352 100644 --- a/src/main/kotlin/function/builtin/predicate/GENSYM_EQUAL.java +++ b/src/main/kotlin/function/builtin/predicate/GENSYM_EQUAL.java @@ -4,7 +4,9 @@ import function.ArgumentValidator; import function.FunctionNames; import function.LispFunction; import sexpression.Cons; +import sexpression.Nil; import sexpression.SExpression; +import sexpression.Symbol; import java.util.HashMap; import java.util.Map; @@ -13,8 +15,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import static function.builtin.GENSYM.GENSYM_PREFIX; -import static sexpression.Nil.NIL; -import static sexpression.Symbol.T; @FunctionNames({ "GENSYM-EQUAL", "GENSYM-EQUAL?" }) public class GENSYM_EQUAL extends LispFunction { @@ -41,7 +41,7 @@ public class GENSYM_EQUAL extends LispFunction { String firstEqualized = equalizeGensyms(firstArgument); String secondEqualized = equalizeGensyms(secondArgument); - return firstEqualized.equals(secondEqualized) ? T : NIL; + return firstEqualized.equals(secondEqualized) ? Symbol.Companion.getT() : Nil.INSTANCE; } private String equalizeGensyms(SExpression expression) { diff --git a/src/main/kotlin/function/builtin/predicate/LISTP.java b/src/main/kotlin/function/builtin/predicate/LISTP.java index e8d0d06..15b790e 100644 --- a/src/main/kotlin/function/builtin/predicate/LISTP.java +++ b/src/main/kotlin/function/builtin/predicate/LISTP.java @@ -4,10 +4,9 @@ import function.ArgumentValidator; import function.FunctionNames; import function.LispFunction; import sexpression.Cons; +import sexpression.Nil; import sexpression.SExpression; - -import static sexpression.Nil.NIL; -import static sexpression.Symbol.T; +import sexpression.Symbol; @FunctionNames({ "LISTP", "LIST?" }) public class LISTP extends LispFunction { @@ -23,6 +22,6 @@ public class LISTP extends LispFunction { public SExpression call(Cons argumentList) { argumentValidator.validate(argumentList); - return argumentList.getFirst().isList() ? T : NIL; + return argumentList.getFirst().isList() ? Symbol.Companion.getT() : Nil.INSTANCE; } } diff --git a/src/main/kotlin/function/builtin/predicate/NULL.java b/src/main/kotlin/function/builtin/predicate/NULL.java index 216cd8c..4be61b8 100644 --- a/src/main/kotlin/function/builtin/predicate/NULL.java +++ b/src/main/kotlin/function/builtin/predicate/NULL.java @@ -4,10 +4,9 @@ import function.ArgumentValidator; import function.FunctionNames; import function.LispFunction; import sexpression.Cons; +import sexpression.Nil; import sexpression.SExpression; - -import static sexpression.Nil.NIL; -import static sexpression.Symbol.T; +import sexpression.Symbol; @FunctionNames({ "NULL", "NULL?" }) public class NULL extends LispFunction { @@ -23,6 +22,6 @@ public class NULL extends LispFunction { public SExpression call(Cons argumentList) { argumentValidator.validate(argumentList); - return argumentList.getFirst().isNull() ? T : NIL; + return argumentList.getFirst().isNull() ? Symbol.Companion.getT() : Nil.INSTANCE; } } diff --git a/src/main/kotlin/function/builtin/predicate/NUMERIC_GREATER.java b/src/main/kotlin/function/builtin/predicate/NUMERIC_GREATER.java index e3dc795..4c70522 100644 --- a/src/main/kotlin/function/builtin/predicate/NUMERIC_GREATER.java +++ b/src/main/kotlin/function/builtin/predicate/NUMERIC_GREATER.java @@ -6,12 +6,12 @@ import function.LispFunction; import recursion.TailCall; import sexpression.Cons; import sexpression.LispNumber; +import sexpression.Nil; import sexpression.SExpression; +import sexpression.Symbol; import static recursion.TailCalls.done; import static recursion.TailCalls.tailCall; -import static sexpression.Nil.NIL; -import static sexpression.Symbol.T; @FunctionNames({ ">" }) public class NUMERIC_GREATER extends LispFunction { @@ -35,7 +35,7 @@ public class NUMERIC_GREATER extends LispFunction { Cons remainingArguments = (Cons) argumentList.getRest(); if (remainingArguments.isNull()) - return done(T); + return done(Symbol.Companion.getT()); SExpression firstArgument = argumentList.getFirst(); SExpression secondArgument = remainingArguments.getFirst(); @@ -43,7 +43,7 @@ public class NUMERIC_GREATER extends LispFunction { LispNumber number2 = (LispNumber) secondArgument; if (!isFirstGreater(number1, number2)) - return done(NIL); + return done(Nil.INSTANCE); return tailCall(() -> callTailRecursive(remainingArguments)); } diff --git a/src/main/kotlin/function/builtin/predicate/NUMERIC_LESS.java b/src/main/kotlin/function/builtin/predicate/NUMERIC_LESS.java index ac5d8c7..8c2aadd 100644 --- a/src/main/kotlin/function/builtin/predicate/NUMERIC_LESS.java +++ b/src/main/kotlin/function/builtin/predicate/NUMERIC_LESS.java @@ -6,12 +6,12 @@ import function.LispFunction; import recursion.TailCall; import sexpression.Cons; import sexpression.LispNumber; +import sexpression.Nil; import sexpression.SExpression; +import sexpression.Symbol; import static recursion.TailCalls.done; import static recursion.TailCalls.tailCall; -import static sexpression.Nil.NIL; -import static sexpression.Symbol.T; @FunctionNames({ "<" }) public class NUMERIC_LESS extends LispFunction { @@ -35,7 +35,7 @@ public class NUMERIC_LESS extends LispFunction { Cons remainingArguments = (Cons) argumentList.getRest(); if (remainingArguments.isNull()) - return done(T); + return done(Symbol.Companion.getT()); SExpression firstArgument = argumentList.getFirst(); SExpression secondArgument = remainingArguments.getFirst(); @@ -43,7 +43,7 @@ public class NUMERIC_LESS extends LispFunction { LispNumber number2 = (LispNumber) secondArgument; if (!isFirstLesser(number1, number2)) - return done(NIL); + return done(Nil.INSTANCE); return tailCall(() -> callTailRecursive(remainingArguments)); } diff --git a/src/main/kotlin/function/builtin/predicate/NumericEqual.kt b/src/main/kotlin/function/builtin/predicate/NumericEqual.kt index cb9863f..ed75ba9 100644 --- a/src/main/kotlin/function/builtin/predicate/NumericEqual.kt +++ b/src/main/kotlin/function/builtin/predicate/NumericEqual.kt @@ -5,9 +5,9 @@ import function.FunctionNames import function.LispFunction import sexpression.Cons import sexpression.LispNumber -import sexpression.Nil.NIL +import sexpression.Nil import sexpression.SExpression -import sexpression.Symbol.T +import sexpression.Symbol.Companion.T @FunctionNames("=") class NumericEqual(name: String) : LispFunction() { @@ -34,6 +34,6 @@ class NumericEqual(name: String) : LispFunction() { val number1 = argumentList.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) } } diff --git a/src/main/kotlin/function/builtin/special/AND.java b/src/main/kotlin/function/builtin/special/AND.java index 160e431..93ccb8f 100644 --- a/src/main/kotlin/function/builtin/special/AND.java +++ b/src/main/kotlin/function/builtin/special/AND.java @@ -6,11 +6,11 @@ import function.LispSpecialFunction; import recursion.TailCall; import sexpression.Cons; import sexpression.SExpression; +import sexpression.Symbol; import static function.builtin.EVAL.eval; import static recursion.TailCalls.done; import static recursion.TailCalls.tailCall; -import static sexpression.Symbol.T; @FunctionNames({ "AND" }) public class AND extends LispSpecialFunction { @@ -25,7 +25,7 @@ public class AND extends LispSpecialFunction { public SExpression call(Cons argumentList) { argumentValidator.validate(argumentList); - return callTailRecursive(argumentList, T).invoke(); + return callTailRecursive(argumentList, Symbol.Companion.getT()).invoke(); } private TailCall callTailRecursive(Cons argumentList, SExpression lastValue) { diff --git a/src/main/kotlin/function/builtin/special/CASE.java b/src/main/kotlin/function/builtin/special/CASE.java index 8cce375..b1c3de4 100644 --- a/src/main/kotlin/function/builtin/special/CASE.java +++ b/src/main/kotlin/function/builtin/special/CASE.java @@ -7,13 +7,12 @@ import recursion.TailCall; import sexpression.Cons; import sexpression.Nil; import sexpression.SExpression; +import sexpression.Symbol; import static function.builtin.EVAL.eval; import static function.builtin.predicate.EQUAL.isEqual; import static recursion.TailCalls.done; import static recursion.TailCalls.tailCall; -import static sexpression.Nil.NIL; -import static sexpression.Symbol.T; @FunctionNames({ "CASE" }) public class CASE extends LispSpecialFunction { @@ -37,7 +36,7 @@ public class CASE extends LispSpecialFunction { private TailCall callTailRecursive(SExpression key, Cons argumentList) { if (argumentList.isNull()) - return done(NIL); + return done(Nil.INSTANCE); Cons clause = (Cons) argumentList.getFirst(); Cons remainingClauses = (Cons) argumentList.getRest(); @@ -55,7 +54,7 @@ public class CASE extends LispSpecialFunction { else if (keyList.isCons()) 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) { @@ -75,7 +74,7 @@ public class CASE extends LispSpecialFunction { } private SExpression evaluateConsequents(SExpression consequentList) { - SExpression lastConsequentValue = NIL; + SExpression lastConsequentValue = Nil.INSTANCE; for (; consequentList.isCons(); consequentList = advanceCons(consequentList)) lastConsequentValue = eval(getFirst(consequentList)); diff --git a/src/main/kotlin/function/builtin/special/COND.java b/src/main/kotlin/function/builtin/special/COND.java index c769a9d..12166ab 100644 --- a/src/main/kotlin/function/builtin/special/COND.java +++ b/src/main/kotlin/function/builtin/special/COND.java @@ -11,7 +11,6 @@ import sexpression.SExpression; import static function.builtin.EVAL.eval; import static recursion.TailCalls.done; import static recursion.TailCalls.tailCall; -import static sexpression.Nil.NIL; @FunctionNames({ "COND" }) public class COND extends LispSpecialFunction { @@ -33,7 +32,7 @@ public class COND extends LispSpecialFunction { private TailCall callTailRecursive(Cons argumentList) { if (argumentList.isNull()) - return done(NIL); + return done(Nil.INSTANCE); Cons clause = (Cons) argumentList.getFirst(); Cons remainingClauses = (Cons) argumentList.getRest(); @@ -46,7 +45,7 @@ public class COND extends LispSpecialFunction { } private boolean isTestSuccessful(SExpression test) { - return test != NIL; + return test != Nil.INSTANCE; } private SExpression evaluateConsequents(SExpression consequentList, SExpression test) { diff --git a/src/main/kotlin/function/builtin/special/LET.java b/src/main/kotlin/function/builtin/special/LET.java index 8d594a4..a2c3c9e 100644 --- a/src/main/kotlin/function/builtin/special/LET.java +++ b/src/main/kotlin/function/builtin/special/LET.java @@ -4,13 +4,13 @@ import function.ArgumentValidator; import function.FunctionNames; import function.LispSpecialFunction; import sexpression.Cons; +import sexpression.Nil; import sexpression.SExpression; import sexpression.Symbol; import table.ExecutionContext; import table.SymbolTable; import static function.builtin.EVAL.eval; -import static sexpression.Nil.NIL; @FunctionNames({ "LET" }) public class LET extends LispSpecialFunction { @@ -79,7 +79,7 @@ public class LET extends LispSpecialFunction { } private SExpression evaluateBody(Cons body) { - SExpression lastEvaluation = NIL; + SExpression lastEvaluation = Nil.INSTANCE; for (; body.isCons(); body = (Cons) body.getRest()) lastEvaluation = eval(body.getFirst()); diff --git a/src/main/kotlin/function/builtin/special/PROGN.java b/src/main/kotlin/function/builtin/special/PROGN.java index 12f1a47..e8719b2 100644 --- a/src/main/kotlin/function/builtin/special/PROGN.java +++ b/src/main/kotlin/function/builtin/special/PROGN.java @@ -5,12 +5,12 @@ import function.FunctionNames; import function.LispSpecialFunction; import recursion.TailCall; import sexpression.Cons; +import sexpression.Nil; import sexpression.SExpression; import static function.builtin.EVAL.eval; import static recursion.TailCalls.done; import static recursion.TailCalls.tailCall; -import static sexpression.Nil.NIL; @FunctionNames({ "PROGN", "BEGIN" }) public class PROGN extends LispSpecialFunction { @@ -25,7 +25,7 @@ public class PROGN extends LispSpecialFunction { public SExpression call(Cons argumentList) { argumentValidator.validate(argumentList); - return callTailRecursive(argumentList, NIL).invoke(); + return callTailRecursive(argumentList, Nil.INSTANCE).invoke(); } private TailCall callTailRecursive(Cons argumentList, SExpression lastValue) { diff --git a/src/main/kotlin/sexpression/AtSignExpression.java b/src/main/kotlin/sexpression/AtSignExpression.java deleted file mode 100644 index 98c3008..0000000 --- a/src/main/kotlin/sexpression/AtSignExpression.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/kotlin/sexpression/AtSignExpression.kt b/src/main/kotlin/sexpression/AtSignExpression.kt new file mode 100644 index 0000000..7f420e9 --- /dev/null +++ b/src/main/kotlin/sexpression/AtSignExpression.kt @@ -0,0 +1,9 @@ +package sexpression + +class AtSignExpression(val expression: SExpression) : SExpression() { + + override val isAtSign: Boolean + get() = true + + override fun toString() = "@$expression" +} diff --git a/src/main/kotlin/sexpression/Atom.java b/src/main/kotlin/sexpression/Atom.java deleted file mode 100644 index 14ff7b1..0000000 --- a/src/main/kotlin/sexpression/Atom.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/kotlin/sexpression/Atom.kt b/src/main/kotlin/sexpression/Atom.kt new file mode 100644 index 0000000..2cd3917 --- /dev/null +++ b/src/main/kotlin/sexpression/Atom.kt @@ -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 +} diff --git a/src/main/kotlin/sexpression/BackquoteExpression.java b/src/main/kotlin/sexpression/BackquoteExpression.java deleted file mode 100644 index ec59adc..0000000 --- a/src/main/kotlin/sexpression/BackquoteExpression.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/kotlin/sexpression/BackquoteExpression.kt b/src/main/kotlin/sexpression/BackquoteExpression.kt new file mode 100644 index 0000000..4dbe500 --- /dev/null +++ b/src/main/kotlin/sexpression/BackquoteExpression.kt @@ -0,0 +1,9 @@ +package sexpression + +class BackquoteExpression(val expression: SExpression) : SExpression() { + + override val isBackquote: Boolean + get() = true + + override fun toString() = "`$expression" +} diff --git a/src/main/kotlin/sexpression/CommaExpression.java b/src/main/kotlin/sexpression/CommaExpression.java deleted file mode 100644 index 71e4744..0000000 --- a/src/main/kotlin/sexpression/CommaExpression.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/kotlin/sexpression/CommaExpression.kt b/src/main/kotlin/sexpression/CommaExpression.kt new file mode 100644 index 0000000..ca93423 --- /dev/null +++ b/src/main/kotlin/sexpression/CommaExpression.kt @@ -0,0 +1,9 @@ +package sexpression + +class CommaExpression(val expression: SExpression) : SExpression() { + + override val isComma: Boolean + get() = true + + override fun toString() = ",$expression" +} diff --git a/src/main/kotlin/sexpression/Cons.java b/src/main/kotlin/sexpression/Cons.java deleted file mode 100644 index fa2d1b7..0000000 --- a/src/main/kotlin/sexpression/Cons.java +++ /dev/null @@ -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 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()); - } -} diff --git a/src/main/kotlin/sexpression/Cons.kt b/src/main/kotlin/sexpression/Cons.kt new file mode 100644 index 0000000..d0972ac --- /dev/null +++ b/src/main/kotlin/sexpression/Cons.kt @@ -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 { + 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()) + } +} diff --git a/src/main/kotlin/sexpression/DisplayName.java b/src/main/kotlin/sexpression/DisplayName.java deleted file mode 100644 index d116ce7..0000000 --- a/src/main/kotlin/sexpression/DisplayName.java +++ /dev/null @@ -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(); -} diff --git a/src/main/kotlin/sexpression/DisplayName.kt b/src/main/kotlin/sexpression/DisplayName.kt new file mode 100644 index 0000000..8c65814 --- /dev/null +++ b/src/main/kotlin/sexpression/DisplayName.kt @@ -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) diff --git a/src/main/kotlin/sexpression/LambdaExpression.java b/src/main/kotlin/sexpression/LambdaExpression.java deleted file mode 100644 index 0c46ebc..0000000 --- a/src/main/kotlin/sexpression/LambdaExpression.java +++ /dev/null @@ -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(); - } -} diff --git a/src/main/kotlin/sexpression/LambdaExpression.kt b/src/main/kotlin/sexpression/LambdaExpression.kt new file mode 100644 index 0000000..1138fec --- /dev/null +++ b/src/main/kotlin/sexpression/LambdaExpression.kt @@ -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() +} diff --git a/src/main/kotlin/sexpression/LispNumber.java b/src/main/kotlin/sexpression/LispNumber.java deleted file mode 100644 index 696e64b..0000000 --- a/src/main/kotlin/sexpression/LispNumber.java +++ /dev/null @@ -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); - } - } -} diff --git a/src/main/kotlin/sexpression/LispNumber.kt b/src/main/kotlin/sexpression/LispNumber.kt new file mode 100644 index 0000000..ea4cc1b --- /dev/null +++ b/src/main/kotlin/sexpression/LispNumber.kt @@ -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) + } +} diff --git a/src/main/kotlin/sexpression/LispString.java b/src/main/kotlin/sexpression/LispString.java deleted file mode 100644 index e433eac..0000000 --- a/src/main/kotlin/sexpression/LispString.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/kotlin/sexpression/LispString.kt b/src/main/kotlin/sexpression/LispString.kt new file mode 100644 index 0000000..fc1f8cb --- /dev/null +++ b/src/main/kotlin/sexpression/LispString.kt @@ -0,0 +1,8 @@ +package sexpression + +@DisplayName("string") +class LispString(text: String) : Atom(text) { + + override val isString: Boolean + get() = true +} diff --git a/src/main/kotlin/sexpression/Nil.java b/src/main/kotlin/sexpression/Nil.java deleted file mode 100644 index 6192673..0000000 --- a/src/main/kotlin/sexpression/Nil.java +++ /dev/null @@ -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"; - } -} diff --git a/src/main/kotlin/sexpression/Nil.kt b/src/main/kotlin/sexpression/Nil.kt new file mode 100644 index 0000000..705b290 --- /dev/null +++ b/src/main/kotlin/sexpression/Nil.kt @@ -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" +} diff --git a/src/main/kotlin/sexpression/SExpression.java b/src/main/kotlin/sexpression/SExpression.java deleted file mode 100644 index 476bf97..0000000 --- a/src/main/kotlin/sexpression/SExpression.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/kotlin/sexpression/SExpression.kt b/src/main/kotlin/sexpression/SExpression.kt new file mode 100644 index 0000000..dcdf92c --- /dev/null +++ b/src/main/kotlin/sexpression/SExpression.kt @@ -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 +} diff --git a/src/main/kotlin/sexpression/Symbol.java b/src/main/kotlin/sexpression/Symbol.java deleted file mode 100644 index 3e998b9..0000000 --- a/src/main/kotlin/sexpression/Symbol.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/kotlin/sexpression/Symbol.kt b/src/main/kotlin/sexpression/Symbol.kt new file mode 100644 index 0000000..b5eeca7 --- /dev/null +++ b/src/main/kotlin/sexpression/Symbol.kt @@ -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") + } +} diff --git a/src/main/kotlin/table/ExecutionContext.kt b/src/main/kotlin/table/ExecutionContext.kt index aec7a42..eefaa24 100644 --- a/src/main/kotlin/table/ExecutionContext.kt +++ b/src/main/kotlin/table/ExecutionContext.kt @@ -2,7 +2,7 @@ package table import function.LispFunction import sexpression.Cons -import sexpression.Nil.NIL +import sexpression.Nil import sexpression.SExpression import table.SymbolTable.NullSymbolTable import java.util.Stack @@ -39,7 +39,7 @@ object ExecutionContext { } fun toList(): Cons { - var symbols: Cons = NIL + var symbols: Cons = Nil for (table in scope) symbols = Cons(table.toList(), symbols) diff --git a/src/main/kotlin/table/SymbolTable.kt b/src/main/kotlin/table/SymbolTable.kt index eea1a27..50da9e6 100644 --- a/src/main/kotlin/table/SymbolTable.kt +++ b/src/main/kotlin/table/SymbolTable.kt @@ -3,14 +3,14 @@ package table import function.builtin.cons.APPEND.append import function.builtin.cons.LIST.makeList import sexpression.Cons -import sexpression.Nil.NIL +import sexpression.Nil import sexpression.SExpression import sexpression.Symbol import kotlin.collections.Map.Entry open class SymbolTable @JvmOverloads constructor(open val parent: SymbolTable? = NullSymbolTable) : Iterable { - private val table = mutableMapOf() + private val table = mutableMapOf() override fun iterator(): Iterator = SymbolTableIterator(this) 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 toList(): Cons { - var context: Cons = NIL + var context: Cons = Nil for (binding in table.toSortedMap().entries) context = append(context, makeList(makeSymbolValuePair(binding))) diff --git a/src/main/kotlin/token/QuoteMark.kt b/src/main/kotlin/token/QuoteMark.kt index a6df641..be8abc2 100644 --- a/src/main/kotlin/token/QuoteMark.kt +++ b/src/main/kotlin/token/QuoteMark.kt @@ -2,7 +2,7 @@ package token import file.FilePosition import sexpression.Cons -import sexpression.Nil.NIL +import sexpression.Nil import sexpression.SExpression import sexpression.Symbol @@ -12,6 +12,6 @@ class QuoteMark(text: String, position: FilePosition) : Token(text, position) { val nextToken = getNextToken() val argument = nextToken.parseSExpression(getNextToken) - return Cons(Symbol.createQuote(), Cons(argument, NIL)) + return Cons(Symbol.createQuote(), Cons(argument, Nil)) } } diff --git a/src/main/kotlin/token/RightParenthesis.kt b/src/main/kotlin/token/RightParenthesis.kt index e8432ba..3c9c0b7 100644 --- a/src/main/kotlin/token/RightParenthesis.kt +++ b/src/main/kotlin/token/RightParenthesis.kt @@ -5,7 +5,7 @@ import file.FilePosition import recursion.TailCall import recursion.TailCalls.done import sexpression.Cons -import sexpression.Nil.NIL +import sexpression.Nil import sexpression.SExpression 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 { - return done(NIL) + return done(Nil) } override fun parseListTailRecursive(start: Cons, end: Cons, getNextToken: () -> Token): TailCall { diff --git a/src/main/kotlin/token/Token.kt b/src/main/kotlin/token/Token.kt index 2fa2f44..c1f8708 100644 --- a/src/main/kotlin/token/Token.kt +++ b/src/main/kotlin/token/Token.kt @@ -4,7 +4,7 @@ import file.FilePosition import recursion.TailCall import recursion.TailCalls.tailCall import sexpression.Cons -import sexpression.Nil.NIL +import sexpression.Nil import sexpression.SExpression 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 open fun parseListTail(getNextToken: () -> Token): TailCall { - val firstCons = Cons(parseSExpression(getNextToken), NIL) + val firstCons = Cons(parseSExpression(getNextToken), Nil) val next = getNextToken() return tailCall { next.parseListTailRecursive(firstCons, firstCons, getNextToken) } } protected open fun parseListTailRecursive(start: Cons, end: Cons, getNextToken: () -> Token): TailCall { - val newEnd = Cons(parseSExpression(getNextToken), NIL) + val newEnd = Cons(parseSExpression(getNextToken), Nil) val next = getNextToken() end.rest = newEnd diff --git a/src/main/resources/dlambda.lisp b/src/main/resources/dlambda.lisp index 4d67997..c43fc95 100644 --- a/src/main/resources/dlambda.lisp +++ b/src/main/resources/dlambda.lisp @@ -3,13 +3,11 @@ (defmacro dlambda (&rest methods) (let ((arguments (gensym))) - `(lambda (&rest ,arguments) - (case (first ,arguments) - ,@(mapcar - (lambda (method) - `(,(first method) - (apply (lambda ,@(rest method)) - ,(if (equal t (first method)) - arguments - `(rest ,arguments))))) - methods))))) + `(lambda (&rest, arguments) + (case (first, arguments), @(mapcar + (lambda (method)) + `(, (first method)) + (apply (lambda, @(rest method)), (if (equal t (first method))) + arguments + `(rest, arguments)) + methods))))) diff --git a/src/main/resources/functions.lisp b/src/main/resources/functions.lisp index 985b765..72701e6 100644 --- a/src/main/resources/functions.lisp +++ b/src/main/resources/functions.lisp @@ -6,9 +6,9 @@ (defun maplist (function-name the-list) (cond - ((null the-list) nil) - (t (cons (funcall function-name the-list) - (maplist function-name (rest the-list)))))) + ((null the-list) nil) + (t (cons (funcall function-name the-list) + (maplist function-name (rest the-list)))))) (defun map (function the-list) (reverse (map-tail function the-list nil))) @@ -42,7 +42,7 @@ (defun reverse-tail (accumulator the-list) (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) (if the-list @@ -55,9 +55,9 @@ (defun nth (n listA) (cond - ((equal 0 n) (first listA)) - (t (nth (- n 1) (rest listA))))) + ((equal 0 n) (first listA)) + (t (nth (- n 1) (rest listA))))) (eval (let ((expr (gensym))) - `(defun global-eval (,expr) (eval ,expr)))) + `(defun global-eval (, expr) (eval, expr)))) diff --git a/src/test/kotlin/function/ArgumentValidatorTest.java b/src/test/kotlin/function/ArgumentValidatorTest.java index c3ded9d..2aefbb0 100644 --- a/src/test/kotlin/function/ArgumentValidatorTest.java +++ b/src/test/kotlin/function/ArgumentValidatorTest.java @@ -16,18 +16,16 @@ import static error.Severity.ERROR; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static sexpression.Nil.NIL; -import static sexpression.Symbol.T; public class ArgumentValidatorTest { private ArgumentValidator validator; private Cons makeArgumentListOfSize(int size) { - Cons argumentList = NIL; + Cons argumentList = Nil.INSTANCE; for (int i = 0; i < size; i++) - argumentList = new Cons(NIL, argumentList); + argumentList = new Cons(Nil.INSTANCE, argumentList); return argumentList; } @@ -84,7 +82,7 @@ public class ArgumentValidatorTest { @Test public void tooManyArgumentsException_HasCorrectAttributes() { - TooManyArgumentsException e = new TooManyArgumentsException("TEST", NIL); + TooManyArgumentsException e = new TooManyArgumentsException("TEST", Nil.INSTANCE); assertEquals(ERROR, e.getSeverity()); assertNotNull(e.getMessage()); @@ -93,7 +91,7 @@ public class ArgumentValidatorTest { @Test public void tooFewArgumentsException_HasCorrectAttributes() { - TooFewArgumentsException e = new TooFewArgumentsException("TEST", NIL); + TooFewArgumentsException e = new TooFewArgumentsException("TEST", Nil.INSTANCE); assertEquals(ERROR, e.getSeverity()); assertNotNull(e.getMessage()); @@ -102,7 +100,7 @@ public class ArgumentValidatorTest { @Test 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()); assertNotNull(e.getMessage()); @@ -123,7 +121,7 @@ public class ArgumentValidatorTest { @Test 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.setTrailingArgumentExpectedType(Cons.class); @@ -132,7 +130,7 @@ public class ArgumentValidatorTest { @Test(expected = BadArgumentTypeException.class) 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.setTrailingArgumentExpectedType(Cons.class); @@ -141,7 +139,7 @@ public class ArgumentValidatorTest { @Test(expected = BadArgumentTypeException.class) 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.setTrailingArgumentExpectedType(Symbol.class); @@ -150,7 +148,7 @@ public class ArgumentValidatorTest { @Test 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() {}; validator.setEveryArgumentExpectedType(withoutDisplayName.getClass()); @@ -165,21 +163,22 @@ public class ArgumentValidatorTest { @Test(expected = DottedArgumentListException.class) public void givenDottedArgumentList_ThrowsException() { - Cons argumentList = new Cons(T, T); + Cons argumentList = new Cons(Symbol.Companion.getT(), Symbol.Companion.getT()); validator.validate(argumentList); } @Test(expected = DottedArgumentListException.class) 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); } @Test public void dottedArgumentListException_HasCorrectAttributes() { - DottedArgumentListException e = new DottedArgumentListException("TEST", NIL); + DottedArgumentListException e = new DottedArgumentListException("TEST", Nil.INSTANCE); assertEquals(ERROR, e.getSeverity()); assertNotNull(e.getMessage()); @@ -189,36 +188,36 @@ public class ArgumentValidatorTest { @Test public void excludedFirstArgumentType_DoesNotAffectTrailingArguments() { 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 public void excludedTrailingArgumentType_DoesNotAffectFirstArgument() { 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) public void excludedFirstArgumentType_ThrowsException() { 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) public void excludedTrailingArgumentType_ThrowsException() { 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) public void excludedArgumentType_ThrowsExceptionOnFirstArgument() { 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) public void excludedArgumentType_ThrowsExceptionOnTrailingArgument() { 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))); } } diff --git a/src/test/kotlin/function/UserDefinedFunctionTest.java b/src/test/kotlin/function/UserDefinedFunctionTest.java index cb3334b..2078e9c 100644 --- a/src/test/kotlin/function/UserDefinedFunctionTest.java +++ b/src/test/kotlin/function/UserDefinedFunctionTest.java @@ -7,13 +7,13 @@ import function.UserDefinedFunction.IllegalKeywordRestPositionException; import org.junit.Test; import sexpression.Cons; import sexpression.LispNumber; +import sexpression.Nil; import sexpression.SExpression; import sexpression.Symbol; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static sexpression.Nil.NIL; import static testutil.TestUtilities.assertSExpressionsMatch; public class UserDefinedFunctionTest { @@ -21,24 +21,27 @@ public class UserDefinedFunctionTest { private static final String FUNCTION_NAME = "TEST"; 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() { - 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 public void nilFunctionCall() { UserDefinedFunction function = createNoArgumentFunctionThatReturnsNil(); - assertEquals(NIL, function.call(NIL)); + assertEquals(Nil.INSTANCE, function.call(Nil.INSTANCE)); } @Test public void nilFunctionToString() { 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()); } @@ -47,7 +50,7 @@ public class UserDefinedFunctionTest { public void oneArgumentFunction_ReturnsCorrectValue() { UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument(); SExpression argument = new LispNumber("23"); - Cons argumentList = new Cons(argument, NIL); + Cons argumentList = new Cons(argument, Nil.INSTANCE); assertSExpressionsMatch(argument, function.call(argumentList)); } @@ -56,7 +59,7 @@ public class UserDefinedFunctionTest { public void oneArgumentFunction_ThrowsExceptionWithTooManyArguments() { UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument(); 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); } @@ -65,12 +68,13 @@ public class UserDefinedFunctionTest { public void oneArgumentFunction_ThrowsExceptionWithTooFewArguments() { UserDefinedFunction function = createOneArgumentFunctionThatReturnsArgument(); - function.call(NIL); + function.call(Nil.INSTANCE); } @Test public void illegalKeywordRestPositionException_HasCorrectAttributes() { - IllegalKeywordRestPositionException e = new IllegalKeywordRestPositionException(FUNCTION_NAME, NIL); + IllegalKeywordRestPositionException e = new IllegalKeywordRestPositionException(FUNCTION_NAME, + Nil.INSTANCE); assertNotNull(e.getMessage()); assertTrue(e.getMessage().length() > 0); diff --git a/src/test/kotlin/function/builtin/BackquoteEvaluatorTest.java b/src/test/kotlin/function/builtin/BackquoteEvaluatorTest.java index 1be36b2..318eeac 100644 --- a/src/test/kotlin/function/builtin/BackquoteEvaluatorTest.java +++ b/src/test/kotlin/function/builtin/BackquoteEvaluatorTest.java @@ -12,11 +12,10 @@ import sexpression.CommaExpression; import sexpression.Cons; import sexpression.LispNumber; import sexpression.LispString; +import sexpression.Nil; import sexpression.SExpression; import sexpression.Symbol; -import static sexpression.Nil.NIL; -import static sexpression.Symbol.T; import static testutil.TestUtilities.assertIsErrorWithMessage; import static testutil.TestUtilities.assertSExpressionsMatch; import static testutil.TestUtilities.makeList; @@ -29,9 +28,9 @@ public class BackquoteEvaluatorTest { @Test public void evaluateNil() { - BackquoteEvaluator evaluator = createBackquoteEvaluator(NIL); + BackquoteEvaluator evaluator = createBackquoteEvaluator(Nil.INSTANCE); - assertSExpressionsMatch(NIL, evaluator.evaluate()); + assertSExpressionsMatch(Nil.INSTANCE, evaluator.evaluate()); } @Test @@ -155,14 +154,17 @@ public class BackquoteEvaluatorTest { @Test(expected = DottedArgumentListException.class) public void evaluateDottedList() { - BackquoteEvaluator evaluator = createBackquoteEvaluator(new Cons(T, T)); + BackquoteEvaluator evaluator = + createBackquoteEvaluator(new Cons(Symbol.Companion.getT(), Symbol.Companion.getT())); evaluator.evaluate(); } @Test(expected = DottedArgumentListException.class) 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); evaluator.evaluate(); diff --git a/src/test/kotlin/function/builtin/EVALTest.java b/src/test/kotlin/function/builtin/EVALTest.java index ca36fca..40c07ac 100644 --- a/src/test/kotlin/function/builtin/EVALTest.java +++ b/src/test/kotlin/function/builtin/EVALTest.java @@ -10,12 +10,12 @@ import function.builtin.EVAL.UnmatchedAtSignException; import function.builtin.EVAL.UnmatchedCommaException; import function.builtin.special.RECUR.RecurNotInTailPositionException; import org.junit.Test; +import sexpression.Nil; import testutil.SymbolAndFunctionCleaner; import static function.builtin.EVAL.lookupSymbol; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; -import static sexpression.Nil.NIL; import static testutil.TestUtilities.assertIsErrorWithMessage; import static testutil.TestUtilities.assertSExpressionsMatch; import static testutil.TestUtilities.evaluateString; @@ -100,12 +100,12 @@ public class EVALTest extends SymbolAndFunctionCleaner { @Test public void undefinedFunctionException_HasCorrectAttributes() { - assertIsErrorWithMessage(new UndefinedFunctionException(NIL)); + assertIsErrorWithMessage(new UndefinedFunctionException(Nil.INSTANCE)); } @Test public void undefinedSymbolException_HasCorrectAttributes() { - assertIsErrorWithMessage(new UndefinedSymbolException(NIL)); + assertIsErrorWithMessage(new UndefinedSymbolException(Nil.INSTANCE)); } @Test(expected = UnmatchedCommaException.class) diff --git a/src/test/kotlin/function/builtin/SYMBOL_FUNCTIONTest.java b/src/test/kotlin/function/builtin/SYMBOL_FUNCTIONTest.java index 9aeb813..e27ff9a 100644 --- a/src/test/kotlin/function/builtin/SYMBOL_FUNCTIONTest.java +++ b/src/test/kotlin/function/builtin/SYMBOL_FUNCTIONTest.java @@ -5,13 +5,13 @@ import function.ArgumentValidator.TooFewArgumentsException; import function.ArgumentValidator.TooManyArgumentsException; import function.builtin.SYMBOL_FUNCTION.UndefinedSymbolFunctionException; import org.junit.Test; +import sexpression.Nil; import testutil.SymbolAndFunctionCleaner; import static error.Severity.ERROR; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static sexpression.Nil.NIL; import static testutil.TestUtilities.evaluateString; public class SYMBOL_FUNCTIONTest extends SymbolAndFunctionCleaner { @@ -63,7 +63,7 @@ public class SYMBOL_FUNCTIONTest extends SymbolAndFunctionCleaner { @Test public void undefinedSymbolFunctionException_HasCorrectAttributes() { - UndefinedSymbolFunctionException e = new UndefinedSymbolFunctionException(NIL); + UndefinedSymbolFunctionException e = new UndefinedSymbolFunctionException(Nil.INSTANCE); assertEquals(ERROR, e.getSeverity()); assertNotNull(e.getMessage()); diff --git a/src/test/kotlin/function/builtin/special/LETTest.java b/src/test/kotlin/function/builtin/special/LETTest.java index 234f50f..cc5ec18 100644 --- a/src/test/kotlin/function/builtin/special/LETTest.java +++ b/src/test/kotlin/function/builtin/special/LETTest.java @@ -8,9 +8,9 @@ import function.builtin.EVAL.UndefinedSymbolException; import org.junit.Test; import sexpression.Cons; import sexpression.LispNumber; +import sexpression.Nil; import testutil.SymbolAndFunctionCleaner; -import static sexpression.Nil.NIL; import static testutil.TestUtilities.assertSExpressionsMatch; import static testutil.TestUtilities.evaluateString; @@ -27,14 +27,14 @@ public class LETTest extends SymbolAndFunctionCleaner { public void emptyLet_ReturnsNil() { String input = "(let ())"; - assertSExpressionsMatch(NIL, evaluateString(input)); + assertSExpressionsMatch(Nil.INSTANCE, evaluateString(input)); } @Test public void letWithSymbolsOnly_SetsValuesToNil() { 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 diff --git a/src/test/kotlin/function/builtin/special/LET_STARTest.java b/src/test/kotlin/function/builtin/special/LET_STARTest.java index df7074c..4ea20d2 100644 --- a/src/test/kotlin/function/builtin/special/LET_STARTest.java +++ b/src/test/kotlin/function/builtin/special/LET_STARTest.java @@ -8,9 +8,9 @@ import function.builtin.EVAL.UndefinedSymbolException; import org.junit.Test; import sexpression.Cons; import sexpression.LispNumber; +import sexpression.Nil; import testutil.SymbolAndFunctionCleaner; -import static sexpression.Nil.NIL; import static testutil.TestUtilities.assertSExpressionsMatch; import static testutil.TestUtilities.evaluateString; @@ -27,14 +27,14 @@ public class LET_STARTest extends SymbolAndFunctionCleaner { public void emptyLet_ReturnsNil() { String input = "(let* ())"; - assertSExpressionsMatch(NIL, evaluateString(input)); + assertSExpressionsMatch(Nil.INSTANCE, evaluateString(input)); } @Test public void letStarWithSymbolsOnly_SetsValuesToNil() { 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 diff --git a/src/test/kotlin/function/builtin/special/LambdaTest.kt b/src/test/kotlin/function/builtin/special/LambdaTest.kt index feb8185..808d44b 100644 --- a/src/test/kotlin/function/builtin/special/LambdaTest.kt +++ b/src/test/kotlin/function/builtin/special/LambdaTest.kt @@ -12,10 +12,10 @@ import org.junit.jupiter.api.Assertions.assertThrows import org.junit.jupiter.api.Test import sexpression.Cons import sexpression.LispNumber -import sexpression.LispNumber.ONE -import sexpression.Nil.NIL +import sexpression.LispNumber.Companion.ONE +import sexpression.Nil import sexpression.Symbol -import sexpression.Symbol.T +import sexpression.Symbol.Companion.T import testutil.SymbolAndFunctionCleaner import testutil.TestUtilities.assertSExpressionsMatch import testutil.TestUtilities.evaluateString @@ -46,7 +46,7 @@ class LambdaTest : SymbolAndFunctionCleaner() { @Test 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() } @@ -58,7 +58,7 @@ class LambdaTest : SymbolAndFunctionCleaner() { @Test 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) } @@ -79,7 +79,7 @@ class LambdaTest : SymbolAndFunctionCleaner() { @Test 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) } } diff --git a/src/test/kotlin/sexpression/SExpressionTest.java b/src/test/kotlin/sexpression/SExpressionTest.java index ab8e99e..6cca9fb 100644 --- a/src/test/kotlin/sexpression/SExpressionTest.java +++ b/src/test/kotlin/sexpression/SExpressionTest.java @@ -11,7 +11,6 @@ import static error.Severity.ERROR; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static sexpression.Nil.NIL; import static testutil.TestUtilities.assertSExpressionsMatch; import static testutil.TestUtilities.makeList; @@ -25,7 +24,7 @@ public class SExpressionTest { public void nil_ToString() { String input = "NIL"; - assertSExpressionMatchesString(input, NIL); + assertSExpressionMatchesString(input, Nil.INSTANCE); } @Test @@ -83,7 +82,8 @@ public class SExpressionTest { @Test public void lambdaExpression_ToString() { 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); } @@ -91,7 +91,8 @@ public class SExpressionTest { @Test public void lambdaExpression_GetLambdaExpression() { 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()); } @@ -99,7 +100,7 @@ public class SExpressionTest { @Test public void lambdaExpression_GetFunction() { 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); assertEquals(function, lambda.getFunction()); @@ -107,28 +108,28 @@ public class SExpressionTest { @Test public void firstOfNilIsNil() { - assertEquals(NIL, NIL.getFirst()); + assertEquals(Nil.INSTANCE, Nil.INSTANCE.getFirst()); } @Test public void restOfNilIsNil() { - assertEquals(NIL, NIL.getRest()); + assertEquals(Nil.INSTANCE, Nil.INSTANCE.getRest()); } @Test public void afterSettingFirstOfNil_ShouldStillBeNil() { - Cons nil = NIL; + Cons nil = Nil.INSTANCE; nil.setFirst(new LispNumber("2")); - assertEquals(NIL, nil.getFirst()); + assertEquals(Nil.INSTANCE, nil.getFirst()); } @Test public void afterSettingRestOfNil_ShouldStillBeNil() { - Cons nil = NIL; + Cons nil = Nil.INSTANCE; nil.setRest(new LispNumber("2")); - assertEquals(NIL, nil.getRest()); + assertEquals(Nil.INSTANCE, nil.getRest()); } @Test @@ -159,8 +160,8 @@ public class SExpressionTest { @Test public void lispNumberConstants() { - assertEquals(BigInteger.ZERO, LispNumber.ZERO.getValue()); - assertEquals(BigInteger.ONE, LispNumber.ONE.getValue()); + assertEquals(BigInteger.ZERO, LispNumber.Companion.getZERO().getValue()); + assertEquals(BigInteger.ONE, LispNumber.Companion.getONE().getValue()); } @Test diff --git a/src/test/kotlin/table/ExecutionContextTest.kt b/src/test/kotlin/table/ExecutionContextTest.kt index 5b2051d..72235eb 100644 --- a/src/test/kotlin/table/ExecutionContextTest.kt +++ b/src/test/kotlin/table/ExecutionContextTest.kt @@ -6,8 +6,8 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS -import sexpression.Nil.NIL -import sexpression.Symbol.T +import sexpression.Nil +import sexpression.Symbol.Companion.T import table.SymbolTable.NullSymbolTable @TestInstance(PER_CLASS) @@ -75,11 +75,11 @@ class ExecutionContextTest { fun `lookup a shadowed variable`() { val scope = SymbolTable(ExecutionContext.scope) - scope["shadowed"] = NIL + scope["shadowed"] = Nil ExecutionContext.scope["shadowed"] = T ExecutionContext.scope = scope - assertThat(ExecutionContext.lookupSymbolValue("shadowed")).isEqualTo(NIL) + assertThat(ExecutionContext.lookupSymbolValue("shadowed")).isEqualTo(Nil) } @Test diff --git a/src/test/kotlin/table/FunctionTableTest.kt b/src/test/kotlin/table/FunctionTableTest.kt index 675ec6e..87d9ceb 100644 --- a/src/test/kotlin/table/FunctionTableTest.kt +++ b/src/test/kotlin/table/FunctionTableTest.kt @@ -13,8 +13,7 @@ import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS import sexpression.Cons import sexpression.LispString import sexpression.Nil -import sexpression.Nil.NIL -import sexpression.Symbol.T +import sexpression.Symbol.Companion.T import table.FunctionTable.LispFunctionInstantiationException import table.FunctionTable.defineFunction import table.FunctionTable.isAlreadyDefined @@ -31,11 +30,11 @@ class FunctionTableTest { @FunctionNames("BAD") class BadFunction : LispFunction() { - override fun call(argumentList: Cons): Nil = NIL + override fun call(argumentList: Cons): Nil = Nil } class UglyFunction : LispFunction() { - override fun call(argumentList: Cons): Nil = NIL + override fun call(argumentList: Cons): Nil = Nil } private fun createLispFunction() = object : LispFunction() { diff --git a/src/test/kotlin/table/SymbolTableTest.kt b/src/test/kotlin/table/SymbolTableTest.kt index 9c010ce..fb1aeea 100644 --- a/src/test/kotlin/table/SymbolTableTest.kt +++ b/src/test/kotlin/table/SymbolTableTest.kt @@ -5,8 +5,8 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS -import sexpression.Nil.NIL -import sexpression.Symbol.T +import sexpression.Nil +import sexpression.Symbol.Companion.T @TestInstance(PER_CLASS) class SymbolTableTest { @@ -40,9 +40,9 @@ class SymbolTableTest { @Test fun `redefine the value of a symbol`() { symbolTable["symbol"] = T - symbolTable["symbol"] = NIL + symbolTable["symbol"] = Nil - assertThat(symbolTable["symbol"]).isEqualTo(NIL) + assertThat(symbolTable["symbol"]).isEqualTo(Nil) } @Test diff --git a/src/test/kotlin/testutil/TestUtilities.kt b/src/test/kotlin/testutil/TestUtilities.kt index b46a384..3d36e5c 100644 --- a/src/test/kotlin/testutil/TestUtilities.kt +++ b/src/test/kotlin/testutil/TestUtilities.kt @@ -6,7 +6,7 @@ import function.builtin.EVAL.eval import org.assertj.core.api.Assertions.assertThat import parser.LispParser import sexpression.Cons -import sexpression.Nil.NIL +import sexpression.Nil import sexpression.SExpression import java.io.ByteArrayInputStream import java.io.IOException @@ -64,7 +64,7 @@ object TestUtilities { @JvmStatic() fun makeList(vararg expressionList: SExpression): Cons { if (expressionList.isEmpty()) - return NIL + return Nil val rest = makeList(*Arrays.copyOfRange(expressionList, 1, expressionList.size)) diff --git a/src/test/kotlin/testutil/TypeAssertions.kt b/src/test/kotlin/testutil/TypeAssertions.kt index a313402..5390aaa 100644 --- a/src/test/kotlin/testutil/TypeAssertions.kt +++ b/src/test/kotlin/testutil/TypeAssertions.kt @@ -1,9 +1,9 @@ package testutil import org.assertj.core.api.Assertions.assertThat -import sexpression.Nil.NIL +import sexpression.Nil import sexpression.SExpression -import sexpression.Symbol.T +import sexpression.Symbol.Companion.T object TypeAssertions { @@ -24,7 +24,7 @@ object TypeAssertions { @JvmStatic() fun assertNil(sExpression: SExpression) { - assertThat(sExpression).isEqualTo(NIL) + assertThat(sExpression).isEqualTo(Nil) assertThat(sExpression.isAtom).isTrue() assertThat(sExpression.isCons).isFalse()