コード例 #1
0
 /// <summary>
 /// Initializes a new instance of the EvaluateTimeBase class.
 /// </summary>
 /// <param name="expr">The expression to evaluate.</param>
 /// <param name="count">The number of times to evaluate.</param>
 /// <param name="env">The evaluation environment</param>
 /// <param name="caller">The caller.  Return to this when done.</param>
 protected EvaluateTimeBase(SchemeObject expr, int count, Environment env, Evaluator caller)
     : base(InitialStep, expr, env, caller)
 {
     this.counter = count;
     this.startMem = GC.GetTotalMemory(true);
     this.stopwatch = Stopwatch.StartNew();
 }
コード例 #2
0
ファイル: List.cs プロジェクト: cchayden/SimpleScheme
        /// <summary>
        /// Create a new list of the given length, where each element is given.
        /// </summary>
        /// <param name="n">The length of the list.</param>
        /// <param name="fill">The element to place in each list element.</param>
        /// <returns>A list filled with the given element.</returns>
        public static SchemeObject Fill(int n, SchemeObject fill)
        {
            SchemeObject res = EmptyList.Instance;
            for (int i = 0; i < n; i++)
            {
                res = Cons(fill, res);
            }

            return res;
        }
コード例 #3
0
ファイル: Continuation.cs プロジェクト: cchayden/SimpleScheme
 /// <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;
 }
コード例 #4
0
        /// <summary>
        /// Call the parallel evaluator.
        /// </summary>
        /// <param name="expr">The expressions 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 parallel evaluator.</returns>
        internal static Evaluator Call(SchemeObject expr, Environment env, Evaluator caller)
        {
            if (expr is EmptyList)
            {
                caller = caller.Caller;
                caller.ReturnedExpr = EmptyList.Instance;
                return caller;
            }

            return new EvaluateParallel(expr, env, caller);
        }
コード例 #5
0
 /// <summary>
 /// Open a file for input.
 /// </summary>
 /// <param name="filename">The filename of the file to open.</param>
 /// <param name="interp">The interpreter.</param>
 /// <returns>The input port, used for reading.</returns>
 internal static InputPort OpenInputFile(SchemeObject filename, Interpreter interp)
 {
     try
     {
         return InputPort.New(new StreamReader(filename.ToString(false)), interp);
     }
     catch (FileNotFoundException)
     {
         return (InputPort)ErrorHandlers.IoError("No such file: " + filename.ToString(true));
     }
     catch (IOException ex)
     {
         return (InputPort)ErrorHandlers.IoError("IOException: " + ex.Message);
     }
 }
コード例 #6
0
ファイル: List.cs プロジェクト: cchayden/SimpleScheme
        /// <summary>
        /// Make a copy of the given expression.
        /// If the expression is not a list, then just return it.
        /// This is used in connection with destructive operations where the original values
        /// might need to be preserved.
        /// </summary>
        /// <param name="expr">The list to copy.</param>
        /// <returns>A copy of the list.</returns>
        public static SchemeObject Copy(SchemeObject expr)
        {
            // TODO is this needed?
            if (!(expr is Pair))
            {
                return expr;
            }

            Pair result = MakeList();
            Pair accum = result;

            // Iterate down the list, building a list of the results.
            while (expr is Pair)
            {
                accum = accum.SetRest(Cons(First(expr), EmptyList.Instance));
                expr = Rest(expr);
            }

            return Rest(result);
        }
コード例 #7
0
 /// <summary>
 /// Take a list of CLR method arguments and turn them into an array, suitable for
 ///   calling the method.
 /// Add the extra async arguments for the Begin call.
 /// Check to make sure the number and types of the arguments in the list match 
 ///    what is expected.
 /// </summary>
 /// <param name="args">A list of the method arguments.</param>
 /// <param name="state">State, passed on to completion function.</param>
 /// <param name="caller">The calling evaluator.</param>
 /// <returns>An array of arguments for the method call.</returns>
 private object[] ToArgListBegin(SchemeObject args, object state, Evaluator caller)
 {
     object[] additionalArgs = { (AsyncCallback)this.CompletionMethod, state };
     return this.ToArgList(args, additionalArgs, "AsynchronousClrProcedure", caller);
 }
コード例 #8
0
ファイル: Interpreter.cs プロジェクト: cchayden/SimpleScheme
        /// <summary>
        /// Begin an asynchronous evaluation
        /// </summary>
        /// <param name="expr">The expression to evaluate.</param>
        /// <param name="cb">Call this when evaluation is complete.</param>
        /// <param name="state">Pass this through for the callback function.</param>
        /// <returns>Async result, used to monitor progress.</returns>
        private IAsyncResult UnsafeBeginEval(SchemeObject expr, AsyncCallback cb, object state)
        {
            this.asyncResult = new AsyncResult<SchemeObject>(cb, state);
            SchemeObject res = this.Eval(expr, this.GlobalEnvironment);
            if ((res is ClrObject) && ((ClrObject)res).Value is SuspendedEvaluator)
            {
                return this.asyncResult;
            }

            if (!this.asyncResult.IsCompleted)
            {
                this.asyncResult.SetAsCompleted(res, true);
            }

            return this.asyncResult;
        }
コード例 #9
0
ファイル: Interpreter.cs プロジェクト: cchayden/SimpleScheme
 /// <summary>
 /// Evaluate an expression (expressed as a list) in the global environment.
 /// </summary>
 /// <param name="expr">The expression to evaluate.</param>
 /// <returns>The result of the evaluation.</returns>
 private SchemeObject UnsafeEval(SchemeObject expr)
 {
     return this.Eval(expr, this.GlobalEnvironment);
 }
コード例 #10
0
ファイル: Interpreter.cs プロジェクト: cchayden/SimpleScheme
 /// <summary>
 /// Evaluate an expression in an environment.
 /// Do it by executing a set of steps.
 /// </summary>
 /// <param name="expr">The expression to evaluate.</param>
 /// <param name="env">The environment in which to evaluate it.</param>
 /// <returns>The result of the evaluation.</returns>
 internal SchemeObject Eval(SchemeObject expr, Environment env)
 {
     return this.EvalSteps(EvaluateExpression.Call(expr, env, this.halted));
 }
コード例 #11
0
ファイル: Interpreter.cs プロジェクト: cchayden/SimpleScheme
 /// <summary>
 /// Set the asynchronous completion value, if we were
 ///   doing an async call.
 /// </summary>
 /// <param name="returnedExpr">The value to return as the asynchronous result.</param>
 internal void SetComplete(SchemeObject returnedExpr)
 {
     if (this.asyncResult != null)
     {
         this.asyncResult.SetAsCompleted(returnedExpr, false);
     }
 }
コード例 #12
0
ファイル: ClrProcedure.cs プロジェクト: cchayden/SimpleScheme
        /// <summary>
        /// Take a list of ArgType or type name elements and create a corresponding 
        ///   List of ArgType.
        /// </summary>
        /// <param name="args">A list of ArgType or type name elements.  There may be more than this.</param>
        /// <param name="extra">Number of extra types to allocate.</param>
        /// <returns>An array of Types corresponding to the list.</returns>
        protected static Type[] ClassList(SchemeObject args, int extra = 0)
        {
            var array = new Type[ListLength(args) + extra];

            int i = 0;
            while (args is Pair)
            {
                array[i++] = Class(First(args));
                args = Rest(args);
            }

            return array;
        }
コード例 #13
0
ファイル: Interpreter.cs プロジェクト: cchayden/SimpleScheme
 /// <summary>
 /// Create a printable representation of the object.
 /// </summary>
 /// <param name="obj">The object to print.</param>
 /// <returns>The string representing the object.</returns>
 public string Print(SchemeObject obj)
 {
     try
     {
         return obj.ToString(true);
     }
     catch (Exception ex)
     {
         ErrorHandlers.PrintException(ex);
         return string.Empty;
     }
 }
コード例 #14
0
ファイル: OutputPort.cs プロジェクト: cchayden/SimpleScheme
 /// <summary>
 /// Write a character on a given port.
 /// The output is not quoted.
 /// If the expr is not actually a character, it is written nevertheless.
 /// </summary>
 /// <param name="expr">The expression to write.</param>
 /// <returns>The undefined object.</returns>
 private SchemeObject WriteChar(SchemeObject expr)
 {
     this.Write(expr.ToString(false));
     return Undefined.Instance;
 }
コード例 #15
0
 /// <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;
 }
コード例 #16
0
ファイル: ClrProcedure.cs プロジェクト: cchayden/SimpleScheme
        /// <summary>
        /// Take a list of CLR method arguments and turn them into a list, suitable for
        ///   calling the method.
        /// Check to make sure the number and types of the arguments in the list match 
        ///    what is expected.
        /// </summary>
        /// <param name="args">A list of the method arguments.</param>
        /// <param name="additionalArgs">A list of the additional args, not supplied by the caller. 
        /// These are part of the asynchronous calling pattern.</param>
        /// <param name="evaluatorName">The evaluator name, for the error message.</param>
        /// <param name="caller">The calling evaluator.</param>
        /// <returns>An array of arguments for the method call.</returns>
        protected object[] ToArgList(SchemeObject args, object[] additionalArgs, string evaluatorName, Evaluator caller)
        {
            // This has been checked once already, in Procedure.CheckArgCount, but that included
            //  an instance argument.  Check again to protect the rest of this method.
            int additionalN = additionalArgs != null ? additionalArgs.Length : 0;
            int numArgs = ListLength(args) + additionalN;
            int expectedArgs = this.ArgClasses.Length;
            if (numArgs != expectedArgs)
            {
                this.ArgCountError(numArgs, expectedArgs, args, evaluatorName, caller);
            }

            var array = new object[numArgs];

            int a = 0;
            while (args is Pair)
            {
                array[a] = ClrObject.ToClrObject(First(args), this.ArgClasses[a]);
                a++;
                args = Rest(args);
            }

            for (int i = 0; i < additionalN; i++)
            {
                Debug.Assert(additionalArgs != null, "ClrProcedure: additionalArgs != null");
                array[a++] = additionalArgs[i];
            }

            return array;
        }
コード例 #17
0
ファイル: OutputPort.cs プロジェクト: cchayden/SimpleScheme
 /// <summary>
 /// Determine the port object to use with the OutputPort primitives.
 /// The port is optional: if supplied, it is the port to use.
 /// Otherwise, the current output port is used instead.
 /// </summary>
 /// <param name="port">The port to use, if supplied.  If is is not empty list, then it is an output port.</param>
 /// <param name="curr">The current output port.</param>
 /// <returns>The port to use.</returns>
 private static OutputPort Port(SchemeObject port, OutputPort curr)
 {
     return port is EmptyList ? curr : (OutputPort)port;
 }
コード例 #18
0
 /// <summary>
 /// Take a list of ArgType or type name elements and create a corresponding 
 ///   array of ArgType.
 /// Add the extra async arguments for a Begin method.
 /// </summary>
 /// <param name="args">A list of ArgType or type name elements.</param>
 /// <returns>An array of Types corresponding to the list.</returns>
 private static Type[] ClassListBegin(SchemeObject args)
 {
     Type[] array = ClassList(args, 2);
     array[array.Length - 2] = typeof(AsyncCallback);
     array[array.Length - 1] = typeof(object);
     return array;
 }
コード例 #19
0
ファイル: Scanner.cs プロジェクト: cchayden/SimpleScheme
 /// <summary>
 /// Clear the token buffer.
 /// </summary>
 private void Clear()
 {
     this.present = false;
     this.buffer = null;
 }
コード例 #20
0
ファイル: Scanner.cs プロジェクト: cchayden/SimpleScheme
 /// <summary>
 /// Push the character into the buffer.
 /// </summary>
 /// <param name="token">The token to push.</param>
 internal void Push(SchemeObject token)
 {
     this.present = true;
     this.buffer = token;
 }
コード例 #21
0
ファイル: Scanner.cs プロジェクト: cchayden/SimpleScheme
 /// <summary>
 /// Push a token into the buffer.
 /// </summary>
 /// <param name="token">The token to push.</param>
 internal void PushToken(SchemeObject token)
 {
     this.tokBuffer.Push(token);
 }
コード例 #22
0
ファイル: ClrProcedure.cs プロジェクト: cchayden/SimpleScheme
 /// <summary>
 /// Create an array of objects.
 /// These can throw a variety of exceptions.  Let them propogate up and be caught at
 ///   a higher level.
 /// </summary>
 /// <param name="className">The class name of the array elements.</param>
 /// <param name="length">The array length.</param>
 /// <returns>An array of the given length.</returns>
 private static object NewArray(string className, SchemeObject length)
 {
     return Array.CreateInstance(Class(className), Number.AsInt(length));
 }
コード例 #23
0
ファイル: ClrObject.cs プロジェクト: cchayden/SimpleScheme
        /// <summary>
        /// Convert an scheme object to the given type of clr object.
        /// </summary>
        /// <param name="elem">The object to convert.</param>
        /// <param name="clrClass">The desired clr class to convert it to.</param>
        /// <returns>The converted object.</returns>
        public static object ToClrObject(SchemeObject elem, Type clrClass)
        {
            if (elem is ClrObject)
            {
                var value = ((ClrObject)elem).Value;
                if (value.GetType() == clrClass)
                {
                    return value;
                }
            }

            if (clrClass != null && toClrMap.ContainsKey(clrClass))
            {
                return toClrMap[clrClass](elem);
            }

            return elem;
        }
コード例 #24
0
        /// <summary>
        /// Apply the method to the given arguments.
        /// If the method is static, all arguments are passed to the method.
        /// Otherwise, the first argument is the class instance, and the rest are passed 
        ///    to the method.
        /// </summary>
        /// <param name="args">Arguments to pass to the method.</param>
        /// <param name="env">The environment of the application.</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.</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, "AsynchronousClrProcedure", caller);
            #endif
            SchemeObject target = null;
            if (!this.MethodInfo.IsStatic)
            {
                target = First(args);
                args = Rest(args);
            }

            var actualTarget = ClrObject.ToClrObject(target, this.InstanceClass);
            var argArray = this.ToArgListBegin(args, new Tuple<object, Evaluator>(actualTarget, returnTo), caller);
            var res = this.MethodInfo.Invoke(actualTarget, argArray) as IAsyncResult;

            // res is not converted because it is IAsyncResult -- convert in completion method
            return new SuspendedEvaluator(ClrObject.New(res), returnTo).NextStep();
        }
コード例 #25
0
ファイル: OutputPort.cs プロジェクト: cchayden/SimpleScheme
 /// <summary>
 /// Print the obj on the console.
 /// </summary>
 /// <param name="x">The obj to print.</param>
 /// <returns>Undefined value.</returns>
 private SchemeObject P(SchemeObject x)
 {
     this.WriteLine(x.ToString(false));
     return Undefined.Instance;
 }
コード例 #26
0
ファイル: Interpreter.cs プロジェクト: cchayden/SimpleScheme
 /// <summary>
 /// Begin an asynchronous evaluation.
 /// Catch any exceptions that might happen.
 /// </summary>
 /// <param name="expr">The expression to evaluate.</param>
 /// <param name="cb">Call this when evaluation is complete.</param>
 /// <param name="state">Pass this through for the callback function.</param>
 /// <returns>Async result, used to monitor progress.</returns>
 public IAsyncResult BeginEval(SchemeObject expr, AsyncCallback cb, object state)
 {
     this.asyncResult = null;
     try
     {
         return this.UnsafeBeginEval(expr, cb, state);
     }
     catch (Exception ex)
     {
         ErrorHandlers.PrintException(ex);
         return null;
     }
 }
コード例 #27
0
ファイル: OutputPort.cs プロジェクト: cchayden/SimpleScheme
        /// <summary>
        /// Convert to text writer
        /// </summary>
        /// <param name="obj">The object.</param>
        /// <returns>The text writer.</returns>
        internal static TextWriter AsTextWriter(SchemeObject obj)
        {
            if (obj is OutputPort)
            {
                return ((OutputPort)obj).Writer;
            }

            ErrorHandlers.TypeError(typeof(OutputPort), obj);
            return null;
        }
コード例 #28
0
ファイル: Interpreter.cs プロジェクト: cchayden/SimpleScheme
 /// <summary>
 /// Evaluate an expression (expressed as a list) in the global environment.
 /// Catch any exceptions that may happen.
 /// </summary>
 /// <param name="expr">The expression to evaluate.</param>
 /// <returns>The result of the evaluation.</returns>
 public SchemeObject Eval(SchemeObject expr)
 {
     this.asyncResult = null;
     try
     {
         return this.UnsafeEval(expr);
     }
     catch (Exception ex)
     {
         ErrorHandlers.PrintException(ex);
         return Undefined.Instance;
     }
 }
コード例 #29
0
 /// <summary>
 /// Create an evaluator with output file.
 /// </summary>
 /// <param name="args">A pair, containing a filename and a proc to evaluate.</param>
 /// <param name="caller">The caller.  Return to this when done.</param>
 /// <returns>The created evaluator.</returns>
 internal static Evaluator Call(SchemeObject args, Evaluator caller)
 {
     OutputPort port = OpenOutputFile(First(args), caller.Interp);
     return new EvaluateCallWithOutputFile(args, caller.Env, caller, port);
 }
コード例 #30
0
ファイル: Interpreter.cs プロジェクト: cchayden/SimpleScheme
 /// <summary>
 /// Load a file.  
 /// Open the file and read it.
 /// Evaluate whatever it contains.
 /// This may be one or more expressions.
 /// If any of them are asynchronous, then the evaluation is NOT blocked, but continues on.
 /// </summary>
 /// <param name="fileName">The filename.</param>
 /// <param name="outp">If not null, input and results are written here.</param>
 public void LoadFile(SchemeObject fileName, OutputPort outp)
 {
     string name = string.Empty;
     try
     {
         name = fileName.ToString();
         using (var fs = new FileStream(name, FileMode.Open, FileAccess.Read))
         {
             this.Load(InputPort.New(new StreamReader(fs), this), outp);
         }
     }
     catch (IOException)
     {
         ErrorHandlers.IoError("Can't load " + name);
     }
 }