rename 'package' to 'module'
[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 end
70
71 # The main class of the program.
72 # `Sys` is a singleton class, its only instance is `sys` defined in `Object`.
73 # `sys` is used to invoke methods on the program on the system.
74 class Sys
75 # Instructions outside classes implicitly redefine this method.
76 fun main do end
77 end
78
79 ###############################################################################
80 # Abstract Classes #
81 ###############################################################################
82
83 # The ancestor of class where objects are in a total order.
84 # In order to work, the method '<' has to be redefined.
85 interface Comparable
86 # What `self` can be compared to?
87 type OTHER: Comparable
88
89 # Is `self` lesser than `other`?
90 fun <(other: OTHER): Bool is abstract
91
92 # not `other` < `self`
93 # Note, the implementation must ensure that: `(x<=y) == (x<y or x==y)`
94 fun <=(other: OTHER): Bool do return not other < self
95
96 # not `self` < `other`
97 # Note, the implementation must ensure that: `(x>=y) == (x>y or x==y)`
98 fun >=(other: OTHER): Bool do return not self < other
99
100 # `other` < `self`
101 fun >(other: OTHER): Bool do return other < self
102
103 # -1 if <, +1 if > and 0 otherwise
104 # Note, the implementation must ensure that: (x<=>y == 0) == (x==y)
105 fun <=>(other: OTHER): Int
106 do
107 if self < other then
108 return -1
109 else if other < self then
110 return 1
111 else
112 return 0
113 end
114 end
115
116 # c <= self <= d
117 fun is_between(c: OTHER, d: OTHER): Bool
118 do
119 return c <= self and self <= d
120 end
121
122 # The maximum between `self` and `other` (prefers `self` if equals).
123 fun max(other: OTHER): OTHER
124 do
125 if self < other then
126 return other
127 else
128 return self
129 end
130 end
131
132 # The minimum between `self` and `c` (prefer `self` if equals)
133 fun min(c: OTHER): OTHER
134 do
135 if c < self then
136 return c
137 else
138 return self
139 end
140 end
141 end
142
143 # Discrete total orders.
144 interface Discrete
145 super Comparable
146
147 redef type OTHER: Discrete
148
149 # The next element.
150 fun succ: OTHER do return self + 1
151
152 # The previous element.
153 fun prec: OTHER do return self - 1
154
155 # The `i`-th successor element.
156 fun +(i: Int): OTHER is abstract
157
158 # The `i`-th previous element.
159 fun -(i: Int): OTHER is abstract
160
161 # The distance between self and d.
162 #
163 # assert 10.distance(15) == 5
164 # assert 'Z'.distance('A') == 25
165 fun distance(d: OTHER): Int
166 do
167 var cursor: OTHER
168 var stop: OTHER
169 if self < d then
170 cursor = self
171 stop = d
172 else if self > d then
173 cursor = d
174 stop = self
175 else
176 return 0
177 end
178
179 var nb = 0
180 while cursor < stop do
181 cursor = cursor.succ
182 nb += 1
183 end
184 return nb
185 end
186 end
187
188 ###############################################################################
189 # Native classes #
190 ###############################################################################
191
192 # Native Booleans.
193 # `true` and `false` are the only instances.
194 # Boolean are manipulated trough three special operators:
195 # `and`, `or`, `not`.
196 # Booleans are mainly used by conditional statement and loops.
197 universal Bool
198 redef fun object_id is intern
199 redef fun ==(b) is intern
200 redef fun !=(b) is intern
201 redef fun output is intern
202 end
203
204 # Native floating point numbers.
205 # Corresponds to C float.
206 universal Float
207 redef fun object_id is intern
208 redef fun output is intern
209
210 fun <=(i: Float): Bool is intern
211 fun <(i: Float): Bool is intern
212 fun >=(i: Float): Bool is intern
213 fun >(i: Float): Bool is intern
214 fun +(i: Float): Float is intern
215 fun -: Float is intern
216 fun -(i: Float): Float is intern
217 fun *(i: Float): Float is intern
218 fun /(i: Float): Float is intern
219
220 # The integer part of `self`.
221 #
222 # assert (0.0).to_i == 0
223 # assert (0.9).to_i == 0
224 # assert (-0.9).to_i == 0
225 # assert (9.9).to_i == 9
226 # assert (-9.9).to_i == -9
227 fun to_i: Int is intern
228 end
229
230 # Native integer numbers.
231 # Correspond to C int.
232 universal Int
233 super Discrete
234 redef type OTHER: Int
235
236 redef fun object_id is intern
237 redef fun ==(i) is intern
238 redef fun !=(i) is intern
239 redef fun output is intern
240
241 redef fun <=(i) is intern
242 redef fun <(i) is intern
243 redef fun >=(i) is intern
244 redef fun >(i) is intern
245 redef fun +(i) is intern
246 fun -: Int is intern
247 redef fun -(i) is intern
248 fun *(i: Int): Int is intern
249 fun /(i: Int): Int is intern
250 fun %(i: Int): Int is intern
251
252 # `i` bits shift fo the left (aka <<)
253 #
254 # assert 5.lshift(1) == 10
255 fun lshift(i: Int): Int is intern
256
257 # `i` bits shift fo the right (aka >>)
258 #
259 # assert 5.rshift(1) == 2
260 fun rshift(i: Int): Int is intern
261
262 # The float equivalent of `self`
263 #
264 # assert 5.to_f == 5.0
265 # assert 5.to_f != 5 # Float and Int are not equals
266 fun to_f: Float is intern
267
268 redef fun succ is intern
269 redef fun prec is intern
270 redef fun distance(i)
271 do
272 var d = self - i
273 if d >= 0 then
274 return d
275 else
276 return -d
277 end
278 end
279
280 redef fun <=>(other)
281 do
282 if self < other then
283 return -1
284 else if other < self then
285 return 1
286 else
287 return 0
288 end
289 end
290
291 redef fun is_between(c, d)
292 do
293 if self < c or d < self then
294 return false
295 else
296 return true
297 end
298 end
299
300 redef fun max(other)
301 do
302 if self < other then
303 return other
304 else
305 return self
306 end
307 end
308
309 redef fun min(c)
310 do
311 if c < self then
312 return c
313 else
314 return self
315 end
316 end
317
318 # The character whose ASCII value is `self`.
319 #
320 # assert 65.ascii == 'A'
321 # assert 10.ascii == '\n'
322 fun ascii: Char is intern
323
324 # Number of digits of an integer in base `b` (plus one if negative)
325 #
326 # assert 123.digit_count(10) == 3
327 # assert 123.digit_count(2) == 7 # 1111011 in binary
328 fun digit_count(b: Int): Int
329 do
330 if b == 10 then return digit_count_base_10
331 var d: Int # number of digits
332 var n: Int # current number
333 # Sign
334 if self < 0 then
335 d = 1
336 n = - self
337 else if self == 0 then
338 return 1
339 else
340 d = 0
341 n = self
342 end
343 # count digits
344 while n > 0 do
345 d += 1
346 n = n / b # euclidian division /
347 end
348 return d
349 end
350
351 # Optimized version for base 10
352 fun digit_count_base_10: Int
353 do
354 var val: Int
355 var result: Int
356 if self < 0 then
357 result = 2
358 val = -self
359 else
360 result = 1
361 val = self
362 end
363 loop
364 if val < 10 then return result
365 if val < 100 then return result+1
366 if val < 1000 then return result+2
367 if val < 10000 then return result+3
368 val = val / 10000
369 result += 4
370 end
371 end
372
373 # Return the corresponding digit character
374 # If 0 <= `self` <= 9, return the corresponding character.
375 # assert 5.to_c == '5'
376 # If 10 <= `self` <= 36, return the corresponding letter [a..z].
377 # assert 15.to_c == 'f'
378 fun to_c: Char
379 do
380 assert self >= 0 and self <= 36 # TODO plan for this
381 if self < 10 then
382 return (self + '0'.ascii).ascii
383 else
384 return (self + ('a'.ascii - 10)).ascii
385 end
386 end
387
388 # Execute 'each' for each integer in [self..last]
389 fun enumerate_to(last: Int)
390 !each(i: Int)
391 do
392 var cur = self
393 while cur <= last do
394 each(cur)
395 cur += 1
396 end
397 end
398
399 # Execute 'each' for each integer in [self..after[
400 fun enumerate_before(after: Int)
401 !each(i: Int)
402 do
403 var cur = self
404 while cur < after do
405 each(cur)
406 cur += 1
407 end
408 end
409
410 # The absolute value of self
411 #
412 # assert (-10).abs == 10
413 # assert 10.abs == 10
414 # assert 0.abs == 0
415 fun abs: Int
416 do
417 if self >= 0
418 then
419 return self
420 else
421 return -1 * self
422 end
423 end
424 end
425
426 # Native characters.
427 # Characters are denoted with simple quote.
428 # eg. `'a'` or `'\n'`.
429 universal Char
430 super Discrete
431 redef type OTHER: Char
432
433 redef fun object_id is intern
434 redef fun ==(o) is intern
435 redef fun !=(o) is intern
436 redef fun output is intern
437
438 redef fun <=(i) is intern
439 redef fun <(i) is intern
440 redef fun >=(i) is intern
441 redef fun >(i) is intern
442
443 redef fun succ is intern
444 redef fun prec is intern
445
446 redef fun distance(c)
447 do
448 var d = self.ascii - c.ascii
449 if d >= 0 then
450 return d
451 else
452 return -d
453 end
454 end
455
456 # If `self` is a digit then return this digit else return -1.
457 #
458 # assert '5'.to_i == 5
459 fun to_i: Int
460 do
461
462 if self == '-' then
463 return -1
464 else if is_digit then
465 return self.ascii - '0'.ascii
466 else
467 return self.to_lower.ascii - ('a'.ascii + 10)
468 end
469 end
470
471 # the ascii value of self
472 #
473 # assert 'a'.ascii == 97
474 # assert '\n'.ascii == 10
475 fun ascii: Int is intern
476
477 redef fun +(i) is intern
478 redef fun -(i) is intern
479
480 # Return the lower case version of self.
481 # If self is not a letter, then return self
482 #
483 # assert 'A'.to_lower == 'a'
484 # assert 'a'.to_lower == 'a'
485 # assert '$'.to_lower == '$'
486 fun to_lower: Char
487 do
488 if is_upper then
489 return (ascii + ('a'.distance('A'))).ascii
490 else
491 return self
492 end
493 end
494
495 # Return the upper case version of self.
496 # If self is not a letter, then return self
497 #
498 # assert 'a'.to_upper == 'A'
499 # assert 'A'.to_upper == 'A'
500 # assert '$'.to_upper == '$'
501 fun to_upper: Char
502 do
503 if is_lower then
504 return (ascii - ('a'.distance('A'))).ascii
505 else
506 return self
507 end
508 end
509
510 # Is self a digit? (from '0' to '9')
511 #
512 # assert '0'.is_digit == true
513 # assert '9'.is_digit == true
514 # assert 'a'.is_digit == false
515 fun is_digit : Bool
516 do
517 return self >= '0' and self <= '9'
518 end
519
520 # Is self a lower case letter? (from 'a' to 'z')
521 #
522 # assert 'a'.is_lower == true
523 # assert 'z'.is_lower == true
524 # assert 'A'.is_lower == false
525 # assert '$'.is_lower == false
526 fun is_lower : Bool
527 do
528 return self >= 'a' and self <= 'z'
529 end
530
531 # Is self a upper case letter? (from 'A' to 'Z')
532 #
533 # assert 'A'.is_upper == true
534 # assert 'A'.is_upper == true
535 # assert 'z'.is_upper == false
536 # assert '$'.is_upper == false
537 fun is_upper : Bool
538 do
539 return self >= 'A' and self <= 'Z'
540 end
541
542 # Is self a letter? (from 'A' to 'Z' and 'a' to 'z')
543 #
544 # assert 'A'.is_letter == true
545 # assert 'A'.is_letter == true
546 # assert 'z'.is_letter == true
547 # assert '$'.is_letter == false
548 fun is_letter : Bool
549 do
550 return is_lower or is_upper
551 end
552 end
553
554 # Pointer classes are used to manipulate extern C structures.
555 extern Pointer
556 end