1
0
mirror of https://github.com/Baidicoot/rpncalc-v4 synced 2024-12-12 11:10:26 +00:00

thanks, uberpolymorphism!

This commit is contained in:
Aidan K. Ewart 2020-05-31 02:52:02 +01:00
parent 678dc200b2
commit 56bfc23f98
4 changed files with 38 additions and 29 deletions

View File

@ -86,11 +86,13 @@ const cloneElem = (elem) => {
const lookupScope = (name, scope) => { const lookupScope = (name, scope) => {
let n = scope[name]; let n = scope[name];
console.log(n);
if (n) { if (n) {
return cloneElem(n); return cloneElem(n);
} }
n = builtinDefn[name]; n = builtinDefn[name];
if (n) { if (n) {
console.log(name, n);
return cloneElem(n); return cloneElem(n);
} else { } else {
throw 'var "' + name + '" not in scope' throw 'var "' + name + '" not in scope'
@ -107,20 +109,24 @@ const giveArg = (closure, arg, scope) => {
} }
const apply = (elem, stack) => { const apply = (elem, stack) => {
if (elem.type === "closure") { if (Array.isArray(elem)) {
if (elem.func.nargs === 0) { applyMany(elem, stack);
applyMany(elem.func.defn(stack.scope, []), stack); } else {
} else if (stack.stack.length > 0) { if (elem.type === "closure") {
let out = giveArg(elem, stack.stack.pop(), stack.scope); if (elem.func.nargs === 0) {
applyMany(out, stack); apply(elem.func.defn(stack.scope, []), stack);
} else if (stack.stack.length > 0) {
let out = giveArg(elem, stack.stack.pop(), stack.scope);
apply(out, stack);
} else {
stack.stack.push(elem);
}
} else if (elem.type === "ident") {
let id = lookupScope(elem.val, stack.scope);
apply(id, stack);
} else { } else {
stack.stack.push(elem); stack.stack.push(elem);
} }
} else if (elem.type === "ident") {
let id = lookupScope(elem.val, stack.scope);
apply(id, stack);
} else {
stack.stack.push(elem);
} }
} }
@ -140,7 +146,7 @@ const pushS = (elem, stack) => {
} }
const defn = (elem, name, stack) => { const defn = (elem, name, stack) => {
stack.scope[name] = makeObj(elem); stack.scope[name] = execRPN(stack.scope, elem).stack;
} }
const doStep = (ins, stack) => { const doStep = (ins, stack) => {

View File

@ -1,13 +1,12 @@
<html> <html>
<style>
* {
background-color: #101020;
color: ghostwhite;
}
</style>
<h1>RPNCalc V4 Public Testing</h1> <h1>RPNCalc V4 Public Testing</h1>
<p>@ me (aidanprattewart@protonmail.com) if you have any errors, with console output please.</p> <p>@ me (aidanprattewart@protonmail.com) if you have any errors, with console output please.</p>
<p>
Example Programs:
<br>
<code>(swap; a b -> a b) 1 2 swap</code> N.B. args are in reverse order
<br>
<code>1 + 2 (v partial -> 'v partial)</code> Evaluate a partial
</p>
<textarea type="text" id="inbox"></textarea> <textarea type="text" id="inbox"></textarea>
<button id="submit">execute</button> <button id="submit">execute</button>
<p id="outbox"></p> <p id="outbox"></p>

18
main.js
View File

@ -14,7 +14,7 @@ const show = (elem) => {
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 "(args: {" + prettyprint(elem.args) + "} of " + elem.func.nargs + ")" return "(args: {" + prettyprint(elem.args) + "} of " + elem.func.nargs + ")"
} else if (elem.type === "string") { } else if (elem.type === "type") {
return elem.val return elem.val
} else if (elem.type === "array") { } else if (elem.type === "array") {
return "[" + prettyprint(elem.val) + "]" return "[" + prettyprint(elem.val) + "]"
@ -45,11 +45,15 @@ submit.onclick = (event) => {
return; return;
} }
console.log(ast.parsed); console.log(ast.parsed);
let out = execRPN({}, ast.parsed); try {
if (!out) { let out = execRPN({}, ast.parsed);
outbox.innerHTML = "failed to execute"; if (!out) {
return; outbox.innerHTML = "failed to execute";
return;
}
console.log(out);
outbox.innerHTML = prettyprint(out.stack);
} catch (error) {
outbox.innerHTML = error;
} }
console.log(out);
outbox.innerHTML = prettyprint(out.stack);
} }

View File

@ -175,11 +175,11 @@ const parsePush = (stream) => {
const parseDefn = (stream) => { const parseDefn = (stream) => {
let name = parseName(stream); let name = parseName(stream);
if (name.parsed === null) { if (name.parsed === null) {
return {parsed:null, stream:name.stream}; throw 'no name found!'
} }
let expr = parseExpr(stream); let expr = parseExprs(stream);
if (expr.parsed === null) { if (expr.parsed === null) {
return {parsed:null, stream:expr.stream}; throw 'no body found!'
} }
return {parsed:{type:"defn", ident:name.parsed, defn:expr.parsed}, stream:expr.stream} return {parsed:{type:"defn", ident:name.parsed, defn:expr.parsed}, stream:expr.stream}
} }