summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2015-01-09 19:49:51 -0800
committerJohn MacFarlane <jgm@berkeley.edu>2015-01-09 19:49:51 -0800
commit85dc5b4171bfd71b0737aed7039deb5cc750a405 (patch)
tree48479cedcc45c9256a3465cf6ae18b3c3f342cc2
parent65059ef600773928a6c9b9c96657a541a6286650 (diff)
Non-recursive version of toAST().
Closes #272.
-rw-r--r--js/lib/node.js47
1 files changed, 30 insertions, 17 deletions
diff --git a/js/lib/node.js b/js/lib/node.js
index e57a281..6c15761 100644
--- a/js/lib/node.js
+++ b/js/lib/node.js
@@ -162,34 +162,47 @@ Node.prototype.walker = function() {
return walker;
};
-Node.prototype.toAST = function() {
- var children;
- var cur;
- var result = { t: this.t };
-
+var toASTNode = function(node) {
+ var result = {};
var propsToShow = ['t', 'literal', 'list_data', 'sourcepos',
'info', 'level'];
for (var i = 0; i < propsToShow.length; i++) {
var prop = propsToShow[i];
- if (this[prop] !== undefined) {
- result[prop] = this[prop];
+ if (node[prop] !== undefined) {
+ result[prop] = node[prop];
}
}
+ return result;
+};
- if (isContainer(this)) {
- children = [];
- if (this.firstChild) {
- cur = this.firstChild;
- while (cur) {
- // TODO avoid recursion here...
- children.push(cur.toAST());
- cur = cur.next;
+Node.prototype.toAST = function() {
+ var childrenStack = [];
+ var walker = this.walker();
+ var event;
+ while ((event = walker.next())) {
+ var node = event.node;
+ var entering = event.entering;
+ var container = node.isContainer();
+ var astnode;
+
+ if (container) {
+ if (entering) {
+ childrenStack.push([]);
+ } else {
+ astnode = toASTNode(node);
+ astnode.children = childrenStack.pop();
+ if (childrenStack.length > 0) {
+ childrenStack[childrenStack.length - 1].push(astnode);
+ }
}
- result.children = children;
+ } else {
+ astnode = toASTNode(node);
+ childrenStack[childrenStack.length - 1].push(astnode);
}
}
- return result;
+
+ return astnode;
};