QuestionQuestion

For this assignment, you will implement several new features and unit tests for JBefunge, creating the next generation of Befunge programming - Befunge++.

These features will include the commands 'i' (increment counter), 'd' (decrement counter), 't' (take value from counter), 'r' (reverse stack), and '(' and ')' (comment / end comment).

Specific requirements for this program are in the requirements.md file in this directory.

Sample output is also provided for several runs of the program.

Unlike the manual testing test plan, you do not need to map your unit tests to the requirements.

You should use some exploratory testing to ensure that the system meets all of the requirements, but the focus in this deliverable is to use unit testing to test the methods you have added.

Solution PreviewSolution Preview

These solutions may offer step-by-step problem-solving explanations or good writing examples that include modern styles of formatting and construction of bibliographies out of text citations and references. Students may use these solutions for personal skill-building and practice. Unethical use is strictly forbidden.

package com.laboon;

import java.util.*;

/**
* This class handles all actual execution of the program.
* Note that it is _extremely_ stateful - methods will modify the
* ProgramStack _ps and ProgramArea _pa, but will seldom return
* values. This adds a challenge to testing and may make doubling
* or mocking difficult!
*/

// Befunge Commands:
// +   Addition: Pop two values a and b, then push the result of a+b
// -   Subtraction: Pop two values a and b, then push the result of b-a
// *   Multiplication: Pop two values a and b, then push the result of a*b
// /   Integer division: Pop two values a and b, then push the result of b/a, rounded down. According to the specifications, if a is zero, ask the user what result they want.
// %   Modulo: Pop two values a and b, then push the remainder of the integer division of b/a.
// !   Logical NOT: Pop a value. If the value is zero, push 1; otherwise, push zero.
// `   Greater than: Pop two values a and b, then push 1 if b>a, otherwise zero.
// >   PC direction right
// <   PC direction left
// ^   PC direction up
// v   PC direction down
// ?   Random PC direction
// _   Horizontal IF: pop a value; set direction to right if value=0, set to left otherwise
// |   Vertical IF: pop a value; set direction to down if value=0, set to up otherwise
// "   Toggle stringmode (push each character's ASCII value all the way up to the next ")
// :   Duplicate top stack value
// \   Swap top stack values
// $   Pop (remove) top stack value and discard
// .   Pop top of stack and output as integer
// ,   Pop top of stack and output as ASCII character
// #   Bridge: jump over next command in the current direction of the current PC
// g   A "get" call (a way to retrieve data in storage). Pop two values y and x, then push the ASCII value of the character at that position in the program. If (x,y) is out of bounds, push 0
// p   A "put" call (a way to store a value for later use). Pop three values y, x and v, then change the character at the position (x,y) in the program to the character with ASCII value v
// &   Get integer from user and push it
// ~   Get character from user and push it
// @   End program
// 0 – 9   Push corresponding number onto the stack

public class ProgramExecutor {

// Random number generator. Used solely for the '?' opcode.
// Static because we don't really need a new RNG for each program
// Also, no worries about thread safety since program execution is
// single-threaded
public static Random _r = new Random();

// A reference to the MainPanel, which will allow us to update
// the stack and output areas.
private MainPanel _mp;

// True if program has completed execution; false otherwise.
private boolean _programComplete = false;

// A reference to a ProgramArea (i.e., the array with the code in it)
public ProgramArea _pa;

// The ProgramStack for this program.
public ProgramStack _ps;

// The current direction of the PC. It starts moving right but
// can be modified by the '<', '>', '^' and 'v' opcodes.
public Direction _d = Direction.RIGHT;

// The current (x, y) location of the PC.
private int _x = 0;
private int _y = 0;

// True if anything to update on text area, false otherwise
private boolean _updateTa = false;

// True if anything to update on stack area, false otherwise
private boolean _updateStack = false;

// True if anything to update on output area, false otherwise
private boolean _updateOutput = false;

// Whether or not we are currently reading the input in as a string.
// The opcode '"' puts us into string mode when first encountered, and
// will exit that mode when a second '"' opcode is encountered.
public boolean _inStringMode = false;

private static int counter = 0;

private static boolean comment = false;

public void executeInstruction(char c) {
   
    if (comment == true && c != ')') {
      return;
    }
   
    // If the stack is empty, and is not otherwise caught,
    // ignore the instruction
    try {
      // Default variables, re-used throughout the big switch..case
      int a = 0;
      int b = 0;
      int x = 0;
      int y = 0;
      
      // Uncomment for debugging info
      // System.out.println("String mode?" + _inStringMode);
      
      // If we are in string mode, read in char as the int version
      // of its ASCII value.
      
      if (_inStringMode) {
       if (c == '"') {
          // Uncomment for debugging info
          // System.out.println("Leaving string mode...");
          // Leave string mode
          _inStringMode = false;
       } else {
          // Get int version of character, put it on the stack
          int intC = (int) c;
          _ps.push(intC);
       }
       return;
      }
      
      // If not in string entry mode, we are executing instructions
      
      switch (c) {
      
       case 'i':
          counter++;
          break;
         
       case 'd':
          counter--;
          break;
         
       case 't':
          _ps.push(counter);
          break;
         
       case 'r':
          _ps.reverse();
          break;
         
       case '(':
          comment = true;
          break;
         
       case ')':
          comment = false;
          break;
      
       // (space) - ignore
       case ' ':
          // DO NOTHING, KEEP MOVING
          break;
         
          // +   Addition: Pop two values a and b, then push the result of a+b
       case '+':
          add();
          break;
         
          // -   Subtraction: Pop two values a and b, then push the result of b-a   
       case '-':
          subtract();
          break;
         
          // *   Multiplication: Pop two values a and b, then push the result of a*b
       case '*':
          multiply();
          break;
         
          // /   Integer division: Pop two values a and b, then push the result of b/a, rounded down. According to the specifications, if a is zero, ask the user what result they want.
       case '/':
          divide();
          break;
         
          // %   Modulo: Pop two values a and b, then push the remainder of the integer division of b/a.
       case '%':
          modulo();
          break;
         
          // !   Logical NOT: Pop a value. If the value is zero, push 1; otherwise, push zero.
       case '!':
          not();
          break;
         
          // `   Greater than: Pop two values a and b, then push 1 if b>a, otherwise zero.
       case '`':
          greaterThan();
          break;
         
          // >   PC direction right
       case '>':
          _d = Direction.RIGHT;
          break;
         
          // <   PC direction left
       case '<':
          _d = Direction.LEFT;
          break;
         
          // ^   PC direction up
       case '^':
          _d = Direction.UP;
          break;
         
          // v   PC direction down
       case 'v':
          _d = Direction.DOWN;
          break;
         
          // ?   Random PC direction
       case '?':
          randomDir();
          break;
         
          // _   Horizontal IF: pop a value; set direction to right if value=0, set to left otherwise
       case '_':
          horizontalIf();
          break;
         
          // |   Vertical IF: pop a value; set direction to down if value=0, set to up otherwise
       case '|':
          verticalIf();
          break;
         
          // "   Toggle stringmode (push each character's ASCII value all the way up to the next ")
       case '"':
          _inStringMode = true;
          break;
         
          // :   Duplicate top stack value
          case ':':
            duplicate();
            break;
            
            // \   Swap top stack values
       case '\\':
          swap();
          break;
         
          // $   Pop (remove) top stack value and discard
       case '$':
          pop();
          break;
         
          // .   Pop top of stack and output as integer
       case '.':
          printInt();
          break;
         
          // ,   Pop top of stack and output as ASCII character
       case ',':
          printChar();
          break;
         
          // #   Bridge: jump over next command in the current direction of the current PC
       case '#':
          // Move but don't execute
          moveOneSpace();
          break;
         
          // g   A "get" call (a way to retrieve data in storage). Pop two values y and x, then push the ASCII value of the character at that position in the program. If (x,y) is out of bounds, push 0
       case 'g':
          get();
          break;
         
          // p   A "put" call (a way to store a value for later use). Pop three values y, x and v, then change the character at the position (x,y) in the program to the character with ASCII value v
       case 'p':
          put();
          break;
         
          // &   Get integer from user and push it
       case '&':
          getInt();
          break;
         
          // ~   Get character from user and push it
       case '~':
          getChar();
          break;
         
          // @   End program
       case '@':
          _programComplete = true;
          counter = 0;
          break;
          // 0 – 9   Push corresponding number onto the stack
       case '0':
       case '1':
       case '2':
       case '3':
       case '4':
       case '5':
       case '6':
       case '7':
       case '8':
       case '9':
          int intC = Character.g...

By purchasing this solution you'll be able to access the following files:
JBefunge.zip, ProgramModificationsTest.java, JBefungeOUTPUT1.png, JBefungeOUTPUT2.png, JBefungeOUTPUT3.png, JBefungeOUTPUT4.png and JBefungeOUTPUT5.png.

$60.00
for this solution

or FREE if you
register a new account!

PayPal, G Pay, ApplePay, Amazon Pay, and all major credit cards accepted.

Find A Tutor

View available Java Programming Tutors

Get College Homework Help.

Are you sure you don't want to upload any files?

Fast tutor response requires as much info as possible.

Decision:
Upload a file
Continue without uploading

SUBMIT YOUR HOMEWORK
We couldn't find that subject.
Please select the best match from the list below.

We'll send you an email right away. If it's not in your inbox, check your spam folder.

  • 1
  • 2
  • 3
Live Chats