public override void LoadInstructions()
 {
     base.LoadInstructions();
     instructions["!"]
         = new ReorderWrapper("!",
                              StrictInstruction.factory.Binary((Stack stack, Symbol s, object x) => {
         AddInstruction(s.name, new DeferInstruction(s.name, Type.EmptyTypes, new Type[] { x.GetType() }));
         var code = new Stack();
         code.Push(new Symbol("!"));
         code.Push(x);
         code.Push(s);
         stack.Push(new Defer(code, typeof(void)));
     }));
     // How do I let one instruction go through?
     // Damn, the reorder is more complicated than the thing in itself.
     // instructions["pop"] = new InstructionFunc(stack => {
     //     if (stack.Any()) {
     //       var o = stack.Pop();
     //       var t = typeof(void);
     //       var s = new Stack();
     //       s.Push(new Symbol("pop"));
     //       s.Push(o);
     //       stack.Push(new Defer(s, t));
     //     }
     //   });
 }
        public void TestPolymorphicReorder()
        {
            interpreter = reorderInterpreter;
            var factory   = ReorderWrapper.GetFactory(StrictInstruction.factory);
            var addInt    = factory.Binary((int a, int b) => a + b);
            var addFloat  = factory.Binary((float a, float b) => a + b);
            var addString = factory.Binary((string a, string b) => a + b);

            var addPoly
                = new PolymorphicInstruction(new [] { addInt, addFloat, addString })
                {
                tryBestFit = true
                };

            interpreter.AddInstruction("+", addPoly);
            Assert.Equal("[[] 1.1 5]", Run("[[3 1.1 2 +]]"));
            Assert.Equal("[[] 1.1 2]", Run("[[1.1 2 +]]"));
            Assert.Equal(@"[[] 2 1.1 ""hi there""]", Run(@"[[""hi "" 1.1 2 ""there"" +]]"));
            Assert.Equal(@"[[] sym 2 1.1 ""hi there""]", Run(@"[[""hi "" 1.1 2 ""there"" sym +]]"));
        }
 public NonstrictInterpreter()
 {
     this.instructionFactory
              = ReorderWrapper.GetFactory(StrictInstruction.factory);
     isStrict = false;
 }