Exemple #1
0
        /// <summary>
        /// Evaluates an expression in a given lexical environment
        /// </summary>
        /// <param name="form"></param>
        /// <param name="environment"></param>
        /// <returns></returns>
        public static Object Eval(Object expression, Environment environment)
        {
            profiler.TraceCall(expression);

            if (expression == Reader.EOFVALUE)
            {
                return(profiler.TraceReturn(expression));
            }

            if (expression == null)
            {
                return(profiler.TraceReturn(null));
            }

            // The expression is either an atom or a list
            if (Primitives.IsAtom(expression))
            {
                // Number
                if (expression is double)
                {
                    return(profiler.TraceReturn(expression));
                }

                if (expression is int)
                {
                    return(profiler.TraceReturn(expression));
                }

                // Character
                if (expression is char)
                {
                    return(profiler.TraceReturn(expression));
                }

                // String
                if (expression is string)
                {
                    return(profiler.TraceReturn(expression));
                }

                Symbol sym = expression as Symbol;

                if (sym == Symbol.TRUE)
                {
                    return(profiler.TraceReturn(true));
                }

                if (sym == Symbol.FALSE)
                {
                    return(profiler.TraceReturn(false));
                }

                if (sym == Symbol.NULL)
                {
                    return(profiler.TraceReturn(null));
                }

                // If the symbol is bound to a value in this lexical environment
                if (environment.Contains(sym))
                {
                    // Then it's a variable so return it's value
                    return(profiler.TraceReturn(environment.GetValue(sym)));
                }
                else
                {
                    // Otherwise symbols evaluate to themselves
                    return(profiler.TraceReturn(expression));
                }
            }
            else
            {
                // The expression must be a list
                Cons cons = (Cons)expression;

                // Lists are assumed to be of the form (function arguments)

                // See if there is a binding to a function, clsoure, macro or special form
                // in this lexical environment
                object function = environment.GetValue((Symbol)cons.First());

                // If there is no binding, then use the function name directly - it's probably
                // the name of a .NET method
                if (function == null)
                {
                    function = cons.First();
                }

                // If it's a special form
                if (function is SpecialForm)
                {
                    return(profiler.TraceReturn(((SpecialForm)function)((Cons)cons.Cdr(), environment)));
                }

                // If its a macro application
                if (function is Macro)
                {
                    object expansion = ((Macro)function).Expand((Cons)cons.Cdr());
                    return(profiler.TraceReturn(Runtime.Eval(expansion, environment)));
                }

                // It must be a function, closure or method invocation,
                // so call apply
                Object arguments = EvalList((Cons)cons.Cdr(), environment);
                return(profiler.TraceReturn(Runtime.Apply(function, arguments, environment)));
            }
        }