// const STR = (s) => ({type: "string", value: s}); // const FN = (f) => ({type: "function", value: f}); // const NUL = () => ({type: "null", value: null}); // const SYM = (s) => ({type: "symbol", value: s}); // const UNDEF = () => ({type: "undefined", value: null}); // const PROG = (p) => ({type: "program", value: p}); // const THUNK = (t) => ({type: "thunk", value: t}); // const BOOL = (b) => ({type: "boolean", value: b}); // const my_prog = [ // SYM("print"), STR("hi"), // SYM("if"), BOOL(false), THUNK([ // SYM("print"), STR("hi2"), // ]), // SYM("else"), THUNK([ // SYM("print"), STR("hi3"), // ]), // ]; // const my_env = { // print: FN((arg) => { // console.log(arg.value); // return {result: UNDEF()}; // }), // if: FN((arg) => { // if (arg.type === "boolean" && arg.value) { // return { // result: FN((thunk) => { // return { // result: eval_program(thunk.value, my_env).result, // handled: BOOL(true), // }; // }) // }; // } // return { // result: UNDEF(), // handled: BOOL(false), // }; // }), // else: FN((arg, passalong) => { // console.log('ELSE', arg, passalong); // if (passalong.handled === false) { // return { // result: eval_program(arg.value, my_env).result, // }; // } // return { // result: UNDEF(), // }; // }), // } // const debugLog = (...args) => { // // console.log(args); // } // const eval_program = (program, env) => { // debugLog('evaluating program'); // let val = {result: UNDEF()}; // while (program.length) { // val = eval_phrase(program, env, val); // } // debugLog('program evaluated to', val); // return val; // } // const eval_phrase = (program, env, passalong) => { // debugLog('evaluating phrase'); // const phraseStart = program.shift(); // let head = eval_expression(phraseStart, env, passalong); // while (program.length && head.result.type === "function") { // debugLog('head', head); // const tail = eval_expression(program.shift(), env, head); // debugLog('tail', tail); // head = head.result.value(tail.result, passalong, tail); // } // debugLog('end of phrase, result:', head, 'start:', phraseStart); // return head; // } // const eval_expression = (expr, env) => { // debugLog('evaluating expression', expr); // let result = {result: UNDEF()}; // if (expr.type === "symbol") { // result = { // result: env[expr.value], // name: STR(expr.value), // } // } else if (expr.type === "string") { // result = { // result: expr, // } // } else if (expr.type === "boolean") { // result = { // result: expr, // } // } else if (expr.type === "thunk") { // result = { // result: expr, // } // } // debugLog('expression evaluated to', result); // return result; // } // console.log(eval_program(my_prog, my_env));