mirror of
				https://github.com/Baidicoot/rpncalc-v4
				synced 2025-10-31 15:43:00 +00:00 
			
		
		
		
	added better error handling
This commit is contained in:
		| @@ -13,6 +13,8 @@ code { | |||||||
| <button id="step">step</button> | <button id="step">step</button> | ||||||
| <button id="play">play</button> | <button id="play">play</button> | ||||||
| <button id="load">load</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="insbox"></pre> | ||||||
| <pre id="outbox"></pre> | <pre id="outbox"></pre> | ||||||
| <script src="./main.js" type="module"></script> | <script src="./main.js" type="module"></script> | ||||||
|   | |||||||
| @@ -13,6 +13,8 @@ const stepb = document.getElementById("step") | |||||||
| const play = document.getElementById("play") | const play = document.getElementById("play") | ||||||
| const load = document.getElementById("load") | const load = document.getElementById("load") | ||||||
|  |  | ||||||
|  | const usestd = document.getElementById("use-std") | ||||||
|  |  | ||||||
| let state = null; | let state = null; | ||||||
| let input = null; | let input = null; | ||||||
|  |  | ||||||
| @@ -36,7 +38,23 @@ const loadState = () => { | |||||||
|     } |     } | ||||||
|     insbox.innerHTML = input; |     insbox.innerHTML = input; | ||||||
|     outbox.innerHTML = ""; |     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 = _ => { | load.onclick = _ => { | ||||||
| @@ -49,9 +67,12 @@ play.onclick = _ => { | |||||||
|     } |     } | ||||||
|     insbox.innerHTML = ""; |     insbox.innerHTML = ""; | ||||||
|     while (state.calls[0].length > 0 || state.calls.length > 1) { |     while (state.calls[0].length > 0 || state.calls.length > 1) { | ||||||
|         step(state, customHandler); |         try { | ||||||
|         if (state.stacks.length > 4096) { |             step(state, customHandler, showIns); | ||||||
|             insbox.innerHTML = "max recursion depth exceeded" |         } catch (err) { | ||||||
|  |             insbox.innerHTML = err; | ||||||
|  |             state = null; | ||||||
|  |             input = null; | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -65,7 +86,15 @@ stepb.onclick = _ => { | |||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     if (state.calls[0].length > 0 || state.calls.length > 1) { |     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)) { |         if (!(pos.start === 0 && pos.end === 0)) { | ||||||
|             insbox.innerHTML = highlight(input, pos.start, pos.end, "green"); |             insbox.innerHTML = highlight(input, pos.start, pos.end, "green"); | ||||||
|         } |         } | ||||||
| @@ -74,10 +103,6 @@ stepb.onclick = _ => { | |||||||
|         } else { |         } else { | ||||||
|             outbox.innerHTML = prettyprint(state.stacks[0]); |             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") { |     if (elem.type === "pair") { | ||||||
|         return "{" + show(elem.val.fst) + ", " + show(elem.val.snd) + "}" |         return "{" + show(elem.val.fst) + ", " + show(elem.val.snd) + "}" | ||||||
|     } else if (elem.type === "closure") { |     } else if (elem.type === "closure") { | ||||||
|         return "(needs: " + elem.val.args.join(", ") + ")" |         return "(needs " + elem.val.args.length + ")" | ||||||
|     } else if (elem.type === "array") { |     } else if (elem.type === "array") { | ||||||
|         return "[" + prettyprint(elem.val) + "]" |         return "[" + prettyprint(elem.val) + "]" | ||||||
|     } else { |     } else { | ||||||
|   | |||||||
| @@ -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[state.calls.length-1].length === 0) { | ||||||
|         if (state.calls.length === 1) { |         if (state.calls.length === 1) { | ||||||
|             throw 'finished execution' |             throw 'finished execution' | ||||||
| @@ -137,18 +140,19 @@ export const step = (state, handler) => { | |||||||
|     } else { |     } else { | ||||||
|         let ins = state.calls[state.calls.length-1][0]; |         let ins = state.calls[state.calls.length-1][0]; | ||||||
|         state.calls[state.calls.length-1] = state.calls[state.calls.length-1].slice(1); |         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; |         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]}; |     let state = {scopes:[scope], stacks:[[]], calls:[ins]}; | ||||||
|     while (state.calls[0].length > 0 || state.calls.length > 1) { |     while (state.calls[0].length > 0 || state.calls.length > 1) { | ||||||
|         step(state, handler); |         step(state, handler, showIns, maxdepth); | ||||||
|         if (state.stacks.length > 4096) { |  | ||||||
|             throw 'max recursion depth exceeded' |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|     return state; |     return state; | ||||||
| } | } | ||||||
		Reference in New Issue
	
	Block a user
	 Aidan K. Ewart
					Aidan K. Ewart