def test_simple_map_empty(self):
     # f: (e){ e + 1 }
     # {
     #   map: (list){
     #     ([f(list[0])] + me(list[1:])) or []
     #   }
     #   map([])
     # }()
     result = evaluate_module(items={
         'f': LV(lambda: create_scope(
             defaults=[('e', None)],
             expression=LV(
                 lambda: call(attribute(create_string('+'), resolve('e')), [(None, LV(lambda: create_number(1)))])))),
     }, expression=LV(lambda: call(create_scope(items={
         'map': LV(lambda: create_scope(
             defaults=[('list', None)],
             expression=LV(lambda: call(attribute(create_string('or'), call(
                 attribute(create_string('+'), create_list(
                     [call(resolve('f'), [(None, LV(lambda: attribute(create_number(0), resolve('list'))))])])),
                 [(None, LV(lambda: call(
                     resolve('me'),
                     [(None, LV(lambda: slice(resolve('list'), 1)))]
                 )))]
             )), [(None, LV(lambda: create_list([])))])))),
     }, expression=LV(lambda: call(resolve('map'), [(None, LV(lambda: create_list([])))]))), [])))
     self._test(result, [])
 def test_simple_map(self):
     # f: (e){ e + 1 }
     # {
     #   map: (list){
     #     ([f(list[0])] + me(list[1:])) or []
     #   }
     #   map([0, 1, 2])
     # }()
     result = evaluate_module(
         items={
             'f':
             LV(lambda: create_scope(
                 defaults=[('e', None)],
                 expression=LV(lambda: call(
                     attribute(create_string('+'), resolve('e')), [(
                         None, LV(lambda: create_number(1)))])))),
         },
         expression=LV(lambda: call(
             create_scope(items={
                 'map':
                 LV(lambda: create_scope(
                     defaults=[('list', None)],
                     expression=LV(lambda: call(
                         attribute(
                             create_string('or'),
                             call(
                                 attribute(
                                     create_string('+'),
                                     create_list([
                                         call(resolve('f'), [(
                                             None,
                                             LV(lambda: attribute(
                                                 create_number(0),
                                                 resolve('list'))))])
                                     ])),
                                 [(None,
                                   LV(lambda: call(resolve('me'), [(
                                       None,
                                       LV(lambda: slice(resolve('list'), 1)
                                          ))])))])),
                         [(None, LV(lambda: create_list([])))])))),
             },
                          expression=LV(lambda: call(
                              resolve('map'), [(None,
                                                LV(lambda: create_list([
                                                    create_number(0),
                                                    create_number(1),
                                                    create_number(2)
                                                ])))]))), [])))
     self._test(result, [1, 2, 3])
 def test_12_infinite_recursion(self):
     # sum: (list){
     #   (me(list[1:] + list[0]) or 0
     # }
     # sum([4, 8])
     # this fails because slicing never fails, so instead of calling the
     # failing term list[0] and breaking out we just infinitely call [][1:]
     result = evaluate_module(
         items={
             'sum':
             LV(lambda: create_scope(
                 defaults=[('list', None)],
                 expression=LV(lambda: call(
                     attribute(
                         create_string('or'),
                         call(
                             attribute(
                                 create_string('+'),
                                 call(resolve('me'), [
                                     (None,
                                      LV(lambda: slice(resolve('list'), 1)))
                                 ])), [(None,
                                        LV(lambda: attribute(
                                            create_number(0),
                                            resolve('list'))))])),
                     [(None, LV(lambda: create_number(0)))]))))
         },
         expression=LV(lambda: call(resolve('sum'), [(
             None,
             LV(lambda: create_list([create_number(4),
                                     create_number(8)])))])))
     self._test(result, 12)
 def test_e12(self):
     # sum: (list){
     #   (list[0] + me(list[1:]) or 0
     # }
     # sum([3, 3, 3, 3])
     result = evaluate_module(items={
         'sum':
         LV(lambda: create_scope(
             defaults=[('list', None)],
             expression=LV(lambda: call(
                 attribute(
                     create_string('or'),
                     call(
                         attribute(create_string('+'),
                                   get(create_number(0), resolve('list'))),
                         [(None,
                           LV(lambda: call(resolve('me'), [
                               (None, LV(lambda: slice(resolve('list'), 1)))
                           ])))])), [(None, LV(lambda: create_number(0)))])
                           )))
     },
                              expression=LV(lambda: call(
                                  resolve('sum'), [(None,
                                                    LV(lambda: create_list([
                                                        create_number(3),
                                                        create_number(3),
                                                        create_number(3),
                                                        create_number(3)
                                                    ])))])))
     self._test(result, 12)
 def test_list_length2(self):
     # [0, 1, 2].length()
     result = evaluate_module(
         expression=LV(lambda: call(attribute(create_string('length'), create_list([create_number(0),
                                                                                    create_number(1),
                                                                                    create_number(2)])), [])))
     self._test(result, 3)
 def test_list_length2(self):
     # [0, 1, 2].length()
     result = evaluate_module(expression=LV(lambda: call(
         attribute(
             create_string('length'),
             create_list(
                 [create_number(0),
                  create_number(1),
                  create_number(2)])), [])))
     self._test(result, 3)
 def test_map(self):
     # wrapper: (list){
     #   map: (f){
     #     map: (list){
     #       ([f(list[0])] + me(list[1:])) or []
     #     }
     #     map(list)
     #   }
     # }
     # wrapper([0, 3, 2, 1]).map((e){ e + 1 })
     result = evaluate_module(items={
         'wrapper': LV(lambda: create_scope(defaults=[('list', None)], items={
             'map': LV(lambda: create_scope(defaults=[('f', None)], items={
                 'map': LV(lambda: create_scope(
                     defaults=[('list', None)],
                     expression=LV(lambda: call(attribute(create_string('or'), call(
                         attribute(create_string('+'),
                                   create_list([call(resolve('f'),
                                                     [(None, LV(lambda: attribute(create_number(0), resolve('list'))))])])),
                         [(None, LV(lambda: call(
                             resolve('me'),
                             [(None, LV(lambda: slice(resolve('list'), 1)))]
                         )))]
                     )), [(None, LV(lambda: create_list([])))])))),
             }, expression=LV(lambda: call(resolve('map'), [(None, LV(lambda: resolve('list')))]))))
         }), )
     }, expression=LV(
         lambda: call(
             attribute(create_string('map'), call(resolve('wrapper'), [(None, LV(lambda: create_list([create_number(0),
                                                                                                      create_number(3),
                                                                                                      create_number(2),
                                                                                                      create_number(1)])))])),
             [(None, LV(lambda: create_scope(defaults=[('e', None)],
                                             expression=LV(lambda: call(attribute(create_string('+'), resolve('e')), [
                                                  (None, LV(lambda: create_number(1)))])))))])))
     self._test(result, [1, 4, 3, 2])
 def test_12_infinite_recursion(self):
     # sum: (list){
     #   (me(list[1:] + list[0]) or 0
     # }
     # sum([4, 8])
     # this fails because slicing never fails, so instead of calling the
     # failing term list[0] and breaking out we just infinitely call [][1:]
     result = evaluate_module(
         items={'sum': LV(lambda: create_scope(
             defaults=[('list', None)],
             expression=LV(lambda: call(attribute(create_string('or'), call(
                 attribute(create_string('+'), call(
                     resolve('me'),
                     [(None, LV(lambda: slice(resolve('list'), 1)))]
                 )),
                 [(None, LV(lambda: attribute(create_number(0), resolve('list'))))]
             )), [(None, LV(lambda: create_number(0)))]))
         ))},
         expression=LV(lambda: call(resolve('sum'),
                                    [(None, LV(lambda: create_list([create_number(4), create_number(8)])))])))
     self._test(result, 12)
 def test_e12(self):
     # sum: (list){
     #   (list[0] + me(list[1:]) or 0
     # }
     # sum([3, 3, 3, 3])
     result = evaluate_module(
         items={'sum': LV(lambda: create_scope(
             defaults=[('list', None)],
             expression=LV(lambda: call(attribute(create_string('or'), call(
                 attribute(create_string('+'), get(create_number(0), resolve('list'))),
                 [(None, LV(lambda: call(
                     resolve('me'),
                     [(None, LV(lambda: slice(resolve('list'), 1)))]
                 )))]
             )), [(None, LV(lambda: create_number(0)))]))
         ))},
         expression=LV(lambda: call(resolve('sum'), [(None, LV(lambda: create_list([create_number(3),
                                                                                    create_number(3),
                                                                                    create_number(3),
                                                                                    create_number(3)])))])))
     self._test(result, 12)
 def test_list_length1(self):
     # [].length()
     result = evaluate_module(expression=LV(lambda: call(
         attribute(create_string('length'), create_list([])), [])))
     self._test(result, 0)
 def test_map(self):
     # wrapper: (list){
     #   map: (f){
     #     map: (list){
     #       ([f(list[0])] + me(list[1:])) or []
     #     }
     #     map(list)
     #   }
     # }
     # wrapper([0, 3, 2, 1]).map((e){ e + 1 })
     result = evaluate_module(items={
         'wrapper':
         LV(
             lambda: create_scope(
                 defaults=[('list', None)],
                 items={
                     'map':
                     LV(lambda: create_scope(
                         defaults=[('f', None)],
                         items={
                             'map':
                             LV(lambda: create_scope(
                                 defaults=[('list', None)],
                                 expression=LV(lambda: call(
                                     attribute(
                                         create_string('or'),
                                         call(
                                             attribute(
                                                 create_string('+'),
                                                 create_list([
                                                     call(
                                                         resolve('f'),
                                                         [(None,
                                                           LV(lambda:
                                                              attribute(
                                                                  create_number(
                                                                      0),
                                                                  resolve(
                                                                      'list'
                                                                  ))))])
                                                 ])),
                                             [(None,
                                               LV(lambda: call(
                                                   resolve('me'),
                                                   [(None,
                                                     LV(lambda: slice(
                                                         resolve('list'), 1)
                                                        ))])))])),
                                     [(None, LV(lambda: create_list([])))])
                                               ))),
                         },
                         expression=LV(lambda: call(resolve('map'), [(
                             None, LV(lambda: resolve('list')))]))))
                 }), )
     },
                              expression=LV(lambda: call(
                                  attribute(
                                      create_string('map'),
                                      call(resolve('wrapper'), [(
                                          None,
                                          LV(lambda: create_list([
                                              create_number(0),
                                              create_number(3),
                                              create_number(2),
                                              create_number(1)
                                          ])))])),
                                  [(None,
                                    LV(lambda: create_scope(
                                        defaults=[('e', None)],
                                        expression=LV(lambda: call(
                                            attribute(
                                                create_string('+'),
                                                resolve('e')),
                                            [(None,
                                              LV(lambda: create_number(1)))
                                             ])))))])))
     self._test(result, [1, 4, 3, 2])
 def test_fail1(self):
     # [][0]
     result = evaluate_module(expression=LV(
         lambda: attribute(create_number(0), create_list([]))))
     self._test_fail(result)
 def test_list_length1(self):
     # [].length()
     result = evaluate_module(
         expression=LV(lambda: call(attribute(create_string('length'), create_list([])), [])))
     self._test(result, 0)
 def test_fail1(self):
     # [][0]
     result = evaluate_module(expression=LV(lambda: attribute(create_number(0), create_list([]))))
     self._test_fail(result)