コード例 #1
0
ファイル: Reader.cs プロジェクト: toshok/shelisp
        private static Shelisp.Vector ReadVector(StreamReader s)
        {
            Debug.Print ("ReadVector>");
            // consume the [
            s.Read();

            List<Shelisp.Object> objs = new List<Shelisp.Object>();
            Shelisp.Object obj;
            while ((obj = Read (s, ']')) != null) {
                Debug.Print ("+ {0}", obj);
                objs.Add (obj);
            }

            var rv = new Vector (objs.ToArray());
            Debug.Print ("ReadList returning {0}", rv);
            return rv;
        }
コード例 #2
0
ファイル: List.cs プロジェクト: toshok/shelisp
        public static Shelisp.Object ApplyLambda(L l, Shelisp.Object fun, Shelisp.Object args, [LispOptional] Shelisp.Object env, bool eval_args = true)
        {
            try {
                if (l.eval_depth ++ >= L.max_lisp_eval_depth)
                    throw new Exception ("max eval depth exceeded");

                // 			Console.WriteLine ("in ApplyLambda, fun = {0}, args = {1}, eval_args = {2}", fun, args, eval_args);
                // 			Console.WriteLine (Environment.StackTrace);

                if (env == null) env = l.Environment;

                if (!L.CONSP(fun))
                    Console.WriteLine ("{0} is not a cons cell!  we're about to die!", fun);

                if (L.CAR(fun).LispEq (L.Qclosure)) {
                    // this sets fun = ( environment args rest... ) where args rest... came from the original lambda.
                    // so the cdr below meant to skip the lambda actually skips the environment.
                    fun = L.CDR(fun);
                    env = L.CAR(fun);
                }

                Shelisp.Object rest = L.CDR (fun); // get rid of the lambda

                Shelisp.Object arg_names = L.CAR(rest);

                Shelisp.Object body = L.CDR (rest);

                /* evaluate each of the arguments in the current environment, then add them to the environment and evaluate the body of the lambda */
                Shelisp.Object lexenv = env;

                if (L.CONSP (arg_names)) {
                    IEnumerator<Shelisp.Object> argname_enumerator = ((List)arg_names).GetEnumerator();
                    IEnumerator<Shelisp.Object> arg_enumerator = L.NILP (args) ? (new List<Shelisp.Object>()).GetEnumerator() : ((List)args).GetEnumerator();

                    bool optional_seen = false;
                    bool rest_seen = false;
                    while (argname_enumerator.MoveNext()) {
                        if (((Symbol)argname_enumerator.Current).name == "&optional") {
                            optional_seen = true;
                            continue;
                        }
                        if (((Symbol)argname_enumerator.Current).name == "&rest") {
                            rest_seen = true;
                            continue;
                        }

                        if (rest_seen) {
                            // gather up the rest of the args into a single list, add it to the lexenv using the current argname,
                            // and break out of the loop
                            List<Shelisp.Object> list = new List<Shelisp.Object>();
                            while (arg_enumerator.MoveNext())
                                list.Add (eval_args ? arg_enumerator.Current.Eval (l, env) : arg_enumerator.Current);
                            Shelisp.Object rest_args = list.Count == 0 ? L.Qnil : new List(list.ToArray());
                            lexenv = new List (new List (argname_enumerator.Current, rest_args), lexenv);
                            break;
                        }
                        else if (optional_seen) {
                            // if there is nothing else in arg_enumerator, set parameters to nil
                            if (!arg_enumerator.MoveNext()) {
                                lexenv = new List (new List (argname_enumerator.Current, L.Qnil), lexenv);
                                continue;
                            }
                        }
                        else {
                            if (!arg_enumerator.MoveNext())
                                throw new Exception ("not enough args");
                        }

                        lexenv = new List (new List (argname_enumerator.Current, eval_args ? arg_enumerator.Current.Eval (l, env) : arg_enumerator.Current), lexenv);
                    }
                }

                var old_env = l.Environment;
                l.Environment = lexenv;

                try {
                    Shelisp.Object rv = L.Qnil;
                    foreach (var form in (List)body) {
                        L.EvalIndent();
                        rv = form.Eval (l, lexenv);
                        L.EvalOutdent();
                    }

                    return rv;
                }
                catch (Exception) {
                    Debug.Print ("at lisp {0}", body);
                    throw;
                }
                finally {
                    l.Environment = old_env;
                }
            }
            finally {
                l.eval_depth --;
            }
        }
コード例 #3
0
ファイル: Reader.cs プロジェクト: toshok/shelisp
        private static Shelisp.Object ReadList(StreamReader s)
        {
            Debug.Print ("ReadList>");
            // consume the (
            s.Read();

            List<Shelisp.Object> objs = new List<Shelisp.Object>();
            Shelisp.Object obj;
            bool dot_seen = false;
            bool el_after_dot = false;
            while ((obj = Read (s, ')')) != null) {
                if (obj.LispEq (L.intern("."))) {
                    if (dot_seen)
                        throw new LispInvalidReadSyntaxException (". in wrong context");
                    dot_seen = true;
                    continue;
                }
                else if (dot_seen) {
                    if (el_after_dot)
                        throw new LispInvalidReadSyntaxException (". in wrong context");
                    el_after_dot = true;
                }
                Debug.Print ("+ {0}", obj);
                objs.Add (obj);
            }

            Shelisp.Object rv;
            if (dot_seen)
                rv = L.make_list_atom_tail (objs.ToArray());
            else
                rv = L.make_list (objs.ToArray());

            Debug.Print ("ReadList returning {0}", rv);
            return rv;
        }