示例#1
0
 /// <summary>
 /// Execute the continuation.
 /// Transfers execution to the evaluator saved when the continuation was created.
 /// The environment in effect at that time is also restored.
 /// Again, the chain of steps back to the beginning need to be clones so that this application
 ///   does not alter the evaluation, making it impossible to return back to the continuation.
 /// </summary>
 /// <param name="args">The value to return.</param>
 /// <param name="env"></param>
 /// <param name="returnTo">The evaluator to return to.  This can be different from caller if this is the last step in evaluation</param>
 /// <param name="caller">The calling evaluator.  Not used, since control is transferred away.</param>
 /// <returns>The next evaluator to execute.</returns>
 internal override Evaluator Apply(SchemeObject args, Environment env, Evaluator returnTo, Evaluator caller)
 {
     #if Check
     this.CheckArgCount(ListLength(args), args, "Continuation", caller);
     #endif
     Evaluator nextStep = this.savedEvaluator.CloneChain();
     nextStep.ReturnedExpr = First(args);
     nextStep.ReturnedEnv = this.savedEvaluator.Env;
     return nextStep;
 }
示例#2
0
 /// <summary>
 /// Initializes a new instance of the Environment class.
 /// This is used to create the global environment.
 /// When we refer to "parent" we mean the enclosing lexical environment.
 /// </summary>
 /// <param name="interp">The interpreter.</param>
 /// <param name="lexicalParent">The lexical parent environment.</param>
 public Environment(Interpreter interp, Environment lexicalParent)
 {
     this.interp = interp;
     this.lexicalParent = lexicalParent;
     this.symbolTable = new SymbolTable(0);
     if (interp != nullInterp)
     {
         interp.IncrementCounter(this.GetType().Name + ":ctor");
     }
 }
 /// <summary>
 /// Initializes a new instance of the EvaluateCallWithOutputFile class.
 /// </summary>
 /// <param name="args">A pair, containing a filename and a proc to evaluate.</param>
 /// <param name="env">The evaluation environment</param>
 /// <param name="caller">The caller.  Return to this when done.</param>
 /// <param name="port">The output port.</param>
 private EvaluateCallWithOutputFile(SchemeObject args, Environment env, Evaluator caller, OutputPort port)
     : base(InitialStep, args, env, caller)
 {
     this.port = port;
 }
示例#4
0
 /// <summary>
 /// Initializes a new instance of the Environment class.
 /// Start out with a set of variable bindings and a lexical parent environment.
 /// The initial variable bindings are the formal parameters and the corresponding argument values.
 /// </summary>
 /// <param name="formals">A list of variable names.</param>
 /// <param name="vals">The values for these variables.</param>
 /// <param name="lexicalParent">The lexical parent environment.</param>
 public Environment(SchemeObject formals, SchemeObject vals, Environment lexicalParent)
 {
     this.interp = lexicalParent.Interp;
     this.lexicalParent = lexicalParent;
     this.symbolTable = new SymbolTable(formals, vals);
 }
示例#5
0
 /// <summary>
 /// Initializes a new instance of the Environment class.
 /// Creates a new empty environment.
 /// </summary>
 /// <param name="lexicalParent">The lexically enclosing environment.</param>
 /// <returns>The new environment.</returns>
 public Environment(Environment lexicalParent)
     : this(lexicalParent.Interp, lexicalParent)
 {
 }
 /// <summary>
 /// Initializes a new instance of the EvaluateExpression class.
 /// At this point, fn is something that evaluates to a proc.
 /// It might be a symbol that, when looked up, resolves to a primitive or to a
 ///   proc of some kind, like a lambda.
 /// It is not a symbol like "and" where there are special argument-evaluation rules, so
 ///   the first task is to evaluate all the arguments.
 /// </summary>
 /// <param name="fn">The function to evaluate (the expression in the first position).</param>
 /// <param name="args">The function args to evaluate (the rest of the expressions in the list).</param>
 /// <param name="env">The evaluation environment</param>
 /// <param name="caller">The caller.  Return to this when done.</param>
 private EvaluateExpression(SchemeObject fn, SchemeObject args, Environment env, Evaluator caller)
     : base(InitialStep, args, env, caller)
 {
     this.fn = fn;
     if (fn is Symbol)
     {
         // If the fun is a symbol, we can avoid the first step.
         this.Pc = ApplyProcStep;
         Call(fn, env, this);
     }
     else if (fn is Procedure)
     {
         // Or if the fun is already a procedure, skip the first step.
         this.Pc = ApplyProcStep;
         this.ReturnedExpr = fn;
     }
 }
        /// <summary>
        /// Increment the variable.
        /// The intention is that this should be atomic.
        /// Used by increment! primitive.
        /// </summary>
        /// <param name="expr">The symbol whose value is incremented.</param>
        /// <param name="env">The environment.</param>
        /// <param name="caller">Return to this caller.</param>
        /// <returns>The next step to execute.</returns>
        private static Evaluator Increment(SchemeObject expr, Environment env, Evaluator caller)
        {
            SchemeObject lhs = First(expr);
            if (!(lhs is Symbol))
            {
                ErrorHandlers.SemanticError(string.Format(@"Increment: first argument must be a symbol.  Got: ""{0}""", lhs), null);
            }

            caller.ReturnedExpr = env.Increment(lhs);
            return caller;
        }
 /// <summary>
 /// Evaluate a quote expression.
 /// </summary>
 /// <param name="args">The args to quote.</param>
 /// <param name="env">The environment (unused).</param>
 /// <param name="caller">The caller.</param>
 /// <returns>The quoted expression.</returns>
 private static Evaluator EvalQuote(SchemeObject args, Environment env, Evaluator caller)
 {
     caller.ReturnedExpr = First(args);
     return caller;
 }
        /// <summary>
        /// Test the fun to apply to see if it is a special procedure.
        /// The special procedures do not evaluate their arguments.
        /// These must be implemented as primitives.
        /// </summary>
        /// <param name="args">The args to apply.</param>
        /// <param name="env">The environment in which to do the application.</param>
        /// <param name="caller">The caller to return to.</param>
        /// <param name="fun">The procedure to apply.</param>
        /// <returns>An evaluator.</returns>
        private static Evaluator ApplySpecial(SchemeObject args, Environment env, Evaluator caller, Procedure fun)
        {
            if (!fun.EvaluateArgs)
            {
                return fun.Apply(args, env, caller, caller);
            }

            return null;
        }
示例#10
0
        /// <summary>
        /// First check for a form that does not need to create an evaluator.  If it is one of these,
        ///   just return the answer.  Otherwise create an EvaluateExpression to handle it.
        /// This version uses a supplied environment.  This is used with a lambda
        ///   to evaluate in the lambda's environment rather than in the current one.
        /// </summary>
        /// <param name="expr">The expression to evaluate.</param>
        /// <param name="env">The environment to evaluate in.</param>
        /// <param name="caller">The caller.  Return to this when done.</param>
        /// <returns>The evaluator.</returns>
        internal static Evaluator Call(SchemeObject expr, Environment env, Evaluator caller)
        {
            // If we don't need to do any steps, then
            // do not create an evaluator -- just return the value directly.
            //
            // First look for a symbol.
            if (expr is Symbol)
            {
                var symbol = (Symbol)expr;
                caller.LineNumber = symbol.LineNumber;

                // Evaluate a symbol by looking it up in the environment.
                // It should correspond to a variable name, for which there
                //    is a corresponding value.
                Debug.Assert(env != null, "EvaluateExpression:Call env is null");
                caller.ReturnedExpr = env.Lookup(symbol);
                return caller;
            }

            // Look for all other non-pair forms.
            if (!(expr is Pair))
            {
                // If we are evaluating something that is not a pair,
                //    it must be a constant.
                // Return the integer, real, boolean, or vector.
                caller.ReturnedExpr = expr;
                return caller;
            }

            // Break apart and evaluate the fn and args
            // Handle special forms that do not need an evaluator instance.
            var obj = expr;
            var fn = First(obj);
            var args = Rest(obj);
            if (fn is Symbol)
            {
                var funSymbol = (Symbol)fn;
                caller.LineNumber = funSymbol.LineNumber;
                SpecialAction action = funSymbol.SpecialForm;
                if (action != null)
                {
                    return action(args, env, caller);
                }

                if (specialActions.TryGetValue(funSymbol.ToString(), out action))
                {
                    funSymbol.SpecialForm = action;
                    return action(args, env, caller);
                }

                // If fn is still a symbol, then it needs its arguments evaluated
                // and so it needs an instance of EvaluateExpression to manage that.
            }

            // Actually create an evaluator to do the operation.
            return new EvaluateExpression(fn, args, env, caller);
        }
示例#11
0
 /// <summary>
 /// Initializes a new instance of the Evaluator class.
 /// This class is not instantiated itself, but only derived classes.
 /// </summary>
 /// <param name="initialPc">The initial pc value.</param>
 /// <param name="args">The expression to evaluate.</param>
 /// <param name="env">The evaluator environment.</param>
 /// <param name="caller">The caller evaluator.</param>
 protected internal Evaluator(Stepper initialPc, SchemeObject args, Environment env, Evaluator caller)
 {
     this.expr = args;
     this.env = env;
     this.caller = caller;
     this.pc = initialPc;
     this.lineNumber = 0;
     this.returnedExpr = Undefined.Instance;
     this.returnFlag = ReturnType.SynchronousReturn;
     this.finished = false;
     this.caught = 0;
     #if Diagnostics
     this.IncrementCounter(this.GetType().Name + ":ctor");
     #endif
 }