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