示例#1
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)
示例#2
0
def make_builtin_type_annotation(
    owner: ast.AstNodeOwner, span: span_mod.Span, tok: scanner.Token,
    dims: Tuple[ast.Expr, ...]) -> ast.TypeAnnotation:
  elem_type = ast.BuiltinTypeAnnotation(owner, span, tok_to_builtin_type(tok))
  for dim in dims:
    elem_type = ast.ArrayTypeAnnotation(owner, span, elem_type, dim)
  return elem_type
示例#3
0
    def _generate_map(self, level,
                      env: Env) -> Tuple[ast.Invocation, ast.TypeAnnotation]:
        """Generates an invocation of the map builtin."""

        map_fn_name = self.gensym()
        # generate_function, in turn, can call generate_map, so we need some way of
        # bounding the recursion. To limit explosion, we increase level by three
        # (chosen empirically) instead of just one.
        map_fn = self.generate_function(map_fn_name, level + 3, param_count=1)
        self._functions.append(map_fn)

        map_arg_signedness, map_arg_bits = builtin_type_to_signedness_and_bits(
            map_fn.params[0].type_)

        array_size = self.rng.randrange(
            1, max(2, self.options.max_width_aggregate_types // map_arg_bits))
        return_type = self._make_array_type(map_fn.return_type, array_size)

        # Seems pretty unlikely that we'll have the exact array we need, so we'll
        # just create one.
        # TODO(b/144724970): Consider creating arrays from values in the env.
        def get_number():
            return self._generate_number(env, map_arg_bits, map_arg_signedness)

        args = self._make_constant_array(
            tuple(get_number()[0] for i in range(array_size)))
        args.type_ = ast.ArrayTypeAnnotation(
            self.fake_span, map_fn.params[0].type_,
            self._make_number(array_size, None))

        fn_ref = self._make_name_ref(self._make_name_def(map_fn_name))
        invocation = ast.Invocation(self.fake_span,
                                    self._builtin_name_ref('map'),
                                    (args, fn_ref))
        return invocation, return_type
示例#4
0
def make_type_ref_type_annotation(
    owner: ast.AstNodeOwner,
    span: span_mod.Span,
    type_ref: ast.TypeRef,
    dims: Tuple[ast.Expr, ...],
    parametrics: Optional[Tuple[ast.Expr, ...]] = None) -> ast.TypeAnnotation:
  """Creates a type ref annotation that may be wrapped in array dimensions."""
  assert dims is not None, dims
  elem_type = ast.TypeRefTypeAnnotation(owner, span, type_ref, parametrics)
  for dim in dims:
    elem_type = ast.ArrayTypeAnnotation(owner, span, elem_type, dim)
  return elem_type