예제 #1
0
 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())
예제 #2
0
 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))
예제 #3
0
 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)
예제 #4
0
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)
예제 #5
0
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)