1
0
mirror of https://github.com/osmarks/website synced 2025-11-12 11:24:43 +00:00

initial commit

This commit is contained in:
2020-03-08 17:13:14 +00:00
commit ccd4f72d2d
54 changed files with 4730 additions and 0 deletions

15
experiments/rpncalc-v2/calc.css Executable file
View File

@@ -0,0 +1,15 @@
.stack-box {
text-align: center;
border: solid 1px black;
min-width: 30vmin;
max-width: 30vmin; /* will normally be dynamically set */
line-height: 30vmin;
height: 30vmin;
font-size: 7vmin;
margin: -1px; /* make edges join neatly */
}
#input {
width: 100%;
font-size: 2em;
}

157
experiments/rpncalc-v2/calc.js Executable file
View File

@@ -0,0 +1,157 @@
// Reads the input box for a RPN expression
// Calculates result
// Outputs it as nicely formatted boxes.
function calculateFromInput() {
var expr = document.getElementById("input").value;
var output = document.getElementById("output")
var result = calculateRPN(expr.split(" "));
output.innerHTML = ""; // Clear the output div
result.stack.forEach(function(num) {
num = num.toString().replace("NaN", "Error");
var box = createBox(num);
box.style["max-width"] = num.length + "em";
output.appendChild(box);
});
if (result.errors.length > 0) { // If errors exist output them separated by line breaks.
result.errors.forEach(error => {
output.appendChild(document.createTextNode(error.toString()))
output.appendChild(document.createElement("br"))
})
}
}
function add(x, y) {
return x + y;
}
function multiply(x, y) {
return x * y;
}
function divide(x, y) {
return x / y;
}
function flip(x, y) {
return [y, x];
}
function subtract(x, y) {
return x - y;
}
function sum(vals) {
var acc = 0;
vals.forEach(function(el) {
acc += el;
});
return acc;
}
function range(low, high) {
var r = [];
for (var i = low; i <= high; i++) {
r.push(i);
}
return r;
}
function createBox(contents) {
var el = document.createElement("div");
el.setAttribute("class", "stack-box");
el.innerText = contents;
return el;
}
// Takes a two-argument function and lifts it to a binary stack op
function binaryOp(fun) {
return function(stack) {
var x = stack.pop();
var y = stack.pop();
stack.push(fun(y, x));
return stack;
}
}
// Takes a function and lifts it to a unary op using a stack. Returns new stack.
function unaryOp(fun) {
return function(stack) {
var x = stack.pop();
stack.push(fun(x));
return stack;
}
}
// Takes a function and lifts it to an op which takes the entire stack and reduces it to one value. Returns new stack.
function greedyOp(fun) {
return function(stack) {
return [fun(stack)];
}
}
// Lifs to an operator which takes two values and adds an array of them to the stack. Returns a new stack.
function binaryMultioutOp(fun) {
return function(stack) {
var x = stack.pop();
var y = stack.pop();
return stack.concat(fun(y, x));
}
}
function calculateRPN(tokens) {
var stack = [];
var errors = [];
for (var i = 0; i < tokens.length; i++) {
var token = tokens[i];
switch (token) {
case "+":
stack = binaryOp(add)(stack);
break;
case "*":
stack = binaryOp(multiply)(stack);
break;
case "/":
stack = binaryOp(divide)(stack);
break;
case "-":
stack = binaryOp(subtract)(stack);
break;
case "range":
stack = binaryMultioutOp(range)(stack);
break;
case "flip":
stack = binaryMultioutOp(flip)(stack);
break;
case "sum":
stack = greedyOp(sum)(stack);
break;
case "": // This may be entered by accident.
break;
default:
var parsed = parseFloat(token);
if (parsed === parsed) { // check for NaNs from a failed parse
stack.push(parsed);
} else {
errors.push("Token '" + token + "' (#" + (i + 1) + ")" + " invalid");
}
}
}
return {stack: stack, errors: errors};
}

View File

@@ -0,0 +1,16 @@
---
title: RPNCalc v2
slug: rpncalc2
description: A Reverse Polish Notation (check wikipedia) calculator, version 2. Buggy and kind of unreliable. This updated version implements subtraction.
---
<link rel="stylesheet" href="calc.css">
<center><div id="output"></div></center>
<hr>
<input type="text" id="input" default="Input RPN expression" oninput="calculateFromInput()">
</div>
<script src="calc.js"></script>