transcendental-lisp/src/function/builtin/SET.java

50 lines
1.4 KiB
Java

package function.builtin;
import function.*;
import sexpression.*;
import table.*;
public class SET extends LispFunction {
private ArgumentValidator argumentValidator;
private ExecutionContext executionContext;
public SET() {
this.argumentValidator = new ArgumentValidator("SET");
this.argumentValidator.setExactNumberOfArguments(2);
this.argumentValidator.setFirstArgumentExpectedType(Symbol.class);
this.executionContext = ExecutionContext.getInstance();
}
public SExpression call(Cons argumentList) {
argumentValidator.validate(argumentList);
Cons rest = (Cons) argumentList.getRest();
SExpression symbol = argumentList.getFirst();
SExpression value = rest.getFirst();
SymbolTable table = findScopeOfSymbol(symbol);
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;
}
}