示例#1
0
        public override RecursionResult <KObject> Combine(KObject args, KEnvironment env, Continuation <KObject> cont)
        {
            var res = CheckParameter(args, 1, "load");


            if (res != null)
            {
                return(CPS.Error(res, cont));
            }
            KObject val = First(args) as KString;

            if (!(val is KString))
            {
                return(CPS.Error("load: not a string", cont));
            }
            string path = (val as KString).Value;

            try
            {
                List <KObject> tokens = Parser.ParseAll(File.ReadAllText(path));
                foreach (var token in tokens)
                {
                    Evaluator.Eval(token, env);
                }
                return(CPS.Return(new KInert(), cont));
            }
            catch (Exception e)
            {
                return(CPS.Error("Failed to load file: " + e.Message, cont));
            }
        }
示例#2
0
        public override RecursionResult <KObject> Combine(KObject args, KEnvironment env, Continuation <KObject> cont)
        {
            var res = CheckParameter(args, 3, "guard-continuation");

            if (res != null)
            {
                return(CPS.Error(res, cont));
            }
            KContinuation c     = Second(args) as KContinuation;
            KObject       entry = First(args);
            KObject       exit  = Third(args);

            try
            {
                if (null == c)
                {
                    throw new RuntimeException("guard-continuation: not a continution");
                }
                c.Value.EntryGuard = assignGuards(entry);
                c.Value.ExitGuard  = assignGuards(exit);
                return(CPS.Return(c, cont));
            }
            catch (Exception e)
            {
                return(CPS.Error(e.Message, cont));
            }
        }
示例#3
0
        public virtual RecursionResult <KObject> Combine(KObject args, KEnvironment env, Continuation <KObject> cont)
        {
            object result = null;

            try {
                result = Do(args, env, cont);
            } catch (RuntimeException e) {
                return(CPS.Error <KObject>(getName() + ": " + e.Message, cont));
            }
            if (result is KObject)
            {
                return(CPS.Return(result as KObject, cont));
            }
            else if (result is bool)
            {
                return(CPS.Return(new KBoolean((bool)result), cont));
            }
            else if (result is RecursionResult <KObject> )
            {
                return(result as RecursionResult <KObject>);
            }
            else
            {
                return(CPS.Return(new KInert(), cont));
            }
        }
示例#4
0
        public override object Do(KObject args, KEnvironment env, Continuation <KObject> cont)
        {
            CPara(args, 1);
            Continuation <KObject> result = myc.Value;

            if (result.Context == null)
            {
                return(CPS.Return(First(args), CPS.RootContinuation <KObject>()));
            }
            return(result.Call(First(args)));
        }
示例#5
0
        public override object Do(KObject args, KEnvironment env, Continuation <KObject> cont)
        {
            CPara(args, 2);
            KObject definand = First(args), expr = Second(args);
            var     cc = new Continuation <KObject>((e) => {
                try {
                    Evaluator.BindFormalTree(definand, e, env);
                } catch (Exception ex) {
                    return(CPS.Error <KObject>(ex.Message, cont));
                }
                return(CPS.Return <KObject>(new KInert(), cont));
            }, cont, "define");

            return(CPS.PassTo(() => Evaluator.rceval(expr, env, cc)));
        }
示例#6
0
        public override RecursionResult <KObject> Combine(KObject args, KEnvironment env, Continuation <KObject> cont)
        {
            var res = CheckParameter(args, 1, "continuation->applicative");

            if (res != null)
            {
                return(CPS.Error(res, cont));
            }
            KObject c = First(args);

            if (c is KContinuation)
            {
                return(CPS.Return(new KApplicative(new PPassCont(c as KContinuation)), cont));
            }
            return(CPS.Error("continuation->applicative: not a continuation given", cont));
        }
示例#7
0
        public override RecursionResult <KObject> Combine(KObject args, KEnvironment env, Continuation <KObject> cont)
        {
            // first of all I wanna check for exit guards
            //Continuation<KObject> loop = cont;
            Continuation <KObject> result = myc.Value;

            /*var conts = new LinkedList<Continuation<KObject>>();
             * while (loop != null)
             * {
             *  conts.AddFirst(loop);
             *  loop = loop.Parent;
             * }
             * loop = cont;
             * Continuation<KObject> innerloop = myc.Value;
             * while(true)
             * {
             *  if (innerloop == null)
             *      break;
             *  if (continuationEqual(innerloop, cont))
             *  {
             *      loop = null;
             *      break;
             *  }
             *  innerloop = innerloop.Parent;
             * }
             * while (loop != null)
             * {
             *  if (loop.ExitGuard != null && loop.ExitGuard.Count > 0)
             *  {
             *      // ok, found something, now check
             *      foreach (KGuard guard in loop.ExitGuard)
             *      {
             *          foreach (Continuation<KObject> c in conts)
             *          {
             *              // from the last to the first
             *              if (continuationEqual(c, guard.Selector.Value))
             *              {
             *                  var child = new Continuation<KObject>((x, ctxt) =>
             *                      {
             *                          return Evaluator.rceval(new KPair(guard.Interceptor, new KPair(x, new KPair(new KNil(), new KNil(), true), true), true), KEnvironment.GetGroundEnv(), ctxt._RemainingGuards);
             *                      }, result, new KString("guard"));
             *                  child._RemainingGuards = result;
             *                  result = child;
             *              }
             *          }
             *      }
             *  }
             *  loop = loop.Parent;
             * }*/

            if (result.isError)
            {
                Continuation <KObject> cc = new Continuation <KObject>(null, cont, null);
                cc.isError = true;
                return(CPS.Return(args, cc));
            }
            if (result.Context == null)
            {
                //well, top level reached hm hm
                return(CPS.Return(args, result));
            }
            return(result.NextStep(args, result));
        }
示例#8
0
        public static RecursionResult <KObject> rceval(KObject datum, KEnvironment env, Continuation <KObject> cont)
        {
            // useful for debugging
            //Console.WriteLine(datum.Display());

            if (datum is KPair)
            {
                KPair p = datum as KPair;

                // this function get called when the operator is evaluated to f
                var childCont = new Continuation <KObject>((f) =>
                {
                    if (f is KOperative)
                    {
                        return(combineOp(f as KOperative, p.Cdr, env, cont));
                    }
                    else if (f is KApplicative && (p.Cdr is KPair || p.Cdr is KNil))
                    {
                        if (p.Cdr is KNil)
                        {
                            return(combineApp(f as KApplicative, p.Cdr, env, cont));
                        }
                        KPair ops = p.Cdr as KPair;
                        LinkedList <KObject> input = new LinkedList <KObject>();
                        KPair.Foreach(x =>
                        {
                            input.AddLast(x);
                        }, ops);
                        LinkedList <KObject> pairs = new LinkedList <KObject>();
                        Func <KObject, RecursionResult <KObject> > recursion = null;
                        bool firstRun = true;

                        // this continuation is called with the next argument evaled to x. Place next value
                        recursion = (x) =>
                        {
                            if (CPS.getContext() is int && !firstRun)
                            {
                                // restore elements when reentering continuation
                                int oldInputCount = (int)CPS.getContext() + 1;
                                input             = new LinkedList <KObject>();
                                KPair.Foreach(e =>
                                {
                                    input.AddLast(e);
                                }, ops);
                                int leaveOutputs = input.Count - oldInputCount;
                                while (input.Count > oldInputCount)
                                {
                                    input.RemoveFirst();
                                }
                                while (pairs.Count >= leaveOutputs)
                                {
                                    pairs.RemoveFirst();
                                }
                                firstRun = true;
                            }
                            pairs.AddFirst(x);
                            if (input.Count == 0)
                            {
                                // we are finished
                                KObject output = new KNil();
                                foreach (var el in pairs)
                                {
                                    output = new KPair(el, output);
                                }
                                firstRun = false;
                                return(combineApp(f as KApplicative, output, env, cont));
                            }
                            else
                            {
                                // do something with the next Head argument
                                KObject next = input.First.Value;
                                input.RemoveFirst();
                                var cc2 = new Continuation <KObject>(recursion, cont, input.Count);
                                return(CPS.PassTo(() => rceval(next, env, cc2)));
                            }
                        };
                        KObject next2 = input.First.Value;
                        input.RemoveFirst();
                        var cc = new Continuation <KObject>(recursion, cont, input.Count);
                        return(CPS.PassTo(() => rceval(next2, env, cc)));
                    }
                    return(CPS.Error <KObject>("Unsuitable operation of " + f.Write(), cont));
                }, cont, "eval op/app");
                return(CPS.PassTo(() => rceval(p.Car, env, childCont)));
            }
            else if (datum is KSymbol)
            {
                KObject val = env.Lookup(((KSymbol)datum).Value);
                if (null == val)
                {
                    return(CPS.Error <KObject>("Unbound variable " + ((KSymbol)datum).Value, cont));
                }
                return(CPS.Return(val, cont));
            }
            else
            {
                return(CPS.Return(datum, cont));
            }
        }