Removed duplicate code in SET and SETF

This commit is contained in:
Mike Cifelli 2017-02-26 13:01:47 -05:00
parent 49e145d098
commit 8fdaaeb23d
4 changed files with 15 additions and 29 deletions

View File

@ -7,8 +7,8 @@ public class APPLY extends LispFunction {
private ArgumentValidator argumentValidator; private ArgumentValidator argumentValidator;
public static SExpression apply(Cons argList) { public static SExpression apply(Cons argumentList) {
return new APPLY().call(argList); return new APPLY().call(argumentList);
} }
public APPLY() { public APPLY() {

View File

@ -1,9 +1,9 @@
package function.builtin; package function.builtin;
import static function.builtin.APPLY.apply; import static function.builtin.APPLY.apply;
import static function.builtin.cons.LIST.makeList;
import function.*; import function.*;
import function.builtin.cons.LIST;
import sexpression.*; import sexpression.*;
public class FUNCALL extends LispFunction { public class FUNCALL extends LispFunction {
@ -17,7 +17,7 @@ public class FUNCALL extends LispFunction {
public SExpression call(Cons argumentList) { public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList); argumentValidator.validate(argumentList);
Cons applyArgs = new Cons(argumentList.getFirst(), LIST.makeList(argumentList.getRest())); Cons applyArgs = new Cons(argumentList.getFirst(), makeList(argumentList.getRest()));
return apply(applyArgs); return apply(applyArgs);
} }

View File

@ -9,6 +9,10 @@ public class SET extends LispFunction {
private ArgumentValidator argumentValidator; private ArgumentValidator argumentValidator;
private ExecutionContext executionContext; private ExecutionContext executionContext;
public static SExpression set(Cons argumentList) {
return new SET().call(argumentList);
}
public SET() { public SET() {
this.argumentValidator = new ArgumentValidator("SET"); this.argumentValidator = new ArgumentValidator("SET");
this.argumentValidator.setExactNumberOfArguments(2); this.argumentValidator.setExactNumberOfArguments(2);

View File

@ -1,51 +1,33 @@
package function.builtin.special; package function.builtin.special;
import static function.builtin.EVAL.eval; import static function.builtin.EVAL.eval;
import static function.builtin.SET.set;
import static function.builtin.cons.LIST.makeList;
import function.*; import function.*;
import sexpression.*; import sexpression.*;
import table.*;
public class SETF extends LispSpecialFunction { public class SETF extends LispSpecialFunction {
private ArgumentValidator argumentValidator; private ArgumentValidator argumentValidator;
private ExecutionContext executionContext;
public SETF() { public SETF() {
this.argumentValidator = new ArgumentValidator("SETF"); this.argumentValidator = new ArgumentValidator("SETF");
this.argumentValidator.setExactNumberOfArguments(2); this.argumentValidator.setExactNumberOfArguments(2);
this.argumentValidator.setFirstArgumentExpectedType(Symbol.class); this.argumentValidator.setFirstArgumentExpectedType(Symbol.class);
this.executionContext = ExecutionContext.getInstance();
} }
public SExpression call(Cons argumentList) { public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList); argumentValidator.validate(argumentList);
return set(evaluateValueOnly(argumentList));
}
private Cons evaluateValueOnly(Cons argumentList) {
Cons rest = (Cons) argumentList.getRest(); Cons rest = (Cons) argumentList.getRest();
SExpression symbol = argumentList.getFirst();
SExpression value = eval(rest.getFirst()); SExpression value = eval(rest.getFirst());
SymbolTable table = findScopeOfSymbol(symbol); return new Cons(argumentList.getFirst(), makeList(value));
table.put(symbol.toString(), value);
return value;
}
private SymbolTable findScopeOfSymbol(SExpression symbol) {
SymbolTable table = executionContext.getScope();
while (!isSymbolInTable(symbol, table) && !isGlobalTable(table))
table = table.getParent();
return table;
}
private boolean isSymbolInTable(SExpression symbol, SymbolTable table) {
return table.contains(symbol.toString());
}
private boolean isGlobalTable(SymbolTable table) {
return table.getParent() == null;
} }
} }