aboutsummaryrefslogtreecommitdiff
path: root/lib/ast.js
diff options
context:
space:
mode:
authorMihai Bazon <mihai.bazon@gmail.com>2015-11-11 22:15:25 +0200
committerMihai Bazon <mihai.bazon@gmail.com>2015-11-11 22:15:25 +0200
commit7691bebea525e96cb74d52e0bb8f294cf778c966 (patch)
treed2485ce55b215edb1846cbbe9cc3e4e3ad28725d /lib/ast.js
parent3c4346728e5067608b6393ba98e24849ac22adea (diff)
downloadtracifyjs-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.js30
1 files changed, 24 insertions, 6 deletions
diff --git a/lib/ast.js b/lib/ast.js
index e7952847..f5225d78 100644
--- a/lib/ast.js
+++ b/lib/ast.js
@@ -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;