public void StartExecuting(CancellationToken ct) { while (ProgramIterator < _programCode.Length) { if (ct.IsCancellationRequested) { break; } ExecuteNext(ct); } EndOfExecutionEvent?.Invoke(this, EventArgs.Empty); }
public void ExecuteNext(CancellationToken ct) { if (ProgramIterator >= _programCode.Length - 1 || ct.IsCancellationRequested) { EndOfExecutionEvent?.Invoke(this, EventArgs.Empty); return; } switch (_programCode[ProgramIterator]) { case var word when new Regex(@"Put this ([^ ]*?) pancake on top!").IsMatch(word): { var match = Regex.Match(word, @"Put this ([^ ]*?) pancake on top!"); PancakeStack.Push(match.Groups[1].Value.Length); break; } case "Eat the pancake on top!": if (CheckPancakeStackCount(1)) { PancakeStack.Pop(); } break; case "Put the top pancakes together!": { if (CheckPancakeStackCount(2)) { var firstTopItem = PancakeStack.Pop(); var secondTopItem = PancakeStack.Pop(); PancakeStack.Push(firstTopItem + secondTopItem); } break; } case "Give me a pancake!": Input = ""; while (string.IsNullOrEmpty(Input)) { if (ct.IsCancellationRequested) { break; } WaitingForInputEvent?.Invoke(this, new WaitingForInputEventArgs() { Type = InputType.Numeric }); WaitHandle.WaitOne(); } if (!ct.IsCancellationRequested) { if (CheckIfValueIsInt32(Input)) { PancakeStack.Push(Convert.ToInt32(Input)); Input = ""; } } break; case "How about a hotcake?": while (string.IsNullOrEmpty(Input)) { if (ct.IsCancellationRequested) { break; } WaitingForInputEvent?.Invoke(this, new WaitingForInputEventArgs() { Type = InputType.Alphanumeric }); WaitHandle.WaitOne(); } if (!ct.IsCancellationRequested) { PancakeStack.Push(Input[0]); Input = Input.Remove(0, 1); // imitate console buffer } break; case "Show me a pancake!": if (CheckPancakeStackCount(1)) { NewOutputEvent?.Invoke(this, new OutputEventArgs() { Type = OutputType.Character, CharacterOutput = (char)PancakeStack.Peek() }); } break; case "Take from the top pancakes!": { if (CheckPancakeStackCount(2)) { var firstTopItem = PancakeStack.Pop(); var secondTopItem = PancakeStack.Pop(); PancakeStack.Push(firstTopItem - secondTopItem); } break; } case "Flip the pancakes on top!": { if (CheckPancakeStackCount(2)) { var firstTopItem = PancakeStack.Pop(); var secondTopItem = PancakeStack.Pop(); PancakeStack.Push(firstTopItem); PancakeStack.Push(secondTopItem); } break; } case "Put another pancake on top!": { if (CheckPancakeStackCount(1)) { var topItem = PancakeStack.Pop(); PancakeStack.Push(topItem); PancakeStack.Push(topItem); } break; } case var label when new Regex(@"\[(.*)\]").IsMatch(label): { if (CheckPancakeStackCount(1)) { var match = Regex.Match(label, @"\[(.*)\]"); if (Labels.Any(item => item.Key == match.Groups[1].Value)) { break; } Labels[match.Groups[1].Value] = PancakeStack.Peek() - 2; //Pancake stack language start counting lines from 1 LabelDictionaryChangedEvent?.Invoke(this, Labels); } break; } case var label when new Regex(@"If the pancake isn't tasty, go over to ""(.*)"".").IsMatch(label): { var match = Regex.Match(label, @"If the pancake isn't tasty, go over to ""(.*)""."); if (CheckPancakeStackCount(1) && CheckIfLabelExist(match.Groups[1].Value)) { if (PancakeStack.Peek() == 0) { ProgramIterator = Labels[match.Groups[1].Value]; } } break; } case var label when new Regex(@"If the pancake is tasty, go over to ""(.*)"".").IsMatch(label): { var match = Regex.Match(label, @"If the pancake is tasty, go over to ""(.*)""."); if (CheckPancakeStackCount(1) && CheckIfLabelExist(match.Groups[1].Value)) { if (PancakeStack.Peek() != 0) { ProgramIterator = Labels[match.Groups[1].Value]; } } break; } case "Put syrup on the pancakes!": PancakeStack = new Stack <int>(PancakeStack.Select(item => item + 1).Reverse()); break; case "Put butter on the pancakes!": { if (CheckPancakeStackCount(1)) { var topItem = PancakeStack.Pop(); PancakeStack.Push(topItem + 1); } break; } case "Take off the syrup!": PancakeStack = new Stack <int>(PancakeStack.Select(item => item - 1).Reverse()); break; case "Take off the butter!": { if (CheckPancakeStackCount(1)) { var topItem = PancakeStack.Pop(); PancakeStack.Push(topItem - 1); } break; } case "Show me a numeric pancake!": if (CheckPancakeStackCount(1)) { NewOutputEvent?.Invoke(this, new OutputEventArgs() { Type = OutputType.Line, LineOutput = PancakeStack.Peek().ToString() }); } break; case "Eat all of the pancakes!": ProgramIterator = _programCode.Length; return; } PancakeStackChangedEvent?.Invoke(this, PancakeStack); ProgramIterator++; }