compile: add program arguments passed to C compiler; gcc's -l, -L, -I and -c
[nit.git] / src / compiling / compiling_base.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2008 Jean Privat <jean@pryen.org>
4 #
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
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
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.
16
17 # Common things for NIT compilation and C generation
18 package compiling_base
19
20 import mmloader
21 private import utils
22 import primitive_info
23 import program
24
25 redef class ToolContext
26 readable writable var _compdir: nullable String = null
27 readable writable var _clibdir: nullable String = null
28 readable writable var _bindir: nullable String = null
29 readable writable var _output_file: nullable String = null
30 readable writable var _boost: Bool = false
31 readable writable var _no_cc: Bool = false
32 readable writable var _cc_link: Bool = false
33 readable writable var _cc_libs: Array[String] = new Array[String]
34 readable writable var _cc_lib_paths: Array[String] = new Array[String]
35 readable writable var _cc_include_paths: Array[String] = new Array[String]
36 readable writable var _ext_prefix: String = ""
37 end
38
39 # Class used to generate files.
40 # Note that in fact it is not a visitor.
41 # Note also that this class is unefficient and poorly designed thus requires love.
42 class CompilerVisitor
43 # Add a line in the current declaration block
44 fun add_decl(s: String...)
45 do
46 add_line_to(_ctx.decls, s)
47 end
48
49 # Add a line in the current instr block
50 fun add_instr(s: String...)
51 do
52 add_line_to(_ctx.instrs, s)
53 end
54
55 fun add_line_to(a: Array[String], s: Array[String])
56 do
57 if _indent_level >= 8 then
58 a.add("\t\t")
59 else
60 for i in [0.._indent_level[ do
61 a.add(" ")
62 end
63 end
64 for i in s do
65 a.add(i)
66 end
67 a.add("\n")
68 end
69
70 # Add a assignment between a variable and an expression
71 fun add_assignment(v: String, s: String)
72 do
73 if v != s then
74 add_instr(v, " = ", s, ";")
75 end
76 end
77
78 # C outputs written outside the current C function.
79 readable writable var _out_contexts: Array[CContext] = new Array[CContext]
80
81 # Return a unique new number for the instance
82 fun new_number: Int
83 do
84 var res = _number_cpt
85 _number_cpt = res + 1
86 return res
87 end
88 # next number for new_number
89 var _number_cpt: Int = 0
90
91 # Add an indent level.
92 # New decl and instr will be indented.
93 fun indent do _indent_level += 1
94
95 # Remove an indent level.
96 fun unindent
97 do
98 _indent_level -= 1
99 if _indent_level < 0 then _indent_level = 0
100 end
101
102 # Return a big string containing all decl and instr
103 redef fun to_s
104 do
105 var out = new Array[String]
106 out.append(_ctx.decls)
107 out.append(_ctx.instrs)
108 return out.to_s
109 end
110
111 # The processed module
112 readable var _module: MMModule
113
114 # Where instr and decl are stored
115 readable writable var _ctx: CContext = new CContext
116
117 # The current indent lever
118 readable writable var _indent_level: Int = 0
119
120 # The program we are compiling
121 readable var _program: Program
122
123 # Create a new CompilerVisitor based on a module
124 init(module: MMModule, p: Program)
125 do
126 _module = module
127 _program = p
128 end
129 end
130
131 # Where instr and decl are stored for a module
132 # Note that this class is as badly designed as CompilerVisitor
133 class CContext
134 readable var _decls: Array[String] = new Array[String]
135 readable var _instrs: Array[String] = new Array[String]
136
137 fun append(c: CContext)
138 do
139 _instrs.append(c.decls)
140 _instrs.append(c.instrs)
141 end
142
143 fun merge(c: CContext)
144 do
145 _decls.append(c.decls)
146 _instrs.append(c.instrs)
147 end
148
149 init do end
150 end
151
152 redef class MMGlobalProperty
153 # C symbol refering a method inocation
154 fun meth_call: String
155 do
156 return "CALL_{intro.cname}"
157 end
158
159 # C symbol refering an attribure access
160 fun attr_access: String
161 do
162 return "ATTR_{intro.cname}"
163 end
164 end
165
166 redef class MMGlobalClass
167 # C symbol refering the identifier of the class
168 fun id_id: String
169 do
170 return "ID_{intro.name}"
171 end
172
173 # C symbol refering the color of the class (for subtype tests)
174 fun color_id: String
175 do
176 return "COLOR_{intro.name}"
177 end
178
179 # C symbol refering the init table position of the class (for constructor linearization)
180 fun init_table_pos_id: String
181 do
182 return "INIT_TABLE_POS_{intro.name}"
183 end
184 end
185
186 redef class MMLocalProperty
187 # Cacher result of cname
188 var _cname_cache: nullable String
189
190 # The mangled name of the method
191 fun cname: String
192 do
193 var cname = _cname_cache
194 if cname == null then
195 cname = cmangle(module.name, local_class.name, name)
196 _cname_cache = cname
197 end
198 return cname
199 end
200
201 # C macro used to get the function for the call of a super property
202 fun super_meth_call: String
203 do
204 return "CALL_SUPER_{cname}"
205 end
206 end
207