Esempio n. 1
0
 private Symbol(PrimitiveSymbol prim)
 {
     switch (prim) {
     case PrimitiveSymbol.Unbound:
         this.name = "unbound";
         this.value = this.function = this;
         break;
     default:
         throw new NotSupportedException();
     }
 }
Esempio n. 2
0
        public Hash(L l, Shelisp.Object test, Shelisp.Object weakness, Shelisp.Object size, Shelisp.Object rehash_size, Shelisp.Object rehash_threshold)
        {
            this.l = l;
            this.test = test;
            this.weakness = weakness;
            this.size = size;
            this.rehash_size = size;
            this.rehash_threshold = rehash_threshold;

            this.count = 0;
            // map weakness to our enum
            if (L.NILP (weakness)) {
                weakness_ = Weakness.None;
            }
            else if (weakness.LispEq (L.Qt)) {
                weakness_ = Weakness.KeyAndValue;
            }
            else if (weakness.LispEq (L.Qkey)) {
                weakness_ = Weakness.Key;
            }
            else if (weakness.LispEq (L.Qvalue)) {
                weakness_ = Weakness.Value;
            }
            else if (weakness.LispEq (L.Qkey_or_value)) {
                weakness_ = Weakness.KeyOrValue;
            }
            else if (weakness.LispEq (L.Qkey_and_value)) {
                weakness_ = Weakness.KeyAndValue;
            }
            else
                throw new Exception (string.Format ("invalid weakness {0}", weakness));

            compare = null;
            // use a builtin comparison function for the builtin test types
            if (test.LispEq (L.intern ("eq"))) {
                compare = compare_eq;
            }
            else if (test.LispEq (L.intern ("eql"))) {
                compare = compare_eql;
            }
            else if (test.LispEqual (L.intern ("equal"))) {
                compare = compare_equal;
            }

            table = new Tuple<Shelisp.Object,Shelisp.Object>[(int)((Number)size).boxed];
        }
Esempio n. 3
0
        public override Shelisp.Object Eval(L l, Shelisp.Object env = null)
        {
            try {
                if (l.eval_depth ++ >= L.max_lisp_eval_depth)
                    throw new Exception ("max eval depth exceeded");

                env = env ?? l.Environment;

                Debug.Print (this);

                // function evaluation gets stuffed in here unfortunately
                Object first = L.CAR(this);
                Object rest = L.CDR(this);

                Shelisp.Object fun = first;

                retry:

            #if my_stupid_way
                if (first is Symbol) {
                    Debug.Print ("first is {0}", first);
                    Shelisp.Object lex_binding = List.Fassq (l, first, env);
                    if (!L.NILP (lex_binding)) {
                        var binding = L.CDR (lex_binding);
                        if (binding is Symbol && !(L.Qunbound.LispEq (((Symbol)binding).Function)))
                            fun = ((Symbol)binding).Function;
                    }

                    if (fun is Symbol) {
                        fun = L.Findirect_function (l, fun);
                        Debug.Print ("first was a symbol, function = {0}", fun);
                    }
                }
            #else
                fun = first;
                if ((fun is Symbol) && !fun.LispEq (L.Qunbound)) {
                    fun = ((Symbol)fun).Function;
                    if (fun is Symbol)
                        fun = L.Findirect_function (l, fun, L.Qnil);
                }
            #endif

                if (fun is Subr) {
                    Subr subr = (Subr)fun;
                    Shelisp.Object[] args;

                    L.EvalSpew ("evaluating subr application, {0}", fun);

                    if (!L.LISTP(rest))
                        throw new WrongTypeArgumentException ("listp", rest);
                    if (L.NILP (rest)) {
                        args = new Shelisp.Object[0];
                    }
                    else {
                        Shelisp.List rest_list = L.CONS(rest);
                        args = new Shelisp.Object[rest_list.Length];
                        int argnum = 0;
                        if (subr.unevalled) {
                            Debug.Print ("   unevalled args");
                        }
                        else {
                            Debug.Print ("   evalled args");
                        }

                        L.EvalIndent(1);
                        foreach (var o in rest_list) {
                            L.EvalSpew ("arg: {0}", o);
                            if (subr.unevalled) {
                                args[argnum++] = o;
                            }
                            else {
                                var evalled = o.Eval (l, env);
                                if (L.Qunbound.LispEq (evalled))
                                    throw new Exception (string.Format ("form {0} evaluated to unbound.  this is NOT what you want", o));
                                args[argnum++] = evalled;
                            }
                        }
                        L.EvalOutdent(1);
                    }

                    try {
                        L.EvalIndent();
                        Shelisp.Object rv = ((Subr)fun).Call (l, args);
                        L.EvalOutdent();
                        L.EvalSpew ("evaluating of {0} resulted in {1}", fun, rv);
                        return rv;
                    }
                    catch {
                        Debug.Print ("at lisp {0}", fun);
                        throw;
                    }
                }
                else {
                    if (L.NILP (fun) || fun.LispEq(L.Qunbound)) {
                        Console.WriteLine ("entire application is {0}", this);
                        throw new LispVoidFunctionException (first);
                    }
                    if (!L.LISTP (fun))
                        throw new LispInvalidFunctionException (first);
                    Shelisp.Object funcar = L.CAR (fun);
                    if (!(funcar is Symbol)) {
                        throw new LispInvalidFunctionException (first);
                    }
                    if (funcar.LispEq (L.Qautoload)) {
                        FileIO.DoAutoload (l, fun, first);
                        goto retry;
                    }
            #if notyet
                    if (EQ (funcar, Qmacro))
                        val = eval_sub (apply1 (Fcdr (fun), original_args));
                    else if (EQ (funcar, Qlambda)
                         || EQ (funcar, Qclosure))
                        val = apply_lambda (fun, original_args);
                    else
                        xsignal1 (Qinvalid_function, original_fun);
            #else
                    if (funcar.LispEq (L.Qmacro)) {
                        L.EvalSpew ("evaluating macro application, {0} = {1}, ", first, L.CDR(fun));
                        L.EvalIndent(1);
                        foreach (var r in (List)rest)
                            L.EvalSpew ("arg: {0}", r);
                        L.EvalOutdent(1);

                        L.EvalIndent();
                        var expanded = List.ApplyLambda (l, L.CDR(fun), rest, env, false);
                        L.EvalOutdent();

                        L.EvalSpew ("macro {0} expanded to {1}", first, expanded);

                        var expanded_evalled = expanded.Eval (l, env);
                        L.EvalSpew ("evaluating of {0} resulted in {1}", first, expanded_evalled);

                        return expanded_evalled;
                    }
                    if (funcar.LispEq (L.Qlambda)
                        || funcar.LispEq (L.Qclosure)) {

                        L.EvalSpew ("evaluating function application, {0} = {1}, ", first, L.CDR(fun));
                        if (L.CONSP(rest)) {
                            L.EvalIndent (1);
                            foreach (var r in (List)rest)
                                L.EvalSpew ("arg: {0}", r);
                            L.EvalOutdent (1);
                        }

                        L.EvalIndent();
                        var rv = List.ApplyLambda (l, fun, rest, env);
                        L.EvalOutdent();

                        L.EvalSpew ("evaluating of {0} resulted in {1}", first, rv);

                        return rv;
                    }
                    else {
                        throw new LispInvalidFunctionException (first);
                    }
            #endif
                }
            }
            finally {
                l.eval_depth --;
            }
        }
Esempio n. 4
0
 public Symbol(string name)
 {
     this.name = name;
     this.value = Unbound;
     this.function = Unbound;
 }
Esempio n. 5
0
        public static Shelisp.Object Fmake_hash_table(L l, params Shelisp.Object[] keyword_args)
        {
            Shelisp.Object test = L.intern ("eql"); // this is wrong, it's not just numbers, right?
            Shelisp.Object weakness = L.Qnil;
            Shelisp.Object size = new Number (65);
            Shelisp.Object rehash_size = new Number (1.5);
            Shelisp.Object rehash_threshold = new Number (0.8);

            for (int i = 0; i < keyword_args.Length; i += 2) {
                var keyword = keyword_args[i];

                Console.WriteLine (keyword);

                if (i == keyword_args.Length - 1)
                    throw new Exception (string.Format ("keyword {0} has no value", keyword));

                var value = keyword_args[i+1];

                if (keyword.LispEq (L.Qtest))
                    test = value;
                else if (keyword.LispEq (L.Qweakness))
                    weakness = value;
                else if (keyword.LispEq (L.Qsize))
                    size = value;
                else if (keyword.LispEq (L.Qrehash_size))
                    rehash_size = value;
                else if (keyword.LispEq (L.Qrehash_threshold))
                    rehash_threshold = value;
            }

            return new Hash (l, test, weakness, size, rehash_size, rehash_threshold);
        }