Example #1
0
 def _generate_bit_slice(self,
                         env: Env) -> Tuple[ast.Index, ast.TypeAnnotation]:
   """Generates a bit slice AST node."""
   make_arg, arg_type = self._choose_env_value(env, self._not_tuple_or_array)
   bit_count = self._get_type_bit_count(arg_type)
   slice_type = self.rng.choice(['bit_slice', 'width_slice', 'dynamic_slice'])
   while True:
     start_low = 0 if slice_type == 'width_slice' else -bit_count - 1
     start = (
         self.rng.randrange(start_low, bit_count + 1) if self.rng.choice(
             (True, False)) else None)
     limit = (
         self.rng.randrange(-bit_count - 1, bit_count + 1) if self.rng.choice(
             (True, False)) else None)
     _, width = bit_helpers.resolve_bit_slice_indices(bit_count, start, limit)
     if width <= 0:  # Make sure we produce non-zero-width things.
       continue
     else:
       break
   if slice_type == 'width_slice':
     index_slice = ast.WidthSlice(self.m, self.fake_span,
                                  self._make_number(start or 0, None),
                                  self._make_type_annotation(False, width))
   elif slice_type == 'bit_slice':
     index_slice = ast.Slice(
         self.m, self.fake_span,
         None if start is None else self._make_number(start, None),
         None if limit is None else self._make_number(limit, None))
   else:
     start_arg, _ = self._choose_env_value(env, self._is_unsigned_bit_vector)
     index_slice = ast.WidthSlice(self.m, self.fake_span, start_arg(),
                                  self._make_type_annotation(False, width))
   type_ = self._make_type_annotation(False, width)
   return (ast.Index(self.m, self.fake_span, make_arg(), index_slice), type_)
Example #2
0
    def _generate_tuple_or_index(
            self, env: Env) -> Tuple[ast.Expr, ast.TypeAnnotation]:
        """Generates either a tupling operation or an index-a-tuple operation."""
        p = self.rng.random()
        do_index = p <= 0.5 and self._env_contains_tuple(env)
        if do_index:
            make_tuple_expr, tuple_type = self._choose_env_value(
                env, self._is_tuple)
            # TODO(leary): 2019-08-07 Also make it possible to select a value from
            # the environment to use as an index.
            assert isinstance(tuple_type, ast.TupleTypeAnnotation), tuple_type
            i = self.randrange(len(tuple_type.members))
            index_expr = self._make_number(i,
                                           type_=self._make_type_annotation(
                                               False, 32))
            tuple_expr = make_tuple_expr()
            assert isinstance(tuple_type, ast.TupleTypeAnnotation), tuple_type
            return ast.Index(self.m, self.fake_span, tuple_expr,
                             index_expr), tuple_type.members[i]
        else:
            members = []
            types = []
            total_bit_count = 0
            for i in range(self._generate_nary_operand_count(env)):
                make_expr, type_ = self._choose_env_value(env, self._not_array)
                if total_bit_count + self._get_type_bit_count(
                        type_) > self.options.max_width_aggregate_types:
                    continue
                members.append(make_expr())
                types.append(type_)
                total_bit_count += self._get_type_bit_count(type_)

            return ast.XlsTuple(self.m, self.fake_span,
                                tuple(members)), self._make_tuple_type(
                                    tuple(types))
Example #3
0
    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])