Convert predicates to kotlin

This commit is contained in:
Mike Cifelli 2018-11-04 08:34:07 -05:00
parent 8bc0ae744f
commit add24979d5
22 changed files with 247 additions and 291 deletions

View File

@ -1,28 +0,0 @@
package function.builtin.predicate;
import function.ArgumentValidator;
import function.FunctionNames;
import function.LispFunction;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
@FunctionNames({ "ATOM", "ATOM?" })
public class ATOM extends LispFunction {
private ArgumentValidator argumentValidator;
public ATOM(String name) {
this.argumentValidator = new ArgumentValidator(name);
this.argumentValidator.setExactNumberOfArguments(1);
}
@Override
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
SExpression argument = argumentList.getFirst();
return argument.isAtom() ? Symbol.Companion.getT() : Nil.INSTANCE;
}
}

View File

@ -0,0 +1,24 @@
package function.builtin.predicate
import function.ArgumentValidator
import function.FunctionNames
import function.LispFunction
import sexpression.Cons
import sexpression.Nil
import sexpression.SExpression
import sexpression.Symbol
@FunctionNames("ATOM", "ATOM?")
class Atom(name: String) : LispFunction() {
private val argumentValidator = ArgumentValidator(name).apply {
setExactNumberOfArguments(1)
}
override fun call(argumentList: Cons): SExpression {
argumentValidator.validate(argumentList)
val argument = argumentList.first
return if (argument.isAtom) Symbol.T else Nil
}
}

View File

@ -1,54 +0,0 @@
package function.builtin.predicate;
import function.ArgumentValidator;
import function.FunctionNames;
import function.LispFunction;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
@FunctionNames({ "EQ", "EQ?" })
public class EQ extends LispFunction {
private ArgumentValidator argumentValidator;
public EQ(String name) {
this.argumentValidator = new ArgumentValidator(name);
this.argumentValidator.setExactNumberOfArguments(2);
}
@Override
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
Cons rest = (Cons) argumentList.getRest();
SExpression firstArgument = argumentList.getFirst();
SExpression secondArgument = rest.getFirst();
return eq(firstArgument, secondArgument);
}
private SExpression eq(SExpression firstArgument, SExpression secondArgument) {
if (isAtomPair(firstArgument, secondArgument))
return atomEq(firstArgument, secondArgument);
return listEq(firstArgument, secondArgument);
}
private boolean isAtomPair(SExpression firstArgument, SExpression secondArgument) {
return firstArgument.isAtom() && secondArgument.isAtom();
}
private SExpression atomEq(SExpression firstArgument, SExpression secondArgument) {
return isEq(firstArgument, secondArgument) ? Symbol.Companion.getT() : Nil.INSTANCE;
}
private boolean isEq(SExpression firstArgument, SExpression secondArgument) {
return firstArgument.toString().equals(secondArgument.toString());
}
private SExpression listEq(SExpression firstArgument, SExpression secondArgument) {
return (firstArgument == secondArgument) ? Symbol.Companion.getT() : Nil.INSTANCE;
}
}

View File

@ -1,39 +0,0 @@
package function.builtin.predicate;
import function.ArgumentValidator;
import function.FunctionNames;
import function.LispFunction;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
@FunctionNames({ "EQUAL", "EQUAL?" })
public class EQUAL extends LispFunction {
public static boolean isEqual(SExpression firstArgument, SExpression secondArgument) {
return firstArgument.toString().equals(secondArgument.toString());
}
private ArgumentValidator argumentValidator;
public EQUAL(String name) {
this.argumentValidator = new ArgumentValidator(name);
this.argumentValidator.setExactNumberOfArguments(2);
}
@Override
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
Cons rest = (Cons) argumentList.getRest();
SExpression firstArgument = argumentList.getFirst();
SExpression secondArgument = rest.getFirst();
return equal(firstArgument, secondArgument);
}
private SExpression equal(SExpression firstArgument, SExpression secondArgument) {
return isEqual(firstArgument, secondArgument) ? Symbol.Companion.getT() : Nil.INSTANCE;
}
}

View File

@ -0,0 +1,45 @@
package function.builtin.predicate
import function.ArgumentValidator
import function.FunctionNames
import function.LispFunction
import sexpression.Cons
import sexpression.Nil
import sexpression.SExpression
import sexpression.Symbol.Companion.T
@FunctionNames("EQ", "EQ?")
class Eq(name: String) : LispFunction() {
private val argumentValidator = ArgumentValidator(name).apply {
setExactNumberOfArguments(2)
}
override fun call(argumentList: Cons): SExpression {
argumentValidator.validate(argumentList)
val rest = argumentList.rest as Cons
val firstArgument = argumentList.first
val secondArgument = rest.first
return eq(firstArgument, secondArgument)
}
private fun eq(firstArgument: SExpression, secondArgument: SExpression) =
if (isAtomPair(firstArgument, secondArgument))
atomEq(firstArgument, secondArgument)
else
listEq(firstArgument, secondArgument)
private fun isAtomPair(firstArgument: SExpression, secondArgument: SExpression) =
firstArgument.isAtom && secondArgument.isAtom
private fun atomEq(firstArgument: SExpression, secondArgument: SExpression) =
if (isEq(firstArgument, secondArgument)) T else Nil
private fun isEq(firstArgument: SExpression, secondArgument: SExpression) =
firstArgument.toString() == secondArgument.toString()
private fun listEq(firstArgument: SExpression, secondArgument: SExpression) =
if (firstArgument === secondArgument) T else Nil
}

View File

@ -0,0 +1,36 @@
package function.builtin.predicate
import function.ArgumentValidator
import function.FunctionNames
import function.LispFunction
import sexpression.Cons
import sexpression.Nil
import sexpression.SExpression
import sexpression.Symbol.Companion.T
@FunctionNames("EQUAL", "EQUAL?")
class Equal(name: String) : LispFunction() {
private val argumentValidator = ArgumentValidator(name).apply {
setExactNumberOfArguments(2)
}
override fun call(argumentList: Cons): SExpression {
argumentValidator.validate(argumentList)
val rest = argumentList.rest as Cons
val firstArgument = argumentList.first
val secondArgument = rest.first
return equal(firstArgument, secondArgument)
}
private fun equal(firstArgument: SExpression, secondArgument: SExpression) =
if (isEqual(firstArgument, secondArgument)) T else Nil
companion object {
fun isEqual(firstArgument: SExpression, secondArgument: SExpression) =
firstArgument.toString() == secondArgument.toString()
}
}

View File

@ -1,27 +0,0 @@
package function.builtin.predicate;
import function.ArgumentValidator;
import function.FunctionNames;
import function.LispFunction;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
@FunctionNames({ "LISTP", "LIST?" })
public class LISTP extends LispFunction {
private ArgumentValidator argumentValidator;
public LISTP(String name) {
this.argumentValidator = new ArgumentValidator(name);
this.argumentValidator.setExactNumberOfArguments(1);
}
@Override
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
return argumentList.getFirst().isList() ? Symbol.Companion.getT() : Nil.INSTANCE;
}
}

View File

@ -0,0 +1,23 @@
package function.builtin.predicate
import function.ArgumentValidator
import function.FunctionNames
import function.LispFunction
import sexpression.Cons
import sexpression.Nil
import sexpression.SExpression
import sexpression.Symbol.Companion.T
@FunctionNames("LISTP", "LIST?")
class Listp(name: String) : LispFunction() {
private val argumentValidator = ArgumentValidator(name).apply {
setExactNumberOfArguments(1)
}
override fun call(argumentList: Cons): SExpression {
argumentValidator.validate(argumentList)
return if (argumentList.first.isList) T else Nil
}
}

View File

@ -1,27 +0,0 @@
package function.builtin.predicate;
import function.ArgumentValidator;
import function.FunctionNames;
import function.LispFunction;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
@FunctionNames({ "NULL", "NULL?" })
public class NULL extends LispFunction {
private ArgumentValidator argumentValidator;
public NULL(String name) {
this.argumentValidator = new ArgumentValidator(name);
this.argumentValidator.setExactNumberOfArguments(1);
}
@Override
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
return argumentList.getFirst().isNull() ? Symbol.Companion.getT() : Nil.INSTANCE;
}
}

View File

@ -1,54 +0,0 @@
package function.builtin.predicate;
import function.ArgumentValidator;
import function.FunctionNames;
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;
@FunctionNames({ ">" })
public class NUMERIC_GREATER extends LispFunction {
private ArgumentValidator argumentValidator;
public NUMERIC_GREATER(String name) {
this.argumentValidator = new ArgumentValidator(name);
this.argumentValidator.setMinimumNumberOfArguments(1);
this.argumentValidator.setEveryArgumentExpectedType(LispNumber.class);
}
@Override
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
return callTailRecursive(argumentList).invoke();
}
private TailCall<SExpression> callTailRecursive(Cons argumentList) {
Cons remainingArguments = (Cons) argumentList.getRest();
if (remainingArguments.isNull())
return done(Symbol.Companion.getT());
SExpression firstArgument = argumentList.getFirst();
SExpression secondArgument = remainingArguments.getFirst();
LispNumber number1 = (LispNumber) firstArgument;
LispNumber number2 = (LispNumber) secondArgument;
if (!isFirstGreater(number1, number2))
return done(Nil.INSTANCE);
return tailCall(() -> callTailRecursive(remainingArguments));
}
private boolean isFirstGreater(LispNumber number1, LispNumber number2) {
return number1.getValue().compareTo(number2.getValue()) > 0;
}
}

View File

@ -1,54 +0,0 @@
package function.builtin.predicate;
import function.ArgumentValidator;
import function.FunctionNames;
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;
@FunctionNames({ "<" })
public class NUMERIC_LESS extends LispFunction {
private ArgumentValidator argumentValidator;
public NUMERIC_LESS(String name) {
this.argumentValidator = new ArgumentValidator(name);
this.argumentValidator.setMinimumNumberOfArguments(1);
this.argumentValidator.setEveryArgumentExpectedType(LispNumber.class);
}
@Override
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
return callTailRecursive(argumentList).invoke();
}
private TailCall<SExpression> callTailRecursive(Cons argumentList) {
Cons remainingArguments = (Cons) argumentList.getRest();
if (remainingArguments.isNull())
return done(Symbol.Companion.getT());
SExpression firstArgument = argumentList.getFirst();
SExpression secondArgument = remainingArguments.getFirst();
LispNumber number1 = (LispNumber) firstArgument;
LispNumber number2 = (LispNumber) secondArgument;
if (!isFirstLesser(number1, number2))
return done(Nil.INSTANCE);
return tailCall(() -> callTailRecursive(remainingArguments));
}
private boolean isFirstLesser(LispNumber number1, LispNumber number2) {
return number1.getValue().compareTo(number2.getValue()) < 0;
}
}

View File

@ -0,0 +1,23 @@
package function.builtin.predicate
import function.ArgumentValidator
import function.FunctionNames
import function.LispFunction
import sexpression.Cons
import sexpression.Nil
import sexpression.SExpression
import sexpression.Symbol.Companion.T
@FunctionNames("NULL", "NULL?")
class Null(name: String) : LispFunction() {
private val argumentValidator = ArgumentValidator(name).apply {
setExactNumberOfArguments(1)
}
override fun call(argumentList: Cons): SExpression {
argumentValidator.validate(argumentList)
return if (argumentList.first.isNull) T else Nil
}
}

View File

@ -0,0 +1,42 @@
package function.builtin.predicate
import function.ArgumentValidator
import function.FunctionNames
import function.LispFunction
import sexpression.Cons
import sexpression.LispNumber
import sexpression.Nil
import sexpression.SExpression
import sexpression.Symbol.Companion.T
@FunctionNames(">")
class NumericGreater(name: String) : LispFunction() {
private val argumentValidator = ArgumentValidator(name).apply {
setMinimumNumberOfArguments(1)
setEveryArgumentExpectedType(LispNumber::class.java)
}
override fun call(argumentList: Cons): SExpression {
argumentValidator.validate(argumentList)
return callTailRecursive(argumentList)
}
private tailrec fun callTailRecursive(argumentList: Cons): SExpression {
val remainingArguments = argumentList.rest as Cons
if (remainingArguments.isNull)
return T
val firstArgument = argumentList.first
val secondArgument = remainingArguments.first
val number1 = firstArgument as LispNumber
val number2 = secondArgument as LispNumber
return if (number1.value > number2.value)
callTailRecursive(remainingArguments)
else
Nil
}
}

View File

@ -0,0 +1,46 @@
package function.builtin.predicate
import function.ArgumentValidator
import function.FunctionNames
import function.LispFunction
import recursion.TailCall
import sexpression.Cons
import sexpression.LispNumber
import sexpression.Nil
import sexpression.SExpression
import recursion.TailCalls.done
import recursion.TailCalls.tailCall
import sexpression.Symbol.Companion.T
@FunctionNames("<")
class NumericLess(name: String) : LispFunction() {
private val argumentValidator = ArgumentValidator(name).apply {
setMinimumNumberOfArguments(1)
setEveryArgumentExpectedType(LispNumber::class.java)
}
override fun call(argumentList: Cons): SExpression {
argumentValidator.validate(argumentList)
return callTailRecursive(argumentList)
}
private tailrec fun callTailRecursive(argumentList: Cons): SExpression {
val remainingArguments = argumentList.rest as Cons
if (remainingArguments.isNull)
return T
val firstArgument = argumentList.first
val secondArgument = remainingArguments.first
val number1 = firstArgument as LispNumber
val number2 = secondArgument as LispNumber
return if (number1.value < number2.value)
callTailRecursive(remainingArguments)
else
Nil
}
}

View File

@ -4,7 +4,7 @@ import function.ArgumentValidator
import function.FunctionNames
import function.LispSpecialFunction
import function.builtin.Eval.Companion.eval
import function.builtin.predicate.EQUAL.isEqual
import function.builtin.predicate.Equal.Companion.isEqual
import sexpression.Cons
import sexpression.Nil
import sexpression.SExpression

View File

@ -9,7 +9,7 @@ import static testutil.TestUtilities.evaluateString;
import static testutil.TypeAssertions.assertNil;
import static testutil.TypeAssertions.assertT;
public class ATOMTest extends SymbolAndFunctionCleaner {
public class AtomTest extends SymbolAndFunctionCleaner {
@Test
public void atomIsAtom() {

View File

@ -9,7 +9,7 @@ import static testutil.TestUtilities.evaluateString;
import static testutil.TypeAssertions.assertNil;
import static testutil.TypeAssertions.assertT;
public class EQTest extends SymbolAndFunctionCleaner {
public class EqTest extends SymbolAndFunctionCleaner {
@Test
public void eqWithEqualAtoms() {

View File

@ -9,7 +9,7 @@ import static testutil.TestUtilities.evaluateString;
import static testutil.TypeAssertions.assertNil;
import static testutil.TypeAssertions.assertT;
public class EQUALTest extends SymbolAndFunctionCleaner {
public class EqualTest extends SymbolAndFunctionCleaner {
@Test
public void equalWithTwoEqualAtoms() {

View File

@ -9,7 +9,7 @@ import static testutil.TestUtilities.evaluateString;
import static testutil.TypeAssertions.assertNil;
import static testutil.TypeAssertions.assertT;
public class LISTPTest extends SymbolAndFunctionCleaner {
public class ListpTest extends SymbolAndFunctionCleaner {
@Test
public void listpWithList() {

View File

@ -9,7 +9,7 @@ import static testutil.TestUtilities.evaluateString;
import static testutil.TypeAssertions.assertNil;
import static testutil.TypeAssertions.assertT;
public class NULLTest extends SymbolAndFunctionCleaner {
public class NullTest extends SymbolAndFunctionCleaner {
@Test
public void nilIsNull() {

View File

@ -9,7 +9,7 @@ import static testutil.TestUtilities.evaluateString;
import static testutil.TypeAssertions.assertNil;
import static testutil.TypeAssertions.assertT;
public class NUMERIC_GREATERTest extends SymbolAndFunctionCleaner {
public class NumericGreaterTest extends SymbolAndFunctionCleaner {
@Test
public void greaterThanWithOneNumber_ReturnsT() {

View File

@ -9,7 +9,7 @@ import static testutil.TestUtilities.evaluateString;
import static testutil.TypeAssertions.assertNil;
import static testutil.TypeAssertions.assertT;
public class NUMERIC_LESSTest extends SymbolAndFunctionCleaner {
public class NumericLessTest extends SymbolAndFunctionCleaner {
@Test
public void lessThanWithOneNumber_ReturnsT() {