def _generate_retval(self, env: Env) -> Tuple[ast.Expr, ast.TypeAnnotation]: """Generates a return-value positioned expression.""" retval_count = self._generate_nary_operand_count(env) sorted_env = sorted(env.items()) env_params = [(v[0], v[1]) for _, v in sorted_env if v[2]] env_non_params = [(v[0], v[1]) for _, v in sorted_env if not v[2]] make_exprs = [] types = [] total_bit_count = 0 for _ in range(retval_count): p = self.rng.random() # Pick parameter values as retvals with low probability. if p < 0.1 or not env_non_params: make_expr, type_ = self.rng.choice(env_params) else: make_expr, type_ = self.rng.choice(env_non_params) assert isinstance(type_, ast.TypeAnnotation) if total_bit_count + self._get_type_bit_count( type_) > self.options.max_width_aggregate_types: continue make_exprs.append(make_expr) types.append(type_) total_bit_count += self._get_type_bit_count(type_) assert len(types) == len(make_exprs), (len(types), len(make_exprs)) if len(types) == 1: return make_exprs[0](), types[0] else: assert len(types) != 1 es = tuple(make_expr() for make_expr in make_exprs) return ast.XlsTuple(self.m, self.fake_span, es), self._make_tuple_type(tuple(types))
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_stringify_single_member_tuple(self): fake_pos = Pos('<fake>', 0, 0) fake_span = Span(fake_pos, fake_pos) t = ast.XlsTuple(self.m, fake_span, (self.five, )) self.assertEqual('(5,)', str(t))