diff --git a/src/main/kotlin/function/builtin/special/DEFINE_SPECIAL.java b/src/main/kotlin/function/builtin/special/DEFINE_SPECIAL.java deleted file mode 100644 index d69d2a1..0000000 --- a/src/main/kotlin/function/builtin/special/DEFINE_SPECIAL.java +++ /dev/null @@ -1,20 +0,0 @@ -package function.builtin.special; - -import function.FunctionNames; -import function.UserDefinedFunction; -import function.UserDefinedSpecialFunction; -import sexpression.Cons; -import sexpression.SExpression; - -@FunctionNames({ "DEFINE-SPECIAL" }) -public class DEFINE_SPECIAL extends Define { - - public DEFINE_SPECIAL(String name) { - super(name); - } - - @Override - protected UserDefinedFunction createFunction(SExpression functionName, Cons lambdaList, Cons functionBody) { - return new UserDefinedSpecialFunction(functionName.toString(), lambdaList, functionBody); - } -} diff --git a/src/main/kotlin/function/builtin/special/DEFMACRO.java b/src/main/kotlin/function/builtin/special/DEFMACRO.java deleted file mode 100644 index d228678..0000000 --- a/src/main/kotlin/function/builtin/special/DEFMACRO.java +++ /dev/null @@ -1,20 +0,0 @@ -package function.builtin.special; - -import function.FunctionNames; -import function.UserDefinedFunction; -import function.UserDefinedMacro; -import sexpression.Cons; -import sexpression.SExpression; - -@FunctionNames({ "DEFMACRO" }) -public class DEFMACRO extends Define { - - public DEFMACRO(String name) { - super(name); - } - - @Override - protected UserDefinedFunction createFunction(SExpression functionName, Cons lambdaList, Cons functionBody) { - return new UserDefinedMacro(functionName.toString(), lambdaList, functionBody); - } -} diff --git a/src/main/kotlin/function/builtin/special/DEFUN.java b/src/main/kotlin/function/builtin/special/DEFUN.java deleted file mode 100644 index c7fc9eb..0000000 --- a/src/main/kotlin/function/builtin/special/DEFUN.java +++ /dev/null @@ -1,19 +0,0 @@ -package function.builtin.special; - -import function.FunctionNames; -import function.UserDefinedFunction; -import sexpression.Cons; -import sexpression.SExpression; - -@FunctionNames({ "DEFUN" }) -public class DEFUN extends Define { - - public DEFUN(String name) { - super(name); - } - - @Override - protected UserDefinedFunction createFunction(SExpression functionName, Cons lambdaList, Cons functionBody) { - return new UserDefinedFunction(functionName.toString(), lambdaList, functionBody); - } -} diff --git a/src/main/kotlin/function/builtin/special/Define.java b/src/main/kotlin/function/builtin/special/Define.java deleted file mode 100644 index e21ad93..0000000 --- a/src/main/kotlin/function/builtin/special/Define.java +++ /dev/null @@ -1,76 +0,0 @@ -package function.builtin.special; - -import environment.RuntimeEnvironment; -import error.LispWarning; -import function.ArgumentValidator; -import function.LispSpecialFunction; -import function.UserDefinedFunction; -import sexpression.Cons; -import sexpression.SExpression; -import sexpression.Symbol; -import table.FunctionTable; - -import static function.builtin.cons.LIST.makeList; -import static java.text.MessageFormat.format; - -public abstract class Define extends LispSpecialFunction { - - private ArgumentValidator argumentValidator; - private ArgumentValidator lambdaListIsListValidator; - private ArgumentValidator lambdaListValidator; - private RuntimeEnvironment environment; - - public Define(String functionName) { - this.argumentValidator = new ArgumentValidator(functionName); - this.argumentValidator.setMinimumNumberOfArguments(2); - this.argumentValidator.setFirstArgumentExpectedType(Symbol.class); - - this.lambdaListIsListValidator = new ArgumentValidator(functionName + "|lambda-list|"); - this.lambdaListIsListValidator.setEveryArgumentExpectedType(Cons.class); - - this.lambdaListValidator = new ArgumentValidator(functionName + "|parameter|"); - this.lambdaListValidator.setEveryArgumentExpectedType(Symbol.class); - - this.environment = RuntimeEnvironment.INSTANCE; - } - - @Override - public SExpression call(Cons argumentList) { - argumentValidator.validate(argumentList); - - Cons remainingArguments = (Cons) argumentList.getRest(); - SExpression functionName = argumentList.getFirst(); - SExpression secondArgument = remainingArguments.getFirst(); - lambdaListIsListValidator.validate(makeList(secondArgument)); - - Cons lambdaList = (Cons) secondArgument; - lambdaListValidator.validate(lambdaList); - - Cons functionBody = (Cons) remainingArguments.getRest(); - UserDefinedFunction function = createFunction(functionName, lambdaList, functionBody); - - if (FunctionTable.INSTANCE.isAlreadyDefined(functionName.toString())) - environment.getErrorManager().handle(new RedefiningFunctionWarning(functionName.toString())); - - FunctionTable.INSTANCE.defineFunction(functionName.toString(), function); - - return functionName; - } - - protected abstract UserDefinedFunction createFunction(SExpression functionName, Cons lambdaList, Cons functionBody); - - public class RedefiningFunctionWarning extends LispWarning { - - private static final long serialVersionUID = 1L; - private String functionName; - - public RedefiningFunctionWarning(String functionName) { - this.functionName = functionName; - } - - @Override - public String getMessage() { - return format("redefining function {0}", functionName); - } - } -} diff --git a/src/main/kotlin/function/builtin/special/Define.kt b/src/main/kotlin/function/builtin/special/Define.kt new file mode 100644 index 0000000..5fc23bf --- /dev/null +++ b/src/main/kotlin/function/builtin/special/Define.kt @@ -0,0 +1,59 @@ +package function.builtin.special + +import environment.RuntimeEnvironment +import error.LispWarning +import function.ArgumentValidator +import function.LispSpecialFunction +import function.UserDefinedFunction +import function.builtin.cons.LIST.makeList +import sexpression.Cons +import sexpression.SExpression +import sexpression.Symbol +import table.FunctionTable + +abstract class Define(functionName: String) : LispSpecialFunction() { + + private val argumentValidator = ArgumentValidator(functionName).apply { + setMinimumNumberOfArguments(2) + setFirstArgumentExpectedType(Symbol::class.java) + } + + private val lambdaListIsListValidator = ArgumentValidator("$functionName|lambda-list|").apply { + setEveryArgumentExpectedType(Cons::class.java) + } + + private val lambdaListValidator = ArgumentValidator("$functionName|parameter|").apply { + setEveryArgumentExpectedType(Symbol::class.java) + } + + override fun call(argumentList: Cons): SExpression { + argumentValidator.validate(argumentList) + + val remainingArguments = argumentList.rest as Cons + val functionName = argumentList.first + val secondArgument = remainingArguments.first + lambdaListIsListValidator.validate(makeList(secondArgument)) + + val lambdaList = secondArgument as Cons + lambdaListValidator.validate(lambdaList) + + val functionBody = remainingArguments.rest as Cons + val function = createFunction(functionName, lambdaList, functionBody) + + if (FunctionTable.isAlreadyDefined(functionName.toString())) + RuntimeEnvironment.errorManager!!.handle(RedefiningFunctionWarning(functionName.toString())) + + FunctionTable.defineFunction(functionName.toString(), function) + + return functionName + } + + protected abstract fun createFunction(functionName: SExpression, + lambdaList: Cons, + functionBody: Cons): UserDefinedFunction + + inner class RedefiningFunctionWarning(functionName: String) : LispWarning() { + + override val message = "redefining function $functionName" + } +} diff --git a/src/main/kotlin/function/builtin/special/DefineSpecial.kt b/src/main/kotlin/function/builtin/special/DefineSpecial.kt new file mode 100644 index 0000000..8c82cfd --- /dev/null +++ b/src/main/kotlin/function/builtin/special/DefineSpecial.kt @@ -0,0 +1,14 @@ +package function.builtin.special + +import function.FunctionNames +import function.UserDefinedFunction +import function.UserDefinedSpecialFunction +import sexpression.Cons +import sexpression.SExpression + +@FunctionNames("DEFINE-SPECIAL") +class DefineSpecial(name: String) : Define(name) { + + override fun createFunction(functionName: SExpression, lambdaList: Cons, functionBody: Cons) = + UserDefinedSpecialFunction(functionName.toString(), lambdaList, functionBody) +} diff --git a/src/main/kotlin/function/builtin/special/Defmacro.kt b/src/main/kotlin/function/builtin/special/Defmacro.kt new file mode 100644 index 0000000..aec6402 --- /dev/null +++ b/src/main/kotlin/function/builtin/special/Defmacro.kt @@ -0,0 +1,14 @@ +package function.builtin.special + +import function.FunctionNames +import function.UserDefinedFunction +import function.UserDefinedMacro +import sexpression.Cons +import sexpression.SExpression + +@FunctionNames("DEFMACRO") +class Defmacro(name: String) : Define(name) { + + override fun createFunction(functionName: SExpression, lambdaList: Cons, functionBody: Cons) = + UserDefinedMacro(functionName.toString(), lambdaList, functionBody) +} diff --git a/src/main/kotlin/function/builtin/special/Defun.kt b/src/main/kotlin/function/builtin/special/Defun.kt new file mode 100644 index 0000000..5a69102 --- /dev/null +++ b/src/main/kotlin/function/builtin/special/Defun.kt @@ -0,0 +1,13 @@ +package function.builtin.special + +import function.FunctionNames +import function.UserDefinedFunction +import sexpression.Cons +import sexpression.SExpression + +@FunctionNames("DEFUN") +class Defun(name: String) : Define(name) { + + override fun createFunction(functionName: SExpression, lambdaList: Cons, functionBody: Cons) = + UserDefinedFunction(functionName.toString(), lambdaList, functionBody) +} diff --git a/src/test/kotlin/function/builtin/special/DEFINE_SPECIALTest.java b/src/test/kotlin/function/builtin/special/DefineSpecialTest.java similarity index 98% rename from src/test/kotlin/function/builtin/special/DEFINE_SPECIALTest.java rename to src/test/kotlin/function/builtin/special/DefineSpecialTest.java index 62a2015..669567c 100644 --- a/src/test/kotlin/function/builtin/special/DEFINE_SPECIALTest.java +++ b/src/test/kotlin/function/builtin/special/DefineSpecialTest.java @@ -18,12 +18,12 @@ import static testutil.TestUtilities.assertSExpressionsMatch; import static testutil.TestUtilities.evaluateString; import static testutil.TestUtilities.parseString; -public class DEFINE_SPECIALTest extends SymbolAndFunctionCleaner { +public class DefineSpecialTest extends SymbolAndFunctionCleaner { private ByteArrayOutputStream outputStream; private RuntimeEnvironment environment; - public DEFINE_SPECIALTest() { + public DefineSpecialTest() { this.environment = RuntimeEnvironment.INSTANCE; } diff --git a/src/test/kotlin/function/builtin/special/DEFMACROTest.java b/src/test/kotlin/function/builtin/special/DefmacroTest.java similarity index 98% rename from src/test/kotlin/function/builtin/special/DEFMACROTest.java rename to src/test/kotlin/function/builtin/special/DefmacroTest.java index 15e81de..495f994 100644 --- a/src/test/kotlin/function/builtin/special/DEFMACROTest.java +++ b/src/test/kotlin/function/builtin/special/DefmacroTest.java @@ -18,12 +18,12 @@ import static testutil.TestUtilities.assertSExpressionsMatch; import static testutil.TestUtilities.evaluateString; import static testutil.TestUtilities.parseString; -public class DEFMACROTest extends SymbolAndFunctionCleaner { +public class DefmacroTest extends SymbolAndFunctionCleaner { private ByteArrayOutputStream outputStream; private RuntimeEnvironment environment; - public DEFMACROTest() { + public DefmacroTest() { this.environment = RuntimeEnvironment.INSTANCE; } diff --git a/src/test/kotlin/function/builtin/special/DEFUNTest.java b/src/test/kotlin/function/builtin/special/DefunTest.java similarity index 98% rename from src/test/kotlin/function/builtin/special/DEFUNTest.java rename to src/test/kotlin/function/builtin/special/DefunTest.java index d9f11eb..a75de22 100644 --- a/src/test/kotlin/function/builtin/special/DEFUNTest.java +++ b/src/test/kotlin/function/builtin/special/DefunTest.java @@ -18,12 +18,12 @@ import static testutil.TestUtilities.assertSExpressionsMatch; import static testutil.TestUtilities.evaluateString; import static testutil.TestUtilities.parseString; -public class DEFUNTest extends SymbolAndFunctionCleaner { +public class DefunTest extends SymbolAndFunctionCleaner { private ByteArrayOutputStream outputStream; private RuntimeEnvironment environment; - public DEFUNTest() { + public DefunTest() { this.environment = RuntimeEnvironment.INSTANCE; }