public void EvalOr_ReturnLastItem_WhenEachItemIsFalse(ClCell items, ClObj expected) { var expr = new ClCell(ClSymbol.Or, items); var ctx = expr.Reduce(_ctx); Assert.That(ctx.Value, Is.EqualTo(expected)); }
public void EvalOr_ReturnTruthyItem_WhenAtLeastOneItemIsTrue(ClCell items, ClObj expected) { var expr = new ClCell(ClSymbol.Or, items); var ctx = expr.Reduce(_ctx); Assert.That(ctx.Value, Is.EqualTo(expected)); }
public void EvalIf_EvalThenBranch_WhenConditionIsTrue(ClObj predicate) { var expr = BuiltIn.ListOf(ClSymbol.If, predicate, Value.One, ClBool.False); var ctx = expr.Reduce(_ctx); Assert.That(ctx.Value, Is.EqualTo(Value.One)); }
public void EvalAnd_ReturnFalsyItem_WhenAtLeastOneItemIsFalse(ClCell items, ClObj expected) { var expr = new ClCell(ClSymbol.And, items); var ctx = expr.Reduce(_ctx); Assert.That(ctx.Value, Is.EqualTo(expected)); }
public static T Cast <T>(this ClObj @this) where T : ClObj { if (@this is T t) { return(t); } throw new TypeError($"'{@this}' cannot be converted to {typeof(T).Name}"); }
public void EvalLambda_BodyCanBeAnyExpression(ClObj body) { var expr = BuiltIn.ListOf(ClSymbol.Lambda, ClCell.Nil, body); var fn = expr .Reduce(_ctx) .Value .Cast <ClFn>(); Assert.That(fn.Body, Is.EqualTo(body)); }
static ClObj Transform(ClObj clauses) { if (clauses == ClCell.Nil) { return(ClBool.False); } var clause = BuiltIn.First(clauses) as ClCell; if (clause is null) { throw new SyntaxError("Clause must be a cell"); } if (clause.Car.Equals(ClSymbol.Else)) { return(BuiltIn.Tail(clauses) == ClCell.Nil ? new ClCell(ClSymbol.Begin, clause.Cdr) : throw new SyntaxError("Else clause must be last condition")); } return(BuiltIn.ListOf(ClSymbol.If, clause.Car, new ClCell(ClSymbol.Begin, clause.Cdr), Transform(BuiltIn.Tail(clauses)))); }
public static IEnumerable <ClObj> Seq(ClObj obj) { var cell = obj.Cast <ClCell>(); if (cell == ClCell.Nil) { yield break; } yield return(cell.Car); var tail = cell.Cdr; while (tail is ClCell pair) { if (tail == ClCell.Nil) { yield break; } yield return(pair.Car); tail = pair.Cdr; } yield return(tail); }
public IfSpecialForm(ClObj cdr) : base(ClSymbol.Set, cdr) { }
public DefunSpecialForm(ClObj cdr) : base(ClSymbol.Defun, cdr) { }
public AndSpecialForm(ClObj cdr) : base(ClSymbol.And, cdr) { }
public LambdaSpecialForm(ClObj cdr) : base(ClSymbol.Lambda, cdr) { }
public void EvalLambda_ThrowException_WhenAtLeastOneParameterIsNotSymbolPrimitive(ClObj parameter) { var parameters = BuiltIn.ListOf(parameter, ClBool.True); var expr = BuiltIn.ListOf(ClSymbol.Lambda, parameters, Value.One); var errorMessage = $"Binding statement should have {nameof(ClSymbol)} on the left-hand-side"; Assert.That(() => expr.Reduce(_ctx), Throws.Exception.TypeOf <SyntaxError>().With.Message.EqualTo(errorMessage)); }
public static void Deconstruct(this IContext @this, out ClObj value, out IEnv env) { value = @this.Value; env = @this.Env; }
public static IContext FromValue(this IContext @this, ClObj value) => new Context(value, @this.Env);
public DefineSpecialForm(ClObj cdr) : base(ClSymbol.Define, cdr) { }
public LetSpecialForm(ClObj cdr) : base(ClSymbol.Let, cdr) { }
public static ClObj Quote(ClObj obj) => new ClCell(ClSymbol.Quote, obj);
public TaggedSpecialForm(ClSymbol tag, ClObj cdr) : base(tag, cdr) { }
public BeginSpecialForm(ClObj cdr) : base(ClSymbol.Begin, cdr) { }
public OrSpecialForm(ClObj cdr) : base(ClSymbol.Or, cdr) { }
public void Eval_SelfEvaluatingExpression(ClObj expr) { var ctx = expr.Reduce(_ctx); Assert.That(ctx.Value, Is.EqualTo(expr)); }
public Context(ClObj value, IEnv env) { Value = value; Env = env; }
public ApplySpecialForm(ClCallable car, ClObj cdr) : base(car, cdr) { }