mirror of
https://github.com/Baidicoot/rpncalc-v4
synced 2024-12-12 11:10:26 +00:00
thanks, uberpolymorphism!
This commit is contained in:
parent
678dc200b2
commit
56bfc23f98
30
eval.mjs
30
eval.mjs
@ -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) => {
|
||||||
|
13
index.html
13
index.html
@ -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
18
main.js
@ -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);
|
|
||||||
}
|
}
|
@ -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}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user