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())
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))
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
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)
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)
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
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)
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))))
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)
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
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
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
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)
def test_array_bit_count(self): e = BitsType(signed=False, size=4) a = ArrayType(e, 3) self.assertEqual(a.get_total_bit_count(), 12)
def test_array_of_tuple_all_dims(self): a = ArrayType(TupleType(()), 7) self.assertEqual((7, ), a.get_all_dims())