private static Expr define(boolean isGlobal, Interpreter interpreter, Scope scope, Expr argExpr) { if (!(argExpr instanceof ListExpr)) return interpreter.error("def:is: needs more than one argument."); ListExpr args = (ListExpr) argExpr; if (args.getList().size() != 2) return interpreter.error("def:is: expects two arguments."); // get the list of names being defined Expr nameArg = args.getList().get(0); List<String> names = new ArrayList<String>(); if (nameArg.getType() == ExprType.NAME) { // defining a single name names.add(((NameExpr) nameArg).getName()); } else if (nameArg.getType() == ExprType.LIST) { // defining a list of names ListExpr namesList = (ListExpr) nameArg; for (Expr name : namesList.getList()) { if (name.getType() != ExprType.NAME) { return interpreter.error("First argument to def:is: must be a name, list, or call."); } names.add(((NameExpr) name).getName()); } } else { return interpreter.error("First argument to def:is: must be a name, list, or call."); } // evaluate the value(s) Expr body = args.getList().get(1); Expr value = interpreter.eval(scope, body); // make sure the body matches the names if (names.size() > 1) { if (value.getType() != ExprType.LIST) return interpreter.error("When defining multiple names, the value must be a list."); ListExpr valueList = (ListExpr) value; if (names.size() != valueList.getList().size()) return interpreter.error( "When defining multiple names, the number of names and values must match."); } // define the names in the correct scope if (names.size() == 1) { defineName(isGlobal, interpreter, scope, names.get(0), value); } else { ListExpr values = (ListExpr) value; for (int i = 0; i < names.size(); i++) { defineName(isGlobal, interpreter, scope, names.get(i), values.getList().get(i)); } } return Expr.unit(); }
private static Expr createFunction(boolean isMacro, Scope scope, Expr arg) { // ### bob: need lots of error-handling here ListExpr argList = (ListExpr) arg; // get the parameter name(s) List<String> paramNames = new ArrayList<String>(); Expr parameters = argList.getList().get(0); if (parameters.getType() == ExprType.LIST) { ListExpr paramList = (ListExpr) parameters; for (Expr param : paramList.getList()) { paramNames.add(((NameExpr) param).getName()); } } else { // not a list, so assume it's a single name paramNames.add(((NameExpr) parameters).getName()); } // create the function return new FunctionExpr(scope, isMacro, paramNames, argList.getList().get(1)); // ### bob: need to support closures at some point }