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