def _bind_names(name_def_tree: ast.NameDefTree, type_: ConcreteType, ctx: DeduceCtx) -> None: """Binds names in name_def_tree to corresponding type given in type_.""" if name_def_tree.is_leaf(): name_def = name_def_tree.get_leaf() ctx.type_info[name_def] = type_ return if not isinstance(type_, TupleType): raise XlsTypeError( name_def_tree.span, type_, rhs_type=None, suffix='Expected a tuple type for these names, but got {}.'.format( type_)) if len(name_def_tree.tree) != type_.get_tuple_length(): raise TypeInferenceError( name_def_tree.span, type_, 'Could not bind names, names are mismatched in number vs type; at ' 'this level of the tuple: {} names, {} types.'.format( len(name_def_tree.tree), type_.get_tuple_length())) for subtree, subtype in zip(name_def_tree.tree, type_.get_unnamed_members()): ctx.type_info[subtree] = subtype _bind_names(subtree, subtype, ctx)
def sign_convert_value(concrete_type: ConcreteType, value: Value) -> Value: """Converts the values to matched the signedness of the concrete type. Converts bits-typed Values contained within the given Value to match the signedness of the ConcreteType. Examples: invocation: sign_convert_value(s8, u8:64) returns: s8:64 invocation: sign_convert_value(s3, u8:7) returns: s3:-1 invocation: sign_convert_value((s8, u8), (u8:42, u8:10)) returns: (s8:42, u8:10) This conversion functionality is required because the Values used in the DSLX may be signed while Values in IR interpretation and Verilog simulation are always unsigned. This function is idempotent. Args: concrete_type: ConcreteType to match. value: Input value. Returns: Sign-converted value. """ if isinstance(concrete_type, concrete_type_mod.TupleType): assert value.is_tuple() assert len(value.tuple_members) == concrete_type.get_tuple_length() return Value.make_tuple( tuple( sign_convert_value(t, a) for t, a in zip( concrete_type.get_unnamed_members(), value.tuple_members))) elif isinstance(concrete_type, concrete_type_mod.ArrayType): assert value.is_array() assert len(value.array_payload.elements) == concrete_type.size return Value.make_array( tuple( sign_convert_value(concrete_type.get_element_type(), v) for v in value.array_payload.elements)) elif concrete_type_mod.is_sbits(concrete_type): return Value.make_sbits(value.get_bit_count(), value.get_bits_value()) else: assert concrete_type_mod.is_ubits(concrete_type) return value
def _unify_NameDefTree(self: ast.NameDefTree, type_: ConcreteType, ctx: DeduceCtx) -> None: """Unifies the NameDefTree AST node with the observed RHS type type_.""" resolved_rhs_type = resolve(type_, ctx) if self.is_leaf(): leaf = self.get_leaf() if isinstance(leaf, ast.NameDef): ctx.type_info[leaf] = resolved_rhs_type elif isinstance(leaf, ast.WildcardPattern): pass elif isinstance(leaf, (ast.Number, ast.EnumRef)): resolved_leaf_type = resolve(deduce(leaf, ctx), ctx) if resolved_leaf_type != resolved_rhs_type: raise TypeInferenceError( span=self.span, type_=resolved_rhs_type, suffix= 'Conflicting types; pattern expects {} but got {} from value' .format(resolved_rhs_type, resolved_leaf_type)) else: assert isinstance(leaf, ast.NameRef), repr(leaf) ref_type = ctx.type_info[leaf.name_def] resolved_ref_type = resolve(ref_type, ctx) if resolved_ref_type != resolved_rhs_type: raise TypeInferenceError( span=self.span, type_=resolved_rhs_type, suffix= 'Conflicting types; pattern expects {} but got {} from reference' .format(resolved_rhs_type, resolved_ref_type)) else: assert isinstance(self.tree, tuple) if isinstance(type_, TupleType) and type_.get_tuple_length() == len( self.tree): for subtype, subtree in zip(type_.get_unnamed_members(), self.tree): _unify(subtree, subtype, ctx)