X-Git-Url: http://nitlanguage.org diff --git a/src/compiling/compiling.nit b/src/compiling/compiling.nit index 4f142fd..414c6f6 100644 --- a/src/compiling/compiling.nit +++ b/src/compiling/compiling.nit @@ -17,122 +17,114 @@ # Compute and generate tables for classes and modules. package compiling +import table_computation import compiling_base +import icode_generator private import compiling_global private import compiling_icode -redef class MMModule - # Compile the program - # Generate all sep files (_sep.[ch]), the main file (_table.c) and the build file (_build.sh) - # Then execute the build.sh - fun compile_prog_to_c(tc: ToolContext) +redef class Program + # The type of code generation to use + readable writable var _output_format: String = "none" + + # Compile the program depending on the output format + fun compile_prog do - tc.info("Building tables",1) - for m in mhe.greaters_and_self do - tc.info("Building tables for module: {m.name}",2) - m.local_analysis(tc) + if output_format == "none" then + # Nothing to do + else + # Optimize all iroutines + with_each_iroutines !action(i, m) do i.optimize(m) + + if output_format == "C" then + compile_prog_to_c + else if output_format == "icode" then + generate_icode_files + end end + end - tc.info("Merging all tables",2) - var ga = global_analysis(tc) + # Compile the program to C + # Generate all files (_sep.[ch] or _glob.[ch]), the main file (_table.c) and the build file (_build.sh) + # Then execute the build.sh + fun compile_prog_to_c + do + var cprogram = new CProgram(self) - tc.compdir.mkdir + cprogram.compdir.mkdir + + cprogram.files.add("$CLIBDIR/nit_main.c") + cprogram.files.add("$CLIBDIR/gc.c") + cprogram.files.add("$CLIBDIR/gc_static_objects_list.c") - var files = new Array[String] - var includes = new ArraySet[String] - files.add("$CLIBDIR/nit_main.c") - files.add("$CLIBDIR/gc.c") - files.add("$CLIBDIR/gc_static_objects_list.c") tc.info("Generating C code",1) - for m in mhe.greaters_and_self do - files.add("{tc.compdir}/{m.name}._sep.c") - tc.info("Generating C code for module: {m.name}",2) - m.compile_separate_module(tc, ga) - var native_name = m.location.file.strip_extension(".nit") - if (native_name + "_nit.h").file_exists then - includes.add("-I {native_name.dirname}") - end - native_name += "_nit.c" - if native_name.file_exists then files.add(native_name) - end + for m in main_module.mhe.greaters_and_self do m.compile_separate_module(cprogram) tc.info("Generating main, tables and makefile ...",1) - files.add("{tc.compdir}/{name}._tables.c") - compile_main(tc, ga) - - var fn = "{tc.compdir}/{name}._build.sh" - var f = new OFStream.open(fn) - var verbose = "" + compile_main(cprogram) - if tc.verbose_level > 0 then - verbose = "-" - for i in [1..tc.verbose_level] do verbose = verbose + "v" - end + cprogram.generate_build_file - f.write("#!/bin/sh\n") - f.write("# This shell script is generated by NIT to compile the program {name}.\n") - f.write("CLIBDIR=\"{tc.clibdir}\"\n") - f.write("{tc.bindir}/gccx {verbose} -d {tc.compdir} -I $CLIBDIR {includes.join(" ")}") - if tc.output_file != null then - f.write(" -o {tc.output_file}") - else if tc.ext_prefix.is_empty then - f.write(" -o {name}") - else - f.write(" -o {name}_{tc.ext_prefix}") - end - if tc.boost then f.write(" -O") - f.write(" \"$@\" \\\n {files.join("\\\n ")}\n") - f.close - - if not tc.no_cc then - tc.info("Building",1) - sys.system("sh {fn}") - end + if not tc.no_cc then cprogram.run_c_compiler end # Compile the main file - private fun compile_main(tc: ToolContext, ga: GlobalAnalysis) + private fun compile_main(cprogram: CProgram) do - var v = new GlobalCompilerVisitor(self, tc, ga) + var v = new CompilerVisitor(main_module, cprogram) v.add_decl("#include ") compile_tables_to_c(v) compile_main_part(v) - var f = new OFStream.open("{tc.compdir}/{name}._tables.c") - f.write("/* This C file is generated by NIT to compile program {name}. */\n") - for m in mhe.greaters_and_self do - f.write("#include \"{m.name}._sep.h\"\n") + var filename = "{cprogram.compdir}/{main_module.cname}._tables.c" + cprogram.files.add(filename) + var f = new OFStream.open(filename) + f.write("/* This C file is generated by NIT to compile program {main_module.cname}. */\n") + for m in main_module.mhe.greaters_and_self do + f.write("#include \"{cprogram.module_header_name(m)}\"\n") end - f.write(v.to_s) + v.header_writer.write_to_stream(f) + v.writer.write_to_stream(f) f.close end +end - # Compile the sep files (of the current module only) - private fun compile_separate_module(tc: ToolContext, ga: GlobalAnalysis) +redef class MMModule + # Compile the sep or glob files (of the current module only) + fun compile_separate_module(cprogram: CProgram) do - var v = new GlobalCompilerVisitor(self, tc, ga) + var tc = cprogram.program.tc + tc.info("Generating C code for module: {full_name}",2) + var v = new CompilerVisitor(self, cprogram) v.add_decl("#include ") - var native_name = location.file.strip_extension(".nit") - native_name += ("_nit.h") - if native_name.file_exists then v.add_decl("#include <{native_name.basename("")}>") + + var native_name = location.file.filename.strip_extension(".nit") + var native_header = native_name + "_nit.h" + if native_header.file_exists then + v.add_decl("#include <{native_header.basename("")}>") + cprogram.include_dirs.add("-I {native_name.dirname}") + end + var native_body = native_name + "_nit.c" + if native_body.file_exists then cprogram.files.add(native_body) + declare_class_tables_to_c(v) compile_mod_to_c(v) - var f = new OFStream.open("{tc.compdir}/{name}._sep.h") - f.write("/* This C header file is generated by NIT to compile modules and programs that requires {name}. */\n") - f.write("#ifndef {name}_sep\n") - f.write("#define {name}_sep\n") - for m in mhe.direct_greaters do f.write("#include \"{m.name}._sep.h\"\n") - for s in v.ctx.decls do - f.write(s) - end + + var hfilename = cprogram.module_header_name(self) + var f = new OFStream.open("{cprogram.compdir}/{hfilename}") + f.write("/* This C header file is generated by NIT to compile modules and programs that requires {full_name}. */\n") + f.write("#ifndef {cname}{cprogram.get_file_ending}\n") + f.write("#define {cname}{cprogram.get_file_ending}\n") + for m in mhe.direct_greaters do f.write("#include \"{cprogram.module_header_name(m)}\"\n") + v.header_writer.write_to_stream(f) f.write("#endif\n") f.close - f = new OFStream.open("{tc.compdir}/{name}._sep.c") - f.write("/* This C file is generated by NIT to compile module {name}. */\n") - f.write("#include \"{name}._sep.h\"\n") - for s in v.ctx.instrs do - f.write(s) - end + var cfilename = "{cprogram.compdir}/{cname}.{cprogram.get_file_ending}.c" + cprogram.files.add(cfilename) + f = new OFStream.open("{cfilename}") + f.write("/* This C file is generated by NIT to compile module {cname}. */\n") + f.write("#include \"{hfilename}\"\n") + v.top_writer.write_to_stream(f) f.close end end