3cf33ba12105f8c62cb23ed92447e08d8993ca04
[nit.git] / lib / standard / kernel.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2004-2008 Jean Privat <jean@pryen.org>
4 # Copyright 2006-2008 Floréal Morandat <morandat@lirmm.fr>
5 #
6 # This file is free software, which comes along with NIT. This software is
7 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
9 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
10 # is kept unaltered, and a notification of the changes is added.
11 # You are allowed to redistribute it and sell it, alone or is a part of
12 # another product.
13
14 # Most minimal classes and methods.
15 # This module is the root of the standard module hierarchy.
16 module kernel
17
18 import end # Mark this module is a top level one. (must be only one)
19
20 ###############################################################################
21 # System Classes #
22 ###############################################################################
23
24 # The root of the class hierarchy.
25 # Each class implicitly specialize Object.
26 #
27 # Currently, Object is also used to collect all top-level methods.
28 interface Object
29 # The unique object identifier in the class.
30 # Unless specific code, you should not use this method.
31 # The identifier is used internally to provide a hash value.
32 fun object_id: Int is intern
33
34 # Return true if `self` and `other` have the same dynamic type.
35 # Unless specific code, you should not use this method.
36 fun is_same_type(other: Object): Bool is intern
37
38 # Have `self` and `other` the same value?
39 ##
40 # The exact meaning of "same value" is let to the subclasses.
41 # Implicitly, the default implementation, is `is`
42 fun ==(other: nullable Object): Bool do return self is other
43
44 # Have `self` and `other` different values?
45 ##
46 # != is equivalent with "not ==".
47 fun !=(other: nullable Object): Bool do return not (self == other)
48
49 # Display self on stdout (debug only).
50 # This method MUST not be used by programs, it is here for debugging
51 # only and can be removed without any notice
52 fun output
53 do
54 '<'.output
55 object_id.output
56 '>'.output
57 end
58
59 # Display class name on stdout (debug only).
60 # This method MUST not be used by programs, it is here for debugging
61 # only and can be removed without any notice
62 fun output_class_name is intern
63
64 # Quit the program with a specific return code
65 protected fun exit(exit_value: Int) is intern
66
67 # Return the global sys object, the only instance of the `Sys` class.
68 protected fun sys: Sys is intern
69
70 # The hash code of the object.
71 # Assuming that a == b -> a.hash == b.hash
72 ##
73 # Without redefinition, it is based on the `object_id` of the instance.
74 fun hash: Int do return object_id / 8
75 end
76
77 # The main class of the program.
78 # `Sys` is a singleton class, its only instance is `sys` defined in `Object`.
79 # `sys` is used to invoke methods on the program on the system.
80 class Sys
81 # Instructions outside classes implicitly redefine this method.
82 fun main do end
83 end
84
85 ###############################################################################
86 # Abstract Classes #
87 ###############################################################################
88
89 # The ancestor of class where objects are in a total order.
90 # In order to work, the method '<' has to be redefined.
91 interface Comparable
92 # What `self` can be compared to?
93 type OTHER: Comparable
94
95 # Is `self` lesser than `other`?
96 fun <(other: OTHER): Bool is abstract
97
98 # not `other` < `self`
99 # Note, the implementation must ensure that: `(x<=y) == (x<y or x==y)`
100 fun <=(other: OTHER): Bool do return not other < self
101
102 # not `self` < `other`
103 # Note, the implementation must ensure that: `(x>=y) == (x>y or x==y)`
104 fun >=(other: OTHER): Bool do return not self < other
105
106 # `other` < `self`
107 fun >(other: OTHER): Bool do return other < self
108
109 # -1 if <, +1 if > and 0 otherwise
110 # Note, the implementation must ensure that: (x<=>y == 0) == (x==y)
111 fun <=>(other: OTHER): Int
112 do
113 if self < other then
114 return -1
115 else if other < self then
116 return 1
117 else
118 return 0
119 end
120 end
121
122 # c <= self <= d
123 fun is_between(c: OTHER, d: OTHER): Bool
124 do
125 return c <= self and self <= d
126 end
127
128 # The maximum between `self` and `other` (prefers `self` if equals).
129 fun max(other: OTHER): OTHER
130 do
131 if self < other then
132 return other
133 else
134 return self
135 end
136 end
137
138 # The minimum between `self` and `c` (prefer `self` if equals)
139 fun min(c: OTHER): OTHER
140 do
141 if c < self then
142 return c
143 else
144 return self
145 end
146 end
147 end
148
149 # Discrete total orders.
150 interface Discrete
151 super Comparable
152
153 redef type OTHER: Discrete
154
155 # The next element.
156 fun succ: OTHER do return self + 1
157
158 # The previous element.
159 fun prec: OTHER do return self - 1
160
161 # The `i`-th successor element.
162 fun +(i: Int): OTHER is abstract
163
164 # The `i`-th previous element.
165 fun -(i: Int): OTHER is abstract
166
167 # The distance between self and d.
168 #
169 # assert 10.distance(15) == 5
170 # assert 'Z'.distance('A') == 25
171 fun distance(d: OTHER): Int
172 do
173 var cursor: OTHER
174 var stop: OTHER
175 if self < d then
176 cursor = self
177 stop = d
178 else if self > d then
179 cursor = d
180 stop = self
181 else
182 return 0
183 end
184
185 var nb = 0
186 while cursor < stop do
187 cursor = cursor.succ
188 nb += 1
189 end
190 return nb
191 end
192 end
193
194 ###############################################################################
195 # Native classes #
196 ###############################################################################
197
198 # Native Booleans.
199 # `true` and `false` are the only instances.
200 # Boolean are manipulated trough three special operators:
201 # `and`, `or`, `not`.
202 # Booleans are mainly used by conditional statement and loops.
203 universal Bool
204 redef fun object_id is intern
205 redef fun ==(b) is intern
206 redef fun !=(b) is intern
207 redef fun output is intern
208 redef fun hash
209 do
210 if self then
211 return 1
212 else
213 return 0
214 end
215 end
216 end
217
218 # Native floating point numbers.
219 # Corresponds to C float.
220 universal Float
221 redef fun object_id is intern
222 redef fun output is intern
223
224 fun <=(i: Float): Bool is intern
225 fun <(i: Float): Bool is intern
226 fun >=(i: Float): Bool is intern
227 fun >(i: Float): Bool is intern
228 fun +(i: Float): Float is intern
229 fun -: Float is intern
230 fun -(i: Float): Float is intern
231 fun *(i: Float): Float is intern
232 fun /(i: Float): Float is intern
233
234 # The integer part of `self`.
235 #
236 # assert (0.0).to_i == 0
237 # assert (0.9).to_i == 0
238 # assert (-0.9).to_i == 0
239 # assert (9.9).to_i == 9
240 # assert (-9.9).to_i == -9
241 fun to_i: Int is intern
242 end
243
244 # Native integer numbers.
245 # Correspond to C int.
246 universal Int
247 super Discrete
248 redef type OTHER: Int
249
250 redef fun object_id is intern
251 redef fun hash do return self
252 redef fun ==(i) is intern
253 redef fun !=(i) is intern
254 redef fun output is intern
255
256 redef fun <=(i) is intern
257 redef fun <(i) is intern
258 redef fun >=(i) is intern
259 redef fun >(i) is intern
260 redef fun +(i) is intern
261 fun -: Int is intern
262 redef fun -(i) is intern
263 fun *(i: Int): Int is intern
264 fun /(i: Int): Int is intern
265 fun %(i: Int): Int is intern
266
267 # `i` bits shift fo the left (aka <<)
268 #
269 # assert 5.lshift(1) == 10
270 fun lshift(i: Int): Int is intern
271
272 # `i` bits shift fo the right (aka >>)
273 #
274 # assert 5.rshift(1) == 2
275 fun rshift(i: Int): Int is intern
276
277 # The float equivalent of `self`
278 #
279 # assert 5.to_f == 5.0
280 # assert 5.to_f != 5 # Float and Int are not equals
281 fun to_f: Float is intern
282
283 redef fun succ is intern
284 redef fun prec is intern
285 redef fun distance(i)
286 do
287 var d = self - i
288 if d >= 0 then
289 return d
290 else
291 return -d
292 end
293 end
294
295 redef fun <=>(other)
296 do
297 if self < other then
298 return -1
299 else if other < self then
300 return 1
301 else
302 return 0
303 end
304 end
305
306 redef fun is_between(c, d)
307 do
308 if self < c or d < self then
309 return false
310 else
311 return true
312 end
313 end
314
315 redef fun max(other)
316 do
317 if self < other then
318 return other
319 else
320 return self
321 end
322 end
323
324 redef fun min(c)
325 do
326 if c < self then
327 return c
328 else
329 return self
330 end
331 end
332
333 # The character whose ASCII value is `self`.
334 #
335 # assert 65.ascii == 'A'
336 # assert 10.ascii == '\n'
337 fun ascii: Char is intern
338
339 # Number of digits of an integer in base `b` (plus one if negative)
340 #
341 # assert 123.digit_count(10) == 3
342 # assert 123.digit_count(2) == 7 # 1111011 in binary
343 fun digit_count(b: Int): Int
344 do
345 if b == 10 then return digit_count_base_10
346 var d: Int # number of digits
347 var n: Int # current number
348 # Sign
349 if self < 0 then
350 d = 1
351 n = - self
352 else if self == 0 then
353 return 1
354 else
355 d = 0
356 n = self
357 end
358 # count digits
359 while n > 0 do
360 d += 1
361 n = n / b # euclidian division /
362 end
363 return d
364 end
365
366 # Optimized version for base 10
367 fun digit_count_base_10: Int
368 do
369 var val: Int
370 var result: Int
371 if self < 0 then
372 result = 2
373 val = -self
374 else
375 result = 1
376 val = self
377 end
378 loop
379 if val < 10 then return result
380 if val < 100 then return result+1
381 if val < 1000 then return result+2
382 if val < 10000 then return result+3
383 val = val / 10000
384 result += 4
385 end
386 end
387
388 # Return the corresponding digit character
389 # If 0 <= `self` <= 9, return the corresponding character.
390 # assert 5.to_c == '5'
391 # If 10 <= `self` <= 36, return the corresponding letter [a..z].
392 # assert 15.to_c == 'f'
393 fun to_c: Char
394 do
395 assert self >= 0 and self <= 36 # TODO plan for this
396 if self < 10 then
397 return (self + '0'.ascii).ascii
398 else
399 return (self + ('a'.ascii - 10)).ascii
400 end
401 end
402
403 # Execute 'each' for each integer in [self..last]
404 fun enumerate_to(last: Int)
405 !each(i: Int)
406 do
407 var cur = self
408 while cur <= last do
409 each(cur)
410 cur += 1
411 end
412 end
413
414 # Execute 'each' for each integer in [self..after[
415 fun enumerate_before(after: Int)
416 !each(i: Int)
417 do
418 var cur = self
419 while cur < after do
420 each(cur)
421 cur += 1
422 end
423 end
424
425 # The absolute value of self
426 #
427 # assert (-10).abs == 10
428 # assert 10.abs == 10
429 # assert 0.abs == 0
430 fun abs: Int
431 do
432 if self >= 0
433 then
434 return self
435 else
436 return -1 * self
437 end
438 end
439 end
440
441 # Native characters.
442 # Characters are denoted with simple quote.
443 # eg. `'a'` or `'\n'`.
444 universal Char
445 super Discrete
446 redef type OTHER: Char
447
448 redef fun object_id is intern
449 redef fun hash do return ascii
450 redef fun ==(o) is intern
451 redef fun !=(o) is intern
452 redef fun output is intern
453
454 redef fun <=(i) is intern
455 redef fun <(i) is intern
456 redef fun >=(i) is intern
457 redef fun >(i) is intern
458
459 redef fun succ is intern
460 redef fun prec is intern
461
462 redef fun distance(c)
463 do
464 var d = self.ascii - c.ascii
465 if d >= 0 then
466 return d
467 else
468 return -d
469 end
470 end
471
472 # If `self` is a digit then return this digit else return -1.
473 #
474 # assert '5'.to_i == 5
475 fun to_i: Int
476 do
477
478 if self == '-' then
479 return -1
480 else if is_digit then
481 return self.ascii - '0'.ascii
482 else
483 return self.to_lower.ascii - ('a'.ascii + 10)
484 end
485 end
486
487 # the ascii value of self
488 #
489 # assert 'a'.ascii == 97
490 # assert '\n'.ascii == 10
491 fun ascii: Int is intern
492
493 redef fun +(i) is intern
494 redef fun -(i) is intern
495
496 # Return the lower case version of self.
497 # If self is not a letter, then return self
498 #
499 # assert 'A'.to_lower == 'a'
500 # assert 'a'.to_lower == 'a'
501 # assert '$'.to_lower == '$'
502 fun to_lower: Char
503 do
504 if is_upper then
505 return (ascii + ('a'.distance('A'))).ascii
506 else
507 return self
508 end
509 end
510
511 # Return the upper case version of self.
512 # If self is not a letter, then return self
513 #
514 # assert 'a'.to_upper == 'A'
515 # assert 'A'.to_upper == 'A'
516 # assert '$'.to_upper == '$'
517 fun to_upper: Char
518 do
519 if is_lower then
520 return (ascii - ('a'.distance('A'))).ascii
521 else
522 return self
523 end
524 end
525
526 # Is self a digit? (from '0' to '9')
527 #
528 # assert '0'.is_digit == true
529 # assert '9'.is_digit == true
530 # assert 'a'.is_digit == false
531 fun is_digit : Bool
532 do
533 return self >= '0' and self <= '9'
534 end
535
536 # Is self a lower case letter? (from 'a' to 'z')
537 #
538 # assert 'a'.is_lower == true
539 # assert 'z'.is_lower == true
540 # assert 'A'.is_lower == false
541 # assert '$'.is_lower == false
542 fun is_lower : Bool
543 do
544 return self >= 'a' and self <= 'z'
545 end
546
547 # Is self a upper case letter? (from 'A' to 'Z')
548 #
549 # assert 'A'.is_upper == true
550 # assert 'A'.is_upper == true
551 # assert 'z'.is_upper == false
552 # assert '$'.is_upper == false
553 fun is_upper : Bool
554 do
555 return self >= 'A' and self <= 'Z'
556 end
557
558 # Is self a letter? (from 'A' to 'Z' and 'a' to 'z')
559 #
560 # assert 'A'.is_letter == true
561 # assert 'A'.is_letter == true
562 # assert 'z'.is_letter == true
563 # assert '$'.is_letter == false
564 fun is_letter : Bool
565 do
566 return is_lower or is_upper
567 end
568 end
569
570 # Pointer classes are used to manipulate extern C structures.
571 extern Pointer
572 # Is the address behind this Object at NULL?
573 fun address_is_null: Bool `{ return recv == NULL; `}
574 end