package serene.simple; import java.util.function.Function; public class FnSpecialForm extends SpecialForm { public FnSpecialForm(ListNode paramsAndBody) { super(paramsAndBody); } @Override public Object eval(final Scope parentScope) { final ListNode formalParams = (ListNode) this.node.rest().first(); final ListNode body = this.node.rest().rest(); return new Function() { @Override public Object apply(Object arg) { Object args[] = {arg}; return this.apply(args); } public Object apply(Object... args) { Scope scope = new Scope(parentScope); if (args.length != formalParams.length) { throw new RuntimeException(String.format("Wrong number of arguments. Expected: %s, Got: %s.", formalParams.length, args.length)); } // Map parameter values to formal parameter names int i = 0; for (Node param : formalParams) { SymbolNode paramSymbol = (SymbolNode) param; scope.insertSymbol(paramSymbol.name, args[i]); i++; } // Evaluate body Object output = null; for (Node node : body) { output = node.eval(scope); } return output; } }; } }