Package com.mdraco.calculator.data

Source Code of com.mdraco.calculator.data.SimpleCalculator

package com.mdraco.calculator.data;

import com.mdraco.calculator.Operation;

import java.util.Stack;

/**
* Simple calculator that can parse input and calculate output.
* Works only on integers.
* User: mateusz
* Date: 14.04.2013
* Time: 10:14
* Created with IntelliJ IDEA.
*/
public class SimpleCalculator {
  private final Stack<Operation> operations;
  private final Stack<Integer> values;
  private SimpleCalculator subCalculator;

  /**
   * Clean constructor. Does nothing and waits for operations and values.
   */
  public SimpleCalculator() {
    this.operations = new Stack<Operation>();
    this.values = new Stack<Integer>();
  }

  /**
   * Constructor that parses input string.
   * @param s string that will be parsed
   */
  public SimpleCalculator(String s) {
    this();
    parseString(s);
  }

  /**
   * Adds a value to constructor.
   * @param value new value
   */
  public void add(int value) {
    if (subCalculator != null)
      subCalculator.add(value);
    else {
      if (!operations.isEmpty() && operations.peek() == Operation.Subtract) {
        operations.pop();
        value *= -1;

        if (!operations.isEmpty() || !values.isEmpty()) {
          operations.push(Operation.Add);
        }
      }
      values.push(value);
    }
  }

  /**
   * Adds new operation.
   * @param operation new operation
   */
  public void add(Operation operation) {
    if (operation == Operation.BlockEnd) {
      if (subCalculator == null)
        throw new UnsupportedOperationException("missing opening bracket");
      if (subCalculator.subCalculator != null)
        subCalculator.add(operation);
      else {
        int val = subCalculator.calculate();
        subCalculator = null;
        add(val);
      }
    }
    else if (subCalculator != null) {
      subCalculator.add(operation);
    }
    else if (operation == Operation.BlockBegin)
      this.subCalculator = new SimpleCalculator();
    else
    {
      while (!this.operations.isEmpty() && this.operations.peek().getSignificance() > operation.getSignificance())
      {
        add(this.operations.pop().calculate(this.values.pop(), this.values.pop()));
      }
      this.operations.push(operation);
    }
  }

  /**
   * Calculates result.
   * @return integer result
   * @throws UnsupportedOperationException when there is wrong number of operations or any other problem application throws exception
   */
  public int calculate() throws UnsupportedOperationException {
    if (subCalculator != null)
      throw new UnsupportedOperationException("missing closing bracket");

    int result = 0;
    if (!values.isEmpty()) {
      result = values.pop();
      while (!values.isEmpty()) {
        if (operations.isEmpty())
          throw new UnsupportedOperationException("missing operation");
        if (values.isEmpty())
          throw new UnsupportedOperationException("missing value");

        Operation operation = operations.pop();
        result = operation.calculate(values.pop(), result);
      }
    }
    if (!operations.isEmpty())
      throw new UnsupportedOperationException("wrong number of arguments");
    return result;
  }

  /**
   * Clears all the input, parse string and add any number or operator found in input string.
   * @param text proper input string
   * @return self
   */
  public SimpleCalculator parseString(String text)
  {
    clear();

    String current = "";
    for (Character c : text.toCharArray())
    {
      if (Character.isWhitespace(c))
        continue;

      if (Character.isDigit(c))
      {
        current += c;
      }
      else
      {
        if (!current.isEmpty())
        {
          add(Integer.parseInt(current, 10));
          current = "";
        }
        add(Operation.parseChar(c));
      }
    }
    if (!current.isEmpty())
      add(Integer.parseInt(current, 10));

    return this;
  }

  /**
   * Clear all input.
   */
  public void clear() {
    this.operations.clear();
    this.values.clear();
  }

}
TOP

Related Classes of com.mdraco.calculator.data.SimpleCalculator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.