AssignLocal() public method

Asssigns value to a local variable symbol in this local environment (irrespective of whether symbol is defined in any parent environments).
public AssignLocal ( LSharp.Symbol symbol, object value ) : object
symbol LSharp.Symbol
value object
return object
コード例 #1
0
        /// <summary>
        /// Process the arguments passed to a closure, and add them to the given enviroment.
        /// </summary>
        /// <param name="argumentNameList">The list of names and kewords the closure was created with.</param>
        /// <param name="argumentList">The arguments passed to the closure.</param>
        /// <param name="localEnvironment">The closure's local variables.</param>
        /// <returns>Nothing.</returns>
        public static void ProcessArguments(Cons argumentNameList, Cons argumentList, Environment localEnvironment)
        {
            while (argumentNameList != null)
            {
                // Get the name for the closure's parameter.  Then check to see if it's a keyword, if it is then
                // process the keyword.  Otherwise set up that parameter in the closure's enviroment with the
                // caller specified value.

                Symbol argumentName = (Symbol)argumentNameList.Car();

                switch (argumentName.ToString())
                {
                case "&rest":
                    argumentName = (Symbol)argumentNameList.Cadr();
                    localEnvironment.AssignLocal(argumentName, argumentList);
                    argumentNameList = null;
                    argumentList     = null;
                    break;

                case "&optional":
                    ProcessOptionalArguments((Cons)argumentNameList.Cdr(), argumentList, localEnvironment);
                    argumentNameList = null;
                    argumentList     = null;
                    break;

                case "&key":
                    ProcessKeyArguments((Cons)argumentNameList.Cdr(), argumentList, localEnvironment);
                    argumentNameList = null;
                    argumentList     = null;
                    break;

                default:
                    if (argumentList == null)
                    {
                        throw new LSharpException("Not enough parameters given.");
                    }

                    localEnvironment.AssignLocal(argumentName, argumentList.Car());
                    argumentList     = (Cons)argumentList.Cdr();
                    argumentNameList = (Cons)argumentNameList.Cdr();
                    break;
                }
            }


            // Looks like the caller has supplied more parameters than the closure can use.

            if (argumentList != null)
            {
                throw new LSharpException("Too many parameters given.");
            }
        }
コード例 #2
0
ファイル: TopLoop.cs プロジェクト: anthrax3/xacc.ide
        /// <summary>
        ///  Starts the toploop running using specified input, output and error streams
        ///
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="writer"></param>
        /// <param name="error"></param>
        public void Run(TextReader reader, TextWriter writer, TextWriter error)
        {
            Symbol LAST = Symbol.FromName("?");


            while (true)
            {
                try
                {
                    Object o = trace ? Runtime.EvalString("(eval (prl (read (in Console))))", environment)
            : Runtime.EvalString("(eval (read (in Console)))", environment);

                    if (o == Reader.EOFVALUE)
                    {
                        return;
                    }

                    if (tracereturn)
                    {
                        writer.Write(prompt);
                        writer.WriteLine(Printer.WriteToString(o));
                    }
                    environment.AssignLocal(LAST, o);
                }
                catch (LSharpException e)
                {
                    error.WriteLine(e.Message);
                }
                catch (Exception e)
                {
                    error.WriteLine(e.GetBaseException());
                }
            }
        }
コード例 #3
0
ファイル: SpecialForms.cs プロジェクト: anthrax3/xacc.ide
        public static Object Try(Cons args, Environment environment)
        {
            try
            {
                return(Runtime.Eval(args.First(), environment));
            }
            catch (Exception e)
            {
                environment.AssignLocal(Symbol.IT, e);

                // If a catch form is specified then evaluate it
                if (args.Second() as Symbol == Symbol.NULL)
                {
                    throw;
                }
                return(Runtime.Eval(args.Second(), environment));
            }
            finally
            {
                // If a finally form was specified then evaluate it
                if (args.Length() > 2)
                {
                    Runtime.Eval(args.Third(), environment);
                }
            }
        }
コード例 #4
0
ファイル: SpecialForms.cs プロジェクト: anthrax3/xacc.ide
        public static Object To(Cons args, Environment environment)
        {
            Environment localEnvironment = new Environment(environment);

            localEnvironment.AssignLocal((Symbol)args.First(), 0);
            int endStop = int.Parse(Runtime.Eval(args.Second(), localEnvironment).ToString());

            while ((int)localEnvironment.GetValue((Symbol)args.First()) < endStop)
            {
                foreach (object item in (Cons)args.Cddr())
                {
                    Runtime.Eval(item, localEnvironment);
                }
                localEnvironment.AssignLocal((Symbol)args.First(), ((int)Runtime.Eval(args.First(), localEnvironment)) + 1);
            }
            return(null);
        }
コード例 #5
0
ファイル: Environment.cs プロジェクト: anthrax3/xacc.ide
        /// <summary>
        /// Sets a variable with given symbol to a given value
        /// </summary>
        /// <param name="symbol"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public object Assign(Symbol symbol, object value)
        {
            Environment environment = GetEnvironment(symbol);

            if (environment == null)
            {
                environment = this;
            }

            return(environment.AssignLocal(symbol, value));
        }
コード例 #6
0
        private static void ProcessOptionalArguments(Cons argumentNameList, Cons argumentList,
                                                     Environment localEnvironment)
        {
            // We need to add all the arguments to the closure's environment.

            while (argumentNameList != null)
            {
                Symbol argumentName  = null;
                object argumentValue = null;


                // We need to get the name of the argument, it can either be just the name or, it can be
                // it's own Cons with the name and an expression for the default value.

                if (argumentNameList.Car() is Cons)
                {
                    // It is a Cons, so extract the name and the default value.

                    argumentName  = (Symbol)argumentNameList.Caar();
                    argumentValue = argumentNameList.Cadar();
                }
                else
                {
                    argumentName = (Symbol)argumentNameList.Car();
                }


                // Now, if the caller has specified a value for this argument, get it now.

                if (argumentList != null)
                {
                    argumentValue = argumentList.Car();
                    argumentList  = (Cons)argumentList.Cdr();
                }


                // Finally add the parameter to the closure's list and then move onto the next argument.
                // Because the default can be any expression, we need to evaluate the value every time the
                // function is called.

                localEnvironment.AssignLocal(argumentName, Runtime.Eval(argumentValue, localEnvironment));

                argumentNameList = (Cons)argumentNameList.Cdr();
            }


            // Looks like the caller has supplied more parameters than the closure can use.

            if (argumentList != null)
            {
                throw new LSharpException("Too many parameters given.");
            }
        }
コード例 #7
0
ファイル: SpecialForms.cs プロジェクト: anthrax3/xacc.ide
        public static Object Let(Cons args, Environment environment)
        {
            Environment localEnvironment = new Environment(environment);

            localEnvironment.AssignLocal((Symbol)args.First(), Runtime.Eval(args.Second(), environment));

            object result = null;

            foreach (object item in (Cons)args.Cddr())
            {
                result = Runtime.Eval(item, localEnvironment);
            }
            //return Runtime.Eval(args.Third(),localEnvironment);
            return(result);
        }
コード例 #8
0
ファイル: SpecialForms.cs プロジェクト: anthrax3/xacc.ide
        public static Object ForEach(Cons args, Environment environment)
        {
            Environment localEnvironment = new Environment(environment);

            Symbol variable = (Symbol)args.First();
            Object list     = Runtime.Eval(args.Second(), localEnvironment);

            foreach (object o in (System.Collections.IEnumerable)list)
            {
                localEnvironment.AssignLocal(variable, o);
                //Runtime.Eval(args.Third(),localEnvironment);
                foreach (object item in (Cons)args.Cddr())
                {
                    Runtime.Eval(item, localEnvironment);
                }
            }

            return(null);
        }
コード例 #9
0
ファイル: SpecialForms.cs プロジェクト: anthrax3/xacc.ide
        public static Object With(Cons args, Environment environment)
        {
            Environment localEnvironment = new Environment(environment);

            Cons bindings = (Cons)args.First();

            while ((bindings != null) && (bindings.Length() > 1))
            {
                localEnvironment.AssignLocal((Symbol)bindings.First(), Runtime.Eval(bindings.Second(), environment));
                bindings = (Cons)bindings.Cddr();
            }

            object result = null;

            foreach (object item in (Cons)args.Cdr())
            {
                result = Runtime.Eval(item, localEnvironment);
            }
            return(result);
        }
コード例 #10
0
ファイル: SpecialForms.cs プロジェクト: mlnlover11/MP.LSharp
		/// <summary>
		/// (with ((symbol value)* ) expression*) 
		/// Binds new local variables symbols to values in a new local 
		/// lexical environment, before evaluating expressions. Similar to 
		/// let, but allows multiple local variables to be bound.
		/// </summary>
		/// <param name="args"></param>
		/// <param name="environment"></param>
		/// <returns></returns>
		public static Object With(Cons args, Environment environment) 
		{
			Environment localEnvironment = new Environment(environment);

			Cons bindings = (Cons)args.First();

			while ((bindings != null) && (bindings.Length() > 1))
			{
                localEnvironment.AssignLocal((Symbol)bindings.First(), Runtime.Eval(bindings.Second(), localEnvironment));
				bindings = (Cons)bindings.Cddr();
			}	
			
			object result = null;
			foreach (object item in (Cons)args.Cdr()) 
			{
				result = Runtime.Eval(item, localEnvironment);
			}
			return result;
		}	
コード例 #11
0
ファイル: SpecialForms.cs プロジェクト: mlnlover11/MP.LSharp
		/// <summary>
		/// (try expression catch [finally])
		/// The try special form corresponds to the try-catch-finally construct found 
		/// in C#. If catch is null then there is deemed to be no catch block 
		/// at all. If an exception occurs, the variable "it" is bound to the Exception 
		/// object in the local environment. 
		/// </summary>
		/// <param name="args"></param>
		/// <param name="environment"></param>
		/// <returns></returns>
		public static Object Try(Cons args, Environment environment) 
		{
			try 
			{
				return Runtime.Eval(args.First(),environment);
			} 
			catch (Exception e) 
			{
				environment.AssignLocal(Symbol.IT,e);
						
				// If a catch form is specified then evaluate it
				if (args.Second() == Symbol.NULL)
					throw;
				return Runtime.Eval(args.Second(),environment);
			}
			finally 
			{
				// If a finally form was specified then evaluate it
				if  (args.Length() > 2)
					Runtime.Eval(args.Third(),environment);
			}
		}
コード例 #12
0
ファイル: SpecialForms.cs プロジェクト: mlnlover11/MP.LSharp
		/// <summary>
		/// (to variable limit expression)
		/// Starting at 0, assigns variable to succesive integers upto and 
		/// including limit. Executes expression on each iteration. 
		/// </summary>
		/// <param name="args"></param>
		/// <param name="environment"></param>
		/// <returns></returns>
		public static Object To(Cons args, Environment environment) 
		{
			Environment localEnvironment = new Environment(environment);
			localEnvironment.AssignLocal((Symbol) args.First(), 0);
			int endStop = int.Parse(Runtime.Eval(args.Second(),localEnvironment).ToString());
			while ((int)localEnvironment.GetValue((Symbol) args.First()) < endStop)
			{
				foreach (object item in (Cons)args.Cddr()) 
				{
					Runtime.Eval(item, localEnvironment);
				}
				localEnvironment.AssignLocal((Symbol) args.First(), ((int)Runtime.Eval(args.First(), localEnvironment)) + 1);
				
			}
			return null;
		}
コード例 #13
0
ファイル: SpecialForms.cs プロジェクト: mlnlover11/MP.LSharp
		/// <summary>
		/// (let symbol value expression*)
		/// Binds a new local variable symbol to value in a new local lexical environment, 
		/// before evaluating expressions. Similar to with, but often more convenient for 
		/// decalring a single local variable. 
		/// </summary>
		/// <param name="args"></param>
		/// <param name="environment"></param>
		/// <returns></returns>
		public static Object Let(Cons args, Environment environment) 
		{
			Environment localEnvironment = new Environment(environment);
			localEnvironment.AssignLocal((Symbol) args.First(), Runtime.Eval(args.Second(),environment));
			
			object result = null;
			foreach (object item in (Cons)args.Cddr()) 
			{
				result = Runtime.Eval(item, localEnvironment);
			}
			//return Runtime.Eval(args.Third(),localEnvironment);
			return result;
		}
コード例 #14
0
ファイル: SpecialForms.cs プロジェクト: mlnlover11/MP.LSharp
		/// <summary>
		/// (each symbol IEnumerable expression)
		/// Iterates over any object which impelements IEnumerablewith succesive 
		/// elements being assigned to a variable named symbol; exceutes expression 
		/// on each iteration. Cons (LSharp lists), as well as many .NET collections 
		/// are IEnumerable. Foreach is a synonym for each. 
		/// </summary>
		/// <param name="args"></param>
		/// <param name="environment"></param>
		/// <returns></returns>
		public static Object ForEach(Cons args, Environment environment) 
		{
			Environment localEnvironment = new Environment(environment);

			Symbol variable = (Symbol) args.First();
			Object list = Runtime.Eval(args.Second(),localEnvironment);

			foreach (object o in (System.Collections.IEnumerable)list) 
			{
				localEnvironment.AssignLocal(variable, o);
				//Runtime.Eval(args.Third(),localEnvironment);
				foreach (object item in (Cons)args.Cddr()) 
				{
					Runtime.Eval(item, localEnvironment);
				}
			}

			return null;
		}
コード例 #15
0
ファイル: SpecialForms.cs プロジェクト: mlnlover11/MP.LSharp
		/// <summary>
		/// (defmethod name "arg1 arg2" "(expression1)" "(expression 2)" [...])
		/// Created methods used for DefClass <br />
		/// </summary>
		/// <param name="args"></param>
		/// <param name="e"></param>
		/// <returns></returns>
		public static object DefMethod(Cons args, Environment e)
		{
			string name;
			string[] _args;
			string commands = "";
			name = args.First().ToString();
			_args = args.Second().ToString().Split(new string[] {" "}, StringSplitOptions.None);;
			for (int i = 2; i < args.Length(); i++)
				commands += args.Nth(i) + " ";
			commands = commands.Replace("\\", "\\\\");
			commands = commands.Replace("\"", "\\\"");
			//FIXME: 
			//code = code.Replace("\n", "\\n");
			DefinedMethod ret = new DefinedMethod(commands, name, _args);
			e.AssignLocal(Symbol.FromName(name), ret);
			Console.WriteLine("Assigned '" + ret.Name + "' as a DefinedMethod");
			return ret;
		}
コード例 #16
0
ファイル: Runtime.cs プロジェクト: RobBlackwell/LSharp
        /// <summary>
        /// Creates a new runtime
        /// </summary>
        public Runtime(TextReader textReader, TextWriter writer, TextWriter errorWriter)
        {
            // Initialise the input, output and error streams
            this.stdin = textReader;
            this.stdout = writer;
            this.stderr = errorWriter;

            // Install a new global environemt
            globalEnvironment = new LSharp.Environment();

            // Set up a default definition for the language ..

            // LISP true and false
            globalEnvironment.AssignLocal(T, true);
            globalEnvironment.AssignLocal(NIL, null);

            // .NET true and false are booleans
            globalEnvironment.AssignLocal(Symbol.FromName("true"), true);
            globalEnvironment.AssignLocal(Symbol.FromName("false"), false);

            // Null
            globalEnvironment.AssignLocal(Symbol.FromName("null"), null);

            // Wire up the functions that are defined in C# ..

            globalEnvironment.AssignLocal(Symbol.FromName("+"),
                new Function(new Func<IEnumerable, object>(Runtime.Add),
                    "& xs",
                    "If the first x is a number, returns the sum of xs, otherwise the concatenation of all xs. (+) returns 0.",
                    true));

            globalEnvironment.AssignLocal(Symbol.FromName("-"),
                new Function(new Func<IEnumerable, object>(Runtime.Subtract),
                    "& xs",
                    "Subtraction.", true));

            globalEnvironment.AssignLocal(Symbol.FromName("/"),
                new Function(new Func<object[], object>(Runtime.Divide),
                    "& xs",
                    "Division.", true));

            globalEnvironment.AssignLocal(Symbol.FromName("*"),
                new Function(new Func<object[], object>(Runtime.Multiply),
                    "& xs",
                    "Returns the product of the xs. (*) returns 1.", true));

            globalEnvironment.AssignLocal(Symbol.FromName(">"),
                new Function(new Func<object[], object>(Runtime.GreaterThan),
                    "& xs",
                    "Greater than.", true));

            globalEnvironment.AssignLocal(Symbol.FromName("<"),
                new Function(new Func<object[], object>(Runtime.LessThan),
                    "& xs",
                    "Less than.", true));

            globalEnvironment.AssignLocal(Symbol.FromName("atom?"),
                new Function(new Func<object, bool>(Runtime.IsAtom),
                    "x",
                    "Returns true if x is an atom.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("car"),
                 new Function(new Func<object, object>(Runtime.Car),
                     "seq",
                     "Returns the first item in a sequence.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("caar"),
                 new Function(new Func<object, object>(Runtime.Caar),
                     "seq",
                     "Returns the first item of the first item in a sequence.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("cadr"),
                new Function(new Func<object, object>(Runtime.Cadr),
                    "seq",
                    "Returns the second item in a sequence.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("cddr"),
                new Function(new Func<object, object>(Runtime.Cddr),
                    "seq",
                    "Returns the rest of the rest of a sequence.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("cdr"),
                new Function(new Func<object, object>(Runtime.Cdr),
                    "seq",
                    "Returns the rest of a sequence.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("coerce"),
                new Function(new Func<object, object, object>(Runtime.Coerce),
                    "x t",
                    "Converts objext x to type t.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("compile"),
                new Function(new Func<object, object>(Compile),
                    "expr",
                    "Compiles the expression and returns executable code.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("cons"),
                new Function(new Func<object, object, object>(Runtime.Cons),
                    "x seq",
                    "Creates a new sequence whose head is x and tail is seq.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("do"),
                new Function(new Func<object[], object>(Runtime.Progn),
                    "& body",
                    "Executes body forms in order, returns the result of the last body.", true));

            globalEnvironment.AssignLocal(Symbol.FromName("do1"),
                new Function(new Func<object[], object>(Runtime.Do1),
                    "& body",
                    "Executes body forms in order, returns the result of the first body.", true));

            globalEnvironment.AssignLocal(Symbol.FromName("empty?"),
                new Function(new Func<object, bool>(Runtime.IsEmpty),
                    "x",
                    "Returns true if x is an empty sequence.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("err"),
                new Function(new Func<object, object>(Runtime.Err),
                    "exception",
                    "Raises an exception", false));

            globalEnvironment.AssignLocal(Symbol.FromName("eval"),
                new Function(new Func<object, object>(Eval),
                    "expr",
                    "Evaluates an expression.", false));

            //globalEnvironment.AssignLocal(Symbol.FromName("help"),
            //    new Function(new Func<object, object>(Runtime.Help),
            //        "x",
            //        "Displays help text for x.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("idfn"),
                new Function(new Func<object, object>(Runtime.IdFn),
                    "x",
                    "The identity function, returns x.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("is"),
                new Function(new Func<object, object, bool>(Runtime.Is),
                    "a b",
                    "Returns true if a and b are the same.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("last"),
                new Function(new Func<object, object>(Runtime.Last),
                    "seq",
                    "Returns the last item in a sequence.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("length"),
                new Function(new Func<object, int>(Runtime.Len),
                    "seq",
                    "Returns the length of the sequence.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("list"),
                new Function(new Func<object[], Pair>(Runtime.List),
                    "& xs",
                    "Creates a list of xs.", true));

            globalEnvironment.AssignLocal(Symbol.FromName("load"),
                new Function(new Func<string, object>(Load),
                    "filename",
                    "Loads the lsharp expressions from filename.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("member?"),
                new Function(new Func<object, object, bool>(Runtime.Member),
                    "item seq",
                    "Returns true is item is a member of seq.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("mod"),
                new Function(new Func<object[], object>(Runtime.Mod),
                    "& xs",
                    "Returns the remainder when dividing the args.", true));

            // TODO: Should new be a special form that compiles the constructor call?
            globalEnvironment.AssignLocal(Symbol.FromName("new"),
               new Function(new Func<object[], object>(Runtime.New),
                   "t & xs ",
                   "Constructs a new object of type t with constructir arguments xs.", true));

            globalEnvironment.AssignLocal(Symbol.FromName("not"),
                new Function(new Func<object, bool>(Runtime.Not),
                    "n",
                    "Returns true if n is false, false otherwise.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("nth"),
                new Function(new Func<object, int, object>(Runtime.Nth),
                    "n seq",
                    "Returns the nth element in sequence.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("progn"),
               new Function(new Func<object[], object>(Runtime.Progn),
                   "& xs",
                   "progn xs", true));

            globalEnvironment.AssignLocal(Symbol.FromName("reference"),
               new Function(new Func<object[], object>(Runtime.Reference),
                   "& xs",
                   "Loads the given list of assemblies.", true));

            globalEnvironment.AssignLocal(Symbol.FromName("reverse"),
               new Function(new Func<object, object>(Runtime.Reverse),
                   "seq",
                   "Reverses the sequence.", false));

            //globalEnvironment.AssignLocal(Symbol.FromName("sleep"),
            //   new Function(new Func<double, double>(Runtime.Sleep),
            //       "n",
            //       "Sleeps for n seconds.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("seq"),
               new Function(new Func<object, ISequence>(Runtime.Seq),
                   "x",
                   "Returns x if x is a sequence, otherwise returns a Sequence represenation of x.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("seq?"),
               new Function(new Func<object, bool>(Runtime.IsSeq),
                   "x",
                   "Return true if x is a sequence.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("stdin"),
                new Function(new Func<TextReader>(StdIn),
                    "",
                    "Returns the standard input stream.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("stdout"),
                new Function(new Func<TextWriter>(StdOut),
                    "",
                    "Returns the standard output stream.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("stderr"),
                new Function(new Func<TextWriter>(StdErr),
                    "",
                    "Returns the standard error stream.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("str"),
                new Function(new Func<object[], string>(Runtime.Str),
                    "& xs",
                    "xxx", true));

            globalEnvironment.AssignLocal(Symbol.FromName("toarray"),
                new Function(new Func<IEnumerable, object>(Runtime.AsArray),
                    "seq",
                    "Returns an object[] containing all the members of a sequence.",
                    false));

            globalEnvironment.AssignLocal(Symbol.FromName("tolist"),
                new Function(new Func<IEnumerable, Pair>(Runtime.ToList),
                    "seq",
                    "Returns a list containing all the members of a sequence..",
                    false));

            globalEnvironment.AssignLocal(Symbol.FromName("type"),
                new Function(new Func<object, Type>(Runtime.Type),
                    "x",
                    "Returns the Type of x.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("typeof"),
                new Function(new Func<object, Type>(Runtime.TypeOf),
                    "t",
                    "Returns the Type object named t.", false));

            globalEnvironment.AssignLocal(Symbol.FromName("uniq"),
                new Function(new Func<Symbol>(Runtime.Uniq),
                    "",
                    "", false));

            globalEnvironment.AssignLocal(Symbol.FromName("using"),
                new Function(new Func<object[], object>(Runtime.Using),
                    "xs",
                    "XXX", true));

            // Bootstrap L# ..

            EvalString("(LSharp.Runtime.VarSet (quote set) (LSharp.Runtime.MakeMacro '(x y) (quote `(LSharp.Runtime.VarSet (quote ,x) ,y  environment)) \"Set a variable\" environment) environment)");
            EvalString("(set map (fn (f s) \"Maps a function f over a sequence.\" (LSharp.Runtime.map f s environment)))");

            EvalString("(set bound (fn (sym) \"Returns true if sym is bound in the current environment.\" (LSharp.Runtime.Bound sym environment)))");
            EvalString("(set safeset (macro (var val) `(do (if (bound ',var) (prn \"*** redefining \" ',var)) (set ,var ,val))))");
            EvalString("(set mac (macro (name parms & body) \"Creates a new macro.\" `(safeset ,name (macro ,parms ,@body))))");
            EvalString("(mac def (name parms & body) \"Defines a new function.\" `(safeset ,name (fn ,parms ,@body)))");

            // Some synonyms
            EvalString("(set first car)");
            EvalString("(set rest cdr)");
            EvalString("(set len length)");
            EvalString("(set no not)");
            EvalString("(set throw err)");
            EvalString("(set = set)");

            // Define the rest of the language ..

            EvalString("(def apply (f x) (LSharp.Runtime.Apply f x environment))");
            EvalString("(def even (n) \"Returns true if n is even\" (is (mod n 2) 0))");

            //EvalString("(LSharp.Runtime.VarSet (quote if) (LSharp.Runtime.MakeMacro '(& xs) (quote `(LSharp.Runtime.If (map compile (quote ,xs)) environment)) \"if\" environment) environment)");
            EvalString("(def inspect (x) \"Inspects the object x for debugging purposes.\"  (LSharp.Runtime.Inspect x (stdout)))");
            EvalString("(def msec () \"Returns the current time in milliseconds.\" (/ (.ticks (DateTime.Now)) 10000))");
            EvalString("(def sleep (n) \"Sleeps for n seconds\" (System.Threading.Thread.Sleep (coerce (* n 1000) \"Int32\")))");
            EvalString("(def macex (x) (LSharp.Runtime.MacroExpand x false environment))");
            EvalString("(def macex1 (x) (LSharp.Runtime.MacroExpand x true environment))");
            EvalString("(def range (a b (c 1)) (LSharp.Runtime.Range a b c))");
            EvalString("(def pr (& xs) (LSharp.Runtime.Pr xs (stdout)))");
            EvalString("(def prn (& xs) (LSharp.Runtime.Prn xs (stdout)))");
            EvalString("(def help (f) \"Prints help documentation for f\" (LSharp.Runtime.Help f (stdout)))");
            EvalString("(def sqrt (n) (Math.Sqrt (coerce n \"Double\")))");
            EvalString("(def expt (x y) (Math.Pow x y))");
            EvalString("(def odd (n) \"Returns true if n is odd\" (no (even n)))");
            EvalString("(def isa (x t) \"Returns true if x is of type t.\" (is (type x) t))");
            EvalString("(def pair (xs (f list))(if (no xs) nil (no (cdr xs))(list (list (car xs)))(cons (f (car xs) (cadr xs))(pair (cddr xs) f))))");
            EvalString("(def reduce (f s) (LSharp.Runtime.reduce f s environment))");
            EvalString("(mac and (& xs) `(LSharp.Runtime.And (map compile (quote ,xs))  environment))");
            EvalString("(mac with (parms & body) `((fn ,(map car (pair parms)) ,@body) ,@(map cadr (pair parms))))");
            EvalString("(mac let (var val & body) `(with (,var ,val) ,@body))");
            EvalString("(mac or (& xs) `(LSharp.Runtime.Or (map compile (quote ,xs))  environment))");
            EvalString("(mac each (x xs & body) `(LSharp.Runtime.EachLoop ,xs (fn (,x) ,@body) environment))");
            EvalString("(mac while (test & body) `(LSharp.Runtime.WhileLoop (fn () ,test) (fn () ,@body) environment))");
            EvalString("(mac for (x start finish & body) `(LSharp.Runtime.ForLoop ,start ,finish (fn (,x) ,@body) environment))");
            EvalString("(mac nor args `(no (or ,@args)))");
            EvalString("(mac when (test & body) `(if ,test (do ,@body)))");
            EvalString("(mac unless (test & body) `(if (no ,test) (do ,@body)))");
            EvalString("(mac time (expr) \"Times how long it takes to run the expression.\" `(LSharp.Runtime.Time (quote ,expr) (stdout) environment))");
            EvalString("(def iso (x y) \"Isomorphic comparison of x and y.\"(or (is x y)(and (seq? x)(seq? y)(iso (car x) (car y))(iso (cdr x) (cdr y)))))");
            EvalString("(def testify (x) (if (is x (typeof \"LSharp.Function\")) x (fn (a) (is a x))))");
            EvalString("(def some? (f xs) (apply or (map (testify f) xs)))");
            EvalString("(def every? (f xs) (apply and (map (testify f) xs)))");
        }
コード例 #17
0
        private static void ProcessKeyArguments(Cons argumentNameList, Cons argumentList,
                                                Environment localEnvironment)
        {
            // Make sure that all of the defined key arguments are inserted to the local enviroment with their
            // defaults.

            while (argumentNameList != null)
            {
                Symbol argumentName  = null;
                object argumentValue = null;


                // We need to get the name of the argument, it can either be just the name or, it can be
                // it's own Cons with the name and an expression for the default value.

                if (argumentNameList.Car() is Cons)
                {
                    // It is a Cons, so extract the name and the default value.  Because the default can be
                    // any expression, we need to evaluate the value every time the function is called.

                    argumentName  = (Symbol)argumentNameList.Caar();
                    argumentValue = Runtime.Eval(argumentNameList.Cadar(), localEnvironment);
                }
                else
                {
                    argumentName = (Symbol)argumentNameList.Car();
                }


                // Add this variable to the closure's environment, then advance to the next parameter.

                localEnvironment.AssignLocal(argumentName, argumentValue);

                argumentNameList = (Cons)argumentNameList.Cdr();
            }


            // Now that the parameters and their defaults have been added to the environment we can now
            // process the supplied arguments.

            while (argumentList != null)
            {
                // Because these are keyed parameters, the caller needs to specify the name of each
                // parameter.

                if (argumentList.Car().GetType() != typeof(Symbol))
                {
                    throw new LSharpException("Key parameters must be specified by name.");
                }


                // Grab the current parameter and the value associated with it.  Then make sure that this
                // is a keyword.

                Symbol keywordName   = (Symbol)argumentList.Car();
                object argumentValue = argumentList.Cadr();

                if (keywordName.Name[0] != ':')
                {
                    throw new LSharpException(keywordName + " is not a valid keyword.");
                }


                // Now that we know they supplied a keyword, create a symbol out of it and make sure that
                // it exists.

                //keywordName = new Symbol(keywordName.Name.Substring(1));
                keywordName = Symbol.FromName(keywordName.Name.Substring(1));

                if (localEnvironment.Contains(keywordName) == false)
                {
                    throw new LSharpException(keywordName + " is not a recognised keyword.");
                }


                // Update the parameter with the value that the user specified and then move onto the next
                // argument in the list.

                localEnvironment.AssignLocal(keywordName, argumentValue);
                argumentList = (Cons)argumentList.Cddr();
            }
        }
コード例 #18
0
ファイル: Primitives.cs プロジェクト: westybsa/MP.LSharp
        private static void ProcessOptionalArguments(Cons argumentNameList, Cons argumentList,
                                                     Environment localEnvironment)
        {
            // We need to add all the arguments to the closure's environment.

            while (argumentNameList != null)
            {
                Symbol argumentName = null;
                object argumentValue = null;


                // We need to get the name of the argument, it can either be just the name or, it can be
                // it's own Cons with the name and an expression for the default value.

                if (argumentNameList.Car().GetType() == typeof(Cons))
                {
                    // It is a Cons, so extract the name and the default value.

                    argumentName = (Symbol)argumentNameList.Caar();
                    argumentValue = argumentNameList.Cadar();
                }
                else
                {
                    argumentName = (Symbol)argumentNameList.Car();
                }


                // Now, if the caller has specified a value for this argument, get it now.

                if (argumentList != null)
                {
                    argumentValue = argumentList.Car();
                    argumentList = (Cons)argumentList.Cdr();
                }


                // Finally add the parameter to the closure's list and then move onto the next argument.
                // Because the default can be any expression, we need to evaluate the value every time the
                // function is called.

                localEnvironment.AssignLocal(argumentName, Runtime.Eval(argumentValue, localEnvironment));

                argumentNameList = (Cons)argumentNameList.Cdr();
            }


            // Looks like the caller has supplied more parameters than the closure can use.

            if (argumentList != null)
            {
                throw new LSharpException("Too many parameters given.");
            }
        }
コード例 #19
0
ファイル: Primitives.cs プロジェクト: westybsa/MP.LSharp
        private static void ProcessKeyArguments(Cons argumentNameList, Cons argumentList,
                                                Environment localEnvironment)
        {
            // Make sure that all of the defined key arguments are inserted to the local enviroment with their
            // defaults.

            while (argumentNameList != null)
            {
                Symbol argumentName = null;
                object argumentValue = null;


                // We need to get the name of the argument, it can either be just the name or, it can be
                // it's own Cons with the name and an expression for the default value.

                if (argumentNameList.Car().GetType() == typeof(Cons))
                {
                    // It is a Cons, so extract the name and the default value.  Because the default can be
                    // any expression, we need to evaluate the value every time the function is called.

                    argumentName = (Symbol)argumentNameList.Caar();
                    argumentValue = Runtime.Eval(argumentNameList.Cadar(), localEnvironment);
                }
                else
                {
                    argumentName = (Symbol)argumentNameList.Car();
                }


                // Add this variable to the closure's environment, then advance to the next parameter.

                localEnvironment.AssignLocal(argumentName, argumentValue);

                argumentNameList = (Cons)argumentNameList.Cdr();
            }


            // Now that the parameters and their defaults have been added to the environment we can now
            // process the supplied arguments.

            while (argumentList != null)
            {
                // Because these are keyed parameters, the caller needs to specify the name of each
                // parameter.

                if (argumentList.Car().GetType() != typeof(Symbol))
                {
                    throw new LSharpException("Key parameters must be specified by name.");
                }


                // Grab the current parameter and the value associated with it.  Then make sure that this
                // is a keyword.

                Symbol keywordName = (Symbol)argumentList.Car();
                object argumentValue = argumentList.Cadr();

                if (keywordName.Name[0] != ':')
                {
                    throw new LSharpException(keywordName + " is not a valid keyword.");
                }


                // Now that we know they supplied a keyword, create a symbol out of it and make sure that
                // it exists.

                //keywordName = new Symbol(keywordName.Name.Substring(1));
                keywordName = Symbol.FromName(keywordName.Name.Substring(1));

                if (localEnvironment.Contains(keywordName) == false)
                {
                    throw new LSharpException(keywordName + " is not a recognised keyword.");
                }


                // Update the parameter with the value that the user specified and then move onto the next
                // argument in the list.

                localEnvironment.AssignLocal(keywordName, argumentValue);
                argumentList = (Cons)argumentList.Cddr();
            }

        }
コード例 #20
0
ファイル: NewCompiler.cs プロジェクト: mlnlover11/MP.LSharp
    /// <summary>
    /// (each symbol IEnumerable expression)
    /// </summary>
    public static Object ForEach(Cons args, LSharp.Environment environment)
    {
        //string v = "//(each " + Printer.ConsToString(args) + ")" + NewLine;
        string v = "";
        LSharp.Environment localEnvironment = new LSharp.Environment(environment);
        Symbol variable = (Symbol) args.First();
        
        string vn = localEnvironment.AssignLocal(variable, MakeUnique(variable.Name)) as string;
        
        v += Generate(args.Second(),environment) +
            string.Format(@"
foreach (object {0} in (System.Collections.IEnumerable)retval)
{{", vn);
        
        foreach (object item in (Cons)args.Cddr())
        {
            v += Generate(item, localEnvironment);
        }

        v += "}" + NewLine;

        return v;
    }
コード例 #21
0
ファイル: Primitives.cs プロジェクト: westybsa/MP.LSharp
		/// <summary>
        /// Process the arguments passed to a closure, and add them to the given enviroment.
		/// </summary>
        /// <param name="argumentNameList">The list of names and kewords the closure was created with.</param>
        /// <param name="argumentList">The arguments passed to the closure.</param>
        /// <param name="localEnvironment">The closure's local variables.</param>
		/// <returns>Nothing.</returns>
        public static void ProcessArguments(Cons argumentNameList, Cons argumentList, Environment localEnvironment) 
		{
			while (argumentNameList != null) 
			{
                // Get the name for the closure's parameter.  Then check to see if it's a keyword, if it is then
                // process the keyword.  Otherwise set up that parameter in the closure's enviroment with the
                // caller specified value.

				Symbol argumentName = (Symbol)argumentNameList.Car();

                switch (argumentName.ToString())
                {
                    case "&rest":
                        argumentName = (Symbol)argumentNameList.Cadr();
                        localEnvironment.AssignLocal(argumentName, argumentList);
                        argumentNameList = null;
                        argumentList = null;
                        break;

                    case "&optional":
                        ProcessOptionalArguments((Cons)argumentNameList.Cdr(), argumentList, localEnvironment);
                        argumentNameList = null;
                        argumentList = null;
                        break;

                    case "&key":
                        ProcessKeyArguments((Cons)argumentNameList.Cdr(), argumentList, localEnvironment);
                        argumentNameList = null;
                        argumentList = null;
                        break;

                    default:
                        if (argumentList == null)
                        {
                            throw new LSharpException("Not enough parameters given.");
                        }

                        localEnvironment.AssignLocal(argumentName, argumentList.Car());
                        argumentList = (Cons)argumentList.Cdr();
                        argumentNameList = (Cons)argumentNameList.Cdr();
                        break;
                }
			}


            // Looks like the caller has supplied more parameters than the closure can use.

            if (argumentList != null)
            {
                throw new LSharpException("Too many parameters given.");
            }
		}