private static IExpression QuotationSpecialFormParser <T> (IExpression expression, Func <IExpression, T> creator) where T : IExpression { var combination = expression as ScmCombination; if (!combination.Operands.IsSingle()) { throw new ParserException(UserMessages.MustContainOneExpressionAsArgument, combination); } var datum = ParseExpression(combination.Operands.First()); if (datum is ScmCombination) { var datumAsCombination = datum as ScmCombination; if (datumAsCombination.Expressions.IsEmpty()) { datum = ScmEmptyList.Instance; } else { datum = new ScmPair(datumAsCombination.Expressions); } } var quoteSpecialForm = creator(datum); return(quoteSpecialForm); }
private Bounce ApplyClosureProcedure(ScmCombination combination, Environment env, Cont cont) { //((lambda (b . a) a) 1) var closure = combination.Procedure as ScmClosure; var numberOfArguments = closure.ArgumentList.Count; var operands = new List <IExpression> (combination.Operands); if (!closure.Dotted && numberOfArguments != operands.Count) { throw new EvaluatorException(String.Format("Expecting {0} argument{1}", numberOfArguments, numberOfArguments > 1 ? "s" : ""), combination); } else if (closure.Dotted) { var numberOfArgumentsButLast = numberOfArguments - 1; if (numberOfArgumentsButLast > operands.Count) { throw new EvaluatorException(String.Format("Expecting at least {0} argument{1}", numberOfArgumentsButLast, numberOfArgumentsButLast > 1 ? "s" : ""), combination); } else if (numberOfArgumentsButLast == operands.Count) { operands.Add(ScmEmptyList.Instance); } else { var lastArgument = new ScmPair(operands.TailFrom(numberOfArgumentsButLast)); operands = new List <IExpression> (operands.GetRange(0, numberOfArgumentsButLast)); operands.Add(lastArgument); } } return(() => EvalList(operands, env, evalResults => { var environmentFrame = new EnvironmentFrame(); var evalResultsAsList = evalResults as List <IExpression>; for (int i = 0; i < closure.ArgumentList.Count; ++i) { var argumentName = closure.ArgumentList[i]; var argumentValue = evalResultsAsList[i]; environmentFrame.Set(argumentName, argumentValue); } var newEnvironment = (new Environment(closure.Env)).Extend(environmentFrame); return EvalList(closure.Body.AllButLast(), newEnvironment, bodyEvalResults => { return Eval(closure.Body.Last(), newEnvironment, cont); }); })); }
public ScmPair(List <IExpression> list) { System.Diagnostics.Debug.Assert(list != null && list.Count > 0); ScmPair currPair = this; for (int i = 0; i < list.Count; ++i) { currPair.Car = list[i]; if (i < list.Count - 1) { currPair.Cdr = new ScmPair(); currPair = (ScmPair)currPair.Cdr; } else { currPair.Cdr = ScmEmptyList.Instance; } } }