// RPN (Reverse Polish Notation) calculator module const RPNCalculator = (function() { class RPNCalculator { constructor() { this.clear(); } // Push a number onto the stack push(value) { if (typeof value === 'number' || !isNaN(parseFloat(value))) { this.stack.push(parseFloat(value)); } } // Pop a number from the stack pop() { if (this.stack.length > 0) { return this.stack.pop(); } return undefined; } // Perform an operation on stack values operate(operator) { if (this.stack.length < 2) { return 'Error'; // Need at least 2 values for binary operations } const b = this.pop(); const a = this.pop(); let result; switch (operator) { case '+': result = a + b; break; case '-': result = a - b; break; case '*': result = a * b; break; case '/': if (b === 0) { result = Infinity; } else { result = a / b; } break; case '^': case '**': result = Math.pow(a, b); break; default: return 'Error'; // Unknown operator } // Check for invalid results if (isNaN(result) || !isFinite(result)) { this.push('Error'); return 'Error'; } this.push(result); return result; } // Clear the entire stack clear() { this.stack = []; } // Get current stack state getStack() { return [...this.stack]; // Return a copy to prevent external modification } // Execute RPN expression (e.g., "3 4 +") evaluate(rpnExpression) { try { // Split the expression into tokens const tokens = rpnExpression.trim().split(/\s+/); this.clear(); // Clear the stack before evaluation for (const token of tokens) { if (['+', '-', '*', '/', '^', '**'].includes(token)) { // It's an operator const result = this.operate(token); if (result === 'Error') { return 'Error'; } } else { // It's a number const num = parseFloat(token); if (isNaN(num)) { return 'Error'; // Invalid token } this.push(num); } } // Return the top of the stack if there's a result if (this.stack.length === 1) { return this.stack[0]; } else if (this.stack.length === 0) { return 0; // Empty stack, return 0 } else { return this.stack[this.stack.length - 1]; // Return top of stack } } catch (error) { return 'Error'; } } // Process a single RPN input token processInput(token) { if (['+', '-', '*', '/', '^', '**'].includes(token)) { // Operator return this.operate(token); } else if (token === 'ENTER' || token === 'E') { // ENTER doesn't do anything in implementation, just pushes numbers that were already processed return this.getStack(); } else if (token === 'C' || token === 'CE') { this.clear(); return 0; } else { // Number const num = parseFloat(token); if (!isNaN(num)) { this.push(num); return num; } else { return 'Error'; } } } } return { RPNCalculator }; })();