def test_stringify_type(self): fake_span = self.fake_span number_5 = ast.Number(fake_span, '5') number_2 = ast.Number(fake_span, '2') number_3 = ast.Number(fake_span, '3') bits_token = Token(TokenKind.KEYWORD, value=Keyword.BITS, span=fake_span) type_ = ast.make_builtin_type_annotation(fake_span, bits_token, (number_5, )) self.assertEqual('bits[5]', str(type_)) type_ = ast.make_builtin_type_annotation( fake_span, Token(TokenKind.KEYWORD, value=Keyword.U32, span=fake_span), (number_5, )) self.assertEqual('u32[5]', str(type_)) # "no-volume" bits array. # TODO(leary): 2020-08-24 delete bits in favor of uN type_ = ast.make_builtin_type_annotation(fake_span, bits_token, ()) self.assertEqual('bits', str(type_)) # TypeRef with dims. my_type_tok = Token(TokenKind.IDENTIFIER, value='MyType', span=fake_span) name_def = ast.NameDef(fake_span, 'MyType') type_def = ast.TypeDef(False, name_def, type_) type_ref = ast.TypeRef(fake_span, my_type_tok.value, type_def=type_def) type_ = ast.make_type_ref_type_annotation(fake_span, type_ref, (number_2, number_3)) self.assertEqual('MyType[2][3]', str(type_))
def test_type_annotation_properties(self): fake_span = self.fake_span number_5 = ast.Number(fake_span, '5') number_2 = ast.Number(fake_span, '2') number_3 = ast.Number(fake_span, '3') bits_token = Token(TokenKind.KEYWORD, value=Keyword.BITS, span=fake_span) un_token = Token(TokenKind.KEYWORD, value=Keyword.UN, span=fake_span) u32_token = Token(TokenKind.KEYWORD, value=Keyword.U32, span=fake_span) type_ = ast.make_builtin_type_annotation(fake_span, bits_token, (number_5, )) self.assertEqual('bits[5]', str(type_)) type_ = ast.make_builtin_type_annotation(fake_span, bits_token, (number_5, number_2)) self.assertIsInstance(type_, ast.ArrayTypeAnnotation) self.assertEqual('bits[5][2]', str(type_)) type_ = ast.make_builtin_type_annotation(fake_span, u32_token, ()) self.assertEqual('u32', str(type_)) type_ = ast.make_builtin_type_annotation(fake_span, u32_token, (number_3, )) self.assertIsInstance(type_, ast.ArrayTypeAnnotation) self.assertEqual('u32[3]', str(type_)) type_ = ast.make_builtin_type_annotation(fake_span, un_token, (number_2, )) self.assertEqual('uN[2]', str(type_)) type_ = ast.make_builtin_type_annotation(fake_span, un_token, (number_2, number_3)) self.assertIsInstance(type_, ast.ArrayTypeAnnotation) self.assertEqual('uN[2][3]', str(type_)) # TODO(leary): 2020-08-24 delete bits in favor of uN # "no-volume" bits array. type_ = ast.make_builtin_type_annotation(fake_span, bits_token, ()) self.assertEqual('bits', str(type_)) # TypeRef with dims. name_def = ast.NameDef(fake_span, 'MyType') type_def = ast.TypeDef(False, name_def, type_) type_ref = ast.TypeRef(fake_span, 'MyType', type_def=type_def) type_ = ast.make_type_ref_type_annotation(fake_span, type_ref, (number_2, number_3)) self.assertIsInstance(type_, ast.ArrayTypeAnnotation) self.assertEqual('MyType[2][3]', str(type_)) type_ = ast.TupleTypeAnnotation( fake_span, (ast.make_builtin_type_annotation(fake_span, bits_token, (number_5, )), ast.make_builtin_type_annotation(fake_span, bits_token, (number_2, )))) self.assertIsInstance(type_, ast.TupleTypeAnnotation) self.assertEqual('(bits[5], bits[2])', str(type_))
def _generate_cast_bits_to_array( self, env: Env) -> Tuple[ast.Cast, ast.TypeAnnotation]: """Generates a cast from bits to array type.""" # Get a random bits-typed element from the environment. make_arg, arg_type = self._choose_env_value(env, self._is_builtin_unsigned) # Next, find factors of the bit count and select one pair. bit_count = builtin_type_to_bits(arg_type) factors = [] for i in range(1, bit_count + 1): if bit_count % i == 0: factors.append((i, bit_count // i)) element_size, array_size = self.rng.choice(factors) element_type = ast.make_builtin_type_annotation( self.fake_span, scanner.Token(scanner.TokenKind.KEYWORD, value=scanner.Keyword.UN, span=self.fake_span), (self._make_number(element_size, None), )) outer_array_type = self._make_array_type(element_type, array_size) return (ast.Cast(outer_array_type, make_arg()), outer_array_type)
def _make_large_type_annotation(self, kw_identifier: Text, width: int) -> ast.TypeAnnotation: """Creates type annotations for widths > 64 bits.""" token = scanner.Token(scanner.TokenKind.KEYWORD, self.fake_span, scanner.Keyword[kw_identifier]) dim = self._make_number(width, None) dims = (dim, ) return ast.make_builtin_type_annotation(self.fake_span, token, dims)
def concrete_type_to_annotation( concrete_type: concrete_type_mod.ConcreteType) -> ast.TypeAnnotation: if isinstance(concrete_type, concrete_type_mod.BitsType): keyword = SN_KEYWORD if concrete_type.get_signedness() else UN_KEYWORD num_tok = scanner.Token(scanner.TokenKind.NUMBER, FAKE_SPAN, concrete_type.get_total_bit_count()) return ast.make_builtin_type_annotation( FAKE_SPAN, keyword, dims=(ast.Number(num_tok),)) raise NotImplementedError(concrete_type)
def test_visit_type(self): fake_span = self.fake_span five = self.five # Make a uN[5] type node. t = ast.make_builtin_type_annotation(fake_span, Token(TokenKind.KEYWORD, value=Keyword.BITS, span=fake_span), dims=(five, )) assert isinstance(t, ast.ArrayTypeAnnotation), t c = _Collector() t.accept(c) self.assertEqual(c.collected, [five, t])
def _generate_primitive_type(self) -> ast.TypeAnnotation: """Generates a random primitive-based type (no extra dims or tuples).""" primitive_token = self._generate_type_primitive() return ast.make_builtin_type_annotation(self.fake_span, primitive_token, dims=())
def _make_type_annotation(self, kw_identifier: Text) -> ast.TypeAnnotation: assert kw_identifier in scanner.TYPE_KEYWORD_STRINGS, kw_identifier token = scanner.Token(scanner.TokenKind.KEYWORD, self.fake_span, scanner.Keyword(kw_identifier)) return ast.make_builtin_type_annotation(self.fake_span, token, dims=())