public void EvalAnd_ReturnTrue_WhenTailIsEmptyList()
        {
            var expr = BuiltIn.ListOf(ClSymbol.And);
            var ctx  = expr.Reduce(_ctx);

            Assert.That(ctx.Value, Is.EqualTo(ClBool.True));
        }
        public override IContext Reduce(IContext ctx)
        {
            var funcName = BuiltIn.Head(Cdr);
            var lambda   = new ClCell(ClSymbol.Lambda, BuiltIn.Tail(Cdr));

            return(BuiltIn.ListOf(ClSymbol.Define, funcName, lambda).Reduce(ctx));
        }
        public void EvalCond_ReturnFalse_WhenClausesAreMissed()
        {
            var expr = BuiltIn.ListOf(ClSymbol.Cond);
            var ctx  = expr.Reduce(_ctx);

            Assert.That(ctx.Value, Is.EqualTo(ClBool.False));
        }
        public void EvalBegin_ReturnNil_WhenTailIsEmptyList()
        {
            var expr = BuiltIn.ListOf(ClSymbol.Begin);
            var ctx  = expr.Reduce(_ctx);

            Assert.That(ctx.Value, Is.EqualTo(ClCell.Nil));
        }
        public void EvalDefinition_ReturnNil_WhenOperationIsSuccessful()
        {
            var expr = BuiltIn.ListOf(ClSymbol.Define, Var.Foo, ClBool.False);
            var ctx  = expr.Reduce(_ctx);

            Assert.That(ctx.Value, Is.EqualTo(ClCell.Nil));
        }
        public void EvalDefinition_CreateNewBinding()
        {
            var expr = BuiltIn.ListOf(ClSymbol.Define, Var.Foo, ClBool.True);
            var ctx  = expr.Reduce(_ctx);

            Assert.That(ctx.Env.Lookup(Var.Foo), Is.EqualTo(ClBool.True));
        }
        public void Eval_DoesNotCreateNewScope(Func <ClCell, ClCell> expr)
        {
            var define = BuiltIn.ListOf(ClSymbol.Define, Var.Foo, Value.Foo);
            var ctx    = expr.Invoke(define).Reduce(_ctx);

            Assert.That(ctx.Env.Lookup(Var.Foo), Is.EqualTo(Value.Foo));
        }
        public void EvalAnd_ReturnLastItem_WhenEachItemIsTrue()
        {
            var expr = BuiltIn.ListOf(ClSymbol.And, ClBool.True, Value.Foo);
            var ctx  = expr.Reduce(_ctx);

            Assert.That(ctx.Value, Is.EqualTo(Value.Foo));
        }
        public void EvalLet_LikeConstantFunction()
        {
            var expr = BuiltIn.ListOf(ClSymbol.Let, ClCell.Nil, Value.One);
            var ctx  = expr.Reduce(_ctx);

            Assert.That(ctx.Value, Is.EqualTo(Value.One));
        }
        public void EvalBegin_ReturnLastEvaluatedValue()
        {
            var expr = BuiltIn.ListOf(ClSymbol.Begin, ClBool.False, ClBool.True, Value.One);
            var ctx  = expr.Reduce(_ctx);

            Assert.That(ctx.Value, Is.EqualTo(Value.One));
        }
        public void EvalAssignment_ThrowException_WhenEnvironmentDoesNotContainBinding()
        {
            var expr = BuiltIn.ListOf(ClSymbol.Set, Var.Foo, Value.Foo);

            Assert.That(() => expr.Reduce(_ctx),
                        Throws.Exception.TypeOf <UnboundVariableError>().With.Message.EqualTo("Unbound variable foo"));
        }
        public void EvalDefinition_ThrowException_WhenRighSideVariableDoesNotExist()
        {
            var expr = BuiltIn.ListOf(ClSymbol.Define, Var.Foo, Var.Bar);

            Assert.That(() => expr.Reduce(_ctx),
                        Throws.Exception.TypeOf <UnboundVariableError>().With.Message.EqualTo("Unbound variable bar"));
        }
        public void EvalIf_ReturnNil_WhenConditionIsFalseAndElseBranchIsMissed()
        {
            var expr = BuiltIn.ListOf(ClSymbol.If, ClBool.False, Value.One);
            var ctx  = expr.Reduce(_ctx);

            Assert.That(ctx.Value, Is.EqualTo(ClCell.Nil));
        }
        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));
        }
Beispiel #15
0
        public void EvalOr_ReturnFalse_WhenTailIsEmptyList()
        {
            var expr = BuiltIn.ListOf(ClSymbol.Or);
            var ctx  = expr.Reduce(_ctx);

            Assert.That(ctx.Value, Is.EqualTo(ClBool.False));
        }
        public void Eval_IdentifiersAndKeywordsCoexistIndependently()
        {
            _env.Bind(ClSymbol.And, Value.One);
            var expr = BuiltIn.ListOf(ClSymbol.And, ClBool.True, Value.Foo);

            Assert.That(ClSymbol.And.Reduce(_ctx).Value, Is.EqualTo(Value.One));
            Assert.That(expr.Reduce(_ctx).Value, Is.EqualTo(Value.Foo));
        }
        static IEnumerable <Func <ClCell, ClCell> > DoesNotCreateNewScopeTestCases()
        {
            yield return(new Func <ClCell, ClCell>(x => BuiltIn.ListOf(ClSymbol.If, x, ClBool.True, ClBool.False)));

            yield return(new Func <ClCell, ClCell>(x => BuiltIn.ListOf(ClSymbol.And, x, ClBool.False)));

            yield return(new Func <ClCell, ClCell>(x => BuiltIn.ListOf(ClSymbol.Or, x, ClBool.True)));
        }
Beispiel #18
0
        static IEnumerable <ClObj> InvalidParameterTestCases()
        {
            yield return(Value.One);

            yield return(Value.Foo);

            yield return(BuiltIn.ListOf(ClSymbol.If, ClBool.True, Var.Foo, Var.Bar));
        }
        public void Env_InjectPredifinedEntities()
        {
            var env      = new Env(BuiltIn.Env);
            var nativeFn = env.Lookup(new ClSymbol("head")).Cast <NativeFn>();
            var args     = BuiltIn.ListOf(ClBool.True, ClBool.False);

            Assert.That(nativeFn.Apply(args), Is.EqualTo(ClBool.True));
        }
Beispiel #20
0
        public void EvalLambda_ThrowException_WhenLambdaSpecialFormHasInvalidBody()
        {
            var expr         = BuiltIn.ListOf(ClSymbol.Lambda, ClCell.Nil, ClBool.True, ClBool.False);
            var errorMessage = "Invalid function body format";

            Assert.That(() => expr.Reduce(_ctx),
                        Throws.Exception.TypeOf <SyntaxError>().With.Message.EqualTo(errorMessage));
        }
Beispiel #21
0
        public void EvalLambda_ThrowExceptionWhenParametersIsNotList()
        {
            var expr         = BuiltIn.ListOf(ClSymbol.Lambda, Var.Foo, Var.Foo);
            var errorMessage = "Invalid function parameters format";

            Assert.That(() => expr.Reduce(_ctx),
                        Throws.Exception.TypeOf <SyntaxError>().With.Message.EqualTo(errorMessage));
        }
Beispiel #22
0
        public void EvalApplication_ThrowException_WhenBodyContainsUnboundVariable()
        {
            var procedure = BuiltIn.ListOf(ClSymbol.Lambda, ClCell.Nil, Var.Bar);
            var expr      = BuiltIn.ListOf(procedure);

            Assert.That(() => expr.Reduce(_ctx),
                        Throws.Exception.TypeOf <UnboundVariableError>().With.Message.EqualTo("Unbound variable bar"));
        }
        public void EvalLet_LikeIdentityFunction()
        {
            var bindings = BuiltIn.ListOf(BuiltIn.ListOf(Var.Foo, Value.One));
            var expr     = BuiltIn.ListOf(ClSymbol.Let, bindings, Var.Foo);

            var ctx = expr.Reduce(_ctx);

            Assert.That(ctx.Value, Is.EqualTo(Value.One));
        }
        public void EvalLet_ThrowException_WhenCompoundBody()
        {
            var bindings     = BuiltIn.ListOf(BuiltIn.ListOf(Var.Foo, Value.One));
            var expr         = BuiltIn.ListOf(ClSymbol.Let, bindings, Var.Foo, ClBool.False);
            var errorMessage = "Invalid body of the let special form";

            Assert.That(() => expr.Reduce(_ctx),
                        Throws.Exception.TypeOf <SyntaxError>().With.Message.EqualTo(errorMessage));
        }
        public void EvalLet_ThrowException_WhenSingleBindingIsNil()
        {
            var bindings     = BuiltIn.ListOf(ClCell.Nil);
            var expr         = BuiltIn.ListOf(ClSymbol.Let, bindings, Value.One);
            var errorMessage = $"Variable definition expression cannot be {nameof(ClCell.Nil)}";

            Assert.That(() => expr.Reduce(_ctx),
                        Throws.Exception.TypeOf <SyntaxError>().With.Message.EqualTo(errorMessage));
        }
Beispiel #26
0
        public void EvalApplication_ThrowInvalidFunctionCall_WhenCarIsNotCallable()
        {
            _env.Bind(Var.Fn, Value.One);
            var expr         = BuiltIn.ListOf(Var.Fn, Value.One);
            var errorMessage = $"{nameof(ClInt)} is neither callable nor special from";

            Assert.That(() => expr.Reduce(_ctx),
                        Throws.Exception.TypeOf <SyntaxError>().With.Message.EqualTo(errorMessage));
        }
Beispiel #27
0
        public void EvalApplication_ZeroArityFunction()
        {
            var constantFn = BuiltIn.ListOf(ClSymbol.Lambda, ClCell.Nil, Value.One);
            var expr       = BuiltIn.ListOf(constantFn);

            var context = expr.Reduce(_ctx);

            Assert.That(context.Value, Is.EqualTo(Value.One));
        }
        public void EvalLet_ThrowExceptionWhenTooManyValuesArePassedForBinding()
        {
            var bindings     = BuiltIn.ListOf(BuiltIn.ListOf(Var.Foo, ClBool.True, ClBool.False));
            var expr         = BuiltIn.ListOf(ClSymbol.Let, bindings, Var.Foo);
            var errorMessage = "Variable definition expression should have format (var val)";

            Assert.That(() => expr.Reduce(_ctx),
                        Throws.Exception.TypeOf <SyntaxError>().With.Message.EqualTo(errorMessage));
        }
        public void EvalDefinition_CreateSharedReference()
        {
            _env.Bind(Var.Bar, Value.Bar);
            var expr = BuiltIn.ListOf(ClSymbol.Define, Var.Foo, Var.Bar);

            Ignore(expr.Reduce(_ctx));

            Assert.That(Object.ReferenceEquals(_env.Lookup(Var.Foo), _env.Lookup(Var.Bar)), Is.True);
        }
        public void EvalDefinition_OverrideExistingBinding()
        {
            _env.Bind(Var.Foo, ClBool.True);
            var expr = BuiltIn.ListOf(ClSymbol.Define, Var.Foo, Value.Foo);

            var ctx = expr.Reduce(_ctx);

            Assert.That(ctx.Env.Lookup(Var.Foo), Is.EqualTo(Value.Foo));
        }