Mercurial > hg > Members > shinya > pyrect
changeset 21:a24acddedf89
rename files to follow PEP. and debug llvm_trnslator.py.
author | Ryoma SHINYA <shinya@firefly.cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 05 Jul 2010 19:54:27 +0900 |
parents | de33e445fcc7 |
children | 5149b48b22a9 |
files | src/__init__.py src/cTranslator.py src/c_translator.py src/cbcTranslator.py src/cbc_translator.py src/converter.py src/dotTranslator.py src/dot_translator.py src/llvm_bench.py src/llvm_translator.py |
diffstat | 10 files changed, 271 insertions(+), 245 deletions(-) [+] |
line wrap: on
line diff
--- a/src/__init__.py Mon Jul 05 18:42:11 2010 +0900 +++ b/src/__init__.py Mon Jul 05 19:54:27 2010 +0900 @@ -1,2 +1,5 @@ +#!/usr/bin/env python + +from dfareg import Regexp def compile(regexp): return Regexp(regexp)
--- a/src/cTranslator.py Mon Jul 05 18:42:11 2010 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -#!/Usr/bin/env python - -from dfareg import Regexp, CallGraph -from translator import Translator - -class CTranslator(Translator): - """CTranslator - This Class can translate from DFA or NFA into C source code. - DFA: A simple state transition as tail call (also can implement with CbC). - NFA: using stack, deepening depth-first search. - >>> string = '(A|B)*C' - >>> reg = Regexp(string) - >>> dfacg = CallGraph(reg.dfa) - >>> nfacg = CallGraph(reg.nfa) - >>> CTranslator(string, dfacg).translate() - >>> CTranslator(string, nfacg).translate() - """ - def __init__(self, regexp, cg): - Translator.__init__(self, regexp, cg) - self.funType = 'void ' - self.callType = '' - self.breakStatement = '\t\t\tbreak;' - self.debug = False - if self.cg.type == "DFA": - self.name_hash = self.create_name_hash() - - def modify_state_name(self, state_name): - if state_name == "accept" or state_name == "reject": - return state_name - if self.cg.type == "DFA": - return "state_"+self.name_hash[state_name] - else: - return "state_"+state_name - - def emit_accept_state(self): - self.emit (""" -%saccept(char* s) { -\tprintf(\"\\nstring matches regexp. \\n\\n\"); -}\n""" % self.funType) - - def emit_reject_state(self): - self.emit (""" -%sreject(char* s) { -\tprintf(\"\\nstring does not match regexp. \\n\\n\"); -}\n""" % self.funType) - - def emit_driver(self): - self.emit(""" -int main(int argc, char* argv[]) { -\tputs(\"regexp: %s\"); -\tputs(\"number of state: %d\"); -\tprintf(\"string: %%s\\n\", argv[1]); -\t%s%s(argv[1]); -""" % (self.regexp, len(self.cg.states), self.callType, self.modify_state_name(self.cg.start))) - if self.cg.type == "NFA": - self.emit("\treject(argv[1]);\n") - self.emit(""" -\treturn 0; -}\n\n""") - - def emit_switch(self, case, default=None): - self.emit("\tswitch(s++) {\n") - - for input, next_states in case.iteritems(): - if input != '': - self.emit("\t\tcase '%s': \n" % (input)) - for next_state in next_states: - self.emit("\t\t\t%s%s(s);\n" % (self.callType, self.modify_state_name(next_state))) - if self.breakStatement != '': self.emit(self.breakStatement+'\n') - - if default: - self.emit( """\t\tdefault:\n\t\t\t%s%s(NULL);\n""" % (self.callType, default)) - self.emit("\t}\n") - - - def emit_state(self, cur_state, transition): - self.emit(self.funType + self.modify_state_name(cur_state) + "(char* s) {\n") - if self.debug: - self.emit("\tprintf(\"state: %s, input: %%s\\n\", s);\n" % (cur_state)) - if self.cg.type == "NFA": - if '' in transition: - epsilon_transition = transition.pop('') - for n in epsilon_transition: - self.emit("\t%s%s(s);\n" % (self.callType, self.modify_state_name(n))) - - if cur_state in self.cg.accepts: - transition['\\0'] = ["accept"] - - if transition: - if self.cg.type == "DFA": - self.emit_switch(transition, default="reject") - else: - self.emit_switch(transition) - self.emit("}\n\n") - - def emit_initialization(self): - self.emit("#include <stdio.h>\n\n") - for state in self.cg.map.iterkeys(): - self.emit(self.funType + self.modify_state_name(state) + "(char* s);\n") - self.emit(self.funType + 'accept(char* s);\n') - self.emit(self.funType + 'reject(char* s);\n') - - def emit_from_callgraph(self): - # self.emit C-source code - self.emit_initialization() - self.emit_driver() - - for cur_state, transition in self.cg.map.iteritems(): - self.emit_state(cur_state, transition) - - self.emit_accept_state() - self.emit_reject_state() - -def test(): - import doctest - doctest.testmod() - -if __name__ == '__main__': test()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/c_translator.py Mon Jul 05 19:54:27 2010 +0900 @@ -0,0 +1,118 @@ +#!/Usr/bin/env python + +from dfareg import Regexp, CallGraph +from translator import Translator + +class CTranslator(Translator): + """CTranslator + This Class can translate from DFA or NFA into C source code. + DFA: A simple state transition as tail call (also can implement with CbC). + NFA: using stack, deepening depth-first search. + >>> string = '(A|B)*C' + >>> reg = Regexp(string) + >>> dfacg = CallGraph(reg.dfa) + >>> nfacg = CallGraph(reg.nfa) + >>> CTranslator(string, dfacg).translate() + >>> CTranslator(string, nfacg).translate() + """ + def __init__(self, regexp, cg): + Translator.__init__(self, regexp, cg) + self.funType = 'void ' + self.callType = '' + self.breakStatement = '\t\t\tbreak;' + self.debug = False + if self.cg.type == "DFA": + self.name_hash = self.create_name_hash() + + def modify_state_name(self, state_name): + if state_name == "accept" or state_name == "reject": + return state_name + if self.cg.type == "DFA": + return "state_"+self.name_hash[state_name] + else: + return "state_"+state_name + + def emit_accept_state(self): + self.emit (""" +%saccept(char* s) { +\tprintf(\"\\nstring matches regexp. \\n\\n\"); +}\n""" % self.funType) + + def emit_reject_state(self): + self.emit (""" +%sreject(char* s) { +\tprintf(\"\\nstring does not match regexp. \\n\\n\"); +}\n""" % self.funType) + + def emit_driver(self): + self.emit(""" +int main(int argc, char* argv[]) { +\tputs(\"regexp: %s\"); +\tputs(\"number of state: %d\"); +\tprintf(\"string: %%s\\n\", argv[1]); +\t%s%s(argv[1]); +""" % (self.regexp, len(self.cg.states), self.callType, self.modify_state_name(self.cg.start))) + if self.cg.type == "NFA": + self.emit("\treject(argv[1]);\n") + self.emit(""" +\treturn 0; +}\n\n""") + + def emit_switch(self, case, default=None): + self.emit("\tswitch(s++) {\n") + + for input, next_states in case.iteritems(): + if input != '': + self.emit("\t\tcase '%s': \n" % (input)) + for next_state in next_states: + self.emit("\t\t\t%s%s(s);\n" % (self.callType, self.modify_state_name(next_state))) + if self.breakStatement != '': self.emit(self.breakStatement+'\n') + + if default: + self.emit( """\t\tdefault:\n\t\t\t%s%s(NULL);\n""" % (self.callType, default)) + self.emit("\t}\n") + + + def emit_state(self, cur_state, transition): + self.emit(self.funType + self.modify_state_name(cur_state) + "(char* s) {\n") + if self.debug: + self.emit("\tprintf(\"state: %s, input: %%s\\n\", s);\n" % (cur_state)) + if self.cg.type == "NFA": + if '' in transition: + epsilon_transition = transition.pop('') + for n in epsilon_transition: + self.emit("\t%s%s(s);\n" % (self.callType, self.modify_state_name(n))) + + if cur_state in self.cg.accepts: + transition['\\0'] = ["accept"] + + if transition: + if self.cg.type == "DFA": + self.emit_switch(transition, default="reject") + else: + self.emit_switch(transition) + self.emit("}\n\n") + + def emit_initialization(self): + self.emit("#include <stdio.h>\n\n") + for state in self.cg.map.iterkeys(): + self.emit(self.funType + self.modify_state_name(state) + "(char* s);\n") + self.emit(self.funType + 'accept(char* s);\n') + self.emit(self.funType + 'reject(char* s);\n') + + def emit_from_callgraph(self): + # self.emit C-source code + self.emit_initialization() + self.emit_driver() + + for cur_state, transition in self.cg.map.iteritems(): + self.emit_state(cur_state, transition) + + self.emit_accept_state() + self.emit_reject_state() + +def test(): + import doctest + doctest.testmod() + +if __name__ == '__main__': test()
--- a/src/cbcTranslator.py Mon Jul 05 18:42:11 2010 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -#!/usr/bin/env python - -from dfareg import Regexp, CallGraph -from cTranslator import CTranslator - -class CbCTranslateExeption(Exception): - pass - -class CbCTranslator(CTranslator): - """ - CbCTranslator - >>> string = \"(A|B)*C\" - >>> reg = Regexp(string) - >>> dfacg = CallGraph(reg.dfa) - >>> ct = CbCTranslator(string, dfacg) - >>> ct.translate() - >>> ct.debug = True - >>> ct.translate() - """ - def __init__(self, regexp, cg): - if cg.type == "NFA": raise CbCTranslateExeption("can't translate CbC from NFA") - CTranslator.__init__(self, regexp, cg) - self.funType = '__code ' - self.callType = 'goto ' - self.breakStatement = '' - -def test(): - import doctest - doctest.testmod() - -if __name__ == '__main__' : test()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cbc_translator.py Mon Jul 05 19:54:27 2010 +0900 @@ -0,0 +1,31 @@ +#!/usr/bin/env python + +from dfareg import Regexp, CallGraph +from c_translator import CTranslator + +class CbCTranslateExeption(Exception): + pass + +class CbCTranslator(CTranslator): + """ + CbCTranslator + >>> string = \"(A|B)*C\" + >>> reg = Regexp(string) + >>> dfacg = CallGraph(reg.dfa) + >>> ct = CbCTranslator(string, dfacg) + >>> ct.translate() + >>> ct.debug = True + >>> ct.translate() + """ + def __init__(self, regexp, cg): + if cg.type == "NFA": raise CbCTranslateExeption("can't translate CbC from NFA") + CTranslator.__init__(self, regexp, cg) + self.funType = '__code ' + self.callType = 'goto ' + self.breakStatement = '' + +def test(): + import doctest + doctest.testmod() + +if __name__ == '__main__' : test()
--- a/src/converter.py Mon Jul 05 18:42:11 2010 +0900 +++ b/src/converter.py Mon Jul 05 19:54:27 2010 +0900 @@ -2,9 +2,9 @@ import sys from dfareg import Regexp, CallGraph -from cTranslator import CTranslator -from cbcTranslator import CbCTranslator -from dotTranslator import DotTranslator +from c_translator import CTranslator +from cbc_translator import CbCTranslator +from dot_translator import DotTranslator from llvm_translator import LLVMTranslator from optparse import OptionParser
--- a/src/dotTranslator.py Mon Jul 05 18:42:11 2010 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -#!/usr/bin/env python - -import re -from translator import Translator -from dfareg import CallGraph, Regexp - -class DotTranslator(Translator): - """ - DotToranslator - This Class can translate from DFA or NFA into Dot - Dot is Graph-generater using TeX. - --code/graph/makepdf.sh is generate graph script. - >>> string = \"(A|B)*C\" - >>> reg = Regexp(string) - >>> dfacg = CallGraph(reg.dfa) - >>> nfacg = CallGraph(reg.nfa) - >>> DotTranslator(string, dfacg).translate() - >>> DotTranslator(string, nfacg).translate() - """ - def __init__(self, regexp, cg): - Translator.__init__(self, regexp, cg) - if self.cg.type == "DFA": - self.name_hash = self.create_name_hash() - - def modify_state_name(self, state_name): - if self.cg.type == "DFA": - return "s"+self.name_hash[state_name] - else: - return "s"+state_name - - def emit_from_callgraph(self): - self.emit(''' -digraph G{ -\td2tdocpreamble = "\\usetikzlibrary{automata}"; -\td2tfigpreamble = "\\tikzstyle{every state}= \\ -\t[draw=blue!50,very thick,shape=circle, fill=blue!20]"; -\tnode [style="state"]; -\tedge [lblstyle="fill=blue!20", style="arrows=->", topath="bend left"]; -''') - - self.emit("\t%s [style=\"state, initial\"]\n" % (self.modify_state_name(self.cg.start))) - for accept in self.cg.accepts: - self.emit("\t%s [style=\"state, accepting\"]\n" % (self.modify_state_name(accept))) - - for cur_state, trans in self.cg.map.iteritems(): - for input, next_states in trans.iteritems(): - if input == "" : input = "$\\varepsilon$" - for next_state in next_states: - self.emit("\t%s -> %s [texlbl=\"%s\"]\n" - % (self.modify_state_name(cur_state), self.modify_state_name(next_state), input)) - - self.emit("}") - - -def test(): - import doctest - doctest.testmod() - ''' - reg = Regexp("(A|B)*C") - ct = CTranslator(reg.regexp, CallGraph(reg.dfa)) - ct.translate() - ''' - -if __name__ == '__main__' : test()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dot_translator.py Mon Jul 05 19:54:27 2010 +0900 @@ -0,0 +1,64 @@ +#!/usr/bin/env python + +import re +from translator import Translator +from dfareg import CallGraph, Regexp + +class DotTranslator(Translator): + """ + DotToranslator + This Class can translate from DFA or NFA into Dot + Dot is Graph-generater using TeX. + --code/graph/makepdf.sh is generate graph script. + >>> string = \"(A|B)*C\" + >>> reg = Regexp(string) + >>> dfacg = CallGraph(reg.dfa) + >>> nfacg = CallGraph(reg.nfa) + >>> DotTranslator(string, dfacg).translate() + >>> DotTranslator(string, nfacg).translate() + """ + def __init__(self, regexp, cg): + Translator.__init__(self, regexp, cg) + if self.cg.type == "DFA": + self.name_hash = self.create_name_hash() + + def modify_state_name(self, state_name): + if self.cg.type == "DFA": + return "s"+self.name_hash[state_name] + else: + return "s"+state_name + + def emit_from_callgraph(self): + self.emit(''' +digraph G{ +\td2tdocpreamble = "\\usetikzlibrary{automata}"; +\td2tfigpreamble = "\\tikzstyle{every state}= \\ +\t[draw=blue!50,very thick,shape=circle, fill=blue!20]"; +\tnode [style="state"]; +\tedge [lblstyle="fill=blue!20", style="arrows=->", topath="bend left"]; +''') + + self.emit("\t%s [style=\"state, initial\"]\n" % (self.modify_state_name(self.cg.start))) + for accept in self.cg.accepts: + self.emit("\t%s [style=\"state, accepting\"]\n" % (self.modify_state_name(accept))) + + for cur_state, trans in self.cg.map.iteritems(): + for input, next_states in trans.iteritems(): + if input == "" : input = "$\\varepsilon$" + for next_state in next_states: + self.emit("\t%s -> %s [texlbl=\"%s\"]\n" + % (self.modify_state_name(cur_state), self.modify_state_name(next_state), input)) + + self.emit("}") + + +def test(): + import doctest + doctest.testmod() + ''' + reg = Regexp("(A|B)*C") + ct = CTranslator(reg.regexp, CallGraph(reg.dfa)) + ct.translate() + ''' + +if __name__ == '__main__' : test()
--- a/src/llvm_bench.py Mon Jul 05 18:42:11 2010 +0900 +++ b/src/llvm_bench.py Mon Jul 05 19:54:27 2010 +0900 @@ -4,15 +4,16 @@ from optparse import OptionParser from timeit import Timer from dfareg import Regexp -from reg2llvm import RegLLVM +from dfareg import Regexp, CallGraph +from llvm_translator import LLVMTranslator myusage = "%prog [-O] [-p] [-s string] [-r regexp] [-E]" psr = OptionParser(usage=myusage) -psr.add_option("-O", action="store_true", dest="optimizeFlag", default=False, help="optimimzation") -psr.add_option("-L", action="store_true", dest="implLabel", default=False, help="impliment with label") -psr.add_option("-E", action="store_true", dest="executeFlag", default=False, help="execute Module") -psr.add_option("-p", action="store_true", dest="printFlag", default=False, help="print module") -psr.add_option("-g", action="store_true", dest="dumpFlag", default=False, help="add debug stmt to module") +psr.add_option("-O", action="store_true", dest="optimize", default=False, help="optimimzation") +psr.add_option("-L", action="store_true", dest="label", default=False, help="impliment with label") +psr.add_option("-E", action="store_true", dest="execute", default=False, help="execute Module") +psr.add_option("-p", action="store_true", dest="print_", default=False, help="print module") +psr.add_option("-g", action="store_true", dest="debug", default=False, help="add debug stmt to module") psr.add_option("-n", action="store", type="int", dest="number", default=1000, help="number of eval", metavar="INT") psr.add_option("-r", action="store", type="string", dest="regexp", default="(A|B)*C", help="regexp", metavar="FILE") psr.add_option("-s", action="store", type="string", dest="string", default="A"+"B"*500+"C", help="string", metavar="FILE") @@ -20,12 +21,17 @@ print "regexp = \"%s\", string = \"%s\", loop = %d" % (opts.regexp, opts.string, opts.number) -regLLVM = RegLLVM("regllvm", opts.regexp, opts.string, opts.implLabel, opts.optimizeFlag, opts.dumpFlag) +reg = Regexp(opts.regexp) +dfacg = CallGraph(reg.dfa) +llvmt = LLVMTranslator(reg.regexp, dfacg) +llvmt.string = opts.string +llvmt.debug = opts.debug +llvmt.optimize = opts.optimize -if (opts.printFlag): regLLVM.print_module() +if opts.print_: llvmt.translate() -if (opts.executeFlag): - print "LLVM :", Timer(setup='from __main__ import regLLVM', stmt='regLLVM.execute()').timeit(opts.number) +if opts.execute: + print "LLVM :", Timer(setup='from __main__ import llvmt', stmt='llvmt.execute()').timeit(opts.number) reg = re.compile("^%s$" % opts.regexp) print "re :", Timer(setup='from __main__ import reg', stmt='reg.search("%s")' % opts.string).timeit(opts.number)
--- a/src/llvm_translator.py Mon Jul 05 18:42:11 2010 +0900 +++ b/src/llvm_translator.py Mon Jul 05 19:54:27 2010 +0900 @@ -14,6 +14,7 @@ >>> reg = Regexp(string) >>> dfacg = CallGraph(reg.dfa) >>> lt = LLVMTranslator(string, dfacg) + >>> lt.debug = True >>> lt.translate() >>> isinstance(lt.execute(), llvm.ee.GenericValue) True @@ -29,14 +30,13 @@ def __init__(self, regexp, cg): #(self, modName, regexp, string, self.impl_label, optimized, debug): Translator.__init__(self, regexp, cg) - self.mod = Module.new(self.cg.type) self.optimize = False self.debug = False self.impl_label = False - self.matchp_str = self.new_str_const("ABC") - self.debug_str = self.new_str_const("state: %s, arg: %c(int %d)\n") + self.string = "ABC" if self.cg.type == "DFA": self.name_hash = self.create_name_hash() + self.compiled = False def modify_state_name(self, state_name): if self.cg.type == "DFA": @@ -44,7 +44,10 @@ else: return state_name - def emit_from_callgraph(self): + def _compile(self): + self.llvm_module = Module.new(self.cg.type) + self.matchp_str = self.new_str_const(self.string) + self.debug_str = self.new_str_const("state: %s, arg: %c(int %d)\n") def optional_func_decl(fun): fun.calling_convertion = CC_X86_FASTCALL fun.args[0].name = "index" @@ -53,7 +56,7 @@ optional_func_decl(state) state_ref = dict() - main = self.mod.add_function( + main = self.llvm_module.add_function( Type.function(self.int_t, (self.int_t,)), "main") optional_func_decl(main) main_entry = main.append_basic_block("entry") @@ -66,10 +69,10 @@ Builder.new(reject_state).free(index_ptr) else: # Create function - accept and reject (final state). - accept_state = self.mod.add_function( + accept_state = self.llvm_module.add_function( Type.function(self.int_t, (self.int_t,)), "accept") optional_func_decl(accept_state) - reject_state = self.mod.add_function( + reject_state = self.llvm_module.add_function( Type.function(self.int_t, (self.int_t,)), "reject") optional_func_decl(reject_state) @@ -84,7 +87,7 @@ state_ref[state] = label else: for state in self.cg.map.iterkeys(): - fun = self.mod.add_function( + fun = self.llvm_module.add_function( Type.function(self.int_t, (self.int_t,)), state) optional_func_decl(fun) state_ref[state] = fun @@ -92,13 +95,12 @@ # emit instructions if (self.impl_label): emit = Builder.new(accept_state) else: emit = Builder.new(accept_state.append_basic_block("entry")) - - self.emit_call_printf(emit, "%s does match regexp\n", self.gep_first(emit, self.matchp_str)) + if self.debug: self.emit_call_printf(emit, "%s does match regexp\n", self.gep_first(emit, self.matchp_str)) emit.ret(self.const_one) if (self.impl_label): emit = Builder.new(reject_state) else: emit = Builder.new(reject_state.append_basic_block("entry")) - self.emit_call_printf(emit, "%s does not match regexp\n", self.gep_first(emit, self.matchp_str)) + if self.debug: self.emit_call_printf(emit, "%s does not match regexp\n", self.gep_first(emit, self.matchp_str)) emit.ret(self.const_zero) if (self.impl_label): @@ -115,6 +117,8 @@ char = emit.load(ptr) si = emit.switch(char, state_ref['reject'], len(transition)) local_label = 0 + if state in self.cg.accepts: + transition['\\0'] = "accept" for case, next_states in transition.iteritems(): bb = main.append_basic_block("%s_case%d" % (state, local_label)) #create default bb emit = Builder.new(bb) @@ -124,6 +128,8 @@ else: for state, transition in self.cg.map.iteritems(): cases = dict() + if state in self.cg.accepts: + transition['\\0'] = ["accept"] for case, next_states in transition.iteritems(): cases[self.char_const(case)] = state_ref[next_states[0]] state_fun = state_ref[state] @@ -152,13 +158,20 @@ ret = emit.call(state_ref[self.cg.start], (main.args[0],)) emit.ret(ret) - self.mp = ModuleProvider.new(self.mod) + self.mp = ModuleProvider.new(self.llvm_module) if (self.optimize): self.do_optimize() self.ee = ExecutionEngine.new(self.mp) self.main = main - self.emit(str(self.mod)) + self.compiled = True + + def emit_from_callgraph(self): + if not self.compiled: + self._compile() + self.emit(str(self.llvm_module)) def get_execution_engine(self): + if not self.compiled: + self._compile() return self.ee def do_optimize(self): @@ -166,7 +179,7 @@ pm = PassManager.new() pm.add(TargetData.new('')) pm.add(PASS_FUNCTION_INLINING) - pm.run(self.mod) + pm.run(self.llvm_module) fp = FunctionPassManager.new(self.mp) fp.add(TargetData.new('')) fp.add(PASS_BLOCK_PLACEMENT) @@ -175,19 +188,23 @@ fp.add(PASS_AGGRESSIVE_DCE) fp.add(PASS_DEAD_INST_ELIMINATION) fp.add(PASS_DEAD_CODE_ELIMINATION) - for fun in self.mod.functions: + for fun in self.llvm_module.functions: fp.run(fun) def print_module(self): - print self.mod + if not self.compiled: + self._compile() + print self.llvm_module def execute(self): + if not self.compiled: + self._compile() return self.ee.run_function(self.main, (GenericValue.int(self.int_t, 0),)) def new_str_const(self, val): '''create string(array of int) as a global value ''' - str = self.mod.add_global_variable(Type.array(self.char_t, len(val) + 1), "") + str = self.llvm_module.add_global_variable(Type.array(self.char_t, len(val) + 1), "") str.initializer = Constant.stringz(val) return str @@ -208,9 +225,9 @@ def emit_call_printf(self, emit, string, *args): '''emit libc printf function call instruction''' try: - printf = self.mod.get_function_named("printf") + printf = self.llvm_module.get_function_named("printf") except llvm.LLVMException: - printf = self.mod.add_function( + printf = self.llvm_module.add_function( Type.function(Type.void(), (Type.pointer(self.char_t, 0),), 1), "printf") if isinstance(string, str):