def string_literal(self, string): """ Define a new string literal. """ from qy import Value if string not in self._literals: name = "literal%i" % len(self._literals) value = \ Value.from_low( llvm.GlobalVariable.new( self.module, llvm.Type.array(llvm.Type.int(8), len(string) + 1), name, ), ) value._value.linkage = llvm.LINKAGE_INTERNAL value._value.initializer = llvm.Constant.stringz(string) self._literals[string] = value return value else: return self._literals[string]
def stack_allocate(self, type_, initial = None, name = ""): """ Stack-allocate and return a value. """ from qy import Value allocated = Value.from_low(self.builder.alloca(self.type_from_any(type_), name)) if initial is not None: self.value_from_any(initial).store(allocated) return allocated
def decorator(emit_body): """ Emit the IR for a particular loop body. """ # prepare the loop structure builder = self.builder start = self.basic_block check = self.function.append_basic_block("for_loop_check") flesh = self.function.append_basic_block("for_loop_flesh") leave = self.function.append_basic_block("for_loop_leave") # build the check block builder.branch(check) builder.position_at_end(check) this_index = builder.phi(index_type, "for_loop_index") this_index.add_incoming(llvm.Constant.int(index_type, 0), start) builder.cbranch( builder.icmp( llvm.ICMP_UGT, count.low, this_index, ), flesh, leave, ) # build the flesh block from qy import Value builder.position_at_end(flesh) self._break_stack.append(leave) emit_body(Value.from_low(this_index)) self._break_stack.pop() this_index.add_incoming( builder.add(this_index, llvm.Constant.int(index_type, 1)), builder.basic_block, ) builder.branch(check) # wrap up the loop builder.position_at_end(leave)