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)); } }
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)); } }
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)); } }
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))); }
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))); }
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)); }
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)); }
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)); } }