Skip to content
calc.html 7.46 KiB
Newer Older
<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <title>RPN calculator</title>
    <style type="text/css">
      #container {
	  display: flex;
	  flex-flow: row;
	  width: 700px;
	  margin: 10px auto;
	  border: 1px grey dotted;
      }
      #container > div {
	  border: 1px grey dotted;
      }
      #container > div > p {
	  margin-left: 10px;
      }
      #stack {
	  width: 200px;
	  height: 500px
      }
      #keyboard {
	  width: 300px;
	  height: 500px
      }
      #trail {
	  width: 200px;
	  height: 500px
      }
      #stack-content {
	  margin-left: 10px;
	  font-size: 1.2em;
      }
      #trail-content {
	  margin-left: 10px;
	  font-size: 1.2em;
      }
      .keyboard {
	  font-size: 1.2em;
	  text-align: center;
      }
      .keyboard table {
	  margin: 2px auto;
      }
      .keyboard td {
	  width: 60px;
	  height: 60px;
      }
      #number-display {
	  border: 1px grey solid;
	  width: 100%;
	  text-align: right;
      }
    </style>
  </head>

  <body>
    <div id="container">
      <div id="stack">
	<p>Stack</p>
	<div id="stack-content"></div>
      </div>
      <div id="keyboard">
	<p>Keyboard</p>
	<div class="keyboard">
	  <table>
	    <tr>
	      <td colspan="4" data-bt-name="number-display" id="number-display"></td>
	      <td data-bt-name="num7">7</td>
	      <td data-bt-name="num8">8</td>
	      <td data-bt-name="num9">9</td>
	      <td title="backspace" data-bt-name="backspace">&lt;</td>
	      <td data-bt-name="num4">4</td>
	      <td data-bt-name="num5">5</td>
	      <td data-bt-name="num6">6</td>
	      <td title="times" data-bt-name="times">*</td>
	      <td data-bt-name="num1">1</td>
	      <td data-bt-name="num2">2</td>
	      <td data-bt-name="num3">3</td>
	      <td title="minus" data-bt-name="minus">-</td>
	      <td data-bt-name="num0">0</td>
	      <td title="change sign" data-bt-name="change-sign">±</td>
	      <td title="dot" data-bt-name="dot">.</td>
	      <td title="plus" data-bt-name="plus">+</td>
	      <td title="swap" data-bt-name="swap">SWAP</td>
	      <td title="undo" data-bt-name="undo">UNDO</td>
	      <td title="divide" data-bt-name="divide">÷</td>
	      <td title="confirm or duplicate number" data-bt-name="return">RETURN</td>
	    </tr>
	  </table>
	</div>
      </div>
      <div id="trail">
	<p>Trail</p>
	<div id="trail-content"></div>
      </div>
    </div>
    <script type="text/javascript" src="vendor/jquery.min.js"></script>
    <script type="text/javascript" src="fsm.js"></script>
    <script type="text/javascript">
      (function () {
	  /**
	   * show dumb data for UI testing.
	   */
	  const showDumbData = function () {
	      $("#number-display").text('789');

	      $("#stack-content").append($('<pre>').text('3: 1'));
	      $("#stack-content").append($('<pre>').text('2: 2'));
	      $("#stack-content").append($('<pre>').text('1: 3'));
	      $("#stack-content").append($('<pre>').text('   .'));

	      $("#trail-content").append($('<pre>').text('   1'));
	      $("#trail-content").append($('<pre>').text('   2'));
	      $("#trail-content").append($('<pre>').text('>  3'));
	  };

	  const rpnTestBasic = function () {
	      const m = new fsm.RPNCalculator();
	      console.assert(m.numberStack.length === 0);
	      m.sendKey("num1");
	      m.sendKey("return");
	      m.sendKey("num2");
	      m.sendKey("return");
	      console.assert(m.numberStack.length === 2);
	      m.sendKey("plus");
	      console.assert(m.numberStack.length === 1);
	      console.assert(m.numberStack[0] === 3);
	  };
	  const rpnTestNumberHandling = function () {
	      var m = new fsm.RPNCalculator();
	      console.assert(m.numberStack.length === 0);
	      m.sendKey("num1");
	      m.sendKey("num2");
	      m.sendKey("return");
	      console.assert(m.numberStack.length === 1);
	      console.assert(m.numberStack[0] === 12);
	      console.assert(m.currentNumber === "");

	      m = new fsm.RPNCalculator();
	      console.assert(m.numberStack.length === 0);
	      m.sendKey("num0");
	      m.sendKey("dot");
	      m.sendKey("num1");
	      m.sendKey("num2");
	      m.sendKey("return");
	      console.assert(m.numberStack.length === 1);
	      console.assert(m.numberStack[0] === 0.12);
	      console.assert(m.currentNumber === "");

	      m = new fsm.RPNCalculator();
	      console.assert(m.numberStack.length === 0);
	      m.sendKey("num0");
	      m.sendKey("dot");
	      m.sendKey("num1");
	      m.sendKey("num2");
	      m.sendKey("backspace");
	      console.assert(m.currentNumber === "0.1");
	      m.sendKey("return");
	      console.assert(m.numberStack.length === 1);
	      console.assert(m.numberStack[0] === 0.1);
	      console.assert(m.currentNumber === "");
	  };
	  const rpnTestAutoCommitNumber = function () {
	      const m = new fsm.RPNCalculator();
	      console.assert(m.numberStack.length === 0);
	      m.sendKey("num1");
	      m.sendKey("return");
	      m.sendKey("num2");
	      m.sendKey("plus");
	      console.assert(m.numberStack.length === 1);
	      console.assert(m.numberStack[0] === 3);
	      console.assert(m.currentNumber === "");
	      console.assert(m.currentState === "idle");
	  };
	  const rpnTestOperator = function () {
	      const m = new fsm.RPNCalculator();
	      console.assert(m.numberStack.length === 0);
	      m.sendKey("num1");
	      m.sendKey("return");
	      m.sendKey("num2");
	      m.sendKey("return");
	      console.assert(m.numberStack.length === 2);
	      m.sendKey("minus");
	      console.assert(m.numberStack.length === 1);
	      console.assert(m.numberStack[0] === -1);
	      m.sendKey("num3");
	      m.sendKey("num0");
	      m.sendKey("return");
	      console.assert(m.numberStack.length === 2);
	      m.sendKey("plus");
	      console.assert(m.numberStack.length === 1);
	      console.assert(m.numberStack[0] === 29);
	      m.sendKey("return");    // duplicate
	      m.sendKey("plus");
	      console.assert(m.numberStack.length === 1);
	      console.assert(m.numberStack[0] === 29 * 2);
	      m.sendKey("num9");
	      m.sendKey("change-sign");
	      m.sendKey("swap");
	      console.assert(m.numberStack.length === 2);
	      console.assert(m.numberStack[0] === -9);
	      console.assert(m.numberStack[1] === 29 * 2);
	  };

	  /**
	   * run all tests.
	   */
	  const runTests = function () {
	      console.assert(fsm.matchesSubstringAbb("123abb123") === true);
	      console.assert(fsm.matchesSubstringAbb("123ab123") === false);
	      console.assert(fsm.matchesSubstringAbb("123abaabb123") === true);
	      console.assert(fsm.matchesSubstringAbb("123abbb123") === true);
	      console.assert(fsm.matchesSubstringAbb("123ababab123") === false);
	      console.assert(fsm.matchesSubstringAbb("") === false);
	      console.assert(fsm.matchesSubstringAbb("123") === false);
	      console.assert(fsm.matchesSubstringAbb("123ab") === false);
	      console.assert(fsm.matchesSubstringAbb("123abb") === true);
	      console.assert(fsm.matchesSubstringAbb("abb") === true);

	      rpnTestBasic();
	      rpnTestNumberHandling();
	      rpnTestAutoCommitNumber();
	      rpnTestOperator();
	  };

	  // page init
	  showDumbData();
	  // setup event handler
	  $('.keyboard td').click(function (evt) {
	      const target = evt.target;
	      console.log("user clicked on button: " + $(target).attr('data-bt-name'));
	  });
      }());
    </script>
  </body>

</html>