import NumericOperand from './NumericOperand' ; import ExpressionOperand from './ExpressionOperand' ; import ListOfNumbersExpression from './ListOfNumbersExpression' ; import BitwiseOperationExpression from './BitwiseOperationExpression' ; import { ExpressionInput , ExpressionInputItem , NumberBase } from './expression-interfaces' ; export { default as NumericOperand } from './NumericOperand' ; export { default as ExpressionOperand } from './ExpressionOperand' ; export { default as ListOfNumbersExpression } from './ListOfNumbersExpression' ; export { default as BitwiseOperationExpression } from './BitwiseOperationExpression' ; interface IExpressionParserFactory { canCreate : ( input : string ) => boolean ; create : ( input : string ) => ExpressionInput ; } ; class ExpressionParser { factories : IExpressionParserFactory [ ] ; constructor ( ) { this . factories = [ ] ; } ; canParse ( input ) { var trimmed = input . replace ( /^\s+|\s+$/ , '' ) ; var i = this . factories . length - 1 ; for ( ; i >= 0 ; i -- ) { if ( this . factories [ i ] . canCreate ( trimmed ) === true ) { return true ; } } return false ; } ; parse ( input ) { var trimmed = input . replace ( /^\s+|\s+$/ , '' ) ; var i = 0 , l = this . factories . length , factory ; for ( ; i < l ; i ++ ) { factory = this . factories [ i ] ; if ( factory . canCreate ( trimmed ) == true ) { return factory . create ( trimmed ) ; } } return null ; } ; parseOperand ( input ) { return NumericOperand . parse ( input ) ; } ; createOperand ( number , base ) { return NumericOperand . create ( number , base ) ; } ; addFactory ( factory ) { this . factories . push ( factory ) ; } } class ListOfNumbersExpressionFactory implements IExpressionParserFactory { regex : RegExp ; constructor ( ) { this . regex = /^(-?(?:\d+|0x[\d,a-f]+|0b[0-1])\s?)+$/ ; } canCreate ( input ) { return this . regex . test ( input ) ; } ; create ( input ) { var matches = this . regex . exec ( input ) as RegExpExecArray ; var numbers = [ ] as NumericOperand [ ] ; var input = matches . input ; input . split ( ' ' ) . forEach ( ( n ) => { if ( n . trim ( ) . length > 0 ) { numbers . push ( NumericOperand . parse ( n . trim ( ) ) ) ; } } ) ; return new ListOfNumbersExpression ( input , numbers ) ; } } class BitwiseOperationExpressionFactory implements IExpressionParserFactory { fullRegex : RegExp ; regex : RegExp ; constructor ( ) { this . fullRegex = /^((<<|>>|>>>|\||\&|\^)?(~?-?([b,x,a-f,0-9]+)))+$/ ; this . regex = /(<<|>>|>>>|\||\&|\^)?(~?-?(?:[b,x,a-f,0-9]+))/g ; } canCreate ( input ) { this . fullRegex . lastIndex = 0 ; return this . fullRegex . test ( this . normalizeString ( input ) ) ; } ; create ( input ) { var m , operands = [ ] , normalizedString = this . normalizeString ( input ) ; while ( ( m = this . regex . exec ( normalizedString ) ) != null ) { operands . push ( this . parseMatch ( m ) ) ; } return new BitwiseOperationExpression ( normalizedString , operands ) ; } ; parseMatch ( m ) { var input = m [ 0 ] , sign = m [ 1 ] , num = m [ 2 ] ; var parsed = null ; if ( num . indexOf ( '~' ) == 0 ) { parsed = new ExpressionOperand ( num , NumericOperand . parse ( num . substring ( 1 ) ) , '~' ) ; } else { parsed = NumericOperand . parse ( num ) ; } if ( sign == null ) { return parsed as ExpressionOperand ; } else { return new ExpressionOperand ( input , parsed as NumericOperand , sign ) ; } } ; normalizeString ( input ) { return input . replace ( /\s+/g , '' ) ; } ; } var parser = new ExpressionParser ( ) ; parser . addFactory ( new ListOfNumbersExpressionFactory ( ) ) ; parser . addFactory ( new BitwiseOperationExpressionFactory ( ) ) ; export { parser } ;