def register_variable(self, name, v_type): # Check that the type is valid if not Types.is_valid(v_type.name): v_type.raise_compiler_error("T0", info=v_type.name) if name.name in self.var_identifiers.keys(): if Types.is_quantum(v_type.name): name.raise_compiler_error("Q1", info=name.name) else: name.raise_compiler_error("C0", info=name.name) else: self.var_identifiers[name.name] = (v_type, name)
def visit_c_decl(self, scope): if not self.in_region: scope.raise_compiler_error("F0") t = scope.get_type() if Types.is_quantum(t.name): t.raise_compiler_error("C4") expr = scope.get_expression() if expr.data == "c_lit" and not Types.is_register(t.name): expr.raise_compiler_error("C5") elif Types.is_register(t.name) and not expr.data == "c_lit": expr.raise_compiler_error("C5")
def get_quantum_arguments(self) -> list: arguments = self.owning_scope.get_arg_list().get_arguments() quantum_args = [] for arg in arguments: if Types.is_quantum(arg.get_type().name): quantum_args.append(arg) return quantum_args
def get_classical_arguments(self) -> list: arguments = self.owning_scope.get_arg_list().get_arguments() classical_args = [] for arg in arguments: if Types.is_classical(arg.get_type().name): classical_args.append(arg) return classical_args
def get_quantum_arguments(self) -> list: arguments = self.owning_scope.children quantum_args = [] for arg in arguments: if Types.is_quantum(arg.get_type_name()): quantum_args.append(arg) return quantum_args
def get_classical_arguments(self) -> list: arguments = self.owning_scope.children classical_args = [] for arg in arguments: if Types.is_classical(arg.get_type_name()): classical_args.append(arg) return classical_args
def visit_c_decl(self, scope): name = scope.get_name() v_type = scope.get_type() scope.super_scope.register_variable(name, v_type) if Types.is_register(v_type): bits = scope.get_bits() if "1" in bits: self.ast.region_needs_measurement_qubit(self.current_region)
def evaluate_expression(self, scope): if scope.data == "uint": return scope.value elif scope.data == "v_ident": if Types.is_quantum(scope.get_type_name()): scope.raise_compiler_error("Q7") elif Types.is_register(scope.get_type_name()): scope.raise_compiler_error("C6") return scope.get_classical_value(scope.name) elif scope.data == "operation": op = scope.get_operation() arg1, arg2 = scope.get_operands() operation = { "+": operator.add, "-": operator.sub, "*": operator.mul, "/": operator.floordiv }[op] return operation(self.evaluate_expression(arg1), self.evaluate_expression(arg2))
def visit_q_decl(self, scope): if not self.in_region: scope.raise_compiler_error("F0") t = scope.get_type() name = scope.get_name().name if not Types.is_quantum(t.name) or not Types.is_register(t.name): t.raise_compiler_error("Q0") length = scope.get_length() self.region_counter += length self.quantum_var_sizes[name] = length if self.region_counter > self.qubit_max: if self.ast.does_region_need_measurement_qubit( self.current_region): scope.raise_compiler_error("R1N", info=(scope.get_name().name, self.current_region)) else: scope.raise_compiler_error("R1", info=(scope.get_name().name, self.current_region))
def verify_one_quantum_arg(self, arguments): """ Verify that a function has at least one quantum argument""" for arg in arguments.get_arguments(): if Types.is_quantum(arg.get_type().name): return arguments.raise_compiler_error("F7", info=self.current_function)
def verify_arg_types(self, arguments): """ Verify that a function's arguments are not register values""" for arg in arguments.get_arguments(): if Types.is_register(arg.get_type().name): arg.get_type().raise_compiler_error("F6")
def is_const(self, scope): typename = scope.get_type_for(scope.name).name return Types.is_classical(typename) and not Types.is_register(typename)