1
0
mirror of https://github.com/Baidicoot/rpncalc-v4 synced 2024-12-04 23:39:56 +00:00

added better error handling

This commit is contained in:
Aidan K. Ewart 2020-06-02 18:06:32 +01:00
parent 09a704ae7c
commit 2ec9cf6a0c
3 changed files with 48 additions and 17 deletions

View File

@ -13,6 +13,8 @@ code {
<button id="step">step</button>
<button id="play">play</button>
<button id="load">load</button>
<input type="checkbox" id="use-std" name="use-std" checked>
<label for="use-std">use stdlib?</label>
<pre id="insbox"></pre>
<pre id="outbox"></pre>
<script src="./main.js" type="module"></script>

View File

@ -13,6 +13,8 @@ const stepb = document.getElementById("step")
const play = document.getElementById("play")
const load = document.getElementById("load")
const usestd = document.getElementById("use-std")
let state = null;
let input = null;
@ -36,7 +38,23 @@ const loadState = () => {
}
insbox.innerHTML = input;
outbox.innerHTML = "";
state = {scopes:[scope], stacks:[[]], calls:[ast.parsed.arr]};
if (usestd.checked) {
state = {scopes:[scope], stacks:[[]], calls:[ast.parsed.arr]};
} else {
state = {scopes:[{}], stacks:[[]], calls:[ast.parsed.arr]};
}
}
const showIns = (ins) => {
if (ins.val) {
return ins.val;
} else if (ins.ident) {
return ins.ident;
} else if (ins.name) {
return ins.name;
} else {
return 'anon';
}
}
load.onclick = _ => {
@ -49,9 +67,12 @@ play.onclick = _ => {
}
insbox.innerHTML = "";
while (state.calls[0].length > 0 || state.calls.length > 1) {
step(state, customHandler);
if (state.stacks.length > 4096) {
insbox.innerHTML = "max recursion depth exceeded"
try {
step(state, customHandler, showIns);
} catch (err) {
insbox.innerHTML = err;
state = null;
input = null;
return;
}
}
@ -65,7 +86,15 @@ stepb.onclick = _ => {
return;
}
if (state.calls[0].length > 0 || state.calls.length > 1) {
let pos = step(state, customHandler);
let pos;
try {
pos = step(state, customHandler, showIns);
} catch (err) {
insbox.innerHTML = err;
state = null;
input = null;
return;
}
if (!(pos.start === 0 && pos.end === 0)) {
insbox.innerHTML = highlight(input, pos.start, pos.end, "green");
}
@ -74,10 +103,6 @@ stepb.onclick = _ => {
} else {
outbox.innerHTML = prettyprint(state.stacks[0]);
}
if (state.stacks.length > 4096) {
insbox.innerHTML = "max recursion depth exceeded"
return;
}
}
}
@ -85,7 +110,7 @@ const show = (elem) => {
if (elem.type === "pair") {
return "{" + show(elem.val.fst) + ", " + show(elem.val.snd) + "}"
} else if (elem.type === "closure") {
return "(needs: " + elem.val.args.join(", ") + ")"
return "(needs " + elem.val.args.length + ")"
} else if (elem.type === "array") {
return "[" + prettyprint(elem.val) + "]"
} else {

View File

@ -121,7 +121,10 @@ const doIns = (ins, state, handler) => {
}
}
export const step = (state, handler) => {
export const step = (state, handler, showIns, maxdepth) => {
if (state.stacks.length > maxdepth) {
throw 'max recursion depth exceeded'
}
if (state.calls[state.calls.length-1].length === 0) {
if (state.calls.length === 1) {
throw 'finished execution'
@ -137,18 +140,19 @@ export const step = (state, handler) => {
} else {
let ins = state.calls[state.calls.length-1][0];
state.calls[state.calls.length-1] = state.calls[state.calls.length-1].slice(1);
doIns(ins, state, handler);
try {
doIns(ins, state, handler);
} catch (error) {
throw error + ' while executing "' + showIns(ins) + '"'
}
return ins.pos;
}
}
export const execRPN = (scope, ins, handler=(x)=>[x]) => {
export const execRPN = (scope, ins, handler=(x)=>[x], showIns=(x)=>x.name, maxdepth=16384) => {
let state = {scopes:[scope], stacks:[[]], calls:[ins]};
while (state.calls[0].length > 0 || state.calls.length > 1) {
step(state, handler);
if (state.stacks.length > 4096) {
throw 'max recursion depth exceeded'
}
step(state, handler, showIns, maxdepth);
}
return state;
}