import { lang } from './lang' ; import { op } from './operator' ; test ( 'operator' , ( ) => { const math = op `
    left  "+"   : ${ ( l , r ) => l + r }
          "-"   : ${ ( l , r ) => l - r }
    left  "*"   : ${ ( l , r ) => l * r }
          "/"   : ${ ( l , r ) => l / r }
          "%"   : ${ ( l , r ) => l % r }
    right "**"  : ${ ( l , r ) => l ** r }
    pre   "-"   : ${ x => - x }
    post  "++"  : ${ x => x + 1 }
          "--"  : ${ x => x - 1 }
  ` ; expect ( math `3 * 4 / 5 * 6` ) . toEqual ( ( ( 3 * 4 ) / 5 ) * 6 ) ; expect ( math `3 * (4 / 5) * 6` ) . toEqual ( 3 * ( 4 / 5 ) * 6 ) ; expect ( math `
    1
    + 2
    * 3
    - 4` ) . toEqual ( 1 + 2 * 3 - 4 ) ; expect ( math `2 ** 3 ** 2` ) . toEqual ( 2 ** ( 3 ** 2 ) ) ; } ) ; test ( 'operator invalid syntax' , ( ) => { expect ( ( ) => { op `left "a>" : ${ ( l , r ) => l + r }` . compile ( ) ; } ) . toThrow ( ) ; expect ( ( ) => { op `left ${ 1 } : ${ ( l , r ) => l + r }` . compile ( ) ; } ) . toThrow ( ) ; expect ( ( ) => { op `
    left  "+"   : ${ ( l , r ) => l + r }
          "+"   : ${ ( l , r ) => l - r }
  ` . compile ( ) ; } ) . toThrow ( ) ; } ) ; test ( 'operator parser include' , ( ) => { const expr = lang `
    Expr = include ${ op `
      left "++" : ${ ( xs , ys ) => xs . concat ( ys ) }
      root RootExpr
    ` };
    RootExpr  = #[ Expr ** "," ]
              | value;
  ` ; expect ( expr `["foo", "bar"] ++ ["baz"]` ) . toEqual ( [ 'foo' , 'bar' , 'baz' ] ) ; } ) ; test ( 'operator longest match first' , ( ) => { const eq = op `
    left  "is"        : ${ ( l , r ) => l === r }
          "is" "not"  : ${ ( l , r ) => l !== r }
    pre   "not"       : ${ l => ! l }
  ` ; expect ( eq `4 is 4` ) . toEqual ( true ) ; expect ( eq `4 is not 3` ) . toEqual ( true ) ; expect ( eq `4 is (not 3)` ) . toEqual ( false ) ; } ) ;