示例#1
0
文件: ast_test.py 项目: mfkiwl/xls
    def test_visit_index(self):
        fake_span = self.fake_span
        m = self.m
        # Make a t[i] inde xnode.
        t = ast.NameRef(m, fake_span, 't', ast.NameDef(m, fake_span, 't'))
        i = ast.NameRef(m, fake_span, 'i', ast.NameDef(m, fake_span, 'i'))
        index = ast.Index(m, fake_span, t, i)

        c = _Collector()
        visit(index, c)
        self.assertEqual(c.collected, [t, i, index])
示例#2
0
  def _make_array_type(self, element_type: ast.TypeAnnotation,
                       array_size: int) -> ast.TypeAnnotation:
    """Creates an array type with the given size and element type."""
    assert array_size > 0, array_size

    size_type = None
    if self.rng.random() < 0.5:
      # Get-or-create a module level constant for the array size.
      width = max(1, int(math.ceil(math.log(array_size + 1, 2))))
      identifier = f'W{width}_V{array_size}'
      if identifier in self._constants:
        constant_def = self._constants[identifier]
      else:
        size_type = self._make_type_annotation(signed=False, width=width)
        name_def = ast.NameDef(self.m, self.fake_span, identifier)
        constant_def = ast.Constant(
            self.m,
            self.fake_span,
            name_def,
            self._make_number(array_size, size_type),
            is_public=False)
        name_def.definer = constant_def
        self._constants[identifier] = constant_def
      dim = ast.ConstRef(self.m, self.fake_span, identifier,
                         constant_def.name_def)
    else:
      dim = self._make_number(array_size, None)

    array_type = ast_helpers.make_type_ref_type_annotation(
        self.m, self.fake_span, self._create_type_ref(element_type), (dim,))
    return array_type
示例#3
0
文件: ast_test.py 项目: mfkiwl/xls
    def test_stringify_type(self):
        fake_span = self.fake_span
        m = self.m
        number_5 = ast.Number(m, fake_span, '5')
        number_2 = ast.Number(m, fake_span, '2')
        number_3 = ast.Number(m, fake_span, '3')
        bits_token = Token(value=Keyword.BITS, span=fake_span)

        type_ = ast_helpers.make_builtin_type_annotation(
            m, fake_span, bits_token, (number_5, ))
        self.assertEqual('bits[5]', str(type_))

        type_ = ast_helpers.make_builtin_type_annotation(
            m, fake_span, Token(value=Keyword.U32, span=fake_span),
            (number_5, ))
        self.assertEqual('u32[5]', str(type_))

        # "no-volume" bits array.
        # TODO(leary): 2020-08-24 delete bits in favor of uN
        type_ = ast_helpers.make_builtin_type_annotation(
            m, fake_span, bits_token, ())
        self.assertEqual('bits', str(type_))

        # TypeRef with dims.
        my_type_tok = Token(TokenKind.IDENTIFIER,
                            value='MyType',
                            span=fake_span)
        name_def = ast.NameDef(m, fake_span, 'MyType')
        type_def = ast.TypeDef(m, fake_span, name_def, type_, public=False)
        type_ref = ast.TypeRef(m, fake_span, my_type_tok.value, type_def)
        type_ = ast_helpers.make_type_ref_type_annotation(
            m, fake_span, type_ref, (number_2, number_3))
        self.assertEqual('MyType[2][3]', str(type_))
示例#4
0
文件: ast_test.py 项目: mfkiwl/xls
    def test_type_annotation_properties(self):
        m = self.m
        fake_span = self.fake_span
        number_5 = ast.Number(m, fake_span, '5')
        number_2 = ast.Number(m, fake_span, '2')
        number_3 = ast.Number(m, fake_span, '3')
        bits_token = Token(value=Keyword.BITS, span=fake_span)
        un_token = Token(value=Keyword.UN, span=fake_span)
        u32_token = Token(value=Keyword.U32, span=fake_span)

        type_ = ast_helpers.make_builtin_type_annotation(
            m, fake_span, bits_token, (number_5, ))
        self.assertEqual('bits[5]', str(type_))

        type_ = ast_helpers.make_builtin_type_annotation(
            m, fake_span, bits_token, (number_5, number_2))
        self.assertIsInstance(type_, ast.ArrayTypeAnnotation)
        self.assertEqual('bits[5][2]', str(type_))

        type_ = ast_helpers.make_builtin_type_annotation(
            m, fake_span, u32_token, ())
        self.assertEqual('u32', str(type_))

        type_ = ast_helpers.make_builtin_type_annotation(
            m, fake_span, u32_token, (number_3, ))
        self.assertIsInstance(type_, ast.ArrayTypeAnnotation)
        self.assertEqual('u32[3]', str(type_))

        type_ = ast_helpers.make_builtin_type_annotation(
            m, fake_span, un_token, (number_2, ))
        self.assertEqual('uN[2]', str(type_))

        type_ = ast_helpers.make_builtin_type_annotation(
            m, fake_span, un_token, (number_2, number_3))
        self.assertIsInstance(type_, ast.ArrayTypeAnnotation)
        self.assertEqual('uN[2][3]', str(type_))

        # TODO(leary): 2020-08-24 delete bits in favor of uN
        # "no-volume" bits array.
        type_ = ast_helpers.make_builtin_type_annotation(
            m, fake_span, bits_token, ())
        self.assertEqual('bits', str(type_))

        # TypeRef with dims.
        name_def = ast.NameDef(m, fake_span, 'MyType')
        type_def = ast.TypeDef(m, fake_span, name_def, type_, public=False)
        type_ref = ast.TypeRef(m, fake_span, 'MyType', type_def)
        type_ = ast_helpers.make_type_ref_type_annotation(
            m, fake_span, type_ref, (number_2, number_3))
        self.assertIsInstance(type_, ast.ArrayTypeAnnotation)
        self.assertEqual('MyType[2][3]', str(type_))

        type_ = ast.TupleTypeAnnotation(
            m, fake_span,
            (ast_helpers.make_builtin_type_annotation(m, fake_span, bits_token,
                                                      (number_5, )),
             ast_helpers.make_builtin_type_annotation(m, fake_span, bits_token,
                                                      (number_2, ))))
        self.assertIsInstance(type_, ast.TupleTypeAnnotation)
        self.assertEqual('(bits[5], bits[2])', str(type_))
示例#5
0
 def test_module_with_constant(self):
     m = cpp_ast.Module('test')
     name_def = cpp_ast.NameDef(m, self.fake_span, 'MOL')
     number = cpp_ast.Number(m, self.fake_span, '42')
     constant_def = cpp_ast.Constant(m, name_def, number)
     m.add_top(constant_def)
     self.assertEqual(str(m), 'const MOL = 42;')
示例#6
0
 def test_identity_function(self):
     m = cpp_ast.Module('test')
     name_def_x = cpp_ast.NameDef(m, self.fake_span, 'x')
     name_ref_x = cpp_ast.NameRef(m, self.fake_span, 'x', name_def_x)
     type_u32 = cpp_ast.BuiltinTypeAnnotation(m, self.fake_span,
                                              cpp_ast.BuiltinType.U32)
     param_x = cpp_ast.Param(m, name_def_x, type_u32)
     name_def_f = cpp_ast.NameDef(m, self.fake_span, 'f')
     params = (param_x, )
     f = cpp_ast.Function(m,
                          self.fake_span,
                          name_def_f, (),
                          params,
                          type_u32,
                          name_ref_x,
                          public=False)
     self.assertEqual(str(f), 'fn f(x: u32) -> u32 {\n  x\n}')
示例#7
0
  def _generate_expr(self, env: Env,
                     level: int) -> Tuple[ast.Expr, ast.TypeAnnotation]:
    """Generates an expression AST node and returns it."""
    if self.should_nest(level):
      identifier = self.gensym()
      name_def = ast.NameDef(self.m, self.fake_span, identifier)
      choices = collections.OrderedDict()
      if self.options.emit_loops:
        choices[self._generate_counted_for] = 1.0
      choices[self._generate_tuple_or_index] = 1.0
      choices[self._generate_concat] = 1.0
      choices[self._generate_binop] = 1.0
      choices[self._generate_unop] = 1.0
      choices[self._generate_unop_builtin] = 1.0
      choices[self._generate_one_hot_select_builtin] = 1.0
      choices[self._generate_number] = 1.0
      choices[self._generate_bit_slice] = 1.0
      if not self._codegen_ops_only:
        choices[self._generate_bitwise_reduction] = 1.0
      choices[self._generate_cast_bits_to_array] = 1.0
      # If maps recurse with equal probability, then the output will grow
      # exponentially with level, so we need to scale inversely.
      choices[lambda env: self._generate_map(level, env)] = 1.0 / (10**level)

      rng_choices = getattr(self.rng, 'choices')
      while True:
        expr_generator = rng_choices(
            population=list(choices.keys()),
            weights=list(choices.values()),
            k=1)[0]
        try:
          rhs, rhs_type = expr_generator(env)
        except EmptyEnvError:
          # Try a different generator that may be more accepting of env values.
          del choices[expr_generator]
          if not choices:  # If we ran out of things to try, bail.
            return self._generate_retval(env)
          continue
        else:
          break
      new_env = collections.OrderedDict(env)
      new_env[identifier] = (
          lambda: self._make_name_ref(name_def)), rhs_type, False
      body, body_type = self._generate_expr(new_env, level + 1)
      name_def_tree = ast.NameDefTree(self.m, self.fake_span, name_def)
      let = ast.Let(
          self.m,
          self.fake_span,
          name_def_tree,
          rhs_type,
          rhs,
          body,
          const=None)
      return let, body_type
    else:  # Should not nest any more -- select return values.
      return self._generate_retval(env)
示例#8
0
文件: ast_test.py 项目: mfkiwl/xls
    def test_visit_unop(self):
        fake_span = self.fake_span
        m = self.m
        i_def = ast.NameDef(m, fake_span, 'i')
        i_ref = ast.NameRef(m, fake_span, 'i', i_def)
        negated = ast.Unop(m, fake_span, ast.UnopKind.NEG, i_ref)

        c = _Collector()
        visit(negated, c)
        self.assertEqual(c.collected, [i_ref, negated])
示例#9
0
 def test_named_tuple_vs_tuple_compatibility(self):
     u32 = ConcreteType.U32
     u8 = ConcreteType.U8
     m = ast.Module('test')
     fake_pos = Pos('fake.x', 0, 0)
     fake_span = Span(fake_pos, fake_pos)
     name_def = ast.NameDef(m, fake_span, 'fake')
     s = ast.Struct(m, fake_span, name_def, (), (), False)
     named = TupleType((('x', u32), ('y', u8)), struct=s)
     unnamed = TupleType((u32, u8))
     self.assertTrue(named.compatible_with(unnamed))
     self.assertNotEqual(named, unnamed)
     self.assertEqual(named.tuple_names, ('x', 'y'))
示例#10
0
文件: ast_test.py 项目: mfkiwl/xls
    def test_ndt_preorder(self):
        fake_pos = self.fake_pos
        fake_span = Span(fake_pos, fake_pos)
        m = ast.Module('test')
        t = ast.NameDef(m, fake_span, 't')
        u = ast.NameDef(m, fake_span, 'u')
        wrapped_t = ast.NameDefTree(m, fake_span, t)
        wrapped_u = ast.NameDefTree(m, fake_span, u)

        interior = ast.NameDefTree(m, fake_span, (wrapped_t, wrapped_u))
        outer = ast.NameDefTree(m, fake_span, (interior, ))

        walk_data = []

        def walk(item: ast.NameDefTree, level: int, i: int):
            walk_data.append((item, level, i))

        ast_helpers.do_preorder(outer, walk)

        self.assertLen(walk_data, 3)
        self.assertEqual(walk_data[0], (interior, 1, 0))
        self.assertEqual(walk_data[1], (wrapped_t, 2, 0))
        self.assertEqual(walk_data[2], (wrapped_u, 2, 1))
示例#11
0
 def generate_function(self,
                       name: Text,
                       level: int = 0,
                       param_count: int = None) -> ast.Function:
     if param_count is None:
         param_count = int(math.ceil(self.rng.weibullvariate(1, 1.15) * 4))
     params = self._generate_params(param_count)
     body, body_type = self._generate_body(level, params)
     return ast.Function(self.m,
                         self.fake_span,
                         ast.NameDef(self.m, self.fake_span, name),
                         parametric_bindings=(),
                         params=params,
                         return_type=body_type,
                         body=body,
                         public=False)
示例#12
0
 def _generate_param(self) -> ast.Param:
     identifier = self.gensym()
     type_ = self._generate_bits_type()
     name_def = ast.NameDef(self.m, self.fake_span, identifier)
     return ast.Param(self.m, name_def, type_)
示例#13
0
 def _make_name_def(self, identifier: Text) -> ast.NameDef:
     return ast.NameDef(self.m, self.fake_span, identifier)