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)); } }
private List <KGuard> assignGuards(KObject clauses) { List <KGuard> result = new List <KGuard>(); if (clauses is KPair) { KPair.Foreach(x => { int length = KPair.Length(x); if (length == 2) { KContinuation selector = First(x) as KContinuation; KApplicative interceptor = Second(x) as KApplicative; if (selector == null || interceptor == null) { throw new RuntimeException("guard-continuation: invalid clause, wrong types"); } result.Add(new KGuard { Selector = selector, Interceptor = interceptor }); } else { throw new RuntimeException("guard-continuation: invalid clause"); } }, clauses); } return(result); }
public override object Do(KObject args, KEnvironment env, Continuation <KObject> cont) { CPara(args, 1); KContinuation c = First(args) as KContinuation; Check(c, "expected continuation"); return(new KApplicative(new PPassCont(c))); }
public override RecursionResult <KObject> Combine(KObject args, KEnvironment env, Continuation <KObject> cont) { int len = KPair.Length(args); if (len < 2 || len > 3) { return(CPS.Error("extend-continuation: argument mismatch", cont)); } KContinuation argC = First(args) as KContinuation; KApplicative argA = Second(args) as KApplicative; KEnvironment argE = len == 3 ? Third(args) as KEnvironment : new KEnvironment(); if (argC == null || argA == null || argE == null) { return(CPS.Error("extend-continuation: mismatching arguments", cont)); } var nc = new Continuation <KObject>((val, ctxt) => { return(CPS.Next(() => Evaluator.rceval(new KPair(argA.Combiner, val, true), argE, argC.Value), argC.Value)); }, argC.Value, argA); return(Return(new KContinuation(nc), cont)); }
public PPassCont(KContinuation c) { myc = c; }