示例#1
0
        public static void ThrowsWhenEvaluated <TException>(ILispValue expression, ILispEnvironment environment = null) where TException : LispException
        {
            Assert.IsNotNull(expression);

            try
            {
                ILispValue actual = Evaluator.Evaluate(expression, environment ?? new GlobalEnvironment());
                throw new AssertFailedException(string.Format(
                                                    "Expression returned value instead of throwing: {1}{0}Expected: {2}, Actual: {3}",
                                                    System.Environment.NewLine,
                                                    expression,
                                                    typeof(TException).FullName,
                                                    actual));
            }
            catch (LispException ex)
            {
                if (!(ex is TException))
                {
                    throw new AssertFailedException(string.Format(
                                                        "Expression threw incorrect exception type: {1}{0}Expected: {2}{0}Actual: {3}",
                                                        System.Environment.NewLine,
                                                        expression,
                                                        typeof(TException).FullName,
                                                        ex));
                }
            }
        }
示例#2
0
        private static ILispValue EvaluateProgn(IList <ILispValue> args, ILispEnvironment environment)
        {
            ILispValue result = Nil.Instance;

            foreach (ILispValue arg in args)
            {
                result = Evaluate(arg, environment);
            }
            return(result);
        }
示例#3
0
 private static ILispValue EvaluateQuote(IList <ILispValue> args, ILispEnvironment environment)
 {
     if (args.Count == 0)
     {
         throw new SignatureMismatchException("missing argument to 'quote'");
     }
     if (args.Count > 1)
     {
         throw new SignatureMismatchException("too many arguments supplied");
     }
     return(args[0]);
 }
示例#4
0
        public static void EvaluatesTo(ILispValue expected, ILispValue expression, ILispEnvironment environment = null)
        {
            Assert.IsNotNull(expected);
            Assert.IsNotNull(expression);

            ILispValue actual = Evaluator.Evaluate(expression, environment ?? new GlobalEnvironment());

            if (!EqualityComparer <ILispValue> .Default.Equals(expected, actual))
            {
                throw new AssertFailedException(string.Format(
                                                    "Computed incorrect value while evaluating {1}.{0}Expected: {2}, Actual: {3}",
                                                    System.Environment.NewLine,
                                                    expression,
                                                    expected,
                                                    actual));
            }
        }
示例#5
0
        private static ILispValue EvaluateList(List list, ILispEnvironment environment)
        {
            if (list.IsEmpty)
            {
                return(list);
            }

            ILispValue         head       = list.GetHead();
            IList <ILispValue> parameters = list.CollectProperList().Skip(1).ToList();

            if (head.Type == LispValueType.Symbol)
            {
                // Look for special forms and process them, um..., specially.
                switch (((Symbol)head).Name)
                {
                case "quote":
                    return(EvaluateQuote(parameters, environment));

                case "if":
                    return(EvaluateIf(parameters, environment));

                case "progn":
                    return(EvaluateProgn(parameters, environment));

                case "set!":
                    return(EvaluateSet(parameters, environment));

                case "lambda":
                    return(EvaluateLambdaDefinition(parameters, environment));

                default:
                    return(EvaluateInvocation((Symbol)head, parameters, environment));
                }
            }
            else
            {
                head = Evaluate(head, environment);
                if (head.Type != LispValueType.Symbol)
                {
                    throw new TypeMismatchException(new Symbol("function"), LispValueType.Symbol, head.Type);
                }
                return(EvaluateInvocation((Symbol)head, parameters, environment));
            }
        }
示例#6
0
        public static ILispValue Evaluate(ILispValue value, ILispEnvironment environment)
        {
            switch (value.Type)
            {
            case LispValueType.Boolean:
            case LispValueType.Char:
            case LispValueType.Lambda:
            case LispValueType.Number:
            case LispValueType.String:
            default:
                return(value);

            case LispValueType.Symbol:
                return(environment.Lookup((Symbol)value));

            case LispValueType.List:
                return(EvaluateList((List)value, environment));
            }
        }
示例#7
0
        private static ILispValue EvaluateSet(IList <ILispValue> args, ILispEnvironment environment)
        {
            if (args.Count < 2)
            {
                throw new SignatureMismatchException("too few arguments supplied");
            }
            if (args.Count > 2)
            {
                throw new SignatureMismatchException("too many arguments supplied");
            }
            // this is a special form since we do not evaluate the first argument, which must be a symbol
            if (args[0].Type != LispValueType.Symbol)
            {
                throw new TypeMismatchException(new Symbol("variable"), LispValueType.Symbol, args[0].Type);
            }
            ILispValue value = Evaluate(args[1], environment);

            environment.Set((Symbol)args[0], value);
            return(value);
        }
示例#8
0
        private static ILispValue EvaluateIf(IList <ILispValue> args, ILispEnvironment environment)
        {
            if (args.Count < 3)
            {
                throw new SignatureMismatchException("too few arguments supplied");
            }
            if (args.Count > 3)
            {
                throw new SignatureMismatchException("too many arguments supplied");
            }
            ILispValue test = Evaluate(args[0], environment);

            switch (test.Type)
            {
            case LispValueType.Boolean:
                if (!((TiaLisp.Values.Boolean)test).Value)
                {
                    return(Evaluate(args[2], environment));
                }
                else
                {
                    return(Evaluate(args[1], environment));
                }

            case LispValueType.List:
                if (((List)test).IsEmpty)
                {
                    return(Evaluate(args[2], environment));
                }
                else
                {
                    return(Evaluate(args[1], environment));
                }

            default:
                // Any other value than #f or () is considered true:
                return(Evaluate(args[1], environment));
            }
        }
示例#9
0
 internal LocalEnvironment(ILispEnvironment parentEnvironment)
 {
     this._ParentEnvironment = parentEnvironment;
 }
示例#10
0
 public static void ThrowsWhenEvaluated(ILispValue expression, ILispEnvironment environment = null)
 {
     ThrowsWhenEvaluated <LispException>(expression, environment);
 }
示例#11
0
        private static ILispValue EvaluateInvocation(Symbol funcName, IList <ILispValue> args, ILispEnvironment environment)
        {
            ILispValue func = environment.Lookup(funcName);

            if (func.Type != LispValueType.Lambda)
            {
                throw new TypeMismatchException(new Symbol("function"), LispValueType.Lambda, func.Type);
            }

            ILispLambda        lambda          = (ILispLambda)func;
            IList <ILispValue> parameterValues = args.Select(arg => Evaluate(arg, environment)).ToList();

            return(lambda.Execute(BindParameters(lambda, parameterValues)));
        }
示例#12
0
 private static ILispValue EvaluateLambdaDefinition(IList <ILispValue> args, ILispEnvironment environment)
 {
     throw new NotImplementedException();
 }