def test_sample_evaluation(self): fake_pos = Pos('<fake>', 0, 0) fake_span = Span(fake_pos, fake_pos) e = ParametricMul( ParametricConstant(3), ParametricAdd(ParametricSymbol('M', fake_span), ParametricSymbol('N', fake_span))) self.assertEqual(e, e) self.assertEqual('(3)*((M)+(N))', str(e)) self.assertEqual(6, e.evaluate(dict(N=2, M=0))) self.assertEqual(12, e.evaluate(dict(N=1, M=3))) self.assertEqual(set(['N', 'M']), e.get_freevars())
def test_equality(self): fake_pos = span.Pos('<fake>', 0, 0) fake_span = span.Span(fake_pos, fake_pos) p = BitsType(signed=False, size=ParametricSymbol('N', fake_span)) c = BitsType(signed=False, size=32) self.assertTrue(p.__ne__(c)) self.assertFalse(p.__eq__(c))
def test_simple_folding(self): fake_pos = Pos('<fake>', 0, 0) fake_span = Span(fake_pos, fake_pos) n = ParametricSymbol('N', fake_span) self.assertEqual(n, 0 + n) self.assertEqual(n, 1 * n) self.assertNotEqual(n, 0 * n)
def _dim_to_parametric(self: ast.TypeAnnotation, expr: ast.Expr) -> ParametricExpression: """Converts a dimension expression to a 'parametric' AST node.""" assert not isinstance(expr, ast.ConstRef), expr if isinstance(expr, ast.NameRef): return ParametricSymbol(expr.name_def.identifier, expr.span) if isinstance(expr, ast.Binop): if expr.kind == ast.BinopKind.ADD: return ParametricAdd(_dim_to_parametric(self, expr.lhs), _dim_to_parametric(self, expr.rhs)) msg = 'Could not concretize type with dimension: {}.'.format(expr) raise TypeInferenceError(self.span, self, suffix=msg)
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)