Skip to content

Instantly share code, notes, and snippets.

@d6u
Last active February 13, 2026 03:07
Show Gist options
  • Select an option

  • Save d6u/2e982bdc965e14ce12a545e6996f0af4 to your computer and use it in GitHub Desktop.

Select an option

Save d6u/2e982bdc965e14ce12a545e6996f0af4 to your computer and use it in GitHub Desktop.

Revisions

  1. d6u revised this gist Sep 29, 2016. 1 changed file with 14 additions and 0 deletions.
    14 changes: 14 additions & 0 deletions calculator.html
    Original file line number Diff line number Diff line change
    @@ -65,19 +65,23 @@
    }
    }
    }

    isEmpty() {
    return this.stack.length === 0;
    }

    push(val) {
    this.stack.push(val);
    }

    pop() {
    if (this.isEmpty()) {
    throw new Error('empty stack');
    } else {
    return this.stack.pop();
    }
    }

    peek(n = -1) {
    if (this.isEmpty()) {
    throw new Error('empty stack');
    @@ -86,17 +90,21 @@
    }
    }
    }

    document.getElementById('key-pad').addEventListener('click', (event) => {
    if (event.target.tagName === 'BUTTON') {
    input(event.target.innerHTML);
    render();
    }
    });

    const $screen = document.getElementById('screen');
    const stack = new Stack();
    let shouldResetIfNumber = false;
    let display = 0;

    stack.push(0);

    function input(char) {
    if (isNum(char)) {
    if (shouldResetIfNumber) {
    @@ -129,6 +137,7 @@
    display = res;
    }
    }

    function evaluate(stack, isComplete = false) {
    const values = new Stack();
    const operators = new Stack();
    @@ -149,11 +158,13 @@
    }
    }
    }

    if (isComplete) {
    while (!operators.isEmpty()) {
    values.push(operators.pop());
    }
    }

    const rpn = new Stack();
    for (const val of values) {
    if (isNum(val)) {
    @@ -177,11 +188,14 @@
    }
    }
    }

    return rpn.pop();
    }

    function render() {
    $screen.innerHTML = display;
    }

    function isNum(val) {
    if (typeof val === 'number') {
    return true;
  2. d6u created this gist Sep 29, 2016.
    196 changes: 196 additions & 0 deletions calculator.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,196 @@
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Calculator</title>
    <style>
    * {
    box-sizing: border-box;
    }
    .calculator {
    width: 400px;
    }
    .screen {
    height: 50px;
    border: 1px solid black;
    text-align: right;
    font-size: 30px;
    line-height: 50px;
    padding-right: 10px;
    }
    .key-pad {
    display: flex;
    }
    .num-keys {
    display: flex;
    flex-wrap: wrap;
    width: 300px;
    }
    .num-keys button {
    width: 90px;
    }
    </style>
    </head>
    <body>
    <div class="calculator">
    <p id="screen" class="screen">0</p>
    <div id="key-pad" class="key-pad">
    <div class="num-keys">
    <button>1</button>
    <button>2</button>
    <button>3</button>
    <button>4</button>
    <button>5</button>
    <button>6</button>
    <button>7</button>
    <button>8</button>
    <button>9</button>
    <button>0</button>
    </div>
    <div>
    <button>+</button>
    <button>-</button>
    <button>*</button>
    <button>/</button>
    <button>=</button>
    </div>
    </div>
    </div>
    <script>
    class Stack {
    constructor() {
    this.stack = [];
    this[Symbol.iterator] = function *() {
    for (const el of this.stack) {
    yield el;
    }
    }
    }
    isEmpty() {
    return this.stack.length === 0;
    }
    push(val) {
    this.stack.push(val);
    }
    pop() {
    if (this.isEmpty()) {
    throw new Error('empty stack');
    } else {
    return this.stack.pop();
    }
    }
    peek(n = -1) {
    if (this.isEmpty()) {
    throw new Error('empty stack');
    } else {
    return this.stack[this.stack.length + n];
    }
    }
    }
    document.getElementById('key-pad').addEventListener('click', (event) => {
    if (event.target.tagName === 'BUTTON') {
    input(event.target.innerHTML);
    render();
    }
    });
    const $screen = document.getElementById('screen');
    const stack = new Stack();
    let shouldResetIfNumber = false;
    let display = 0;
    stack.push(0);
    function input(char) {
    if (isNum(char)) {
    if (shouldResetIfNumber) {
    stack.pop();
    stack.push(parseInt(char));
    shouldResetIfNumber = false;
    } else if (isNum(stack.peek())) {
    const n = stack.pop();
    stack.push(n * 10 + parseInt(char));
    } else {
    stack.push(parseInt(char));
    }
    display = stack.peek();
    } else if (char !== '=') {
    shouldResetIfNumber = false;
    if (isNum(stack.peek())) {
    stack.push(char);
    } else {
    stack.pop();
    stack.push(char);
    }
    display = evaluate(stack);
    } else {
    const res = evaluate(stack, true);
    while (!stack.isEmpty()) {
    stack.pop();
    }
    stack.push(res);
    shouldResetIfNumber = true;
    display = res;
    }
    }
    function evaluate(stack, isComplete = false) {
    const values = new Stack();
    const operators = new Stack();
    for (const val of stack) {
    if (isNum(val)) {
    values.push(val);
    } else {
    if (val === '+' || val === '-') {
    while (!operators.isEmpty()) {
    values.push(operators.pop());
    }
    operators.push(val);
    } else {
    while (!operators.isEmpty() && (operators.peek() === '*' || operators.peek() === '/')) {
    values.push(operators.pop());
    }
    operators.push(val);
    }
    }
    }
    if (isComplete) {
    while (!operators.isEmpty()) {
    values.push(operators.pop());
    }
    }
    const rpn = new Stack();
    for (const val of values) {
    if (isNum(val)) {
    rpn.push(val);
    } else {
    const b = rpn.pop();
    const a = rpn.pop();
    switch (val) {
    case '+':
    rpn.push(a + b);
    break;
    case '-':
    rpn.push(a - b);
    break;
    case '/':
    rpn.push(a / b);
    break;
    case '*':
    rpn.push(a * b);
    break;
    }
    }
    }
    return rpn.pop();
    }
    function render() {
    $screen.innerHTML = display;
    }
    function isNum(val) {
    if (typeof val === 'number') {
    return true;
    } else if (typeof val === 'string') {
    return !Number.isNaN(parseInt(val));
    } else {
    return false;
    }
    }
    </script>
    </body>
    </html>