diff options
author | Elizabeth (Lizzy) Hunt <elizabeth.hunt@simponic.xyz> | 2023-04-22 23:42:19 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-22 23:42:19 -0600 |
commit | 560ca09223284abc7f8ab4840adfbc2cbc73177a (patch) | |
tree | d32908c77bda0787fcf2f4a72cbe47f797c6c494 /static/js/lang.js | |
parent | 21a0f4df60c29c5babc3635d2b69d6eb965ee334 (diff) | |
download | tabloid-fake-closure-560ca09223284abc7f8ab4840adfbc2cbc73177a.tar.gz tabloid-fake-closure-560ca09223284abc7f8ab4840adfbc2cbc73177a.zip |
Closure (#1)
* Add 'closures' and sample programs, lodash too
* Remove prettier garbage
Diffstat (limited to 'static/js/lang.js')
-rw-r--r-- | static/js/lang.js | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/static/js/lang.js b/static/js/lang.js index 50fe098..92ff133 100644 --- a/static/js/lang.js +++ b/static/js/lang.js @@ -565,6 +565,18 @@ class Environment { } return rv; } + addClosure(node, closure) { + if (Array.isArray(node)) { + for (let i = 0; i < node.length; ++i) + node[i] = this.addClosure(node[i], closure); + } else if (typeof node === "object") { + for (let key of Object.keys(node).filter((key) => key != "closure")) { + node[key] = this.addClosure(node[key], closure); + node.closure = closure; + } + } + return node; + } eval(node) { const scope = this.scopes[this.scopes.length - 1]; @@ -574,7 +586,10 @@ class Environment { case N.BoolLiteral: return node.val; case N.FnDecl: { - scope[node.name] = node; + node.closure = _.cloneDeep({ ...node.closure, ...scope }); + node.body = this.addClosure(node.body, node.closure); + + scope[node.name] = _.cloneDeep(node); return node; } case N.FnCall: { @@ -610,6 +625,13 @@ class Environment { } i --; } + if (node.closure && node.closure.hasOwnProperty(node.val)) { + const val = node.closure[node.val]; + if (typeof val === "object") { + return this.eval(val); + } + return val; + } throw new Error(`Runtime error: Undefined variable "${node.val}"`); } case N.Assignment: { |