/* * CalculatorState Class * * Developed for "Rethinking CS101", a project of Lynn Andrea Stein's AP Group. * For more information, see the * CS101 homepage or email . * * Copyright (C) 1997 Massachusetts Institute of Technology. * Please do not redistribute without obtaining permission. */ package Calculator; /** * This class holds most of the state information for a Calculator. * Every ButtonHandler should have exactly one. When it is created, * the Calculator's state is "reset": it hasn't seen any numbers, * operations, etc. (It would actually be reasonable for it to have * seen a 0, but this isn't implemented.) It records such things as: * * * @author: Lynn Andrea Stein, las@ai.mit.edu * @author: Luis F. G. Sarmenta, lfgs@mit.edu * @version: $$ * * @see Calculator, ButtonHandler */ public class CalculatorState { /** * When an operation button is pressed, it can't be executed * immediately because its second operand hasn't been supplied. * pendingOperation remembers the operation so that it can be * invoked later (e.g., when an = or other operand button is * pressed).

* Initially, pendingOperation is NOOP, but whenever we see an * operation button, we remember it here. */ private OpButtonObj pendingOperation = OpButtonObj.NO_OP_BUTTON_OBJ; /** * Since operations have to be deferred until their second * operands are read, something has to remember the first operand * (the number that was entered before the operator was pressed). * That's previousOperand's job.

* Initially, there isn't a previousOperand, so it's 0. Whenever * an operation button is pressed, we'll remember the partial * result (or typed-in number) here. */ private double previousOperand = 0; /** * The boolean valued readingNumber is true if we've seen a digit * and are in the process of figuring out what other digits/dots we * might get. Initially, it's false because we haven't seen our * first digit yet. It turns true whenever we see a digit and * false when we see anything else (except dot). */ private boolean readingNumber = false, /** * The boolean seenDot is true if we have seen a decimal place in * this number and false otherwise. (One decimal place per number; * subsequent dots are ignored.) It should be set true whenever we * see the dot and set false whenever we start reading a new number. */ seenDot = false; /* IMPLICIT NO-ARGS CONSTRUCTOR */ /** * Restores the CalculatorState to its pristine start state. *

* Aesthetic note: this should really be called by the * constructor instead of initializing each field separately. * That way, "default" is defined in a single place. */ public void reset() { this.pendingOperation = OpButtonObj.NO_OP_BUTTON_OBJ; this.previousOperand = 0; this.readingNumber = false; this.seenDot = false; } /** * Should be called whenever a first digit is seen. Updates * state to start composing numbers and a (single) decimal point. */ public void startReadingNumber() { this.readingNumber = true; this.seenDot = false; } /** * Should be called whenever a non-digit (non-dot) is seen. * Updates state to reflect that number is done, i.e., new digit * starts new number. */ public void doneReadingNumber() { readingNumber = false; } /** * A test to see if state is in middle of reading number. * * @returns false if called when in middle of reading number, true * otherwise. */ public boolean notReadingNumber() { return ( ! this.readingNumber ); } /** * A test to see if we've seen a decimal place in the number we're * currently reading. * * @returns true if called after a decimal place has been seen in * this number, false if number is integral. */ public boolean noDotYet() { return !this.seenDot; } /** * Should be called when a dot is seen. Modifies state to * indicate that a decimal place has already been seen in this number. */ public void justSawDot() { this.seenDot = true; } /** * Should be called whenever an operation is seen. Records that * operation for future use (after second operand is seen).

* * @param currOp the operation button seen. */ public void setPendingOperation( OpButtonObj currOp ) { this.pendingOperation = currOp; } /** * Should be called when no operations are pending, e.g., after = * or reset. Makes pendingOperation NOOP.

* This should be the sole place that this default is set, so * really reset() should call this method. That way, if we ever * want to change the Calculator's default state, this is the one * place we'd have to make the change. */ public void resetPendingOperation() { this.pendingOperation = OpButtonObj.NO_OP_BUTTON_OBJ; } /** * Accessor ("getter") method for pending operation. * * @returns the currently pending operation (waiting to be done). */ public OpButtonObj getPendingOperation() { return this.pendingOperation; } /** * Mutator ("setter") method for previous operand. Remembers this * operand until after the operation, second operand are available * and the result can be computed. * * @param num the operand to remember. */ public void setPreviousOperand( double num ) { this.previousOperand = num; } /** * Accessor ("getter") method for previous operand. * * @returns the remembered left-hand operand (waiting to be * operated upon). */ public double getPreviousOperand() { return this.previousOperand; } } /* * Comments about possible revision: * [resetPendingOperation should be called by reset(), or it should be * eliminated.] * [doneReadingNumber could sensibly handle recording of * previousOperand, too.] * [setPendingOperation might sensibly calculate result of previous * pending operation, too.] * [reset should call gui clearScreen, which means that probably CalcTextGUI * should be part of this class.] * * $Log: CalculatorState.java,v $ * Revision 1.1.1.1 2002/06/05 21:56:25 root * CS101 comes to Olin finally. * * Revision 1.2 1997/10/24 22:20:41 las * Documented all of the code files, but didn't write the user manual (yet). * */