Skip to content

Instantly share code, notes, and snippets.

@goolord
Created August 11, 2020 05:45
Show Gist options
  • Save goolord/514bdbebdeb8cf1a3728d26370ec85c2 to your computer and use it in GitHub Desktop.
Save goolord/514bdbebdeb8cf1a3728d26370ec85c2 to your computer and use it in GitHub Desktop.
zYqxXvg
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="https://unpkg.com/sakura.css/css/sakura.css" type="text/css">
<style>
button {
width:50px;
height:50px;
border-radius: 50%;
}
.calc {
border: 2px solid gray;
}
#res {
background: #f4eded;
border: 2px solid gray;
}
</style>
</head>
<body>
<div>
<h1>Calculon</h1>
<table class="calc" style="width:40%">
<tbody><tr>
<td id="res" colspan="3"> 0 </td>
<td> <button data-type="op" id="div"> ÷ </button> </td>
</tr>
<tr>
<td> <button data-type="num" id="7"> 7 </button> </td>
<td> <button data-type="num" id="8"> 8 </button> </td>
<td> <button data-type="num" id="9"> 9 </button> </td>
<td> <button data-type="op" id="mul"> × </button> </td>
</tr>
<tr>
<td> <button data-type="num" id="4"> 4 </button> </td>
<td> <button data-type="num" id="5"> 5 </button> </td>
<td> <button data-type="num" id="6"> 6 </button> </td>
<td> <button data-type="op" id="sub"> − </button> </td>
</tr>
<tr>
<td> <button data-type="num" id="1"> 1 </button> </td>
<td> <button data-type="num" id="2"> 2 </button> </td>
<td> <button data-type="num" id="3"> 3 </button> </td>
<td> <button data-type="op" id="add"> + </button> </td>
</tr>
<tr>
<td colspan="2"> <button data-type="num" id="0"> 0 </button> </td>
<td> <button data-type="dec" id="dec"> . </button> </td>
<td> <button data-type="op" id="eq"> = </button> </td>
</tr>
</tbody></table>
</div>
<script src="index.js"></script>
</body>
</html>
// mutable state
let buffer = 0
let decimalPlace = 0
let next = addDigit
let calc = document.querySelector('.calc')
function reset(resolve) {
calc.addEventListener('click', (e) => calcEv(e, resolve), { once: true })
}
async function calcEv(e, resolve) {
const x = buffer
switch (e.target.getAttribute('data-type')) {
case 'num':
update(next(e.target.id))
reset(resolve)
break;
case 'dec':
next = addDecimal
reset(resolve)
break;
case 'op':
switch (e.target.id) {
case 'add': {
next = addDigit
decimalPlace = 0
update(0)
const y = await op()
resolve(x + y)
break;
}
case 'sub': {
next = addDigit
decimalPlace = 0
update(0)
const y = await op()
resolve(x - y)
break;
}
case 'mul': {
next = addDigit
decimalPlace = 0
update(0)
const y = await op()
resolve(x * y)
break;
}
case 'div': {
next = addDigit
decimalPlace = 0
update(0)
const y = await op()
resolve(x / y)
if (y == 0) {
calcError("Undefined")
}
break;
}
case 'eq': {
next = addDigit
decimalPlace = 0
resolve(buffer)
reset(resolve)
break;
}
}
break;
default:
reset(resolve)
}
}
function op() {
return new Promise( resolve => {
const g = (x) => {
update(x)
resolve(x)
}
const f = (e) => calcEv(e, g)
calc.addEventListener('click', f, { once: true })
})
}
reset(update)
function update(x) {
if (numDigits(x) > 10) {
calcError("Error")
} else {
buffer = x
document.getElementById('res').innerHTML = buffer;
}
}
function calcError(x) {
buffer = 0
document.getElementById('res').innerHTML = x;
}
function getNum() {
return new Promise(resolve => {
document.querySelectorAll('.num').forEach(button => {
button.addEventListener('click', () => {
resolve(Number(button.id))
})
})
})
}
function addDigit(id) {
return (buffer * 10) + Number(id)
}
function addDecimal(id) {
decimalPlace += 1
let decimals = Number(id) / Math.pow(10,decimalPlace)
let res = buffer + decimals
console.log(res)
return res
}
function numDigits(x) {
return Math.max(Math.floor(Math.log10(Math.abs(x))), 0) + 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment