Exemplo n.º 1
0
    def visitClassicalType(self, ctx: qasm3Parser.ClassicalTypeContext):
        # TODO: due to the way classical argument is declared, there some duplication
        # Consider refactor classical argument grammar
        if ctx.singleDesignatorType():
            type_name = ctx.singleDesignatorType().getText()
            if type_name in _TYPE_NODE_INIT:
                type_size = self.visit(ctx.designator())
                type_node = _TYPE_NODE_INIT[type_name](type_size)
            else:
                # To capture potential parser errors.
                raise ValueError(f"Type name {type_name} not found.")

            return add_span(
                type_node,
                combine_span(get_span(ctx.singleDesignatorType()),
                             get_span(ctx.designator())),
            )

        elif ctx.noDesignatorType():
            return self.visit(ctx.noDesignatorType())
        elif ctx.bitType():
            return BitType(
                self.visit(ctx.designator()) if ctx.designator() else None, )
        elif ctx.numericType():
            return ComplexType(base_type=self.visit(ctx.numericType()))
Exemplo n.º 2
0
 def visitComplexDeclaration(self,
                             ctx: qasm3Parser.ComplexDeclarationContext):
     return ClassicalDeclaration(
         add_span(
             ComplexType(base_type=self.visit(ctx.numericType())),
             get_span(ctx),
         ),
         add_span(Identifier(ctx.Identifier().getText()),
                  get_span(ctx.Identifier())),
         self.visit(ctx.equalsExpression().expression())
         if ctx.equalsExpression() else None,
     )
Exemplo n.º 3
0
def test_array_declaration():
    p = """
    array[uint[8], 2] a;
    array[int[8], 2] a = {1, 1};
    array[bit, 2] a = b;
    array[float[32], 2, 2] a;
    array[complex[float[64]], 2, 2] a = {{1, 1}, {2, 2}};
    array[uint[8], 2, 2] a = {b, b};
    """.strip()
    program = parse(p)
    a, b = Identifier("a"), Identifier("b")
    one, two, eight = IntegerLiteral(1), IntegerLiteral(2), IntegerLiteral(8)
    SpanGuard().visit(program)
    assert program == Program(statements=[
        ClassicalDeclaration(
            type=ArrayType(base_type=UintType(eight), dimensions=[two]),
            identifier=a,
            init_expression=None,
        ),
        ClassicalDeclaration(
            type=ArrayType(base_type=IntType(eight), dimensions=[two]),
            identifier=a,
            init_expression=ArrayLiteral([one, one]),
        ),
        ClassicalDeclaration(
            type=ArrayType(base_type=BitType(size=None), dimensions=[two]),
            identifier=a,
            init_expression=b,
        ),
        ClassicalDeclaration(
            type=ArrayType(
                base_type=FloatType(IntegerLiteral(32)),
                dimensions=[two, two],
            ),
            identifier=a,
            init_expression=None,
        ),
        ClassicalDeclaration(
            type=ArrayType(
                base_type=ComplexType(FloatType(IntegerLiteral(64))),
                dimensions=[two, two],
            ),
            identifier=a,
            init_expression=ArrayLiteral(
                [ArrayLiteral([one, one]),
                 ArrayLiteral([two, two])], ),
        ),
        ClassicalDeclaration(
            type=ArrayType(base_type=UintType(eight), dimensions=[two, two]),
            identifier=a,
            init_expression=ArrayLiteral([b, b]),
        ),
    ], )
Exemplo n.º 4
0
    def visitClassicalArgument(self,
                               ctx: qasm3Parser.ClassicalArgumentContext):
        if ctx.CONST():
            access = AccessControl.CONST
        elif ctx.MUTABLE():
            access = AccessControl.MUTABLE
        else:
            access = None

        if ctx.singleDesignatorType():
            type_name = ctx.singleDesignatorType().getText()
            if type_name in _TYPE_NODE_INIT:
                type_size = self.visit(ctx.designator())
                type_node = _TYPE_NODE_INIT[type_name](type_size)
            else:
                # To capture potential parser error.
                raise ValueError("Type name {type_name} not found.")

            classical_type = add_span(
                type_node,
                combine_span(get_span(ctx.singleDesignatorType()),
                             get_span(ctx.designator())),
            )

        elif ctx.noDesignatorType():
            classical_type = self.visit(ctx.noDesignatorType())

        elif ctx.COMPLEX():
            classical_type = add_span(
                ComplexType(base_type=self.visit(ctx.numericType())),
                combine_span(get_span(ctx.COMPLEX()),
                             get_span(ctx.RBRACKET())),
            )

        elif ctx.arrayReferenceType():
            classical_type = self.visit(ctx.arrayReferenceType())

        else:
            classical_type = add_span(
                BitType(
                    self.visit(ctx.designator())
                    if ctx.designator() else None, ),
                get_span(ctx.getChild(0)),
            )

        identifier = add_span(Identifier(ctx.Identifier().getText()),
                              get_span(ctx.Identifier()))
        return ClassicalArgument(
            type=classical_type,
            name=identifier,
            access=access,
        )
Exemplo n.º 5
0
def test_complex_declaration():
    p = """
    complex[int[24]] iq;
    """.strip()
    program = parse(p)
    assert program == Program(statements=[
        ClassicalDeclaration(
            ComplexType(base_type=IntType(IntegerLiteral(24))),
            Identifier("iq"),
            None,
        ),
    ])
    SpanGuard().visit(program)
    context_declaration = program.statements[0]
    assert context_declaration.span == Span(1, 0, 1, 19)
Exemplo n.º 6
0
def test_subroutine_signatures():
    p = """
    def a(int[8] b) {}
    def a(complex[float[32]] b, qubit c) -> int[32] {}
    def a(bit[5] b, qubit[2] c) -> complex[float[64]] {}
    def a(qubit b, const array[uint[8], 2, 3] c) {}
    def a(mutable array[uint[8], #dim=5] b, const array[uint[8], 5] c) {}
    """.strip()
    program = parse(p)
    a, b, c = Identifier(name="a"), Identifier(name="b"), Identifier(name="c")
    SpanGuard().visit(program)
    assert program == Program(statements=[
        SubroutineDefinition(
            name=a,
            arguments=[ClassicalArgument(IntType(IntegerLiteral(8)), b)],
            return_type=None,
            body=[],
        ),
        SubroutineDefinition(
            name=a,
            arguments=[
                ClassicalArgument(
                    type=ComplexType(FloatType(IntegerLiteral(32))),
                    name=b,
                ),
                QuantumArgument(qubit=c, size=None),
            ],
            return_type=IntType(IntegerLiteral(32)),
            body=[],
        ),
        SubroutineDefinition(
            name=a,
            arguments=[
                ClassicalArgument(
                    type=BitType(size=IntegerLiteral(5)),
                    name=b,
                ),
                QuantumArgument(qubit=c, size=IntegerLiteral(2)),
            ],
            return_type=ComplexType(FloatType(IntegerLiteral(64))),
            body=[],
        ),
        SubroutineDefinition(
            name=a,
            arguments=[
                QuantumArgument(qubit=b, size=None),
                ClassicalArgument(
                    type=ArrayReferenceType(
                        base_type=UintType(IntegerLiteral(8)),
                        dimensions=[IntegerLiteral(2),
                                    IntegerLiteral(3)],
                    ),
                    name=c,
                    access=AccessControl.CONST,
                ),
            ],
            return_type=None,
            body=[],
        ),
        SubroutineDefinition(
            name=a,
            arguments=[
                # Note that the first ArrayReferenceType has dimensions of
                # IntegerLiteral(5) referring to the number of dimensions,
                # but the second has dimensions [IntegerLiteral(5)] (with a
                # list), because the sizes of the dimensions are given
                # explicitly.
                ClassicalArgument(
                    type=ArrayReferenceType(
                        base_type=UintType(IntegerLiteral(8)),
                        dimensions=IntegerLiteral(5),
                    ),
                    name=b,
                    access=AccessControl.MUTABLE,
                ),
                ClassicalArgument(
                    type=ArrayReferenceType(
                        base_type=UintType(IntegerLiteral(8)),
                        dimensions=[IntegerLiteral(5)],
                    ),
                    name=c,
                    access=AccessControl.CONST,
                ),
            ],
            return_type=None,
            body=[],
        ),
    ])