public Stack Apply(Stack s)
 {
     if (innerInstruction == null)
     {
         throw new Exception("NYI");
     }
     else
     {
         return(innerInstruction.Apply(s));
     }
 }
Exemple #2
0
        private static int FindLargestValue(IEnumerable <string> rawInstructions)
        {
            var registers = new Dictionary <string, int>();

            foreach (string rawInstruction in rawInstructions)
            {
                Instruction instr = CreateInstruction(rawInstruction);
                instr.Apply(registers);
            }

            return(registers.Values.Max());
        }
Exemple #3
0
        private static int FindLargestValueAtAnyTime(IEnumerable <string> rawInstructions)
        {
            var registers = new Dictionary <string, int>();
            int maxValue  = int.MinValue;

            foreach (string rawInstruction in rawInstructions)
            {
                Instruction instr    = CreateInstruction(rawInstruction);
                int         newValue = instr.Apply(registers);
                maxValue = Math.Max(newValue, maxValue);
            }

            return(maxValue);
        }
Exemple #4
0
 /// <summary>
 /// "Steps" on instruction forwards - Executes a single instruction.
 /// </summary>
 /// <param name="instruction">The instruction to execute.</param>
 public void Step(Instruction instruction)
 {
     Machine = instruction.Apply(Machine);
 }
        public virtual Stack Apply(Stack stack)
        {
            var         acceptedArguments = new Stack();
            var         binding           = new Dictionary <string, Type>();
            Instruction foundInstruction  = null;

            int[] acceptedArgumentsCount = new int[instructions.Count()];
            int   i = 0;

            foreach (var instruction in instructions)
            {
                acceptedArguments.Clear();
                binding.Clear();
                IEnumerator stackContents = stack.GetEnumerator();
                foreach (Type consume in instruction.inputTypes)
                {
                    if (!stackContents.MoveNext())
                    {
                        // Not enough elements.
                        // break;
                        if (tryBestFit)
                        {
                            return(stack);
                        }
                        else
                        {
                            throw new Exception("Not enough arguments.");
                        }
                        // goto notFound;
                        // return NotEnoughElements(stack, acceptedArguments);
                    }
                    object o           = stackContents.Current;
                    var    t           = o.GetType();
                    Type   consumeType = consume;
                    // if (t == consume) {
                    if (Variable.IsVariableType(consume))
                    {
                        // XXX What is going on here?
                        // We accept it. But we should track that it now means this type
                        // and fail it it changes.
                        var v = Variable.Instantiate(consume);
                        if (binding.TryGetValue(v.name, out Type vType))
                        {
                            consumeType = vType;
                        }
                        else
                        {
                            binding.Add(v.name, t);
                            consumeType = t;
                        }
                    }

                    if (consumeType.IsAssignableFrom(t))
                    {
                        acceptedArgumentsCount[i]++;
                        acceptedArguments.Push(o);
                    }
                    else
                    {
                        goto notFound;
                        // break;
                    }
                }
                foundInstruction = instruction;
                // break;
notFound:
                ;
                i++;
            }
            // Then run the real instruction.
            if (foundInstruction != null)
            {
                return(foundInstruction.Apply(stack));
            }
            else
            {
                if (!tryBestFit)
                {
                    throw new Exception($"Unable to find an instruction that matches the types.");
                }
                else
                {
                    var max = acceptedArgumentsCount.Max();
                    // We're going to do a little reordering of the first argument that
                    // doesn't match the max number of arguments.
                    var temp = new Stack();
                    // Capture the good arguments.
                    for (int j = 0; j < max; j++)
                    {
                        temp.Push(stack.Pop());
                    }
                    // Create a continuation for the bad argument.
                    var code = new Stack();
                    code.Push(stack.Pop());
                    code.Push(this);
                    // Push the good arguments back onto the stack.
                    while (temp.Any())
                    {
                        stack.Push(temp.Pop());
                    }
                    stack.Push(new Continuation(code));
                    return(stack);
                }
            }
        }