From 34d43452cbdbd7334e1aa8984e05b3d7841c1791 Mon Sep 17 00:00:00 2001 From: "Aidan K. Ewart" Date: Sat, 30 May 2020 20:51:47 +0100 Subject: [PATCH] added builtin declaration eazy functions --- eval.mjs | 17 +++++++++++------ main.js | 21 ++++++++++++++++++++- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/eval.mjs b/eval.mjs index 39f4afc..9075094 100644 --- a/eval.mjs +++ b/eval.mjs @@ -68,9 +68,6 @@ const fst = (_, args) => [args[0].fst]; const snd = (_, args) => [args[0].snd]; -const tru = (_, args) => [args[0]]; -const fls = (_, args) => [args[1]]; - const eq = (_, args) => { if (args[0].type === args[1].type && args[0].val === args[1].val) { return [{type:"ident", val:"true"}]; @@ -79,13 +76,15 @@ const eq = (_, args) => { } } +const stop = (a, b) => { + return [{type:"string", val:"stop"}]; +} + let builtinDefn = { "+": makeEval(["int", "int"], add), "-": makeEval(["int", "int"], sub), "/": makeEval(["int", "int"], div), "*": makeEval(["int", "int"], mult), - "true": makeEval(2, tru), - "false": makeEval(2, fls), "==": makeEval(2, eq), "typeof": makeEval(1, type), "pair": makeEval(2, pair), @@ -97,6 +96,10 @@ export const addDefn = (name, sign, func) => { builtinDefn[name] = makeEval(sign, func); } +export const addRPNASTDefn = (name, ast) => { + builtinDefn[name] = makeLambda(ast); +} + const makeLambda = (lambda) => { return {nargs:lambda.args.length, defn:(scope, args) => { let newscope = Object.create(scope); // I am so sorry... @@ -151,7 +154,9 @@ const giveArg = (closure, arg, scope) => { const apply = (elem, stack) => { 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); applyMany(out, stack); } else { diff --git a/main.js b/main.js index 04d5582..c72a7ac 100644 --- a/main.js +++ b/main.js @@ -1,4 +1,4 @@ -import {execRPN} from './eval.mjs'; +import {execRPN, addRPNASTDefn} from './eval.mjs'; import {parseExprs} from './parse.mjs'; import {tokenize} from './token.mjs'; @@ -29,6 +29,25 @@ const prettyprint = (out) => { 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) => { const input = inbox.value; let toks = tokenize(input);