debugged eval.js, added exports

This commit is contained in:
Aidan K. Ewart 2020-05-21 15:19:31 +01:00
parent 6742bede47
commit 32db1c77b0
2 changed files with 37 additions and 14 deletions

47
eval.js
View File

@ -11,26 +11,28 @@ types of object on list:
{type:"closure", args:[], func:{}} {type:"closure", args:[], func:{}}
{type:"pair", val:{fst:{}, snd:{}}} {type:"pair", val:{fst:{}, snd:{}}}
[{type:"int", val:1},{type:"int", val:1},{type:"builtin", op:"+"}]
exported functions: exported functions:
makeEval - lifts a function to a function definition object addDefn - adds a builtin function
doStep - consumes instruction stream, stack, outputs stack doStep - consumes instruction stream, stack, outputs stack
execRPN - consumes scope, instruction stream, outputs stack execRPN - consumes scope, instruction stream, outputs stack
*/ */
const makeEval = (sign, defn) => { const makeEval = (sign, defnarg) => {
if (typeof sign === "number") { if (typeof sign === "number") {
return {nargs:sign, defn:defn}; return {nargs:sign, defn:defnarg};
} else { } else {
return {nargs:sign.length, defn:(scope, args) => { return {nargs:sign.length, defn:(scope, args) => {
let stripped = []; let stripped = [];
for (let i = 0; i < sign.length; i++) { 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); stripped.push(args[i].val);
} else { } else {
throw 'typeerror' 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 snd = (args) => [args[0].snd];
const 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),
@ -75,6 +77,10 @@ const builtinDefn = {
"snd": makeEval(["pair"], snd) "snd": makeEval(["pair"], snd)
} }
export const addDefn = (name, sign, func) => {
builtinDefn[name] = makeEval(sign, func);
}
const makeLambda = (lambda) => (scope, args) => { const makeLambda = (lambda) => (scope, args) => {
let newscope = Object.create(scope); // I am so sorry... let newscope = Object.create(scope); // I am so sorry...
for (let i = 0; i < lambda.args.length; i++) { for (let i = 0; i < lambda.args.length; i++) {
@ -97,7 +103,7 @@ const makeObj = (elem) => {
const giveArg = (closure, arg, scope) => { const giveArg = (closure, arg, scope) => {
closure.args.push(arg); closure.args.push(arg);
if (closure.args.length === closure.func.nargs) { if (closure.args.length === closure.func.nargs) {
return closure.defn(scope, closure.args) return closure.func.defn(scope, closure.args)
} else { } else {
return [closure]; return [closure];
} }
@ -105,10 +111,13 @@ const giveArg = (closure, arg, scope) => {
const apply = (elem, stack) => { const apply = (elem, stack) => {
if (elem.type === "closure") { 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); applyMany(out, stack);
} else if (elem.type === "ident") {
let id = stack.scope[elem.name];
apply(id, stack);
} else { } else {
stack.push(elem); stack.stack.push(elem);
} }
} }
@ -118,9 +127,22 @@ const applyMany = (outstack, stack) => {
} }
} }
const doStep = (ins, stack) => { const pushS = (elem, stack) => {
let elem = makeObj(ins.pop()); if (elem.type === "ident") {
apply(elem, stack); 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) => { const execRPN = (scope, ins) => {
@ -128,4 +150,5 @@ const execRPN = (scope, ins) => {
while (ins.length > 0) { while (ins.length > 0) {
doStep(ins, stack); doStep(ins, stack);
} }
return stack;
} }

View File

@ -38,7 +38,7 @@ to:
] ]
EXPORTED FUNCTIONS: EXPORTED FUNCTIONS:
parse - takes in tokenstream, outputs AST parseExprs - takes in tokenstream, outputs AST
*/ */
const builtin = [ const builtin = [
@ -209,4 +209,4 @@ const parseLambda = (stream) => {
const parseExpr = or(parseBuiltin, or(parseIdent, or(parseInteger, or(parsePush, attempt(parens(parseLambda)))))); const parseExpr = or(parseBuiltin, or(parseIdent, or(parseInteger, or(parsePush, attempt(parens(parseLambda))))));
/* takes in stream, outputs parsed items */ /* takes in stream, outputs parsed items */
const parseExprs = many(parseExpr); export const parseExprs = many(parseExpr);