Add a simple GENSYM function
This commit is contained in:
parent
8aa00fea27
commit
e78e18df98
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -32,6 +32,7 @@ public class FunctionTable {
|
|||
allBuiltIns.add(EXIT.class);
|
||||
allBuiltIns.add(FIRST.class);
|
||||
allBuiltIns.add(FUNCALL.class);
|
||||
allBuiltIns.add(GENSYM.class);
|
||||
allBuiltIns.add(NUMERIC_GREATER.class);
|
||||
allBuiltIns.add(IF.class);
|
||||
allBuiltIns.add(LAMBDA.class);
|
||||
|
|
|
@ -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)");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package testutil;
|
||||
|
||||
import static function.builtin.EVAL.eval;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
|
@ -37,4 +37,8 @@ public final class TestUtilities {
|
|||
assertEquals(one.toString(), two.toString());
|
||||
}
|
||||
|
||||
public static void assertSExpressionsDoNotMatch(SExpression one, SExpression two) {
|
||||
assertNotEquals(one.toString(), two.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue