def test_stringify_type(self): fake_span = self.fake_span m = self.m number_5 = ast.Number(m, fake_span, '5') number_2 = ast.Number(m, fake_span, '2') number_3 = ast.Number(m, fake_span, '3') bits_token = Token(TokenKind.KEYWORD, value=Keyword.BITS, span=fake_span) type_ = ast_helpers.make_builtin_type_annotation(m, fake_span, bits_token, (number_5,)) self.assertEqual('bits[5]', str(type_)) type_ = ast_helpers.make_builtin_type_annotation( m, 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_helpers.make_builtin_type_annotation(m, 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(m, fake_span, 'MyType') type_def = ast.TypeDef(m, False, name_def, type_) type_ref = ast.TypeRef(m, fake_span, my_type_tok.value, type_def=type_def) type_ = ast_helpers.make_type_ref_type_annotation(m, fake_span, type_ref, (number_2, number_3)) self.assertEqual('MyType[2][3]', str(type_))
def test_type_annotation_properties(self): m = self.m fake_span = self.fake_span number_5 = ast.Number(m, fake_span, '5') number_2 = ast.Number(m, fake_span, '2') number_3 = ast.Number(m, 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_helpers.make_builtin_type_annotation(m, fake_span, bits_token, (number_5,)) self.assertEqual('bits[5]', str(type_)) type_ = ast_helpers.make_builtin_type_annotation(m, fake_span, bits_token, (number_5, number_2)) self.assertIsInstance(type_, ast.ArrayTypeAnnotation) self.assertEqual('bits[5][2]', str(type_)) type_ = ast_helpers.make_builtin_type_annotation(m, fake_span, u32_token, ()) self.assertEqual('u32', str(type_)) type_ = ast_helpers.make_builtin_type_annotation(m, fake_span, u32_token, (number_3,)) self.assertIsInstance(type_, ast.ArrayTypeAnnotation) self.assertEqual('u32[3]', str(type_)) type_ = ast_helpers.make_builtin_type_annotation(m, fake_span, un_token, (number_2,)) self.assertEqual('uN[2]', str(type_)) type_ = ast_helpers.make_builtin_type_annotation(m, 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_helpers.make_builtin_type_annotation(m, fake_span, bits_token, ()) self.assertEqual('bits', str(type_)) # TypeRef with dims. name_def = ast.NameDef(m, fake_span, 'MyType') type_def = ast.TypeDef(m, False, name_def, type_) type_ref = ast.TypeRef(m, fake_span, 'MyType', type_def=type_def) type_ = ast_helpers.make_type_ref_type_annotation(m, fake_span, type_ref, (number_2, number_3)) self.assertIsInstance(type_, ast.ArrayTypeAnnotation) self.assertEqual('MyType[2][3]', str(type_)) type_ = ast.TupleTypeAnnotation( m, fake_span, (ast_helpers.make_builtin_type_annotation(m, fake_span, bits_token, (number_5,)), ast_helpers.make_builtin_type_annotation(m, fake_span, bits_token, (number_2,)))) self.assertIsInstance(type_, ast.TupleTypeAnnotation) self.assertEqual('(bits[5], bits[2])', str(type_))
def _create_element_invocation(owner: ast.AstNodeOwner, span_: span.Span, callee: Union[ast.NameRef, ast.ModRef], arg_array: ast.Expr) -> ast.Invocation: """Creates a function invocation on the first element of the given array. We need to create a fake invocation to deduce the type of a function in the case where map is called with a builtin as the map function. Normally, map functions (including parametric ones) have their types deduced when their ast.Function nodes are encountered (where a similar fake ast.Invocation node is created). Builtins don't have ast.Function nodes, so that inference can't occur, so we essentually perform that synthesis and deduction here. Args: owner: AST node owner. span_: The location in the code where analysis is occurring. callee: The function to be invoked. arg_array: The array of arguments (at least one) to the function. Returns: An invocation node for the given function when called with an element in the argument array. """ annotation = ast_helpers.make_builtin_type_annotation( owner, span_, scanner.Token(scanner.TokenKind.KEYWORD, span_, scanner.Keyword.U32), ()) index_number = ast.Number(owner, span_, '32', ast.NumberKind.OTHER, annotation) index = ast.Index(owner, span_, arg_array, index_number) return ast.Invocation(owner, span_, callee, (index, ))
def test_visit_match_multi_pattern(self): fake_pos = self.fake_pos fake_span = Span(fake_pos, fake_pos) e = ast.Number(fake_span, u'0xf00') p0 = ast.NameDefTree(fake_span, e) p1 = ast.NameDefTree(fake_span, e) arm = ast.MatchArm(patterns=(p0, p1), expr=e) c = _Collector() arm.accept(c) self.assertEqual(c.collected, [e])
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 five(self) -> ast.Number: return ast.Number(self.m, self.fake_span, '5')
def test_binary_number_with_underscores(self): fake_pos = self.fake_pos fake_span = Span(fake_pos, fake_pos) n = ast.Number(self.m, fake_span, u'0b1_0_0_1') self.assertEqual(9, n.get_value_as_int())
def test_hex_number_with_underscores(self): fake_pos = self.fake_pos fake_span = Span(fake_pos, fake_pos) n = ast.Number(self.m, fake_span, '0xf_abcde_1234') self.assertEqual(0xfabcde1234, n.get_value_as_int())
def test_unicode_hex_number(self): fake_pos = self.fake_pos fake_span = Span(fake_pos, fake_pos) n = ast.Number(self.m, fake_span, u'0xf00') self.assertEqual(0xf00, n.get_value_as_int())
def _make_number(self, value: int, type_: Optional[ast.TypeAnnotation]) -> ast.Number: """Creates a number AST node with value 'value' of type 'type_'.""" return ast.Number(self.fake_span, hex(value).rstrip('L'), ast.NumberKind.OTHER, type_)