# This file is part of NIT ( http://www.nitlanguage.org ). # # Copyright 2008 Jean Privat # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # 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 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 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 # 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) 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") tc.info("Generating C code",1) for m in main_module.mhe.greaters_and_self do m.compile_separate_module(cprogram) 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(cprogram: CProgram) do var v = new CompilerVisitor(main_module, cprogram) v.add_decl("#include ") compile_tables_to_c(v) compile_main_part(v) 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 v.header_writer.write_to_stream(f) v.writer.write_to_stream(f) f.close end end redef class MMModule # Compile the sep or glob files (of the current module only) private fun compile_separate_module(cprogram: CProgram) do 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") 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 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}{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 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 \"{hfilename}\"\n") v.top_writer.write_to_stream(f) f.close end end