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.

95 lines
2.3 KiB
JavaScript

"use strict";
const util = require( "../util" );
const __slice = Array.prototype.slice;
// Simple AST node visitor builder.
const visitor = {
build( functions ) {
function visit( node ) {
return functions[ node.type ].apply( null, arguments );
}
const visitNop = util.noop;
function visitExpression( node ) {
const extraArgs = __slice.call( arguments, 1 );
visit.apply( null, [ node.expression ].concat( extraArgs ) );
}
function visitChildren( children, extraArgs ) {
const args = [ void 0 ].concat( extraArgs );
const cb = extraArgs.length
? function withArgs( child ) {
args[ 0 ] = child;
visit.apply( null, args );
}
: function withoutArgs( child ) {
visit( child );
};
children.forEach( cb );
}
const DEFAULT_FUNCTIONS = {
grammar( node ) {
const extraArgs = __slice.call( arguments, 1 );
if ( node.initializer ) {
visit.apply( null, [ node.initializer ].concat( extraArgs ) );
}
node.rules.forEach( rule => {
visit.apply( null, [ rule ].concat( extraArgs ) );
} );
},
initializer: visitNop,
rule: visitExpression,
named: visitExpression,
choice: util.createVisitor( "alternatives", visitChildren ),
action: visitExpression,
sequence: util.createVisitor( "elements", visitChildren ),
labeled: visitExpression,
text: visitExpression,
simple_and: visitExpression,
simple_not: visitExpression,
optional: visitExpression,
zero_or_more: visitExpression,
one_or_more: visitExpression,
group: visitExpression,
semantic_and: visitNop,
semantic_not: visitNop,
rule_ref: visitNop,
literal: visitNop,
class: visitNop,
any: visitNop
};
util.extend( functions, DEFAULT_FUNCTIONS );
return visit;
}
};
module.exports = visitor;