Add a simple GENSYM function

This commit is contained in:
Mike Cifelli 2017-03-10 13:14:16 -05:00
parent 8aa00fea27
commit e78e18df98
4 changed files with 83 additions and 1 deletions

View File

@ -0,0 +1,36 @@
package function.builtin;
import java.math.BigInteger;
import function.*;
import sexpression.*;
@FunctionNames({ "GENSYM" })
public class GENSYM extends LispFunction {
public static final String GENSYM_PREFIX = "#G";
private static BigInteger counter = BigInteger.ZERO;
private static Symbol generateSymbol() {
incrementCounter();
return new Symbol(GENSYM_PREFIX + counter);
}
private static void incrementCounter() {
counter = counter.add(BigInteger.ONE);
}
private ArgumentValidator argumentValidator;
public GENSYM(String name) {
this.argumentValidator = new ArgumentValidator(name);
this.argumentValidator.setMaximumNumberOfArguments(0);
}
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
return generateSymbol();
}
}

View File

@ -32,6 +32,7 @@ public class FunctionTable {
allBuiltIns.add(EXIT.class); allBuiltIns.add(EXIT.class);
allBuiltIns.add(FIRST.class); allBuiltIns.add(FIRST.class);
allBuiltIns.add(FUNCALL.class); allBuiltIns.add(FUNCALL.class);
allBuiltIns.add(GENSYM.class);
allBuiltIns.add(NUMERIC_GREATER.class); allBuiltIns.add(NUMERIC_GREATER.class);
allBuiltIns.add(IF.class); allBuiltIns.add(IF.class);
allBuiltIns.add(LAMBDA.class); allBuiltIns.add(LAMBDA.class);

View File

@ -0,0 +1,41 @@
package function.builtin;
import static function.builtin.GENSYM.GENSYM_PREFIX;
import static testutil.TestUtilities.*;
import static testutil.TypeAssertions.assertSymbol;
import org.junit.Test;
import function.ArgumentValidator.TooManyArgumentsException;
import token.TokenFactory.BadCharacterException;
public class GENSYMTester {
@Test
public void gensymCreatesSymbol() {
assertSymbol(evaluateString("(gensym)"));
}
@Test
public void gensymCreatesUniqueSymbol() {
assertSExpressionsDoNotMatch(evaluateString("(gensym)"), evaluateString("(gensym)"));
}
@Test
public void simpleGensymUsage() {
String input = "(let ((x (gensym))) (set x 23) (eval x))";
assertSExpressionsMatch(evaluateString("23"), evaluateString(input));
}
@Test(expected = BadCharacterException.class)
public void cannotUseGensymValueManually() {
String variableName = GENSYM_PREFIX + 1;
evaluateString("(setq " + variableName + " 100)");
}
@Test(expected = TooManyArgumentsException.class)
public void gensymWithTooManyArguments() {
evaluateString("(gensym 1)");
}
}

View File

@ -1,7 +1,7 @@
package testutil; package testutil;
import static function.builtin.EVAL.eval; import static function.builtin.EVAL.eval;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import java.io.*; import java.io.*;
@ -37,4 +37,8 @@ public final class TestUtilities {
assertEquals(one.toString(), two.toString()); assertEquals(one.toString(), two.toString());
} }
public static void assertSExpressionsDoNotMatch(SExpression one, SExpression two) {
assertNotEquals(one.toString(), two.toString());
}
} }