X-Git-Url: http://nitlanguage.org diff --git a/src/compiling/compiling.nit b/src/compiling/compiling.nit index 445fc50..8dcadba 100644 --- a/src/compiling/compiling.nit +++ b/src/compiling/compiling.nit @@ -19,115 +19,112 @@ package compiling import table_computation import compiling_base +import icode_generator private import compiling_global private import compiling_icode redef class Program - # 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 + # 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.compdir.mkdir + if output_format == "none" then + # Nothing to do + else + # Optimize all iroutines + with_each_iroutines !action(i, m) do i.optimize(m) - 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 module.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(self) - var native_name = m.location.file.strip_extension(".nit") - if (native_name + "_nit.h").file_exists then - includes.add("-I {native_name.dirname}") + if output_format == "C" then + compile_prog_to_c + else if output_format == "icode" then + generate_icode_files end - native_name += "_nit.c" - if native_name.file_exists then files.add(native_name) end + end - tc.info("Generating main, tables and makefile ...",1) - files.add("{tc.compdir}/{module.name}._tables.c") - compile_main + # 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) - var fn = "{tc.compdir}/{module.name}._build.sh" - var f = new OFStream.open(fn) - var verbose = "" + cprogram.compdir.mkdir - if tc.verbose_level > 0 then - verbose = "-" - for i in [1..tc.verbose_level] do verbose = verbose + "v" - end + cprogram.files.add("$CLIBDIR/nit_main.c") + cprogram.files.add("$CLIBDIR/gc.c") + cprogram.files.add("$CLIBDIR/gc_static_objects_list.c") - f.write("#!/bin/sh\n") - f.write("# This shell script is generated by NIT to compile the program {module.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 {module.name}") - else - f.write(" -o {module.name}_{tc.ext_prefix}") - end - if tc.boost then f.write(" -O") - f.write(" \"$@\" \\\n {files.join("\\\n ")}\n") - f.close + tc.info("Generating C code",1) + for m in main_module.mhe.greaters_and_self do m.compile_separate_module(cprogram) - if not tc.no_cc then - tc.info("Building",1) - sys.system("sh {fn}") - end + tc.info("Generating main, tables and makefile ...",1) + compile_main(cprogram) + + cprogram.generate_build_file + + if not tc.no_cc then cprogram.run_c_compiler end # Compile the main file - private fun compile_main + private fun compile_main(cprogram: CProgram) do - var v = new CompilerVisitor(module, self) + 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}/{module.name}._tables.c") - f.write("/* This C file is generated by NIT to compile program {module.name}. */\n") - for m in module.mhe.greaters_and_self do - f.write("#include \"{m.name}._sep.h\"\n") + var filename = "{cprogram.compdir}/{main_module.name}._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.name}. */\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 redef class MMModule - # Compile the sep files (of the current module only) - private fun compile_separate_module(program: Program) + # Compile the sep or glob files (of the current module only) + private fun compile_separate_module(cprogram: CProgram) do - var tc = program.tc - var v = new CompilerVisitor(self, program) + var tc = cprogram.program.tc + tc.info("Generating C code for module: {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_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") + + 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 {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 + f.write("#ifndef {name}{cprogram.get_file_ending}\n") + f.write("#define {name}{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") + var cfilename = "{cprogram.compdir}/{name}.{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 {name}. */\n") - f.write("#include \"{name}._sep.h\"\n") - for s in v.ctx.instrs do - f.write(s) - end + f.write("#include \"{hfilename}\"\n") + v.top_writer.write_to_stream(f) f.close end end