Remove -attr-sim option (was broken) and related classes.
[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 syntax
21 private import utils
22
23 redef class ToolContext
24 readable writable attr _global: Bool = false
25 readable writable attr _compdir: String
26 readable writable attr _clibdir: String
27 readable writable attr _bindir: String
28 readable writable attr _output_file: String
29 readable writable attr _boost: Bool = false
30 readable writable attr _no_cc: Bool = false
31 readable writable attr _ext_prefix: String
32 end
33
34 # Class used to generate files.
35 # Note that in fact it is not a visitor.
36 # Note also that this class is unefficient and poorly designed thus requires love.
37 class CompilerVisitor
38 # Add a line in the current declaration block
39 meth add_decl(s: String)
40 do
41 if _indent_level >= 8 then
42 _ctx.decls.add("\t\t" + s)
43 else
44 _ctx.decls.add(" " * _indent_level + s)
45 end
46 end
47
48 # Add a line in the current instr block
49 meth add_instr(s: String)
50 do
51 if _indent_level >= 8 then
52 _ctx.instrs.add("\t\t" + s)
53 else
54 _ctx.instrs.add(" " * _indent_level + s)
55 end
56 end
57
58 # Return a unique new number for the instance
59 meth new_number: Int
60 do
61 var res = _number_cpt
62 _number_cpt = res + 1
63 return res
64 end
65 # next number for new_number
66 attr _number_cpt: Int = 0
67
68 # Add an indent level.
69 # New decl and instr will be indented.
70 meth indent do _indent_level += 1
71
72 # Remove an indent level.
73 meth unindent
74 do
75 _indent_level -= 1
76 if _indent_level < 0 then _indent_level = 0
77 end
78
79 # Return a big string containing all decl and instr
80 redef meth to_s
81 do
82 var out = new Array[String]
83 out.append(_ctx.decls)
84 out.append(_ctx.instrs)
85 out.add("")
86 return out.join("\n")
87 end
88
89 # The current module processed
90 readable writable attr _module: MMSrcModule
91
92 # Where instr and decl are stored
93 readable writable attr _ctx: CContext = new CContext
94
95 # The current indent lever
96 readable writable attr _indent_level: Int = 0
97
98 # The current ToolContext
99 readable writable attr _tc: ToolContext
100
101 # Create a new CompilerVisitor based on a module
102 init(module: MMSrcModule) do _module = module
103 end
104
105 # Where instr and decl are stored for a module
106 # Note that this class is as badly designed as CompilerVisitor
107 class CContext
108 readable attr _decls: Array[String] = new Array[String]
109 readable attr _instrs: Array[String] = new Array[String]
110
111 meth append(c: CContext)
112 do
113 _instrs.append(c.decls)
114 _instrs.append(c.instrs)
115 end
116
117 meth merge(c: CContext)
118 do
119 _decls.append(c.decls)
120 _instrs.append(c.instrs)
121 end
122
123 init do end
124 end
125
126 redef class MMGlobalProperty
127 # C symbol refering a method inocation
128 meth meth_call: String
129 do
130 return "CALL_{intro.cname}"
131 end
132
133 # C symbol refering an attribure access
134 meth attr_access: String
135 do
136 return "ATTR_{intro.cname}"
137 end
138
139 # C symbol refering the color of the global property
140 meth color_id: String
141 do
142 return "COLOR_{intro.cname}"
143 end
144
145 end
146
147 redef class MMGlobalClass
148 # C symbol refering the identifier of the class
149 meth id_id: String
150 do
151 return "ID_{intro.name}"
152 end
153
154 # C symbol refering the color of the class (for subtype tests)
155 meth color_id: String
156 do
157 return "COLOR_{intro.name}"
158 end
159
160 # C symbol refering the init table position of the class (for constructor linearization)
161 meth init_table_pos_id: String
162 do
163 return "INIT_TABLE_POS_{intro.name}"
164 end
165 end
166
167 redef class MMLocalClass
168 # Cached primitive_info result
169 attr _primitive_info_cache: PrimitiveInfo
170
171 # If primitive_info result cached?
172 attr _primitive_info_b: Bool = false
173
174 # Return the primitive information of the class.
175 # Return null if the class is not primitive
176 # FIXME: Only here since there is no universal type yet
177 meth primitive_info: PrimitiveInfo
178 do
179 if _primitive_info_b == true then return _primitive_info_cache
180
181 var ctypes = once primitive_ctypes
182 if ctypes.has_key(name) then
183 _primitive_info_cache = ctypes[name]
184 _primitive_info_b = true
185 return _primitive_info_cache
186 end
187 var i = ctypes.iterator
188 while i.is_ok do
189 var n = i.key
190 if module.has_global_class_named(n) then
191 var c = module.class_by_name(n)
192 if cshe < c then
193 _primitive_info_cache = i.item
194 _primitive_info_b = true
195 return _primitive_info_cache
196 end
197 end
198 i.next
199 end
200 _primitive_info_b = true
201 return null
202 end
203
204 # Static information of primitive types
205 private meth primitive_ctypes: HashMap[Symbol, PrimitiveInfo]
206 do
207 var res = new HashMap[Symbol, PrimitiveInfo]
208 var pnames = ["Int", "Char", "Bool", "Float", "NativeString", "NativeArray", "Pointer"]
209 var tagged = [true, true, true, false, false, false, false]
210 var cnames = ["bigint", "char", "int", "float", "char *", "val_t *", "void *"]
211 for i in [0..pnames.length[ do
212 var n = pnames[i].to_symbol
213 var pi = new PrimitiveInfo
214 pi.name = n
215 pi.tagged = tagged[i]
216 pi.cname = cnames[i]
217 res[n] = pi
218 end
219 return res
220 end
221 end
222
223 # Information about a primitive class
224 class PrimitiveInfo
225 # The name of the class
226 readable writable attr _name: Symbol
227
228 # Is the class tagged (aka not boxed)
229 readable writable attr _tagged: Bool
230
231 # The corresponding c type for the primitive value
232 readable writable attr _cname: String
233
234 private init do end
235 end
236
237 redef class MMType
238 # The corresponding c type
239 meth cname: String
240 do
241 var pi = local_class.primitive_info
242 if pi == null then
243 return "val_t"
244 else
245 return pi.cname
246 end
247 end
248
249 # The default c value for uninitialized types.
250 # Return "null" for non primitive types and something more specific for primitive types
251 meth default_cvalue: String
252 do
253 var pi = local_class.primitive_info
254 if pi != null and pi.tagged then
255 return "TAG_{local_class.name}(({pi.cname})0)"
256 else
257 return "NIT_NULL"
258 end
259 end
260
261 # Box (or tag) a primitive value
262 # Is identity if not primitive
263 meth boxtype(s: String): String
264 do
265 var pi = local_class.primitive_info
266 if pi == null then
267 return s
268 else if pi.tagged then
269 return "TAG_{local_class.name}({s})"
270 else
271 return "BOX_{local_class.name}({s})"
272 end
273 end
274
275 # Unbox (or untag) a primitive value
276 # Is identity if not primitive
277 meth unboxtype(s: String): String
278 do
279 var pi = local_class.primitive_info
280 if pi == null then
281 return s
282 else if pi.tagged then
283 return "UNTAG_{local_class.name}({s})"
284 else
285 return "UNBOX_{local_class.name}({s})"
286 end
287 end
288 end
289
290 redef class MMLocalProperty
291 # Cacher result of cname
292 attr _cname_cache: String
293
294 # The mangled name of the method
295 meth cname: String
296 do
297 if _cname_cache == null then
298 _cname_cache = cmangle(module.name, local_class.name, name)
299 end
300 return _cname_cache
301 end
302
303 # C symbol refering the color of the super call of a super property
304 meth color_id_for_super: String
305 do
306 return "COLOR_SUPER_{cname}"
307 end
308
309 # C macro used to get the function for the call of a super property
310 meth super_meth_call: String
311 do
312 return "CALL_SUPER_{cname}"
313 end
314 end
315