mirror of https://github.com/Baidicoot/rpncalc-v4
added builtin declaration eazy functions
This commit is contained in:
parent
285910c551
commit
34d43452cb
17
eval.mjs
17
eval.mjs
|
@ -68,9 +68,6 @@ const fst = (_, args) => [args[0].fst];
|
||||||
|
|
||||||
const snd = (_, args) => [args[0].snd];
|
const snd = (_, args) => [args[0].snd];
|
||||||
|
|
||||||
const tru = (_, args) => [args[0]];
|
|
||||||
const fls = (_, args) => [args[1]];
|
|
||||||
|
|
||||||
const eq = (_, args) => {
|
const eq = (_, args) => {
|
||||||
if (args[0].type === args[1].type && args[0].val === args[1].val) {
|
if (args[0].type === args[1].type && args[0].val === args[1].val) {
|
||||||
return [{type:"ident", val:"true"}];
|
return [{type:"ident", val:"true"}];
|
||||||
|
@ -79,13 +76,15 @@ const eq = (_, args) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const stop = (a, b) => {
|
||||||
|
return [{type:"string", val:"stop"}];
|
||||||
|
}
|
||||||
|
|
||||||
let builtinDefn = {
|
let builtinDefn = {
|
||||||
"+": makeEval(["int", "int"], add),
|
"+": makeEval(["int", "int"], add),
|
||||||
"-": makeEval(["int", "int"], sub),
|
"-": makeEval(["int", "int"], sub),
|
||||||
"/": makeEval(["int", "int"], div),
|
"/": makeEval(["int", "int"], div),
|
||||||
"*": makeEval(["int", "int"], mult),
|
"*": makeEval(["int", "int"], mult),
|
||||||
"true": makeEval(2, tru),
|
|
||||||
"false": makeEval(2, fls),
|
|
||||||
"==": makeEval(2, eq),
|
"==": makeEval(2, eq),
|
||||||
"typeof": makeEval(1, type),
|
"typeof": makeEval(1, type),
|
||||||
"pair": makeEval(2, pair),
|
"pair": makeEval(2, pair),
|
||||||
|
@ -97,6 +96,10 @@ export const addDefn = (name, sign, func) => {
|
||||||
builtinDefn[name] = makeEval(sign, func);
|
builtinDefn[name] = makeEval(sign, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const addRPNASTDefn = (name, ast) => {
|
||||||
|
builtinDefn[name] = makeLambda(ast);
|
||||||
|
}
|
||||||
|
|
||||||
const makeLambda = (lambda) => {
|
const makeLambda = (lambda) => {
|
||||||
return {nargs:lambda.args.length, defn:(scope, args) => {
|
return {nargs:lambda.args.length, defn:(scope, args) => {
|
||||||
let newscope = Object.create(scope); // I am so sorry...
|
let newscope = Object.create(scope); // I am so sorry...
|
||||||
|
@ -151,7 +154,9 @@ const giveArg = (closure, arg, scope) => {
|
||||||
|
|
||||||
const apply = (elem, stack) => {
|
const apply = (elem, stack) => {
|
||||||
if (elem.type === "closure") {
|
if (elem.type === "closure") {
|
||||||
if (stack.stack.length > 0) {
|
if (elem.func.nargs === 0) {
|
||||||
|
applyMany(elem.func.defn(stack.scope, []), stack);
|
||||||
|
} else if (stack.stack.length > 0) {
|
||||||
let out = giveArg(elem, stack.stack.pop(), stack.scope);
|
let out = giveArg(elem, stack.stack.pop(), stack.scope);
|
||||||
applyMany(out, stack);
|
applyMany(out, stack);
|
||||||
} else {
|
} else {
|
||||||
|
|
21
main.js
21
main.js
|
@ -1,4 +1,4 @@
|
||||||
import {execRPN} from './eval.mjs';
|
import {execRPN, addRPNASTDefn} from './eval.mjs';
|
||||||
import {parseExprs} from './parse.mjs';
|
import {parseExprs} from './parse.mjs';
|
||||||
import {tokenize} from './token.mjs';
|
import {tokenize} from './token.mjs';
|
||||||
|
|
||||||
|
@ -29,6 +29,25 @@ const prettyprint = (out) => {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const addRPNBuiltin = (name, def) => {
|
||||||
|
let toks = tokenize(def);
|
||||||
|
if (!toks) {
|
||||||
|
throw 'could not load builtin'
|
||||||
|
}
|
||||||
|
let ast = parseExprs(toks);
|
||||||
|
if (!ast.parsed) {
|
||||||
|
throw 'could not load builtin'
|
||||||
|
}
|
||||||
|
console.log(ast);
|
||||||
|
addRPNASTDefn(name, ast.parsed[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
addRPNBuiltin("true", "(a b -> a)");
|
||||||
|
addRPNBuiltin("false", "(a b -> b)");
|
||||||
|
addRPNBuiltin("stop", "(-> \"stop)");
|
||||||
|
addRPNBuiltin("id", "(a -> a)");
|
||||||
|
addRPNBuiltin("fold", "(fn acc x -> '(-> x acc fn 'fn fold) '(-> acc) 'x \"stop ==)");
|
||||||
|
|
||||||
submit.onclick = (event) => {
|
submit.onclick = (event) => {
|
||||||
const input = inbox.value;
|
const input = inbox.value;
|
||||||
let toks = tokenize(input);
|
let toks = tokenize(input);
|
||||||
|
|
Loading…
Reference in New Issue