Example #1
0
    def test_array_vs_multidim_bits_equality(self):
        a = ArrayType(BitsType(signed=False, size=5), 7)
        self.assertEqual(str(a), 'uN[5][7]')
        self.assertEqual(7 * 5, a.get_total_bit_count())
        self.assertEqual(7, a.size)
        self.assertEqual(5, a.get_element_type().size)  # pytype: disable=attribute-error
        self.assertEqual((7, 5), a.get_all_dims())

        self.assertEqual((), TupleType(()).get_all_dims())
Example #2
0
    def test_arrayness(self):
        tabular = [
            # (type, is_array, element_count)
            (TupleType(members=()), False, None),
            (BitsType(signed=False, size=5), False, None),
            (ArrayType(BitsType(False, 5), 7), True, 7),
            (ArrayType(TupleType(members=()), 7), True, 7),
        ]

        for t, is_array, element_count in tabular:
            self.assertEqual(isinstance(t, ArrayType), is_array, msg=str(t))
            if is_array:
                self.assertEqual(t.size, element_count, msg=str(t))
Example #3
0
def concrete_type_from_dims(primitive: Token,
                            dims: Tuple[int, ...]) -> 'ConcreteType':
    """Creates a concrete type from the primitive type token and dims.

  Args:
    primitive: The token holding the primitive type as a keyword.
    dims: Dimensions to apply to the primitive type; e.g. () is scalar, (5) is
      1-D array of 5 elements having the primitive type.

  Returns:
    A concrete type object.

  Raises:
    ValueError: If the primitive keyword is unrecognized or dims are empty.
  """
    if primitive.is_keyword(Keyword.BITS) or primitive.is_keyword(Keyword.UN):
        base_type = BitsType(signed=False, size=dims[-1])
    elif primitive.is_keyword(Keyword.SN):
        base_type = BitsType(signed=True, size=dims[-1])
    else:
        assert primitive.kind == TokenKind.KEYWORD
        signedness, bits = TYPE_KEYWORDS_TO_SIGNEDNESS_AND_BITS[
            primitive.value]
        element_type = BitsType(signedness, bits)
        while dims:
            dims, minor = dims[:-1], dims[-1]
            element_type = ArrayType(element_type, minor)
        return element_type

    result = concrete_type_from_element_type_and_dims(base_type, dims[:-1])
    logging.vlog(4, '%r %r => %r', primitive, dims, result)
    return result
Example #4
0
def fsig(arg_types: ArgTypes, name: Text, span: Span, ctx: DeduceCtx,
         _: Optional[ParametricBindings]) -> ConcreteType:
    _Checker(arg_types, name, span).len(1).is_array(0)
    t = arg_types[0].get_element_type()  # pytype: disable=attribute-error
    e = TupleType((ConcreteType.U32, t))
    return_type = ArrayType(e, arg_types[0].size)  # pytype: disable=attribute-error
    return FunctionType(arg_types, return_type)
Example #5
0
def _deduce_Concat(self: ast.Binop, ctx: DeduceCtx) -> ConcreteType:
    """Deduces the concrete type of a concatenate Binop AST node."""
    lhs_type = deduce(self.lhs, ctx)
    resolved_lhs_type = resolve(lhs_type, ctx)
    rhs_type = deduce(self.rhs, ctx)
    resolved_rhs_type = resolve(rhs_type, ctx)

    # Array-ness must be the same on both sides.
    if (isinstance(resolved_lhs_type, ArrayType) != isinstance(
            resolved_rhs_type, ArrayType)):
        raise XlsTypeError(
            self.span, resolved_lhs_type, resolved_rhs_type,
            'Attempting to concatenate array/non-array values together.')

    if (isinstance(resolved_lhs_type, ArrayType)
            and resolved_lhs_type.get_element_type() !=
            resolved_rhs_type.get_element_type()):
        raise XlsTypeError(
            self.span, resolved_lhs_type, resolved_rhs_type,
            'Array concatenation requires element types to be the same.')

    new_size = resolved_lhs_type.size + resolved_rhs_type.size  # pytype: disable=attribute-error
    if isinstance(resolved_lhs_type, ArrayType):
        return ArrayType(resolved_lhs_type.get_element_type(), new_size)

    return BitsType(signed=False, size=new_size)
Example #6
0
def concrete_type_from_element_type_and_dims(
        element_type: ConcreteType[int], dims: Tuple[int,
                                                     ...]) -> ConcreteType:
    """Wraps element_type in arrays according to `dims`, dims[0] as most minor."""
    t = element_type
    for dim in dims:
        t = ArrayType(t, dim)
    return t
Example #7
0
 def test_generate_array_argument(self):
     rng = random.Random(0)
     args = sample_generator.generate_arguments(
         (ArrayType(BitsType(signed=True, size=4), 24), ), rng)
     self.assertLen(args, 1)
     self.assertTrue(args[0].is_array())
     self.assertLen(args[0].array_payload.elements, 24)
     self.assertTrue(args[0].array_payload.index(0).is_sbits())
     self.assertTrue(args[0].array_payload.index(0).get_bit_count(), 4)
Example #8
0
 def test_sign_convert_array_value(self):
   t = ArrayType(BitsType(signed=True, size=8), 3)
   self.assertEqual(
       sample_runner.sign_convert_value(
           t,
           Value.make_array((Value.make_ubits(8,
                                              0x42), Value.make_ubits(8, 0x43),
                             Value.make_ubits(8, 0x44)))),
       Value.make_array((Value.make_sbits(8, 0x42), Value.make_sbits(8, 0x43),
                         Value.make_sbits(8, 0x44))))
Example #9
0
 def test_stringify(self):
     u32 = BitsType(signed=False, size=32)
     tabular = [
         # type size total_bit_count str
         (ArrayType(u32, 7), 7, 32 * 7, 'uN[32][7]'),
         (u32, 32, 32, 'uN[32]'),
     ]
     for t, size, total_bit_count, s in tabular:
         self.assertEqual(t.size, size)
         self.assertEqual(t.get_total_bit_count(), total_bit_count)
         self.assertEqual(str(t), s)
Example #10
0
def fsig(
    arg_types: ArgTypes, name: Text, span: Span, ctx: DeduceCtx,
    parametric_bindings: Optional[ParametricBindings]
) -> Tuple[ConcreteType, parametric_instantiator.SymbolicBindings]:
    """Returns the inferred/checked return type for a map-style signature."""
    logging.vlog(5, 'Instantiating for builtin %r @ %s', name, span)
    _Checker(arg_types, name, span).len(2).is_array(0).is_fn(1, argc=1)
    t = arg_types[0].get_element_type()  # pytype: disable=attribute-error
    u, symbolic_bindings = parametric_instantiator.instantiate_function(
        span, arg_types[1], (t, ), ctx, parametric_bindings)
    return_type = ArrayType(u, arg_types[0].size)  # pytype: disable=attribute-error
    return FunctionType(arg_types, return_type), symbolic_bindings
Example #11
0
def _deduce_ArrayTypeAnnotation(self: ast.ArrayTypeAnnotation,
                                ctx: DeduceCtx) -> ConcreteType:
    """Deduces the concrete type of an Array type annotation."""
    dim = _dim_to_parametric_or_int(self, self.dim, ctx)
    if (isinstance(self.element_type, ast.BuiltinTypeAnnotation)
            and self.element_type.bits == 0):
        # No-volume builtin types like bits, uN, and sN.
        return BitsType(self.element_type.signedness, dim)
    element_type = deduce(self.element_type, ctx)
    result = ArrayType(element_type, dim)
    logging.vlog(4, 'array type annotation: %s => %s', self, result)
    return result
Example #12
0
def _deduce_Array(self: ast.Array, ctx: DeduceCtx) -> ConcreteType:  # pytype: disable=wrong-arg-types
    """Deduces the concrete type of an Array AST node."""
    member_types = [deduce(m, ctx) for m in self.members]
    resolved_type0 = resolve(member_types[0], ctx)
    for i, x in enumerate(member_types[1:], 1):
        resolved_x = resolve(x, ctx)
        logging.vlog(5, 'array member type %d: %s', i, resolved_x)
        if resolved_x != resolved_type0:
            raise XlsTypeError(
                self.members[i].span, resolved_type0, resolved_x,
                'Array member did not have same type as other members.')

    inferred = ArrayType(resolved_type0, len(member_types))

    if not self.type_:
        return inferred

    annotated = deduce(self.type_, ctx)
    if not isinstance(annotated, ArrayType):
        raise XlsTypeError(self.span, annotated, None,
                           'Array was not annotated with an array type.')
    resolved_element_type = resolve(annotated.get_element_type(), ctx)
    if resolved_element_type != resolved_type0:
        raise XlsTypeError(
            self.span, resolved_element_type, resolved_type0,
            'Annotated element type did not match inferred element type.')

    if self.has_ellipsis:
        # Since there are ellipsis, we determine the size from the annotated type.
        # We've already checked the element types lined up.
        return annotated
    else:
        if annotated.size != len(member_types):
            raise XlsTypeError(
                self.span, annotated, inferred,
                'Annotated array size {!r} does not match inferred array size {!r}.'
                .format(annotated.size, len(member_types)))
        return inferred
Example #13
0
def concrete_type_from_value(value: Value) -> ConcreteType[int]:
    """Returns the concrete type of 'value'.

  Note that:
  * Non-zero-length arrays are assumed (for zero length arrays we can't
    currently deduce the type from the value because the concrete element type
    is not reified in the array value.
  * Enums are strength-reduced to their underlying bits (storage) type.

  Args:
    value: Value to determine the concrete type for.
  """
    if value.tag in (Tag.UBITS, Tag.SBITS):
        signed = value.tag == Tag.SBITS
        return BitsType(signed, value.bits_payload.bit_count)
    elif value.tag == Tag.ARRAY:
        element_type = concrete_type_from_value(value.array_payload.index(0))
        return ArrayType(element_type, len(value))
    elif value.tag == Tag.TUPLE:
        return TupleType(
            tuple(concrete_type_from_value(m) for m in value.tuple_members))
    else:
        assert value.tag == Tag.ENUM, value
        return _strength_reduce_enum(value.type_, value.bits_payload.bit_count)
Example #14
0
 def test_array_bit_count(self):
     e = BitsType(signed=False, size=4)
     a = ArrayType(e, 3)
     self.assertEqual(a.get_total_bit_count(), 12)
Example #15
0
 def test_array_of_tuple_all_dims(self):
     a = ArrayType(TupleType(()), 7)
     self.assertEqual((7, ), a.get_all_dims())