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])
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')