def _resolve(self, annotated: ConcreteType) -> ConcreteType: """Resolves a parametric type via symbolic_bindings.""" if self.constraints: self._verify_constraints() def resolver(dim): if isinstance(dim, parametric_expression.ParametricExpression): return dim.evaluate(self.symbolic_bindings) return dim return annotated.map_size(resolver)
def resolve(type_: ConcreteType, ctx: DeduceCtx) -> ConcreteType: """Resolves "type_" via provided symbolic bindings. Uses the symbolic bindings of the function we're currently inside of to resolve parametric types. Args: type_: Type to resolve any contained dims for. ctx: Deduction context to use in resolving the dims. Returns: "type_" with dimensions resolved according to bindings in "ctx". """ _, fn_symbolic_bindings = ctx.fn_stack[-1] def resolver(dim): if isinstance(dim, ParametricExpression): return dim.evaluate(fn_symbolic_bindings) return dim return type_.map_size(resolver)
def _concretize_struct_annotation(type_annotation: ast.TypeRefTypeAnnotation, struct: ast.Struct, base_type: ConcreteType) -> ConcreteType: """Returns concretized struct type using the provided bindings. For example, if we have a struct defined as `struct [N: u32, M: u32] Foo`, the default TupleType will be (N, M). If a type annotation provides bindings, (e.g. Foo[A, 16]), we will replace N, M with those values. In the case above, we will return (A, 16) instead. Args: type_annotation: The provided type annotation for this parametric struct. struct: The corresponding struct AST node. base_type: The TupleType of the struct, based only on the struct definition. """ assert len(struct.parametric_bindings) == len(type_annotation.parametrics) defined_to_annotated = {} for defined_parametric, annotated_parametric in zip( struct.parametric_bindings, type_annotation.parametrics): assert isinstance(defined_parametric, ast.ParametricBinding), defined_parametric if isinstance(annotated_parametric, ast.Number): defined_to_annotated[defined_parametric.name.identifier] = \ int(annotated_parametric.value) else: assert isinstance(annotated_parametric, ast.NameRef), repr(annotated_parametric) defined_to_annotated[defined_parametric.name.identifier] = \ ParametricSymbol(annotated_parametric.identifier, annotated_parametric.span) def resolver(dim): if isinstance(dim, ParametricExpression): return dim.evaluate(defined_to_annotated) return dim return base_type.map_size(resolver)