RPN calculator
by Lorraine Lee
HTML
<form>
<fieldset>
<legend>RPN calculator</legend>
<div id="display">0</div>
<br />
<div id="keys">
<div class="left">
<!-- ⇆≶≷ -->
<!-- √ -->
<button id="swap" type="button">y≶x</button>
<br />
<button id="last-x" type="button">LST X</button>
<br />
<button class="binop" data-op="**" type="button">y<sup>x</sup></button>
<br />
<button class="monop" data-op="reciprocal" type="button">1/x</button>
</div>
<div class="left">
<button id="enter" type="button">E<br />N<br />T<br />E<br />R</button>
</div>
<div>
<button data-digit="7" class="digit" type="button">7</button>
<button data-digit="8" class="digit" type="button">8</button>
<button data-digit="9" class="digit" type="button">9</button>
<button class="binop" data-op="/" type="button">÷</button>
<br />
<button data-digit="4" class="digit" type="button">4</button>
<button data-digit="5" class="digit" type="button">5</button>
<button data-digit="6" class="digit" type="button">6</button>
<button class="binop" data-op="*" type="button">×</button>
<br />
<button data-digit="1" class="digit" type="button">1</button>
<button data-digit="2" class="digit" type="button">2</button>
<button data-digit="3" class="digit" type="button">3</button>
<button class="binop" data-op="-" type="button">-</button>
<br />
<button data-digit="0" class="digit" type="button">0</button>
<button id="point" type="button">.</button>
<button id="chs" type="button">CHS</button>
<button class="binop" data-op="+" type="button">+</button>
</div>
</div>
</fieldset>
</form>
CSS
button {
width: 6em;
text-align: center;
}
#display {
text-align: right;
background-color: black;
color: white;
padding: 10px;
font-weight: bold;
width: 70%;
margin-left: auto;
margin-right: auto;
font-size: 2em;
font-family: "sans";
}
.left {
float: left;
}
#keys {
width: 50em;
margin-left: auto;
margin-right: auto;
}
JavaScript
// h/t jfriend00 https://stackoverflow.com/a/22754453/948073
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
let stack = [];
let fresh = true;
let lastX;
function displayAndContent() {
let display = document.getElementById("display");
return {display: display, content: display.textContent};
}
function reciprocal(x) {
return 1/x;
}
// digits below is iterable in Firefox but not in Chrome:
let digits = document.getElementsByClassName("digit");
for (let digit of digits) {
digit.addEventListener("click", function () {
dc = displayAndContent();
if (fresh) {
stack.push(Number(dc.content));
dc.display.textContent = digit.dataset.digit;
}
else {
let dc = displayAndContent();
if (dc.content == "0") dc.content = "";
let newContent = dc.content + digit.dataset.digit;
dc.display.textContent = newContent;
}
fresh = false;
});
}
let point = document.getElementById("point");
point.addEventListener("click", function () {
let dc = displayAndContent();
let index = dc.content.indexOf(".");
console.log(index);
if (fresh) {
stack.push(Number(dc.content));
dc.display.textContent = "0.";
fresh = false;
}
else if (index == -1) {
let newContent = dc.content + ".";
dc.display.textContent = newContent;
}
});
let chs = document.getElementById("chs");
chs.addEventListener("click", function () {
let dc = displayAndContent();
dc.display.textContent = (-Number(dc.content)).toString();
});
let binops = document.getElementsByClassName("binop");
for (let binop of binops) {
binop.addEventListener("click", function () {
let dc = displayAndContent();
let x =...