diff options
author | Mihai Bazon <mihai.bazon@gmail.com> | 2015-11-11 22:15:25 +0200 |
---|---|---|
committer | Mihai Bazon <mihai.bazon@gmail.com> | 2015-11-11 22:15:25 +0200 |
commit | 7691bebea525e96cb74d52e0bb8f294cf778c966 (patch) | |
tree | d2485ce55b215edb1846cbbe9cc3e4e3ad28725d /lib/ast.js | |
parent | 3c4346728e5067608b6393ba98e24849ac22adea (diff) | |
download | tracifyjs-7691bebea525e96cb74d52e0bb8f294cf778c966.tar.gz tracifyjs-7691bebea525e96cb74d52e0bb8f294cf778c966.zip |
Rework has_directive
It's now available during tree walking, i.e. walker.has_directive("use
asm"), rather than as part of the scope. It's thus no longer necessary
to call `figure_out_scope` before codegen. Added special bits in the
code generator to overcome the fact that it doesn't inherit from
TreeWalker.
Fix #861
Diffstat (limited to 'lib/ast.js')
-rw-r--r-- | lib/ast.js | 30 |
1 files changed, 24 insertions, 6 deletions
@@ -85,7 +85,7 @@ function DEFNODE(type, props, methods, base) { return ctor; }; -var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before file", { +var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before file literal", { }, null); var AST_Node = DEFNODE("Node", "start end", { @@ -927,27 +927,36 @@ var AST_True = DEFNODE("True", null, { function TreeWalker(callback) { this.visit = callback; this.stack = []; + this.directives = Object.create(null); }; TreeWalker.prototype = { _visit: function(node, descend) { - this.stack.push(node); + this.push(node); var ret = this.visit(node, descend ? function(){ descend.call(node); } : noop); if (!ret && descend) { descend.call(node); } - this.stack.pop(); + this.pop(node); return ret; }, parent: function(n) { return this.stack[this.stack.length - 2 - (n || 0)]; }, push: function (node) { + if (node instanceof AST_Lambda) { + this.directives = Object.create(this.directives); + } else if (node instanceof AST_Directive) { + this.directives[node.value] = this.directives[node.value] ? "up" : true; + } this.stack.push(node); }, - pop: function() { - return this.stack.pop(); + pop: function(node) { + this.stack.pop(); + if (node instanceof AST_Lambda) { + this.directives = Object.getPrototypeOf(this.directives); + } }, self: function() { return this.stack[this.stack.length - 1]; @@ -960,7 +969,16 @@ TreeWalker.prototype = { } }, has_directive: function(type) { - return this.find_parent(AST_Scope).has_directive(type); + var dir = this.directives[type]; + if (dir) return dir; + var node = this.stack[this.stack.length - 1]; + if (node instanceof AST_Scope) { + for (var i = 0; i < node.body.length; ++i) { + var st = node.body[i]; + if (!(st instanceof AST_Directive)) break; + if (st.value == type) return true; + } + } }, in_boolean_context: function() { var stack = this.stack; |