Skip to content

Instantly share code, notes, and snippets.

@acbart
Created April 6, 2016 02:37
Show Gist options
  • Select an option

  • Save acbart/ebd2052e62372df79b025aee60ff450e to your computer and use it in GitHub Desktop.

Select an option

Save acbart/ebd2052e62372df79b025aee60ff450e to your computer and use it in GitHub Desktop.
ast.NodeVisitor for Skulpt
/* Just a silly little bit of example code */
var filename = '__main__.py';
var python_source = 'a, b = 0';
parse = Sk.parse(filename, python_source);
ast = Sk.astFromParse(parse.cst, filename, parse.flags);
/* Actually useful stuff, taken from
https://github.com/python-git/python/blob/master/Lib/ast.py#L219 */
var iter_fields = function(node) {
/** Return a list of [fieldname, value] pairs for each field in "node._fields"
that is present on *node*. Notice we skip every other field, since the odd
elements are accessor functions. **/
var fieldList = [];
for (var i = 0; i < node._fields.length; i += 2) {
var field = node._fields[i];
if (field in node) {
fieldList.push([field, node[field]]);
}
}
return fieldList;
}
/* Constructor for generic NodeVisitor */
function NodeVisitor() {};
/** Visit a node. **/
NodeVisitor.prototype.visit = function(node) {
var method_name = 'visit_' + node._astname;
if (method_name in this) {
return this[method_name](node);
} else {
return this.generic_visit(node);
}
}
/** Called if no explicit visitor function exists for a node. **/
NodeVisitor.prototype.generic_visit = function(node) {
var fieldList = iter_fields(node);
for (var i = 0; i < fieldList.length; i += 1) {
var field = fieldList[i][0], value = fieldList[i][1];
if (Array === value.constructor) {
for (var j = 0; j < value.length; j += 1) {
var subvalue = value[j];
if ("_astname" in subvalue) {
this.visit(subvalue);
}
}
} else if ("_astname" in value) {
this.visit(value);
}
}
}
/* Example of inheriting visitor */
function CodeAnalyzer() {
NodeVisitor.apply(this, Array.prototype.slice.call(arguments));
};
CodeAnalyzer.prototype = new NodeVisitor();
CodeAnalyzer.prototype.visit_Num = function(node) {
console.log(node.n.v);
};
var ca = new CodeAnalyzer();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment