private static Expr Map(List <Expr> args, Dictionary <string, Expr> env) { // first thing in args should be a procedure if (args.Count < 2) { throw new EvaluatorException("the expected number of arguments does not match the given number"); } Expr proc = args[0];//.eval(env); List <Expr> evaled_lists = new List <Expr>(); List <Expr> proc_calls = new List <Expr>(); Expr arg; for (int i = 1; i < args.Count; i++) { arg = args[i].eval(env); if (arg.GetType() != typeof(ConsExpr)) { throw new EvaluatorException("map: contract violation\n expected: list?"); } evaled_lists.Add((ConsExpr)arg); } while (evaled_lists[0].GetType() != typeof(EmptyExpr)) { List <Expr> proc_args = new List <Expr>(); for (int j = 0; j < evaled_lists.Count; j++) { if (evaled_lists[j].GetType() == typeof(EmptyExpr)) { throw new EvaluatorException("map: lists must be of same length"); } ConsExpr arg_ = (ConsExpr)evaled_lists[j]; // check that all lists are proper lists if (arg_.getRest().GetType() != typeof(ConsExpr) && arg_.getRest().GetType() != typeof(EmptyExpr)) { throw new EvaluatorException("map: contract violation\n expected: list?"); } proc_args.Add(arg_.getFirst()); evaled_lists[j] = arg_.getRest(); } proc_calls.Add(new AppExpr(proc, proc_args, env)); } // check that all lists end for (int j = 1; j < evaled_lists.Count; j++) { if (evaled_lists[j].GetType() != typeof(EmptyExpr)) { throw new EvaluatorException("map: all lists must have same size"); } } return(List(proc_calls, env)); }
private static Expr Car(List <Expr> arg, Dictionary <string, Expr> env) { if (arg.Count != 1) { throw new EvaluatorException("expected cons"); } Expr cons = arg[0].eval(env); if (cons.GetType() != typeof(ConsExpr)) { throw new EvaluatorException("car: contract violation\n expected: pair?"); } ConsExpr cons_ = (ConsExpr)cons; return(cons_.getFirst()); }