1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2008 Jean Privat <jean@pryen.org>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 # Compute and generate tables for classes and modules.
20 import table_computation
22 private import icode_generator
23 private import compiling_global
24 private import compiling_icode
25 private import analysis
28 # The type of code generation to use
29 readable writable var _output_format
: String = "none"
31 # Compile the program depending on the output format
34 if output_format
== "none" then
37 # Optimize all iroutines
38 with_each_iroutines
!action
(i
, m
) do i
.optimize
(m
)
40 if output_format
== "C" then
42 else if output_format
== "icode" then
48 # Compile the program to C
49 # Generate all files (_sep.[ch] or _glob.[ch]), the main file (_table.c) and the build file (_build.sh)
50 # Then execute the build.sh
53 var cprogram
= new CProgram(self)
55 cprogram
.compdir
.mkdir
57 cprogram
.files
.add
("$CLIBDIR/nit_main.c")
58 cprogram
.files
.add
("$CLIBDIR/gc.c")
59 cprogram
.files
.add
("$CLIBDIR/gc_static_objects_list.c")
61 tc
.info
("Generating C code",1)
62 for m
in main_module
.mhe
.greaters_and_self
do m
.compile_separate_module
(cprogram
)
64 tc
.info
("Generating main, tables and makefile ...",1)
65 compile_main
(cprogram
)
67 cprogram
.generate_build_file
69 if not tc
.no_cc
then cprogram
.run_c_compiler
72 # Compile the main file
73 private fun compile_main
(cprogram
: CProgram)
75 var v
= new CompilerVisitor(main_module
, cprogram
)
76 v
.add_decl
("#include <nit_common.h>")
77 compile_tables_to_c
(v
)
79 var filename
= "{cprogram.compdir}/{main_module.cname}._tables.c"
80 cprogram
.files
.add
(filename
)
81 var f
= new OFStream.open
(filename
)
82 f
.write
("/* This C file is generated by NIT to compile program {main_module.cname}. */\n")
83 for m
in main_module
.mhe
.greaters_and_self
do
84 f
.write
("#include \"{cprogram.module_header_name(m)}\
"\n")
86 v
.header_writer
.write_to_stream
(f
)
87 v
.writer
.write_to_stream
(f
)
93 # Compile the sep or glob files (of the current module only)
94 fun compile_separate_module
(cprogram
: CProgram)
96 var tc
= cprogram
.program
.tc
97 tc
.info
("Generating C code for module: {full_name}",2)
98 var v
= new CompilerVisitor(self, cprogram
)
99 v
.add_decl
("#include <nit_common.h>")
101 if is_extern_hybrid
then
102 # adds reference to frontier files
103 # if module uses the native interface
104 var nitni_header_name
= "{name}._nitni.h"
105 v
.add_decl
("#include \"{nitni_header_name}\
"")
106 var nitni_body_name
= "{name}._nitni.c"
107 cprogram
.files
.add
( "{cprogram.compdir}/{nitni_body_name}" )
109 # add reference to extern implementation
110 var native_name
= location
.file
.filename
.strip_extension
(".nit")
111 var native_body
= native_name
+ ".nit.c"
112 if native_body
.file_exists
then
113 cprogram
.files
.add
(native_body
)
114 else # try old style filename
115 native_body
= native_name
+ "_nit.c"
116 if native_body
.file_exists
then cprogram
.files
.add
(native_body
)
119 var ffi_header_name
= "{cname}._ffi.h"
120 v
.add_decl
("#include \"{ffi_header_name}\
"")
121 var ffi_body_name
= "{cname}._ffi.c"
122 cprogram
.files
.add
( "{cprogram.compdir}/{ffi_body_name}" )
126 declare_class_tables_to_c
(v
)
129 var hfilename
= cprogram
.module_header_name
(self)
130 var f
= new OFStream.open
("{cprogram.compdir}/{hfilename}")
131 f
.write
("/* This C header file is generated by NIT to compile modules and programs that requires {full_name}. */\n")
132 f
.write
("#ifndef {cname}{cprogram.get_file_ending}\n")
133 f
.write
("#define {cname}{cprogram.get_file_ending}\n")
134 for m
in mhe
.direct_greaters
do f
.write
("#include \"{cprogram.module_header_name(m)}\
"\n")
135 v
.header_writer
.write_to_stream
(f
)
139 var cfilename
= "{cprogram.compdir}/{cname}.{cprogram.get_file_ending}.c"
140 cprogram
.files
.add
(cfilename
)
141 f
= new OFStream.open
("{cfilename}")
142 f
.write
("/* This C file is generated by NIT to compile module {cname}. */\n")
143 f
.write
("#include \"{hfilename}\
"\n")
144 v
.top_writer
.write_to_stream
(f
)