Overclock.net banner

1 - 6 of 6 Posts

·
Registered
Joined
·
649 Posts
Discussion Starter · #1 ·
Hi, this is a little stack machine program I wrote.
The only thing I can't get to work is if there is no 'HLT' command at the end of the data file supplied to the program, it's supposed to print out "[warning - no HLT instruction]". The problem is, it ALWAYS prints that out because I can't get my executeCurrentInstruction to change the boolean variable in main from false to true. This also causes problems with the while loop in my main().

TL;DR: How change boolean in main() from false to true from within a sub method in the same class?

Thank you! And any criticism on my code is welcome, I'm new at this


EDIT: I'm not sure, but it might be helpful if I actually included my code.

Code:
Code:
import java.io.*;
import java.lang.*;
import java.util.*;

public class Proj36527 {

  public static void main(String[] args) {

    boolean halt = false;

    if (args.length < 1) {
      System.out.println("Error: Must supply an argument.");
      System.exit(1);
    }

    File instructionsFile = new File(args[0]);

    //Header output
    System.out.println("Expression Stack Machine - A. McKibben");
    System.out.println("File: " + instructionsFile);
      System.out.println();

    //Creates a new stack
    Stack<Integer> stackMachine = new Stack<Integer>();

    //Attempts to read and execute instructions from file supplied at command line
    try{
      Scanner instructionScan = new Scanner(instructionsFile);

      while (instructionScan.hasNextLine() && (halt != true)) {
        String [] currentLine = new String[0];
          currentLine = splitCurrentLine(instructionScan, currentLine);
        String currentInstruction = new String();
          currentInstruction = getThisInstruction(instructionScan, currentLine, currentInstruction);
        executeCurrentInstruction(currentInstruction, halt, stackMachine, instructionScan, currentLine);
        }        
      } catch (Exception e) {
        e.printStackTrace();
      }

    if (halt == false) {
      System.out.println("[warning - no HLT instruction]");    
    }
  }

  //Splits the current line
  private static String[] splitCurrentLine(Scanner instructionScan, String[] currentLine) {
    currentLine = instructionScan.nextLine().toUpperCase().split(" ");
    return currentLine;
  }

  //Returns the current instruction
  private static String getThisInstruction(Scanner instructionScan, String[] currentLine, String currentInstruction) {
    currentInstruction = currentLine[0];
    return currentInstruction;
  }

  //Executes current Instruction
  private static void executeCurrentInstruction(String currentInstruction, boolean halt, Stack<Integer> stackMachine, Scanner instructionScan, String[] currentLine) {

    int topOfStack = 0;
    int nextToTop = 0;
    switch (currentInstruction) {
      case "CLR": stackMachine.clear();
                  break;
      case "HLT": halt = true;
                  System.out.println("[machine halted]");
                  //System.exit(1);
                  break;
      case "NEG": topOfStack = stackMachine.pop();
                  topOfStack = (topOfStack * -1);
                  stackMachine.push(topOfStack);
                  break;
      case "ADD": topOfStack = stackMachine.pop();
                  nextToTop = stackMachine.pop();
                  int sum = (topOfStack + nextToTop);
                  stackMachine.push(sum);
                  break;
      case "SUB": topOfStack = stackMachine.pop();
                  nextToTop = stackMachine.pop();
                  int difference = (nextToTop - topOfStack);
                  stackMachine.push(difference);
                  break;
      case "MUL": topOfStack = stackMachine.pop();
                  nextToTop = stackMachine.pop();
                  int product = (nextToTop * topOfStack);
                  stackMachine.push(product);
                  break;
      case "DIV": topOfStack = stackMachine.pop();
                  nextToTop = stackMachine.pop();
                  if (topOfStack == 0) {
                    System.out.println("error - division by zero");
                    System.exit(1);
                  }
                  int quotient = (nextToTop/topOfStack);
                  stackMachine.push(quotient);
                  break;
      case "LDC": int constantToLoad = 0;
                  try {
                    constantToLoad = Integer.parseInt(currentLine[1]);
                  } catch (NumberFormatException n) {
                    System.out.println("[warning - illegal command '" + currentLine[0] + " " + currentLine[1] + "' ignored]");
                  }
                  stackMachine.push(constantToLoad);
                  break;
      case "INP": System.out.print("input: ");
                  Scanner kbd = new Scanner(System.in);
                  int kbdInput = 0;
                  try {
                    kbdInput = kbd.nextInt();
                  } catch (InputMismatchException i) {
                    System.out.println("[warning - illegal input ignored]");
                  }
                  stackMachine.push(kbdInput);
                  break;
      case "OUT": topOfStack = stackMachine.pop();
                  System.out.println("output: " + topOfStack);
                  System.out.println();
                  break;
      case "NLN": System.out.println();
                  break;
      case "DBG": System.out.println("DEBUG: " + stackMachine + " (top)");
                  break;
      default:    System.out.println("[warning - no legal commands]");
                  break;
    }
  }
}
 

·
Registered
Joined
·
817 Posts
try having executeCurrentInstruction return halt. i made a few changes to your code to try to show you what i mean. changes are in red obviously.

Code:

Code:
import java.io.*;
import java.lang.*;
import java.util.*;

public class Proj36527 {

  public static void main(String[] args) {

    boolean halt = false;

    if (args.length < 1) {
      System.out.println("Error: Must supply an argument.");
      System.exit(1);
    }

    File instructionsFile = new File(args[0]);

    //Header output
    System.out.println("Expression Stack Machine - A. McKibben");
    System.out.println("File: " + instructionsFile);
      System.out.println();

    //Creates a new stack
    Stack<Integer> stackMachine = new Stack<Integer>();

    //Attempts to read and execute instructions from file supplied at command line
    try{
      Scanner instructionScan = new Scanner(instructionsFile);

      while (instructionScan.hasNextLine() && (halt != true)) {
        String [] currentLine = new String[0];
          currentLine = splitCurrentLine(instructionScan, currentLine);
        String currentInstruction = new String();
          currentInstruction = getThisInstruction(instructionScan, currentLine, currentInstruction);
        [B]halt = [/B]executeCurrentInstruction(currentInstruction, halt, stackMachine, instructionScan, currentLine);
        }        
      } catch (Exception e) {
        e.printStackTrace();
      }

    if (halt == false) {
      System.out.println("[warning - no HLT instruction]");    
    }
  }

  //Splits the current line
  private static String[] splitCurrentLine(Scanner instructionScan, String[] currentLine) {
    currentLine = instructionScan.nextLine().toUpperCase().split(" ");
    return currentLine;
  }

  //Returns the current instruction
  private static String getThisInstruction(Scanner instructionScan, String[] currentLine, String currentInstruction) {
    currentInstruction = currentLine[0];
    return currentInstruction;
  }

  //Executes current Instruction
  private static [B]boolean[/B] executeCurrentInstruction(String currentInstruction, boolean halt, Stack<Integer> stackMachine, Scanner instructionScan, String[] currentLine) {

    int topOfStack = 0;
    int nextToTop = 0;
    switch (currentInstruction) {
      case "CLR": stackMachine.clear();
                  break;
      case "HLT": halt = true;
                  System.out.println("[machine halted]");
                 [B] return halt;[/B]
                  //System.exit(1);
                  break;
      case "NEG": topOfStack = stackMachine.pop();
                  topOfStack = (topOfStack * -1);
                  stackMachine.push(topOfStack);
                  break;
      case "ADD": topOfStack = stackMachine.pop();
                  nextToTop = stackMachine.pop();
                  int sum = (topOfStack + nextToTop);
                  stackMachine.push(sum);
                  break;
      case "SUB": topOfStack = stackMachine.pop();
                  nextToTop = stackMachine.pop();
                  int difference = (nextToTop - topOfStack);
                  stackMachine.push(difference);
                  break;
      case "MUL": topOfStack = stackMachine.pop();
                  nextToTop = stackMachine.pop();
                  int product = (nextToTop * topOfStack);
                  stackMachine.push(product);
                  break;
      case "DIV": topOfStack = stackMachine.pop();
                  nextToTop = stackMachine.pop();
                  if (topOfStack == 0) {
                    System.out.println("error - division by zero");
                    System.exit(1);
                  }
                  int quotient = (nextToTop/topOfStack);
                  stackMachine.push(quotient);
                  break;
      case "LDC": int constantToLoad = 0;
                  try {
                    constantToLoad = Integer.parseInt(currentLine[1]);
                  } catch (NumberFormatException n) {
                    System.out.println("[warning - illegal command '" + currentLine[0] + " " + currentLine[1] + "' ignored]");
                  }
                  stackMachine.push(constantToLoad);
                  break;
      case "INP": System.out.print("input: ");
                  Scanner kbd = new Scanner(System.in);
                  int kbdInput = 0;
                  try {
                    kbdInput = kbd.nextInt();
                  } catch (InputMismatchException i) {
                    System.out.println("[warning - illegal input ignored]");
                  }
                  stackMachine.push(kbdInput);
                  break;
      case "OUT": topOfStack = stackMachine.pop();
                  System.out.println("output: " + topOfStack);
                  System.out.println();
                  break;
      case "NLN": System.out.println();
                  break;
      case "DBG": System.out.println("DEBUG: " + stackMachine + " (top)");
                  break;
      default:    System.out.println("[warning - no legal commands]");
                 [B] return false;[/B]
                  break;
    }
  }
}
 

·
Registered
Joined
·
649 Posts
Discussion Starter · #3 ·
Quote:


Originally Posted by travesty
View Post

try having executeCurrentInstruction return halt. i made a few changes to your code to try to show you what i mean. changes are in red obviously.

Code:
Code:
import java.io.*;
import java.lang.*;
import java.util.*;

public class Proj36527 {

  public static void main(String[] args) {

    boolean halt = false;

    if (args.length < 1) {
      System.out.println("Error: Must supply an argument.");
      System.exit(1);
    }

    File instructionsFile = new File(args[0]);

    //Header output
    System.out.println("Expression Stack Machine - A. McKibben");
    System.out.println("File: " + instructionsFile);
      System.out.println();

    //Creates a new stack
    Stack<Integer> stackMachine = new Stack<Integer>();

    //Attempts to read and execute instructions from file supplied at command line
    try{
      Scanner instructionScan = new Scanner(instructionsFile);

      while (instructionScan.hasNextLine() && (halt != true)) {
        String [] currentLine = new String[0];
          currentLine = splitCurrentLine(instructionScan, currentLine);
        String currentInstruction = new String();
          currentInstruction = getThisInstruction(instructionScan, currentLine, currentInstruction);
        [B]halt = [/B]executeCurrentInstruction(currentInstruction, halt, stackMachine, instructionScan, currentLine);
        }        
      } catch (Exception e) {
        e.printStackTrace();
      }

    if (halt == false) {
      System.out.println("[warning - no HLT instruction]");    
    }
  }

  //Splits the current line
  private static String[] splitCurrentLine(Scanner instructionScan, String[] currentLine) {
    currentLine = instructionScan.nextLine().toUpperCase().split(" ");
    return currentLine;
  }

  //Returns the current instruction
  private static String getThisInstruction(Scanner instructionScan, String[] currentLine, String currentInstruction) {
    currentInstruction = currentLine[0];
    return currentInstruction;
  }

  //Executes current Instruction
  private static [B]boolean[/B] executeCurrentInstruction(String currentInstruction, boolean halt, Stack<Integer> stackMachine, Scanner instructionScan, String[] currentLine) {

    int topOfStack = 0;
    int nextToTop = 0;
    switch (currentInstruction) {
      case "CLR": stackMachine.clear();
                  break;
      case "HLT": halt = true;
                  System.out.println("[machine halted]");
                 [B] return halt;[/B]
                  //System.exit(1);
                  break;
      case "NEG": topOfStack = stackMachine.pop();
                  topOfStack = (topOfStack * -1);
                  stackMachine.push(topOfStack);
                  break;
      case "ADD": topOfStack = stackMachine.pop();
                  nextToTop = stackMachine.pop();
                  int sum = (topOfStack + nextToTop);
                  stackMachine.push(sum);
                  break;
      case "SUB": topOfStack = stackMachine.pop();
                  nextToTop = stackMachine.pop();
                  int difference = (nextToTop - topOfStack);
                  stackMachine.push(difference);
                  break;
      case "MUL": topOfStack = stackMachine.pop();
                  nextToTop = stackMachine.pop();
                  int product = (nextToTop * topOfStack);
                  stackMachine.push(product);
                  break;
      case "DIV": topOfStack = stackMachine.pop();
                  nextToTop = stackMachine.pop();
                  if (topOfStack == 0) {
                    System.out.println("error - division by zero");
                    System.exit(1);
                  }
                  int quotient = (nextToTop/topOfStack);
                  stackMachine.push(quotient);
                  break;
      case "LDC": int constantToLoad = 0;
                  try {
                    constantToLoad = Integer.parseInt(currentLine[1]);
                  } catch (NumberFormatException n) {
                    System.out.println("[warning - illegal command '" + currentLine[0] + " " + currentLine[1] + "' ignored]");
                  }
                  stackMachine.push(constantToLoad);
                  break;
      case "INP": System.out.print("input: ");
                  Scanner kbd = new Scanner(System.in);
                  int kbdInput = 0;
                  try {
                    kbdInput = kbd.nextInt();
                  } catch (InputMismatchException i) {
                    System.out.println("[warning - illegal input ignored]");
                  }
                  stackMachine.push(kbdInput);
                  break;
      case "OUT": topOfStack = stackMachine.pop();
                  System.out.println("output: " + topOfStack);
                  System.out.println();
                  break;
      case "NLN": System.out.println();
                  break;
      case "DBG": System.out.println("DEBUG: " + stackMachine + " (top)");
                  break;
      default:    System.out.println("[warning - no legal commands]");
                 [B] return false;[/B]
                  break;
    }
  }
}
That didn't work, but it got me thinking of some other things. I'll report back later. Thanks!

EDIT: Nevermind, that actually did work. Thanks! Feels like a hack though, I'm going to try to think of a more logical way to write it... eventually. This will do for now
 

·
Registered
Joined
·
239 Posts
I'm not going to look through your code in detail but rather suggest that you use far more methods and think about what each method is for. Put less in the main method and don't create one giant execute method with a switch-case in it.

Your main method should generally construct and execute an instance of your class, and you should be OO from there.

In your original code, halt is a local variable inside main, and that just makes no sense. This architecture is why it doesn't "feel" right.

What would probably be better is having a StackMachine as its own class, constructing it in main, passing it a sequence of instructions and having methods inside it such as StackMachine.halt(); Even if your execute function is just
case "HLT": this.halt(); break;
and all halt() does is set a protected boolean member that's checked by execute.
 

·
Premium Member
Joined
·
1,563 Posts
I'm learning JAVA and OOP but as far as I know, you should declare the variable 'halt' outside of the main method (just inside the class). When you declare it inside main, it becomes a local variable and I'm not sure if you want if you want to access it from another method.
 

·
Registered
Joined
·
817 Posts
Quote:
Originally Posted by {Unregistered};15316304
I'm learning JAVA and OOP but as far as I know, you should declare the variable 'halt' outside of the main method (just inside the class). When you declare it inside main, it becomes a local variable and I'm not sure if you want if you want to access it from another method.
if he made halt a class variable, he'd still have to initialize it somewhere. since only main and executeCurrentInstruction use halt, imo its better to just pass halt as a parameter and return value.
 
1 - 6 of 6 Posts
Top