From 32db1c77b0eb65cec95f1a65c473064bedb514cf Mon Sep 17 00:00:00 2001 From: "Aidan K. Ewart" Date: Thu, 21 May 2020 15:19:31 +0100 Subject: [PATCH] debugged eval.js, added exports --- eval.js | 47 +++++++++++++++++++++++++++++++++++------------ parse.js | 4 ++-- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/eval.js b/eval.js index 1f59c08..45170ea 100644 --- a/eval.js +++ b/eval.js @@ -11,26 +11,28 @@ types of object on list: {type:"closure", args:[], func:{}} {type:"pair", val:{fst:{}, snd:{}}} +[{type:"int", val:1},{type:"int", val:1},{type:"builtin", op:"+"}] + exported functions: -makeEval - lifts a function to a function definition object +addDefn - adds a builtin function doStep - consumes instruction stream, stack, outputs stack execRPN - consumes scope, instruction stream, outputs stack */ -const makeEval = (sign, defn) => { +const makeEval = (sign, defnarg) => { if (typeof sign === "number") { - return {nargs:sign, defn:defn}; + return {nargs:sign, defn:defnarg}; } else { return {nargs:sign.length, defn:(scope, args) => { let stripped = []; for (let i = 0; i < sign.length; i++) { - if (args[i].type === sign[i].type) { + if (args[i].type === sign[i]) { stripped.push(args[i].val); } else { throw 'typeerror' } } - defn(scope, stripped); + return defnarg(scope, stripped); } } } @@ -64,7 +66,7 @@ const fst = (args) => [args[0].fst]; const snd = (args) => [args[0].snd]; -const builtinDefn = { +let builtinDefn = { "+": makeEval(["int", "int"], add), "-": makeEval(["int", "int"], sub), "/": makeEval(["int", "int"], div), @@ -75,6 +77,10 @@ const builtinDefn = { "snd": makeEval(["pair"], snd) } +export const addDefn = (name, sign, func) => { + builtinDefn[name] = makeEval(sign, func); +} + const makeLambda = (lambda) => (scope, args) => { let newscope = Object.create(scope); // I am so sorry... for (let i = 0; i < lambda.args.length; i++) { @@ -97,7 +103,7 @@ const makeObj = (elem) => { const giveArg = (closure, arg, scope) => { closure.args.push(arg); if (closure.args.length === closure.func.nargs) { - return closure.defn(scope, closure.args) + return closure.func.defn(scope, closure.args) } else { return [closure]; } @@ -105,10 +111,13 @@ const giveArg = (closure, arg, scope) => { const apply = (elem, stack) => { if (elem.type === "closure") { - let out = elem.giveArg(elem, stack.stack.pop(), stack.scope); + let out = giveArg(elem, stack.stack.pop(), stack.scope); applyMany(out, stack); + } else if (elem.type === "ident") { + let id = stack.scope[elem.name]; + apply(id, stack); } else { - stack.push(elem); + stack.stack.push(elem); } } @@ -118,9 +127,22 @@ const applyMany = (outstack, stack) => { } } -const doStep = (ins, stack) => { - let elem = makeObj(ins.pop()); - apply(elem, stack); +const pushS = (elem, stack) => { + if (elem.type === "ident") { + let id = stack.scope[elem.name]; + stack.stack.push(id); + } else { + stack.stack.push(elem); + } +} + +export const doStep = (ins, stack) => { + let instruction = ins.shift(); + if (instruction.type === "push") { + pushS(makeObj(instruction.elem), stack); + } else { + apply(makeObj(instruction), stack); + } } const execRPN = (scope, ins) => { @@ -128,4 +150,5 @@ const execRPN = (scope, ins) => { while (ins.length > 0) { doStep(ins, stack); } + return stack; } \ No newline at end of file diff --git a/parse.js b/parse.js index 9bea6f3..2e7379b 100644 --- a/parse.js +++ b/parse.js @@ -38,7 +38,7 @@ to: ] EXPORTED FUNCTIONS: -parse - takes in tokenstream, outputs AST +parseExprs - takes in tokenstream, outputs AST */ const builtin = [ @@ -209,4 +209,4 @@ const parseLambda = (stream) => { const parseExpr = or(parseBuiltin, or(parseIdent, or(parseInteger, or(parsePush, attempt(parens(parseLambda)))))); /* takes in stream, outputs parsed items */ -const parseExprs = many(parseExpr); \ No newline at end of file +export const parseExprs = many(parseExpr); \ No newline at end of file