@ -1,5 +1,6 @@
/* Like Python's |range|, but without |step|. */
function range ( start , stop ) {
var utils = {
/* Like Python's |range|, but without |step|. */
range : function ( start , stop ) {
if ( stop === undefined ) {
stop = start ;
start = 0 ;
@ -10,18 +11,18 @@ function range(start, stop) {
result [ i ] = j ;
}
return result ;
}
} ,
function find ( array , callback ) {
find : function ( array , callback ) {
var length = array . length ;
for ( var i = 0 ; i < length ; i ++ ) {
if ( callback ( array [ i ] ) ) {
return array [ i ] ;
}
}
}
} ,
function contains ( array , value ) {
contains : function ( array , value ) {
/ *
* Stupid IE does not have Array . prototype . indexOf , otherwise this function
* would be a one - liner .
@ -33,77 +34,77 @@ function contains(array, value) {
}
}
return false ;
}
} ,
function each ( array , callback ) {
each : function ( array , callback ) {
var length = array . length ;
for ( var i = 0 ; i < length ; i ++ ) {
callback ( array [ i ] , i ) ;
}
}
} ,
function map ( array , callback ) {
map : function ( array , callback ) {
var result = [ ] ;
var length = array . length ;
for ( var i = 0 ; i < length ; i ++ ) {
result [ i ] = callback ( array [ i ] , i ) ;
}
return result ;
}
} ,
function pluck ( array , key ) {
return map ( array , function ( e ) { return e [ key ] ; } ) ;
}
pluck : function ( array , key ) {
return utils . map ( array , function ( e ) { return e [ key ] ; } ) ;
} ,
function keys ( object ) {
keys : function ( object ) {
var result = [ ] ;
for ( var key in object ) {
result . push ( key ) ;
}
return result ;
}
} ,
function values ( object ) {
values : function ( object ) {
var result = [ ] ;
for ( var key in object ) {
result . push ( object [ key ] ) ;
}
return result ;
}
} ,
function clone ( object ) {
clone : function ( object ) {
var result = { } ;
for ( var key in object ) {
result [ key ] = object [ key ] ;
}
return result ;
}
} ,
function defaults ( object , defaults ) {
defaults : function ( object , defaults ) {
for ( var key in defaults ) {
if ( object [ key ] === undefined ) {
object [ key ] = defaults [ key ] ;
}
}
}
} ,
/ *
/ *
* The code needs to be in sync with the code template in the compilation
* function for "action" nodes .
* /
function subclass ( child , parent ) {
subclass : function ( child , parent ) {
function ctor ( ) { this . constructor = child ; }
ctor . prototype = parent . prototype ;
child . prototype = new ctor ( ) ;
}
} ,
/ *
/ *
* Returns a string padded on the left to a desired length with a character .
*
* The code needs to be in sync with the code template in the compilation
* function for "action" nodes .
* /
function padLeft ( input , padding , length ) {
padLeft : function ( input , padding , length ) {
var result = input ;
var padLength = length - input . length ;
@ -112,16 +113,16 @@ function padLeft(input, padding, length) {
}
return result ;
}
} ,
/ *
/ *
* Returns an escape sequence for given character . Uses \ x for characters <=
* 0xFF to save space , \ u for the rest .
*
* The code needs to be in sync with the code template in the compilation
* function for "action" nodes .
* /
function escape ( ch ) {
escape : function ( ch ) {
var charCode = ch . charCodeAt ( 0 ) ;
var escapeChar ;
var length ;
@ -134,22 +135,22 @@ function escape(ch) {
length = 4 ;
}
return '\\' + escapeChar + padLeft ( charCode . toString ( 16 ) . toUpperCase ( ) , '0' , length ) ;
}
return '\\' + escapeChar + utils . padLeft ( charCode . toString ( 16 ) . toUpperCase ( ) , '0' , length ) ;
} ,
/ *
/ *
* Surrounds the string with quotes and escapes characters inside so that the
* result is a valid JavaScript string .
*
* The code needs to be in sync with the code template in the compilation
* function for "action" nodes .
* /
function quote ( s ) {
quote : function ( s ) {
/ *
* ECMA - 262 , 5 th ed . , 7.8 . 4 : All characters may appear literally in a string
* literal except for the closing quote character , backslash , carriage return ,
* line separator , paragraph separator , and line feed . Any character may
* appear in the form of an escape sequence .
* literal except for the closing quote character , backslash , carriage
* return , line separator , paragraph separator , and line feed . Any character
* may appear in the form of an escape sequence .
*
* For portability , we also escape escape all control and non - ASCII
* characters . Note that "\0" and "\v" escape sequences are not used because
@ -163,15 +164,15 @@ function quote(s) {
. replace ( /\n/g , '\\n' ) // line feed
. replace ( /\f/g , '\\f' ) // form feed
. replace ( /\r/g , '\\r' ) // carriage return
. replace ( /[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g , escape )
. replace ( /[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g , utils . escape )
+ '"' ;
}
} ,
/ *
/ *
* Escapes characters inside the string so that it can be used as a list of
* characters in a character class of a regular expression .
* /
function quoteForRegexpClass ( s ) {
quoteForRegexpClass : function ( s ) {
/ *
* Based on ECMA - 262 , 5 th ed . , 7.8 . 5 & 15.10 . 1.
*
@ -189,21 +190,25 @@ function quoteForRegexpClass(s) {
. replace ( /\v/g , '\\x0B' ) // vertical tab
. replace ( /\f/g , '\\f' ) // form feed
. replace ( /\r/g , '\\r' ) // carriage return
. replace ( /[\x01-\x08\x0E-\x1F\x80-\uFFFF]/g , escape ) ;
}
. replace ( /[\x01-\x08\x0E-\x1F\x80-\uFFFF]/g , utils . escape ) ;
} ,
/ *
/ *
* Builds a node visitor -- a function which takes a node and any number of
* other parameters , calls an appropriate function according to the node type ,
* passes it all its parameters and returns its value . The functions for various
* node types are passed in a parameter to | buildNodeVisitor | as a hash .
* passes it all its parameters and returns its value . The functions for
* various node types are passed in a parameter to | buildNodeVisitor | as a
* hash .
* /
function buildNodeVisitor ( functions ) {
buildNodeVisitor : function ( functions ) {
return function ( node ) {
return functions [ node . type ] . apply ( null , arguments ) ;
} ;
}
} ,
findRuleByName : function ( ast , name ) {
return utils . find ( ast . rules , function ( r ) { return r . name === name ; } ) ;
}
} ;
function findRuleByName ( ast , name ) {
return find ( ast . rules , function ( r ) { return r . name === name ; } ) ;
}
module . exports = utils ;