You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

70 lines
2.0 KiB
JavaScript

var objects = require("../utils/objects"),
arrays = require("../utils/arrays");
/* Simple AST node visitor builder. */
var visitor = {
build: function(functions) {
function visit(node) {
return functions[node.type].apply(null, arguments);
}
function visitNop() { }
function visitExpression(node) {
var extraArgs = Array.prototype.slice.call(arguments, 1);
visit.apply(null, [node.expression].concat(extraArgs));
}
function visitChildren(property) {
return function(node) {
var extraArgs = Array.prototype.slice.call(arguments, 1);
arrays.each(node[property], function(child) {
visit.apply(null, [child].concat(extraArgs));
});
};
}
var DEFAULT_FUNCTIONS = {
grammar: function(node) {
var extraArgs = Array.prototype.slice.call(arguments, 1);
if (node.initializer) {
visit.apply(null, [node.initializer].concat(extraArgs));
}
arrays.each(node.rules, function(rule) {
visit.apply(null, [rule].concat(extraArgs));
});
},
initializer: visitNop,
rule: visitExpression,
named: visitExpression,
choice: visitChildren("alternatives"),
action: visitExpression,
sequence: visitChildren("elements"),
labeled: visitExpression,
text: visitExpression,
simple_and: visitExpression,
simple_not: visitExpression,
semantic_and: visitNop,
semantic_not: visitNop,
optional: visitExpression,
zero_or_more: visitExpression,
one_or_more: visitExpression,
rule_ref: visitNop,
literal: visitNop,
"class": visitNop,
any: visitNop
};
objects.defaults(functions, DEFAULT_FUNCTIONS);
return visit;
}
};
module.exports = visitor;