def _extract_module_level_constants(self, m: ast.Module): """Populates `self.symbolic_bindings` with module-level constant values.""" for constant in m.get_constants(): if isinstance(constant.value, ast.Number): value = ast_helpers.get_value_as_int(constant.value) logging.vlog( 3, 'Found module-level constant %s for symbolic bindings: %s', constant.name.identifier, value) self.symbolic_bindings[constant.name.identifier] = value logging.vlog(2, 'Symbolic bindings now: %s', self.symbolic_bindings)
def _get_array_size(self, array_type: ast.ArrayTypeAnnotation) -> int: """Returns the (constant) size of an array type. Since those are the only array types the generator currently produces, this can be used to determine the length of array types in the environment. Args: array_type: The type to extract the array size/length from. Note: uN[42] is an ArrayTypeAnnotation, and this function will return 42 for it, since it's just evaluating-to-int the value in the "dim" field of the ArrayTypeAnnotation. """ assert isinstance(array_type, ast.ArrayTypeAnnotation), array_type dim = array_type.dim if isinstance(dim, ast.Number): return ast_helpers.get_value_as_int(dim) assert isinstance(dim, ast.ConstRef) const_def = self._constants[dim.identifier] return ast_helpers.get_value_as_int(const_def.value)
def builtin_type_to_bits(type_annotation: ast.TypeAnnotation) -> int: """Converts a type annotation (array of builtin or builtin) to a bit count.""" if isinstance(type_annotation, ast.ArrayTypeAnnotation): assert isinstance(type_annotation.element_type, ast.BuiltinTypeAnnotation) dim = type_annotation.dim assert isinstance(dim, ast.Number), dim return builtin_type_to_bits( type_annotation.element_type) * ast_helpers.get_value_as_int(dim) assert isinstance(type_annotation, ast.BuiltinTypeAnnotation), repr(type_annotation) return type_annotation.bits
def _get_array_size(self, array_type: ast.TypeAnnotation) -> int: """Returns the (constant) size of an array type. Since those are the only array types the generator currently produces, this can be used to determine the length of array types in the environment. Args: array_type: The type to extract the array size/length from. """ assert isinstance(array_type, ast.ArrayTypeAnnotation), array_type dim = array_type.dim assert isinstance(dim, ast.Number), dim return ast_helpers.get_value_as_int(dim)
def get_const_int(self, name_def: ast.NameDef, user_span: Span) -> int: if name_def not in self._name_to_const and self.parent: return self.parent.get_const_int(name_def, user_span) constant = self._name_to_const[name_def] value = constant.value if isinstance(value, ast.Number): return ast_helpers.get_value_as_int(value) raise TypeInferenceError( span=user_span, type_=None, suffix='Expected to find a constant integral value with the name {};' 'got: {}'.format(name_def, constant.value))
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, ast_helpers.get_value_as_int(n))
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, ast_helpers.get_value_as_int(n))
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, ast_helpers.get_value_as_int(n))
def _is_constant_zero(self, node: ast.AstNode) -> bool: return isinstance(node, ast.Number) and ast_helpers.get_value_as_int(node) == 0
def visit_Number(self, node: ast.Number): type_ = self._resolve_type(node) self._def_const(node, ast_helpers.get_value_as_int(node), type_.get_total_bit_count())