def parse(quil: str) -> List[AbstractInstruction]: """ Parse a raw Quil program and return a corresponding list of PyQuil objects. :param str quil: a single or multiline Quil program :return: list of instructions """ return run_parser(quil)
def inst(self, *instructions): """ Mutates the Program object by appending new instructions. This function accepts a number of different valid forms, e.g. >>> p = Program() >>> p.inst(H(0)) # A single instruction >>> p.inst(H(0), H(1)) # Multiple instructions >>> p.inst([H(0), H(1)]) # A list of instructions >>> p.inst(H(i) for i in range(4)) # A generator of instructions >>> p.inst(("H", 1)) # A tuple representing an instruction >>> p.inst("H 0") # A string representing an instruction >>> q = Program() >>> p.inst(q) # Another program It can also be chained: >>> p = Program() >>> p.inst(H(0)).inst(H(1)) :param instructions: A list of Instruction objects, e.g. Gates :return: self for method chaining """ for instruction in instructions: if isinstance(instruction, list): self.inst(*instruction) elif isinstance(instruction, types.GeneratorType): self.inst(*instruction) elif isinstance(instruction, tuple): if len(instruction) == 0: raise ValueError("tuple should have at least one element") elif len(instruction) == 1: self.inst(instruction[0]) else: op = instruction[0] if op == "MEASURE": if len(instruction) == 2: self.measure(instruction[1], None) else: self.measure(instruction[1], instruction[2]) else: params = [] possible_params = instruction[1] rest = instruction[2:] if isinstance(possible_params, list): params = possible_params else: rest = [possible_params] + list(rest) self.gate(op, params, rest) elif isinstance(instruction, string_types): self.inst(run_parser(instruction.strip())) elif isinstance(instruction, Program): if id(self) == id(instruction): raise ValueError("Nesting a program inside itself is not supported") for defgate in instruction._defined_gates: self.inst(defgate) for instr in instruction._instructions: self.inst(instr) # Implementation note: these two base cases are the only ones which modify the program elif isinstance(instruction, DefGate): defined_gate_names = [gate.name for gate in self._defined_gates] if instruction.name in defined_gate_names: warnings.warn("Gate {} has already been defined in this program" .format(instruction.name)) self._defined_gates.append(instruction) elif isinstance(instruction, AbstractInstruction): self._instructions.append(instruction) self._synthesized_instructions = None else: raise TypeError("Invalid instruction: {}".format(instruction)) return self
def inst(self, *instructions): """ Mutates the Program object by appending new instructions. This function accepts a number of different valid forms, e.g. >>> p = Program() >>> p.inst(H(0)) # A single instruction >>> p.inst(H(0), H(1)) # Multiple instructions >>> p.inst([H(0), H(1)]) # A list of instructions >>> p.inst(("H", 1)) # A tuple representing an instruction >>> p.inst("H 0") # A string representing an instruction >>> q = Program() >>> p.inst(q) # Another program It can also be chained: >>> p = Program() >>> p.inst(H(0)).inst(H(1)) :param instructions: A list of Instruction objects, e.g. Gates :return: self for method chaining """ for instruction in instructions: if isinstance(instruction, list): self.inst(*instruction) elif isinstance(instruction, tuple): if len(instruction) == 0: raise ValueError("tuple should have at least one element") elif len(instruction) == 1: self.inst(instruction[0]) else: op = instruction[0] if op == "MEASURE": if len(instruction) == 2: self.measure(instruction[1]) else: self.measure(instruction[1], instruction[2]) else: params = [] possible_params = instruction[1] rest = instruction[2:] if isinstance(possible_params, list): params = possible_params else: rest = [possible_params] + list(rest) self.gate(op, params, rest) elif isinstance(instruction, string_types): self.inst(run_parser(instruction.strip())) elif isinstance(instruction, DefGate): self._defined_gates.append(instruction) elif isinstance(instruction, AbstractInstruction): self._instructions.append(instruction) self._synthesized_instructions = None elif isinstance(instruction, Program): if id(self) == id(instruction): raise ValueError( "Nesting a program inside itself is not supported") self._defined_gates.extend(list(instruction._defined_gates)) self._instructions.extend(list(instruction._instructions)) self._synthesized_instructions = None else: raise TypeError("Invalid instruction: {}".format(instruction)) return self