Convert numeric equal to kotlin
This commit is contained in:
parent
e672247738
commit
28f2351654
|
@ -0,0 +1,124 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
|
@ -14,7 +14,7 @@ import table.ExecutionContext;
|
|||
import table.FunctionTable;
|
||||
|
||||
import static function.builtin.cons.LIST.makeList;
|
||||
import static function.builtin.special.LAMBDA.Lambda;
|
||||
import static function.builtin.special.Lambda.Lambda;
|
||||
import static java.text.MessageFormat.format;
|
||||
import static sexpression.Nil.NIL;
|
||||
import static sexpression.Symbol.T;
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
package function.builtin;
|
||||
|
||||
import environment.RuntimeEnvironment;
|
||||
import function.ArgumentValidator;
|
||||
import function.FunctionNames;
|
||||
import function.LispFunction;
|
||||
import sexpression.Cons;
|
||||
import sexpression.SExpression;
|
||||
|
||||
import static sexpression.Nil.NIL;
|
||||
|
||||
@FunctionNames({ "EXIT" })
|
||||
public class EXIT extends LispFunction {
|
||||
|
||||
private ArgumentValidator argumentValidator;
|
||||
private RuntimeEnvironment environment;
|
||||
|
||||
public EXIT(String name) {
|
||||
this.argumentValidator = new ArgumentValidator(name);
|
||||
this.argumentValidator.setMaximumNumberOfArguments(0);
|
||||
this.environment = RuntimeEnvironment.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SExpression call(Cons argumentList) {
|
||||
argumentValidator.validate(argumentList);
|
||||
environment.terminateSuccessfully();
|
||||
|
||||
return NIL;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package function.builtin
|
||||
|
||||
import environment.RuntimeEnvironment
|
||||
import function.ArgumentValidator
|
||||
import function.FunctionNames
|
||||
import function.LispFunction
|
||||
import sexpression.Cons
|
||||
import sexpression.Nil.NIL
|
||||
import sexpression.SExpression
|
||||
|
||||
@FunctionNames("EXIT")
|
||||
class Exit(name: String) : LispFunction() {
|
||||
|
||||
private val argumentValidator: ArgumentValidator = ArgumentValidator(name)
|
||||
|
||||
init {
|
||||
this.argumentValidator.setMaximumNumberOfArguments(0)
|
||||
}
|
||||
|
||||
override fun call(argumentList: Cons): SExpression {
|
||||
argumentValidator.validate(argumentList)
|
||||
RuntimeEnvironment.terminateSuccessfully()
|
||||
|
||||
return NIL
|
||||
}
|
||||
}
|
|
@ -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.SExpression;
|
||||
|
||||
import static recursion.TailCalls.done;
|
||||
import static recursion.TailCalls.tailCall;
|
||||
import static sexpression.Nil.NIL;
|
||||
import static sexpression.Symbol.T;
|
||||
|
||||
@FunctionNames({ "=" })
|
||||
public class NUMERIC_EQUAL extends LispFunction {
|
||||
|
||||
private ArgumentValidator argumentValidator;
|
||||
|
||||
public NUMERIC_EQUAL(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(T);
|
||||
|
||||
SExpression firstArgument = argumentList.getFirst();
|
||||
LispNumber number1 = (LispNumber) firstArgument;
|
||||
SExpression secondArgument = remainingArguments.getFirst();
|
||||
LispNumber number2 = (LispNumber) secondArgument;
|
||||
|
||||
if (!isEqual(number1, number2))
|
||||
return done(NIL);
|
||||
|
||||
return tailCall(() -> callTailRecursive(remainingArguments));
|
||||
}
|
||||
|
||||
private boolean isEqual(LispNumber number1, LispNumber number2) {
|
||||
return number1.getValue().equals(number2.getValue());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package function.builtin.predicate
|
||||
|
||||
import function.ArgumentValidator
|
||||
import function.FunctionNames
|
||||
import function.LispFunction
|
||||
import sexpression.Cons
|
||||
import sexpression.LispNumber
|
||||
import sexpression.Nil.NIL
|
||||
import sexpression.SExpression
|
||||
import sexpression.Symbol.T
|
||||
|
||||
@FunctionNames("=")
|
||||
class NumericEqual(name: String) : LispFunction() {
|
||||
|
||||
private val argumentValidator: ArgumentValidator = ArgumentValidator(name)
|
||||
|
||||
init {
|
||||
this.argumentValidator.setMinimumNumberOfArguments(1)
|
||||
this.argumentValidator.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 number1 = argumentList.first as LispNumber
|
||||
val number2 = remainingArguments.first as LispNumber
|
||||
|
||||
return if (number1.value != number2.value) NIL else callTailRecursive(remainingArguments)
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ import sexpression.SExpression
|
|||
import sexpression.Symbol
|
||||
|
||||
@FunctionNames("LAMBDA", "Λ")
|
||||
class LAMBDA(name: String) : LispSpecialFunction() {
|
||||
class Lambda(name: String) : LispSpecialFunction() {
|
||||
|
||||
private val argumentValidator: ArgumentValidator = ArgumentValidator(name)
|
||||
private val lambdaListValidator: ArgumentValidator = ArgumentValidator("$name|lambda-list|")
|
||||
|
@ -59,7 +59,7 @@ class LAMBDA(name: String) : LispSpecialFunction() {
|
|||
lambdaValidator.setEveryArgumentExpectedType(Cons::class.java)
|
||||
lambdaValidator.validate(makeList(rest))
|
||||
|
||||
val lambda = LAMBDA("LAMBDA").call(rest as Cons)
|
||||
val lambda = Lambda("LAMBDA").call(rest as Cons)
|
||||
|
||||
return lambda.function
|
||||
}
|
|
@ -5,7 +5,7 @@ import function.FunctionNames
|
|||
import function.LispFunction
|
||||
import function.builtin.APPLY
|
||||
import function.builtin.EVAL
|
||||
import function.builtin.EXIT
|
||||
import function.builtin.Exit
|
||||
import function.builtin.FUNCALL
|
||||
import function.builtin.FUSE
|
||||
import function.builtin.GENSYM
|
||||
|
@ -32,7 +32,7 @@ import function.builtin.predicate.EQUAL
|
|||
import function.builtin.predicate.GENSYM_EQUAL
|
||||
import function.builtin.predicate.LISTP
|
||||
import function.builtin.predicate.NULL
|
||||
import function.builtin.predicate.NUMERIC_EQUAL
|
||||
import function.builtin.predicate.NumericEqual
|
||||
import function.builtin.predicate.NUMERIC_GREATER
|
||||
import function.builtin.predicate.NUMERIC_LESS
|
||||
import function.builtin.special.AND
|
||||
|
@ -42,7 +42,7 @@ import function.builtin.special.DEFINE_SPECIAL
|
|||
import function.builtin.special.DEFMACRO
|
||||
import function.builtin.special.DEFUN
|
||||
import function.builtin.special.IF
|
||||
import function.builtin.special.LAMBDA
|
||||
import function.builtin.special.Lambda
|
||||
import function.builtin.special.LET
|
||||
import function.builtin.special.LET_STAR
|
||||
import function.builtin.special.OR
|
||||
|
@ -72,9 +72,9 @@ object FunctionTable {
|
|||
allBuiltIns.add(DIVIDE::class.java)
|
||||
allBuiltIns.add(EQ::class.java)
|
||||
allBuiltIns.add(EQUAL::class.java)
|
||||
allBuiltIns.add(NUMERIC_EQUAL::class.java)
|
||||
allBuiltIns.add(NumericEqual::class.java)
|
||||
allBuiltIns.add(EVAL::class.java)
|
||||
allBuiltIns.add(EXIT::class.java)
|
||||
allBuiltIns.add(Exit::class.java)
|
||||
allBuiltIns.add(FIRST::class.java)
|
||||
allBuiltIns.add(FUNCALL::class.java)
|
||||
allBuiltIns.add(FUSE::class.java)
|
||||
|
@ -82,7 +82,7 @@ object FunctionTable {
|
|||
allBuiltIns.add(GENSYM_EQUAL::class.java)
|
||||
allBuiltIns.add(NUMERIC_GREATER::class.java)
|
||||
allBuiltIns.add(IF::class.java)
|
||||
allBuiltIns.add(LAMBDA::class.java)
|
||||
allBuiltIns.add(Lambda::class.java)
|
||||
allBuiltIns.add(LENGTH::class.java)
|
||||
allBuiltIns.add(NUMERIC_LESS::class.java)
|
||||
allBuiltIns.add(LET::class.java)
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
package function.builtin
|
||||
|
||||
import environment.RuntimeEnvironment
|
||||
import function.ArgumentValidator.TooManyArgumentsException
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import testutil.SymbolAndFunctionCleaner
|
||||
import testutil.TestUtilities.evaluateString
|
||||
import java.util.HashSet
|
||||
|
||||
class EXITTest : SymbolAndFunctionCleaner() {
|
||||
private val environment: RuntimeEnvironment
|
||||
private var indicatorSet: MutableSet<String>? = null
|
||||
|
||||
init {
|
||||
this.environment = RuntimeEnvironment
|
||||
}
|
||||
|
||||
private fun assertTerminated() {
|
||||
assertTrue(indicatorSet!!.contains(TERMINATED))
|
||||
}
|
||||
|
||||
private fun assertNotTerminated() {
|
||||
assertFalse(indicatorSet!!.contains(TERMINATED))
|
||||
}
|
||||
|
||||
override fun additionalSetUp() {
|
||||
indicatorSet = HashSet()
|
||||
environment.reset()
|
||||
environment.terminationFunction = { indicatorSet!!.add(TERMINATED) }
|
||||
}
|
||||
|
||||
override fun additionalTearDown() {
|
||||
environment.reset()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun exitWorks() {
|
||||
evaluateString("(exit)")
|
||||
assertTerminated()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun exitNotCalled_IndicatorSetIsClean() {
|
||||
assertNotTerminated()
|
||||
}
|
||||
|
||||
@Test(expected = TooManyArgumentsException::class)
|
||||
fun exitWithTooManyArguments() {
|
||||
evaluateString("(exit 1)")
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val TERMINATED = "terminated"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package function.builtin
|
||||
|
||||
import environment.RuntimeEnvironment
|
||||
import function.ArgumentValidator.TooManyArgumentsException
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import org.junit.jupiter.api.Test
|
||||
import testutil.SymbolAndFunctionCleaner
|
||||
import testutil.TestUtilities.evaluateString
|
||||
import java.util.HashSet
|
||||
|
||||
class ExitTest : SymbolAndFunctionCleaner() {
|
||||
|
||||
companion object {
|
||||
private const val TERMINATED = "terminated"
|
||||
}
|
||||
|
||||
private var indicatorSet = HashSet<String>()
|
||||
|
||||
private fun assertTerminated() {
|
||||
assertThat(indicatorSet.contains(TERMINATED)).isTrue()
|
||||
}
|
||||
|
||||
private fun assertNotTerminated() {
|
||||
assertThat(indicatorSet.contains(TERMINATED)).isFalse()
|
||||
}
|
||||
|
||||
override fun additionalSetUp() {
|
||||
indicatorSet.clear()
|
||||
RuntimeEnvironment.reset()
|
||||
RuntimeEnvironment.terminationFunction = { indicatorSet.add(TERMINATED) }
|
||||
}
|
||||
|
||||
override fun additionalTearDown() {
|
||||
RuntimeEnvironment.reset()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `exit works`() {
|
||||
evaluateString("(exit)")
|
||||
assertTerminated()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `no termination when exit not called`() {
|
||||
assertNotTerminated()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `too many arguments`() {
|
||||
assertThrows(TooManyArgumentsException::class.java) { evaluateString("(exit 1)") }
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package function.builtin.predicate;
|
||||
|
||||
import function.ArgumentValidator.BadArgumentTypeException;
|
||||
import function.ArgumentValidator.TooFewArgumentsException;
|
||||
import org.junit.Test;
|
||||
import testutil.SymbolAndFunctionCleaner;
|
||||
|
||||
import static testutil.TestUtilities.evaluateString;
|
||||
import static testutil.TypeAssertions.assertNil;
|
||||
import static testutil.TypeAssertions.assertT;
|
||||
|
||||
public class NUMERIC_EQUALTest extends SymbolAndFunctionCleaner {
|
||||
|
||||
@Test
|
||||
public void numericEqualWithOneNumber() {
|
||||
String input = "(= 1)";
|
||||
|
||||
assertT(evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void numericEqualWithEqualNumbers() {
|
||||
String input = "(= 1 1)";
|
||||
|
||||
assertT(evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void numericEqualWithNonEqualNumbers() {
|
||||
String input = "(= 1 2)";
|
||||
|
||||
assertNil(evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void numericEqualWithManyEqualNumbers() {
|
||||
String input = "(= 4 4 4 4 4 4 4 4 4 4)";
|
||||
|
||||
assertT(evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void numericEqualWithManyNonEqualNumbers() {
|
||||
String input = "(= 4 4 4 4 5 4 4 4 4 4)";
|
||||
|
||||
assertNil(evaluateString(input));
|
||||
}
|
||||
|
||||
@Test(expected = BadArgumentTypeException.class)
|
||||
public void numericEqualWithNonNumbers() {
|
||||
evaluateString("(= 'x 'x)");
|
||||
}
|
||||
|
||||
@Test(expected = TooFewArgumentsException.class)
|
||||
public void numericEqualWithTooFewArguments() {
|
||||
evaluateString("(=)");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package function.builtin.predicate
|
||||
|
||||
import function.ArgumentValidator.BadArgumentTypeException
|
||||
import function.ArgumentValidator.TooFewArgumentsException
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
|
||||
import testutil.SymbolAndFunctionCleaner
|
||||
import testutil.TestUtilities.evaluateString
|
||||
import testutil.TypeAssertions.assertNil
|
||||
import testutil.TypeAssertions.assertT
|
||||
|
||||
@TestInstance(PER_CLASS)
|
||||
class NumericEqualTest : SymbolAndFunctionCleaner() {
|
||||
|
||||
@Test
|
||||
fun `one number`() {
|
||||
assertT(evaluateString("(= 1)"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `equal numbers`() {
|
||||
assertT(evaluateString("(= 1 1)"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `unequal numbers`() {
|
||||
assertNil(evaluateString("(= 1 2)"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `many equal numbers`() {
|
||||
assertT(evaluateString("(= 4 4 4 4 4 4 4 4 4 4)"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `many unequal numbers`() {
|
||||
assertNil(evaluateString("(= 4 4 4 4 5 4 4 4 4 4)"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bad argument types`() {
|
||||
assertThrows(BadArgumentTypeException::class.java) { evaluateString("(= 'x 'x)") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `too few arguments`() {
|
||||
assertThrows(TooFewArgumentsException::class.java) { evaluateString("(=)") }
|
||||
}
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
package function.builtin.special;
|
||||
|
||||
import function.ArgumentValidator.BadArgumentTypeException;
|
||||
import function.ArgumentValidator.DottedArgumentListException;
|
||||
import function.ArgumentValidator.TooFewArgumentsException;
|
||||
import function.ArgumentValidator.TooManyArgumentsException;
|
||||
import function.builtin.EVAL.UndefinedFunctionException;
|
||||
import org.junit.Test;
|
||||
import sexpression.Cons;
|
||||
import sexpression.LispNumber;
|
||||
import sexpression.Symbol;
|
||||
import testutil.SymbolAndFunctionCleaner;
|
||||
|
||||
import static function.builtin.special.LAMBDA.Lambda;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static sexpression.LispNumber.ONE;
|
||||
import static sexpression.Nil.NIL;
|
||||
import static sexpression.Symbol.T;
|
||||
import static testutil.TestUtilities.assertSExpressionsMatch;
|
||||
import static testutil.TestUtilities.evaluateString;
|
||||
import static testutil.TestUtilities.parseString;
|
||||
|
||||
public class LAMBDATest extends SymbolAndFunctionCleaner {
|
||||
|
||||
@Test
|
||||
public void lambda() {
|
||||
String input = "(lambda (x) x)";
|
||||
|
||||
assertSExpressionsMatch(parseString("(LAMBDA (X) X)"), evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lambdaSymbol() {
|
||||
String input = "(λ (x) x)";
|
||||
|
||||
assertSExpressionsMatch(parseString("(LAMBDA (X) X)"), evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lambdaWithNoBody() {
|
||||
String input = "(lambda ())";
|
||||
|
||||
assertSExpressionsMatch(parseString("(LAMBDA ())"), evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lambdaExpressionIsLambdaExpression() {
|
||||
Cons lambdaExpression = new Cons(new Symbol("LAMBDA"), new Cons(NIL, new Cons(NIL, NIL)));
|
||||
|
||||
assertTrue(Lambda.isLambdaExpression(lambdaExpression));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void somethingElseIsNotLambdaExpression() {
|
||||
assertFalse(Lambda.isLambdaExpression(T));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createLambdaExpression() {
|
||||
Cons lambdaExpression = new Cons(new Symbol("LAMBDA"), new Cons(NIL, new Cons(NIL, NIL)));
|
||||
|
||||
assertSExpressionsMatch(parseString("(:LAMBDA () ())"),
|
||||
Lambda.createFunction(lambdaExpression).getLambdaExpression());
|
||||
}
|
||||
|
||||
@Test(expected = DottedArgumentListException.class)
|
||||
public void lambdaWithDottedArgumentList() {
|
||||
String input = "(apply 'lambda (cons '(x) 1))";
|
||||
|
||||
evaluateString(input);
|
||||
}
|
||||
|
||||
@Test(expected = DottedArgumentListException.class)
|
||||
public void lambdaWithDottedLambdaList() {
|
||||
String input = "(funcall 'lambda (cons 'a 'b) ())";
|
||||
|
||||
evaluateString(input);
|
||||
}
|
||||
|
||||
@Test(expected = DottedArgumentListException.class)
|
||||
public void createFunctionWithDottedArgumentList() {
|
||||
Cons lambdaExpression = new Cons(new Symbol("LAMBDA"), new Cons(NIL, ONE));
|
||||
|
||||
Lambda.createFunction(lambdaExpression);
|
||||
}
|
||||
|
||||
@Test(expected = BadArgumentTypeException.class)
|
||||
public void createFunctionWithNonList() {
|
||||
Cons lambdaExpression = new Cons(new Symbol("LAMBDA"), ONE);
|
||||
|
||||
Lambda.createFunction(lambdaExpression);
|
||||
}
|
||||
|
||||
@Test(expected = BadArgumentTypeException.class)
|
||||
public void lambdaWithNonSymbolParameter() {
|
||||
evaluateString("(lambda (1) ())");
|
||||
}
|
||||
|
||||
@Test(expected = TooFewArgumentsException.class)
|
||||
public void lambdaWithTooFewArguments() {
|
||||
evaluateString("(lambda)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void anonymousLambdaCall() {
|
||||
String input = "((lambda (x) x) 203)";
|
||||
|
||||
assertSExpressionsMatch(new LispNumber("203"), evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void anonymousLambdaCallWithMultipleArguments() {
|
||||
String input = "((lambda (x y) (+ x y)) 203 2)";
|
||||
|
||||
assertSExpressionsMatch(new LispNumber("205"), evaluateString(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void anonymousLambdaCallWithSymbol() {
|
||||
String input = "((λ (x) (+ x 1)) 3)";
|
||||
|
||||
assertSExpressionsMatch(new LispNumber("4"), evaluateString(input));
|
||||
}
|
||||
|
||||
@Test(expected = TooFewArgumentsException.class)
|
||||
public void anonymousLambdaCallWithTooFewArguments() {
|
||||
evaluateString("((lambda (x) x))");
|
||||
}
|
||||
|
||||
@Test(expected = TooManyArgumentsException.class)
|
||||
public void anonymousLambdaCallWithTooManyArguments() {
|
||||
evaluateString("((lambda (x y) x) 1 2 3)");
|
||||
}
|
||||
|
||||
@Test(expected = UndefinedFunctionException.class)
|
||||
public void badAnonymousFunctionCall() {
|
||||
evaluateString("((bad-lambda (x y) x) 1 2 3)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lexicalClosure() {
|
||||
evaluateString("(setq increment-count (let ((counter 0)) (lambda () (setq counter (+ 1 counter)))))");
|
||||
|
||||
assertSExpressionsMatch(parseString("1"), evaluateString("(funcall increment-count)"));
|
||||
assertSExpressionsMatch(parseString("2"), evaluateString("(funcall increment-count)"));
|
||||
assertSExpressionsMatch(parseString("3"), evaluateString("(funcall increment-count)"));
|
||||
assertSExpressionsMatch(parseString("4"), evaluateString("(funcall increment-count)"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
package function.builtin.special
|
||||
|
||||
import function.ArgumentValidator.BadArgumentTypeException
|
||||
import function.ArgumentValidator.DottedArgumentListException
|
||||
import function.ArgumentValidator.TooFewArgumentsException
|
||||
import function.ArgumentValidator.TooManyArgumentsException
|
||||
import function.builtin.EVAL.UndefinedFunctionException
|
||||
import function.builtin.special.Lambda.Lambda.createFunction
|
||||
import function.builtin.special.Lambda.Lambda.isLambdaExpression
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
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.Symbol
|
||||
import sexpression.Symbol.T
|
||||
import testutil.SymbolAndFunctionCleaner
|
||||
import testutil.TestUtilities.assertSExpressionsMatch
|
||||
import testutil.TestUtilities.evaluateString
|
||||
import testutil.TestUtilities.parseString
|
||||
|
||||
class LambdaTest : SymbolAndFunctionCleaner() {
|
||||
|
||||
@Test
|
||||
fun `lambda is evaluated`() {
|
||||
val input = "(lambda (x) x)"
|
||||
|
||||
assertSExpressionsMatch(parseString("(LAMBDA (X) X)"), evaluateString(input))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `lambda symbol is evaluated`() {
|
||||
val input = "(λ (x) x)"
|
||||
|
||||
assertSExpressionsMatch(parseString("(LAMBDA (X) X)"), evaluateString(input))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `lambda with no body`() {
|
||||
val input = "(lambda ())"
|
||||
|
||||
assertSExpressionsMatch(parseString("(LAMBDA ())"), evaluateString(input))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `lambda expression is a lambda expression`() {
|
||||
val lambdaExpression = Cons(Symbol("LAMBDA"), Cons(NIL, Cons(NIL, NIL)))
|
||||
|
||||
assertThat(isLambdaExpression(lambdaExpression)).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `something else is not a lambda expression`() {
|
||||
assertThat(isLambdaExpression(T)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `create lambda expression`() {
|
||||
val lambdaExpression = Cons(Symbol("LAMBDA"), Cons(NIL, Cons(NIL, NIL)))
|
||||
|
||||
assertSExpressionsMatch(parseString("(:LAMBDA () ())"), createFunction(lambdaExpression).lambdaExpression)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `dotted argument list`() {
|
||||
val input = "(apply 'lambda (cons '(x) 1))"
|
||||
|
||||
assertThrows(DottedArgumentListException::class.java) { evaluateString(input) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `dotted lambda list`() {
|
||||
val input = "(funcall 'lambda (cons 'a 'b) ())"
|
||||
|
||||
assertThrows(DottedArgumentListException::class.java) { evaluateString(input) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `create function with dotted argument list`() {
|
||||
val lambdaExpression = Cons(Symbol("LAMBDA"), Cons(NIL, ONE))
|
||||
|
||||
assertThrows(DottedArgumentListException::class.java) { createFunction(lambdaExpression) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `create function with non list`() {
|
||||
val lambdaExpression = Cons(Symbol("LAMBDA"), ONE)
|
||||
|
||||
assertThrows(BadArgumentTypeException::class.java) { createFunction(lambdaExpression) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bad argument type`() {
|
||||
assertThrows(BadArgumentTypeException::class.java) { evaluateString("(lambda (1) ())") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `too few arguments`() {
|
||||
assertThrows(TooFewArgumentsException::class.java) { evaluateString("(lambda)") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `anonymous lambda call`() {
|
||||
val input = "((lambda (x) x) 203)"
|
||||
|
||||
assertSExpressionsMatch(LispNumber("203"), evaluateString(input))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `anonymous lambda call with multiple arguments`() {
|
||||
val input = "((lambda (x y) (+ x y)) 203 2)"
|
||||
|
||||
assertSExpressionsMatch(LispNumber("205"), evaluateString(input))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `anonymous lambda call with symbol`() {
|
||||
val input = "((λ (x) (+ x 1)) 3)"
|
||||
|
||||
assertSExpressionsMatch(LispNumber("4"), evaluateString(input))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `anonymous lambda call with too few arguments`() {
|
||||
assertThrows(TooFewArgumentsException::class.java) { evaluateString("((lambda (x) x))") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `anonymous lambda call with too many arguments`() {
|
||||
assertThrows(TooManyArgumentsException::class.java) { evaluateString("((lambda (x y) x) 1 2 3)") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bad anonymous function call`() {
|
||||
assertThrows(UndefinedFunctionException::class.java) { evaluateString("((bad-lambda (x y) x) 1 2 3)") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `lexical closure`() {
|
||||
evaluateString("(setq increment-count (let ((counter 0)) (lambda () (setq counter (+ 1 counter)))))")
|
||||
|
||||
assertSExpressionsMatch(parseString("1"), evaluateString("(funcall increment-count)"))
|
||||
assertSExpressionsMatch(parseString("2"), evaluateString("(funcall increment-count)"))
|
||||
assertSExpressionsMatch(parseString("3"), evaluateString("(funcall increment-count)"))
|
||||
assertSExpressionsMatch(parseString("4"), evaluateString("(funcall increment-count)"))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue