Пример #1
0
 def _generate_logical_binop(self,
                             env: Env) -> Tuple[ast.Binop, ast.TypeAnnotation]:
   """Generates a logical binary operation (e.g. and, xor, or)."""
   make_lhs, lhs_type = self._choose_env_value(env, self._not_tuple_or_array)
   make_rhs, rhs_type = self._choose_env_value(env, self._not_tuple_or_array)
   # Convert into one-bit numbers by checking whether lhs and rhs values are 0.
   lhs = ast.Binop(self.m, self.fake_span, ast.BinopKind.NE, make_lhs(),
                   self._make_number(0, lhs_type))
   rhs = ast.Binop(self.m, self.fake_span, ast.BinopKind.NE, make_rhs(),
                   self._make_number(0, rhs_type))
   # Pick some operation to do.
   op = self.rng.choice([ast.BinopKind.LOGICAL_AND, ast.BinopKind.LOGICAL_OR])
   return ast.Binop(self.m, self.fake_span, op, lhs,
                    rhs), self._make_type_annotation(False, 1)
Пример #2
0
 def test_format_binop(self):
   m = ast.Module('test')
   fake_pos = self.fake_pos
   fake_span = Span(fake_pos, fake_pos)
   le = ast.Binop(m, Token(TokenKind.OANGLE_EQUALS, span=fake_span), self.five,
                  self.five)
   self.assertEqual('(5) <= (5)', str(le))
Пример #3
0
    def _generate_concat(self,
                         env: Env) -> Tuple[ast.Expr, ast.TypeAnnotation]:
        """Returns a (potentially vacuous) concatenate operation of values in `env`.

    Args:
      env: Environment of values that can be selected from for concatenation.
    Note: the concat operation will not exceed the maximum bit width so the
      concat may end up being a nop.
    """
        if self._env_contains_array(env) and self.rng.choice([True, False]):
            return self._generate_array_concat(env)

        count = self._generate_nary_operand_count(env) + 2
        operands = []
        operand_types = []
        for i in range(count):
            make_arg, arg_type = self._choose_env_value(
                env, self._is_builtin_unsigned)
            operands.append(make_arg())
            operand_types.append(arg_type)
        result = operands[0]
        result_bits = builtin_type_to_bits(operand_types[0])
        token = scanner.Token(ast.Binop.CONCAT, self.fake_span,
                              ast.Binop.CONCAT.value)
        for i in range(1, count):
            this_bits = builtin_type_to_bits(operand_types[i])
            if result_bits + this_bits > self.options.max_width_bits_types:
                break
            result = ast.Binop(token, result, operands[i])
            result_bits += this_bits
        assert result_bits <= self.options.max_width_bits_types, result_bits
        return (result, self._make_large_type_annotation('UN', result_bits))
Пример #4
0
    def _generate_array_concat(
            self, env: Env) -> Tuple[ast.Expr, ast.TypeAnnotation]:
        """Returns a binary concatenation of two arrays in env.

    The two arrays to concatenate in env will have the same element type.

    Args:
      env: Environment of values that can be selected from for array
        concatenation.
    Precondition: There must be an array value present in env.
    """
        make_lhs, lhs_type = self._choose_env_value(
            env, lambda t: isinstance(t, ast.ArrayTypeAnnotation))
        assert isinstance(lhs_type, ast.ArrayTypeAnnotation), lhs_type

        def array_same_elem_type(t: ast.TypeAnnotation) -> bool:
            return (isinstance(t, ast.ArrayTypeAnnotation)
                    and t.element_type == lhs_type.element_type)

        make_rhs, rhs_type = self._choose_env_value(env, array_same_elem_type)
        token = scanner.Token(ast.Binop.CONCAT, self.fake_span,
                              ast.Binop.CONCAT.value)
        result = ast.Binop(token, make_lhs(), make_rhs())
        lhs_size = self._get_array_size(lhs_type)
        bits_per_elem = self._get_type_bit_count(lhs_type) // lhs_size
        result_size = lhs_size + self._get_array_size(rhs_type)
        dim = self._make_number(result_size, None)
        result_type = ast.ArrayTypeAnnotation(self.fake_span,
                                              lhs_type.element_type, dim)
        self._type_bit_counts[str(result_type)] = bits_per_elem * result_size
        return (result, result_type)
Пример #5
0
 def _generate_binop_same_input_type(
     self, lhs: ast.Expr, rhs: ast.Expr,
     input_type: ast.TypeAnnotation) -> Tuple[ast.Binop, ast.TypeAnnotation]:
   """Generates a binary operator on lhs/rhs which have the same input type."""
   if self.rng.random() < 0.1:
     op = self.rng.choice(ast.BinopKind.COMPARISON_KIND_LIST)
     output_type = self._make_type_annotation(False, 1)
   else:
     op = self.rng.choice(self._binops)
     if op in ast.BinopKind.SHIFTS and self.rng.random() < 0.8:
       # Clamp the RHS to be in range most of the time.
       assert isinstance(input_type, ast.BuiltinTypeAnnotation), input_type
       bit_count = builtin_type_to_bits(input_type)
       new_upper = self.rng.randrange(bit_count)
       rhs = self._generate_umin(rhs, input_type, new_upper)
     output_type = input_type
   return ast.Binop(self.m, self.fake_span, op, lhs, rhs), output_type
Пример #6
0
 def _make_ge(self, lhs: ast.Expr, rhs: ast.Expr) -> ast.Expr:
     return ast.Binop(
         scanner.Token(ast.Binop.GE, self.fake_span, ast.Binop.GE.value),
         lhs, rhs)
Пример #7
0
 def _make_ge(self, lhs: ast.Expr, rhs: ast.Expr) -> ast.Expr:
   return ast.Binop(self.m, self.fake_span, ast.BinopKind.GE, lhs, rhs)