UNPKG

@alexo/lambda

Version:
101 lines (77 loc) 2.06 kB
"use strict"; const fs = require("fs"); const path = require("path"); const template = fs.readFileSync(path.join(__dirname, "template.txt"), "utf8"); let mkwire, mktwins, getfv, rename; function box(fv, list, lvl) { fv.forEach((ref, atom) => { const agent = `\\bra_{${lvl}}(${ref})`; list.push(`${atom} = ${agent}`); }); } function psi(shared, list, lvl) { shared.forEach((twins, atom) => { const left = twins.left; const right = twins.right; const agent = `\\fan_{${lvl}}`; const tree = `${agent}(${right}, ${left})`; list.push(`${atom} = ${tree}`); }); } function gamma(obj, root, list, lvl) { const node = obj.node; if ("atom" == node) { if (obj.free) { const name = `this.mkid("${obj.name}")`; const agent = `\\atom_{${name}}`; list.push(`${root} = ${agent}`); } else { const agent = `\\cro_{${lvl}}(${root})`; list.push(`${obj.name} = ${agent}`); } } else if ("abst" == node) { const id = obj.bound; const body = obj.body; const fv = getfv(body); const wire = mkwire(); const agent = fv.has(id) ? id : "\\erase"; const tree = `\\lam_{${lvl}}(${agent}, ${wire})`; list.push(`${root} = ${tree}`); gamma(body, wire, list, lvl); } else if ("appl" == node) { const wleft = mkwire(); const wright = mkwire(); const left = obj.left; const right = obj.right; const shared = mktwins(left, right); const agent = `\\app_{${lvl}}`; const tree = `${agent}(${wright}, ${root})`; const fv = getfv(right); fv.forEach((proper, atom, map) => { map.set(atom, mkwire()); }); rename(right, fv); list.push(`${wleft} = ${tree}`); gamma(left, wleft, list, lvl); gamma(right, wright, list, lvl + 1); box(fv, list, lvl); psi(shared, list, lvl); } } function encode(generic, term) { const inconfig = [ "\\read_{this.mkhole()}(!print) = root" ]; mkwire = generic.mkwire; mktwins = generic.mktwins; getfv = generic.getfv; rename = generic.rename; gamma(term, "root", inconfig, 0); inconfig.inet = template; return inconfig; } module.exports = encode;