Convert definition functions to kotlin

This commit is contained in:
Mike Cifelli 2018-10-28 13:22:18 -04:00
parent c6d25275bb
commit a871690e70
11 changed files with 106 additions and 141 deletions

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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"
}
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -18,12 +18,12 @@ import static testutil.TestUtilities.assertSExpressionsMatch;
import static testutil.TestUtilities.evaluateString; import static testutil.TestUtilities.evaluateString;
import static testutil.TestUtilities.parseString; import static testutil.TestUtilities.parseString;
public class DEFINE_SPECIALTest extends SymbolAndFunctionCleaner { public class DefineSpecialTest extends SymbolAndFunctionCleaner {
private ByteArrayOutputStream outputStream; private ByteArrayOutputStream outputStream;
private RuntimeEnvironment environment; private RuntimeEnvironment environment;
public DEFINE_SPECIALTest() { public DefineSpecialTest() {
this.environment = RuntimeEnvironment.INSTANCE; this.environment = RuntimeEnvironment.INSTANCE;
} }

View File

@ -18,12 +18,12 @@ import static testutil.TestUtilities.assertSExpressionsMatch;
import static testutil.TestUtilities.evaluateString; import static testutil.TestUtilities.evaluateString;
import static testutil.TestUtilities.parseString; import static testutil.TestUtilities.parseString;
public class DEFMACROTest extends SymbolAndFunctionCleaner { public class DefmacroTest extends SymbolAndFunctionCleaner {
private ByteArrayOutputStream outputStream; private ByteArrayOutputStream outputStream;
private RuntimeEnvironment environment; private RuntimeEnvironment environment;
public DEFMACROTest() { public DefmacroTest() {
this.environment = RuntimeEnvironment.INSTANCE; this.environment = RuntimeEnvironment.INSTANCE;
} }

View File

@ -18,12 +18,12 @@ import static testutil.TestUtilities.assertSExpressionsMatch;
import static testutil.TestUtilities.evaluateString; import static testutil.TestUtilities.evaluateString;
import static testutil.TestUtilities.parseString; import static testutil.TestUtilities.parseString;
public class DEFUNTest extends SymbolAndFunctionCleaner { public class DefunTest extends SymbolAndFunctionCleaner {
private ByteArrayOutputStream outputStream; private ByteArrayOutputStream outputStream;
private RuntimeEnvironment environment; private RuntimeEnvironment environment;
public DEFUNTest() { public DefunTest() {
this.environment = RuntimeEnvironment.INSTANCE; this.environment = RuntimeEnvironment.INSTANCE;
} }