public FungeEngine() { this.fundgeSpace = new FungeSpace(); this.stackStack = new StackStack(); this.instructionPointer = new FungeSpacePointer(); this.instructionPointerDirection = new FungeSpaceDirection(1, 0); this.randomizer = new Random(); }
public bool Step() { Dump(); try { byte instruction = FundgeSpace.Cells[InstructionPointer]; bool programExecuting = true; bool move = true; int a, b, c; switch (ConversionUtils.ToChar(instruction)) { case ' ': break; case '!': // Logical Not b = StackStack.Pop(); if (b == 0) StackStack.Push(1); else StackStack.Push(0); break; case '\"': // Toggle Stringmode ReadString(); break; case '#': // Trampoline MoveOnePosition(); break; case '$': // Pop StackStack.Pop(); break; case '%': b = StackStack.Pop(); a = StackStack.Pop(); c = Reminder(a, b); StackStack.Push(c); break; case '&': a = ReadInteger(); StackStack.Push(a); break; case '*': b = StackStack.Pop(); a = StackStack.Pop(); c = a * b; StackStack.Push(c); break; case '+': b = StackStack.Pop(); a = StackStack.Pop(); c = a + b; StackStack.Push(c); break; case ',': c = StackStack.Pop(); WriteChar(c); break; case '-': b = StackStack.Pop(); a = StackStack.Pop(); c = a - b; StackStack.Push(c); break; case '.': a = StackStack.Pop(); WriteInt(a); break; case '/': b = StackStack.Pop(); a = StackStack.Pop(); c = Divide(a, b); StackStack.Push(c); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': a = instruction - '0'; StackStack.Push(a); break; case ':': a = StackStack.Pop(); StackStack.Push(a); StackStack.Push(a); break; case '<': instructionPointerDirection = new FungeSpaceDirection(-1, 0); break; case '>': instructionPointerDirection = new FungeSpaceDirection(+1, 0); break; case '?': b = randomizer.Next(4); switch (b) { case 0: instructionPointerDirection = new FungeSpaceDirection(+1, 0); break; case 1: instructionPointerDirection = new FungeSpaceDirection(-1, 0); break; case 2: instructionPointerDirection = new FungeSpaceDirection(0, +1); break; case 3: instructionPointerDirection = new FungeSpaceDirection(0, -1); break; } break; case '@': // halt move = false; programExecuting = false; break; case '\\': b = StackStack.Pop(); a = StackStack.Pop(); StackStack.Push(b); StackStack.Push(a); break; case '^': Ensure2D(); instructionPointerDirection = new FungeSpaceDirection(0, -1); break; case '_': b = StackStack.Pop(); instructionPointerDirection = b != 0 ? new FungeSpaceDirection(-1, 0) : new FungeSpaceDirection(+1, 0); break; case '`': b = StackStack.Pop(); a = StackStack.Pop(); c = a > b ? 1 : 0; StackStack.Push(c); break; case 'g': // get b = StackStack.Pop(); a = StackStack.Pop(); c = FundgeSpace.Cells[a, b]; StackStack.Push(c); break; case 'p': // put b = StackStack.Pop(); a = StackStack.Pop(); c = StackStack.Pop(); FundgeSpace.Cells[a, b] = (byte)c; break; case 'v': Ensure2D(); instructionPointerDirection = new FungeSpaceDirection(0, +1); break; case '|': Ensure2D(); b = StackStack.Pop(); instructionPointerDirection = b != 0 ? new FungeSpaceDirection(0, -1) : new FungeSpaceDirection(0, +1); break; case '~': c = ReadChar(); StackStack.Push(c); break; default: throw new FungeException( String.Format("Unknown instruction {0} at {1}", CurrentInstruction, InstructionPointer)); } if (move) { Skip(); } return programExecuting; } catch (FungeException) { throw; } catch (Exception ex) { throw new FungeException( String.Format("Fundge exception at {0}: {1}", InstructionPointer, ex.Message)); } }
public void Reset() { StackStack.Clear(); FundgeSpace.Clear(); this.instructionPointer = new FungeSpacePointer(); this.instructionPointerDirection = new FungeSpaceDirection(1, 0); }