public void testMoreReordering()
        {
            var strict = new StrictInterpreter();

            // The non-strict interpreter moves around arguments such that they will continue to work.
            Assert.Equal("[[] d c b a 6]", Run("[[2 a negate 3 b c 5 + d +]]"));
            Assert.Equal("[[2 negate 3 5 + + a b c d]]", reorderInterpreter.Reorder("[[2 a negate 3 b c 5 + d +]]".ToStack()).ToRepr());
            Assert.Equal("[[] d c b a 6]", strict.Run("[[2 negate 3 5 + + a b c d]]".ToStack()).ToRepr());
            // Can't run the original with the strict interpreter.
            Assert.Throws <InvalidCastException>(() => strict.Run("[[2 a negate 3 b c 5 + d +]]".ToStack()));
        }
        public void testMoreReordering4()
        {
            var strict = new StrictInterpreter();

            // The non-strict interpreter moves around arguments such that they will continue to work.
            Assert.Equal("[[] d c b a 3]", Run("[[2 a negate 3 pop b c 5 + d + +]]"));
            Assert.Equal("[[3 pop 2 negate 5 + a b c d]]", Reorder("[[2 a negate 3 pop b c 5 + d + +]]"));
            // The same output is produced.
            Assert.Equal("[[] d c b a 3]", strict.Run("[[2 negate 5 + a 3 pop b c d]]".ToStack()).ToRepr());
            // Can't run the original with the strict interpreter.
            Assert.Throws <InvalidCastException>(() => strict.Run("[[2 a negate 3 pop b c 5 + d + +]]".ToStack()));
            Assert.Throws <InvalidOperationException>(() => strict.Run("[[2 +]]".ToStack()));
            Assert.Throws <InvalidOperationException>(() => strict.Run("[[+]]".ToStack()));
        }
Example #3
0
        public InterpreterTestUtil()
        {
            // Maybe I should do these lazily.
            nonstrictInterpreter = new NonstrictInterpreter();
            strictInterpreter    = new StrictInterpreter();
            reorderInterpreter   = new ReorderInterpreter();
            cleanInterpreter     = new Interpreter();
            typeInterpreter      = new TypeInterpreter();
            cleanInterpreter.instructions.Clear();
            interpreter = nonstrictInterpreter;

            // With InstructionFunc you have to do all your own error handling.
            interpreter.instructions["add"]
                  = strictInterpreter.instructions["add"]
                  = new InstructionFunc(stack => {
                if (stack.Count < 2)
                {
                    return(stack);
                }
                object a, b;
                a = stack.Pop();
                if (!(a is int))
                {
                    var code = new Stack();
                    code.Push(a);
                    code.Push(new Symbol("add"));
                    stack.Push(new Continuation(code));
                    return(stack);
                }
                b = stack.Pop();
                if (!(b is int))
                {
                    var code = new Stack();
                    code.Push(b);
                    code.Push(new Symbol("add"));
                    stack.Push(a);
                    stack.Push(new Continuation(code));
                    return(stack);
                }
                stack.Push((int)a + (int)b);
                return(stack);
            });
        }