Beispiel #1
0
 public List(params Object[] objs)
 {
     if (objs.Length == 0)
         throw new Exception ("this ctor can only be used with arrays of length >= 1");
     Object tail = L.Qnil;
     for (int i = objs.Length - 1; i >= 1; i --)
         tail = new List (objs[i] ?? L.Qnil, tail);
     cdr = tail;
     car = objs[0] ?? L.Qnil;
 }
Beispiel #2
0
        public static Shelisp.Object Fautoload(L l, Shelisp.Object function, [LispOptional] Shelisp.Object filename, Shelisp.Object docstring, Shelisp.Object interactive, Shelisp.Object type)
        {
            if (L.Qt.LispEq (Symbol.Ffboundp (l, function)))
                return L.Qnil;

            var autoload_function = new List (new Shelisp.Object[] { L.Qautoload, filename, docstring == null ? (Shelisp.Object)(Shelisp.String)"" : docstring, interactive == null ? L.Qnil : interactive, type == null ? L.Qnil : interactive });
            Symbol.Ffset (l, function, autoload_function);
            //l.Environment = new List (new List(function, function), l.Environment);
            return autoload_function;
        }
Beispiel #3
0
 public static Shelisp.Object Fmake_keymap(L l, [LispOptional] Shelisp.Object str)
 {
     Shelisp.Object tail;
     if (!L.NILP (str)) {
         Console.WriteLine ("str = {0}", str == null ? "null" : "not null");
         tail = new List (str, L.Qnil);
     }
     else
         tail = L.Qnil;
     return new List (L.intern ("keymap"),
              new List (CharTable.Fmake_char_table (l, L.intern ("keymap"), L.Qnil), tail));
 }
Beispiel #4
0
        private static Shelisp.Object merge(L l, Shelisp.Object org_l1, Shelisp.Object org_l2, Shelisp.Object pred)
        {
            Shelisp.Object value;
            Shelisp.Object tail;
            Shelisp.Object tem;
            Shelisp.Object l1, l2;

            l1 = org_l1;
            l2 = org_l2;
            tail = L.Qnil;
            value = L.Qnil;

            while (true) {
                if (L.NILP (l1)) {
                    if (L.NILP (tail))
                        return l2;
                    Fsetcdr (l, tail, l2);
                    return value;
                }
                if (L.NILP (l2)) {
                    if (L.NILP (tail))
                        return l1;
                    Fsetcdr (l, tail, l1);
                    return value;
                }
                tem = new List (new Shelisp.Object[] { pred, Fcar (l, l2), Fcar (l, l1) }).Eval (l);
                if (L.NILP (tem)) {
                    tem = l1;
                    l1 = Fcdr (l, l1);
                    org_l1 = l1;
                }
                else {
                    tem = l2;
                    l2 = Fcdr (l, l2);
                    org_l2 = l2;
                }
                if (L.NILP (tail))
                    value = tem;
                else
                    Fsetcdr (l, tail, tem);
                tail = tem;
            }
        }
Beispiel #5
0
        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 --;
            }
        }
Beispiel #6
0
        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;
        }
Beispiel #7
0
        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;
        }