def test_arrow_proc(self):
     self.run_test( '(arg, arg) -> true',
             r(0,18,r(11,2,v.sym('lambda'),0,10,r(1,3,v.sym('arg'),6,3,v.sym('arg')),14,4,v.boolean(True))))
     self.run_test( '(arg) -> true',
             r(0,13,r(6,2,v.sym('lambda'),0,5,r(1,3,v.sym('arg')),9,4,v.boolean(True))))
     self.run_test( 'arg   -> true',
             r(0,13,r(6,2,v.sym('lambda'),0,3,r(0,3,v.sym('arg')),9,4,v.boolean(True))))
     self.run_test( '() -> { a=b;c }',
             r(0,15,r(3,2,v.sym('lambda'),0,2,r(),6,9,r(8,5,v.sym('do'),8,3,r(9,1,v.sym('let'),8,1,v.sym('a'),10,1,v.sym('b')),12,1,v.sym('c')))))
 def test_desugar_expression_nested(self):
     a = [['and', 'a', 'b']]
     b = [[[
         'biplex', 'a', ['make_csp', ['quote', []], ['quote', 'b']],
         ['make_csp', ['quote', []], ['quote', v.boolean(False)]]
     ]]]
     self.assertEqual(macro_system.desugar_expression(a), b)
 def test_desugar_expression_and(self):
     a = ['and', 'a', 'b']
     syntax = macro_system.expand(a)
     b = [[
         'biplex', 'a', ['make_csp', ['quote', []], ['quote', 'b']],
         ['make_csp', ['quote', []], ['quote', v.boolean(False)]]
     ]]
     self.assertEqual(syntax.desugared(), b)
     self.assertEqual(syntax.resugar_index([0, 1]), [1])
     self.assertEqual(syntax.resugar_index([0, 2, 2, 1]), [2])
Beispiel #4
0
                  CondExpand,
                  desc="""\
.. _cond:
.. object:: (cond (<predicate> <expression>) ...)

  Multiple branching.

  Each predicate and each expression must be a VentureScript expression.
  If none of the predicates match, returns nil.
  The above is the parsed form; no special concrete syntax for `cond`
  is provided.
""")

andMacro = SyntaxRule(
    ['and', 'exp1', 'exp2'],
    ['if', 'exp1', 'exp2', v.boolean(False)],
    desc="""\
.. function:: and(<exp1>, <exp2>)

  Short-circuiting and.
""")

orMacro = SyntaxRule(['or', 'exp1', 'exp2'],
                     ['if', 'exp1', v.boolean(True), 'exp2'],
                     desc="""\
.. function:: or(<exp1>, <exp2>)

  Short-circuiting or.
""")

# Let is not directly a SyntaxRule because the pattern language does
 def test_proc(self):
     self.run_test( 'proc(arg, arg){ true }',
             r(0,22,r(0,4,v.sym('lambda'),4,10,r(5,3,v.sym('arg'),10,3,v.sym('arg')),16,4,v.boolean(True))))
     self.run_test( 'proc(){ a=b;c }',
             r(0,15,r(0,4,v.sym('lambda'),4,2,r(),8,5,r(8,5,v.sym('do'),8,3,r(9,1,v.sym('let'),8,1,v.sym('a'),10,1,v.sym('b')),12,1,v.sym('c')))))
    def test_the_rest_of_the_shizzle(self):
        self.run_legacy_test( 'a**b**c',
                [[v.sym('pow'), v.sym('a'), [v.sym('pow'), v.sym('b'), v.sym('c')]]],
                'exponent')
        self.run_legacy_test( 'a**(b**c)',
                [[v.sym('pow'), v.sym('a'), [v.sym('pow'), v.sym('b'), v.sym('c')]]],
                'exponent')
        self.run_legacy_test( '(a**b)**c',
                [[v.sym('pow'), [v.sym('pow'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'exponent')
        self.run_legacy_test( '((a**b))**c',
                [[v.sym('pow'), [v.sym('pow'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'exponent')
        for x, y in boolean_and_ops + boolean_or_ops + comparison_ops + equality_ops + add_sub_ops + mul_div_ops:
            self.run_legacy_test( '(a ' + x + ' b)**c',
                    [[v.sym('pow'),[v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'exponent')



        # Multiplication and division
        #
        self.run_legacy_test( 'a*b/c',
                [[v.sym('div'),[v.sym('mul'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'mul_div')
        self.run_legacy_test( 'a/b*c',
                [[v.sym('mul'),[v.sym('div'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'mul_div')
        # Don't collapse redundant identities
        self.run_legacy_test( '(a*b)/c',
                [[v.sym('div'),[v.sym('mul'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'mul_div')
        self.run_legacy_test( '(a/b)*c',
                [[v.sym('mul'),[v.sym('div'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'mul_div')
        self.run_legacy_test( 'a*(b/c)',
                [[v.sym('mul'), v.sym('a'), [v.sym('div'), v.sym('b'), v.sym('c')]]],
                'mul_div')
        self.run_legacy_test( 'a/(b*c)',
                [[v.sym('div'), v.sym('a'), [v.sym('mul'), v.sym('b'), v.sym('c')]]],
                'mul_div')
        self.run_legacy_test( 'a/((b/c))',
                [[v.sym('div'), v.sym('a'), [v.sym('div'), v.sym('b'), v.sym('c')]]],
                'mul_div')
        self.run_legacy_test( 'a*(((b*c)))',
                [[v.sym('mul'), v.sym('a'), [v.sym('mul'), v.sym('b'), v.sym('c')]]],
                'mul_div')
        # Test that mul_div has medium precedence
        for x, y in exponent_ops:
            self.run_legacy_test( 'a' + x + 'b*c',
                    [[v.sym('mul'), [v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'mul_div')
        for x, y in boolean_and_ops + boolean_or_ops + equality_ops + comparison_ops + add_sub_ops:
            self.run_legacy_test( '(a ' + x + ' b)*c',
                    [[v.sym('mul'), [v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'mul_div')
        for x, y in exponent_ops:
            self.run_legacy_test( '(a' + x + 'b)*c',
                    [[v.sym('mul'),[v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'mul_div')



        # Addition and subtraction
        #
        self.run_legacy_test( 'a+b-c',
                [[v.sym('sub'),[v.sym('add'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'add_sub')
        self.run_legacy_test( 'a-b+c',
                [[v.sym('add'),[v.sym('sub'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'add_sub')
        self.run_legacy_test( '(a+b)-c',
                [[v.sym('sub'),[v.sym('add'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'add_sub')
        self.run_legacy_test( '(a-b)+c',
                [[v.sym('add'),[v.sym('sub'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'add_sub')
        self.run_legacy_test( 'a+(b-c)',
                [[v.sym('add'), v.sym('a'), [v.sym('sub'), v.sym('b'), v.sym('c')]]],
                'add_sub')
        self.run_legacy_test( 'a-(b+c)',
                [[v.sym('sub'), v.sym('a'), [v.sym('add'), v.sym('b'), v.sym('c')]]],
                'add_sub')
        self.run_legacy_test( 'a-((b-c))',
                [[v.sym('sub'), v.sym('a'), [v.sym('sub'), v.sym('b'), v.sym('c')]]],
                'add_sub')
        self.run_legacy_test( 'a+(((b+c)))',
                [[v.sym('add'), v.sym('a'), [v.sym('add'), v.sym('b'), v.sym('c')]]],
                'add_sub')
        # Test that add_sub has medium precedence
        for x, y in exponent_ops + mul_div_ops:
            self.run_legacy_test( 'a' + x + 'b+c',
                    [[v.sym('add'), [v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'add_sub')
        for x, y in boolean_and_ops + boolean_or_ops + equality_ops + comparison_ops:
            self.run_legacy_test( '(a ' + x + ' b)+c',
                    [[v.sym('add'), [v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'add_sub')
        # Don't collapse identities with greater precedence
        for x, y in exponent_ops + mul_div_ops:
            self.run_legacy_test( '(a' + x + 'b)+c',
                    [[v.sym('add'),[v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'add_sub')

        # Comparison
        #
        self.run_legacy_test( 'a < b < c',
                [[v.sym('lt'),[v.sym('lt'), v.sym('a'), v.sym('b')],v.sym('c')]],
                'comparison')
        # Test all operators
        for x, y in comparison_ops:
            self.run_legacy_test( 'a ' + x + ' b',
                    [[v.sym(y), v.sym('a'), v.sym('b')]],
                    'comparison')
        # Test that comparison has low precedence
        for x, y in add_sub_ops + mul_div_ops + exponent_ops:
            self.run_legacy_test( 'a' + x + 'b < c',
                    [[v.sym('lt'), [v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'comparison')
        for x, y in boolean_and_ops + boolean_or_ops + equality_ops:
            self.run_legacy_test( '(a' + x + 'b)<c',
                    [[v.sym('lt'), [v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'comparison')
        for x, y in mul_div_ops + exponent_ops + add_sub_ops:
            self.run_legacy_test( '(a' + x + 'b) < c',
                    [[v.sym('lt'),[v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'comparison')
        self.run_legacy_test( '(a > b) < (c > d)',
                [[v.sym('lt'),[v.sym('gt'), v.sym('a'), v.sym('b')], [v.sym('gt'), v.sym('c'), v.sym('d')]]],
                'comparison')
        self.run_legacy_test( 'a < ((b > c))',
                [[v.sym('lt'), v.sym('a'), [v.sym('gt'), v.sym('b'), v.sym('c')]]],
                'comparison')

        # Equality
        #
        self.run_legacy_test( 'a==b==c',
                [[v.sym('eq'),[v.sym('eq'), v.sym('a'), v.sym('b')],v.sym('c')]],
                'equality')
        # Test all operators
        for x, y in equality_ops:
            self.run_legacy_test( 'a' + x + 'b',
                    [[v.sym(y), v.sym('a'), v.sym('b')]],
                    'equality')
        # Test that equality has low precedence
        for x, y in add_sub_ops + mul_div_ops + exponent_ops + comparison_ops:
            self.run_legacy_test( 'a ' + x + ' b==c',
                    [[v.sym('eq'), [v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'equality')
        for x, y in boolean_and_ops + boolean_or_ops:
            self.run_legacy_test( '(a' + x + 'b)==c',
                    [[v.sym('eq'), [v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'equality')
        for x, y in mul_div_ops + exponent_ops + add_sub_ops + comparison_ops:
            self.run_legacy_test( '(a ' + x + ' b)==c',
                    [[v.sym('eq'),[v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'equality')
        self.run_legacy_test( '(a!=b)==(c!=d)',
                [[v.sym('eq'),[v.sym('neq'), v.sym('a'), v.sym('b')], [v.sym('neq'), v.sym('c'), v.sym('d')]]],
                'equality')
        self.run_legacy_test( 'a==((b!=c))',
                [[v.sym('eq'), v.sym('a'), [v.sym('neq'), v.sym('b'), v.sym('c')]]],
                'equality')


        # And
        #
        self.run_legacy_test( 'a && b && c',
                [[v.sym('and'), [v.sym('and'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'boolean_and')
        self.run_legacy_test( '(a&&b)&&c',
                [[v.sym('and'), [v.sym('and'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'boolean_and')
        self.run_legacy_test( 'a&&(b&&c)',
                [[v.sym('and'), v.sym('a'), [v.sym('and'), v.sym('b'), v.sym('c')]]],
                'boolean_and')
        self.run_legacy_test( 'a&&((b&&c))',
                [[v.sym('and'), v.sym('a'), [v.sym('and'), v.sym('b'), v.sym('c')]]],
                'boolean_and')
        # Test that and has low precedence
        for x, y in comparison_ops + equality_ops + add_sub_ops + mul_div_ops + exponent_ops:
            self.run_legacy_test( 'a ' + x + ' b&&c',
                    [[v.sym('and'), [v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'boolean_and')
        for x, y in boolean_or_ops:
            self.run_legacy_test( '(a' + x + 'b)&&c',
                    [[v.sym('and'), [v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'boolean_and')
        for x, y in comparison_ops + equality_ops + mul_div_ops + exponent_ops + add_sub_ops:
            self.run_legacy_test( '(a ' + x + ' b)&&c',
                    [[v.sym('and'),[v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'boolean_and')

        # Or
        #
        self.run_legacy_test( 'a || b || c',
                [[v.sym('or'), [v.sym('or'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'boolean_or')
        self.run_legacy_test( '(a||b)||c',
                [[v.sym('or'), [v.sym('or'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'boolean_or')
        self.run_legacy_test( 'a||(b||c)',
                [[v.sym('or'), v.sym('a'), [v.sym('or'), v.sym('b'), v.sym('c')]]],
                'boolean_or')
        self.run_legacy_test( 'a||((b||c))',
                [[v.sym('or'), v.sym('a'), [v.sym('or'), v.sym('b'), v.sym('c')]]],
                'boolean_or')
        # Test that or has low precedence
        for x, y in comparison_ops + equality_ops + add_sub_ops + mul_div_ops + exponent_ops:
            self.run_legacy_test( 'a ' + x + ' b||c',
                    [[v.sym('or'), [v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'boolean_or')
        for x, y in comparison_ops + equality_ops + mul_div_ops + exponent_ops + add_sub_ops:
            self.run_legacy_test( '(a ' + x + ' b)||c',
                    [[v.sym('or'),[v.sym(y), v.sym('a'), v.sym('b')], v.sym('c')]],
                    'boolean_or')


        # Expression
        #
        #identity
        self.run_legacy_test( '(a)',
                [v.sym('a')],
                'expression')
        #let
        self.run_legacy_test( '{ a=b; c=d; e}',
                [[v.sym('do'), [v.sym('let'),v.sym('a'),v.sym('b')], [v.sym('let'),v.sym('c'),v.sym('d')], v.sym('e')]],
                'expression')
        #proc
        self.run_legacy_test( 'proc(){ a=2; b }',
                [[v.sym('lambda'),[],[v.sym('do'),[v.sym('let'), v.sym('a'), v.number(2.0)], v.sym('b')]]],
                'expression')
        #sym
        self.run_legacy_test( 'b',
                [v.sym('b')],
                'expression')
        #literal
        self.run_legacy_test( '3',
                [v.number(3.0)],
                'expression')
        #if_else
        self.run_legacy_test( 'if (a) { b }else {c}',
                [[v.sym('if'), v.sym('a'), v.sym('b'), v.sym('c')]],
                'expression')
        #function application
        self.run_legacy_test( 'a(b)(c)',
                [[[v.sym('a'), v.sym('b')], v.sym('c')]],
                'expression')
        #exponentiation
        self.run_legacy_test( 'a**b**c',
                [[v.sym('pow'), v.sym('a'), [v.sym('pow'), v.sym('b'), v.sym('c')]]],
                'expression')
        #mul_div
        self.run_legacy_test( 'a*b/c',
                [[v.sym('div'),[v.sym('mul'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'expression')
        #add_sub
        self.run_legacy_test( 'a+b-c',
                [[v.sym('sub'),[v.sym('add'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'expression')
        #comparision
        self.run_legacy_test( 'a==b==c',
                [[v.sym('eq'), [v.sym('eq'), v.sym('a'), v.sym('b')], v.sym('c')]],
                'expression')
        #boolean
        self.run_legacy_test( 'true && true || true',
                [[v.sym('or'), [v.sym('and'), v.boolean(True), v.boolean(True)], v.boolean(True)]],
                'expression')


        #fancy expression
        self.run_legacy_test( '''
        (1 + 4)/3**5.11 + 32*4 - 2
        ''',
                [[v.sym('sub'),
                            [v.sym('add'),
                                [v.sym('div'),[v.sym('add'),v.number(1.0),v.number(4.0)],[v.sym('pow'),v.number(3.0),v.number(5.11)]],
                                [v.sym('mul'),v.number(32.0),v.number(4.0)],
                                ],
                            v.number(2.0)]],
                'expression')