public Stack Apply(Stack s) { if (innerInstruction == null) { throw new Exception("NYI"); } else { return(innerInstruction.Apply(s)); } }
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()); }
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); }
/// <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); } } }