public static bool Numberp(KObject args, Func <KFraction, KFraction, bool> cmp) { int length = KPair.Length(args); if (length < 2) { throw new RuntimeException("at least two arguments"); } else { KFraction first = ToExact(Check((args as KPair).Car)); KObject head = (args as KPair).Cdr; while (head is KPair) { KFraction next = NumbersModule.ToExact(NumbersModule.Check((head as KPair).Car)); if (!cmp(first, next)) { return(false); } first = next; head = (head as KPair).Cdr; } return(true); } }
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); }
protected void CPara(KObject p, int len) { int actLen = KPair.Length(p); if (actLen != len) { throw new RuntimeException("mismatching number of ops, expected " + len + ", got " + actLen); } }
public override object Do(KObject args, KEnvironment env, Continuation <KObject> cont) { int length = KPair.Length(args); if (length == -1) { throw new RuntimeException("improper list"); } if (length == 0) { throw new RuntimeException("at least one arg expected"); } else if (length == 1) { KObject a = NumbersModule.Check(First(args)); if (a is KFraction) { return(new KFraction((a as KFraction).Numerator * -1, (a as KFraction).Denominator)); } else { return(new KDouble((a as KDouble).Value * -1)); } } else { KObject dif = NumbersModule.Check(First(args)); KObject head = (args as KPair).Cdr; while (head is KPair) { KObject nextNumber = NumbersModule.Check(First(head)); if (dif is KFraction && nextNumber is KFraction) { dif = (dif as KFraction).Subtract(nextNumber as KFraction); } else { KDouble a = NumbersModule.ToInexact(dif); KDouble b = NumbersModule.ToInexact(nextNumber); dif = new KDouble(a.Value - b.Value); } head = (head as KPair).Cdr; } return(dif); } }
public override RecursionResult <KObject> Combine(KObject args, KEnvironment env, Continuation <KObject> cont) { int len = KPair.Length(args); if (len == -1) { return(CPS.Error("encapsulation?: parameter is not a list", cont)); } else { bool result = true; KPair.Foreach(x => { if (!(x is KEncapsulation) || (x as KEncapsulation).Id != id) { result = false; } }, args); return(ReturnBool(result, cont)); } }
public override object Do(KObject args, KEnvironment env, Continuation <KObject> cont) { int len = KPair.Length(args); if (len == -1) { throw new RuntimeException("parameter is not a list"); } else { bool result = true; KPair.Foreach(x => { if (!(x is KEncapsulation) || (x as KEncapsulation).Id != id) { result = false; } }, args); return(result); } }
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 override object Do(KObject args, KEnvironment env, Continuation <KObject> cont) { int length = KPair.Length(args); if (length == -1) { throw new RuntimeException("improper list"); } if (length == 0) { return(new KFraction(BigInteger.One, BigInteger.One)); } else { // we have a list of at least one elements // we must fold it to something useful KObject product = NumbersModule.Check(First(args)); KObject head = (args as KPair).Cdr; while (head is KPair) { KObject nextNumber = NumbersModule.Check(First(head)); if (product is KFraction && nextNumber is KFraction) { product = (product as KFraction).Multiply(nextNumber as KFraction); } else { KDouble a = NumbersModule.ToInexact(product); KDouble b = NumbersModule.ToInexact(nextNumber); product = new KDouble(a.Value * b.Value); } head = (head as KPair).Cdr; } return(product); } }