19da7f8856acaf7d42eb1183a23fed0d5a356bbf
[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 do return to_i
213
214 # 1 if true and 0 if false
215 fun to_i: Int
216 do
217 if self then
218 return 1
219 else
220 return 0
221 end
222 end
223 end
224
225 # Native floating point numbers.
226 # Corresponds to C float.
227 universal Float
228 redef fun object_id is intern
229 redef fun output is intern
230
231 fun <=(i: Float): Bool is intern
232 fun <(i: Float): Bool is intern
233 fun >=(i: Float): Bool is intern
234 fun >(i: Float): Bool is intern
235 fun +(i: Float): Float is intern
236 fun -: Float is intern
237 fun -(i: Float): Float is intern
238 fun *(i: Float): Float is intern
239 fun /(i: Float): Float is intern
240
241 # The integer part of `self`.
242 #
243 # assert (0.0).to_i == 0
244 # assert (0.9).to_i == 0
245 # assert (-0.9).to_i == 0
246 # assert (9.9).to_i == 9
247 # assert (-9.9).to_i == -9
248 fun to_i: Int is intern
249 end
250
251 # Native integer numbers.
252 # Correspond to C int.
253 universal Int
254 super Discrete
255 redef type OTHER: Int
256
257 redef fun object_id is intern
258 redef fun hash do return self
259 redef fun ==(i) is intern
260 redef fun !=(i) is intern
261 redef fun output is intern
262
263 redef fun <=(i) is intern
264 redef fun <(i) is intern
265 redef fun >=(i) is intern
266 redef fun >(i) is intern
267 redef fun +(i) is intern
268 fun -: Int is intern
269 redef fun -(i) is intern
270 fun *(i: Int): Int is intern
271 fun /(i: Int): Int is intern
272 fun %(i: Int): Int is intern
273
274 # `i` bits shift fo the left (aka <<)
275 #
276 # assert 5.lshift(1) == 10
277 fun lshift(i: Int): Int is intern
278
279 # `i` bits shift fo the right (aka >>)
280 #
281 # assert 5.rshift(1) == 2
282 fun rshift(i: Int): Int is intern
283
284 # The float equivalent of `self`
285 #
286 # assert 5.to_f == 5.0
287 # assert 5.to_f != 5 # Float and Int are not equals
288 fun to_f: Float is intern
289
290 redef fun succ is intern
291 redef fun prec is intern
292 redef fun distance(i)
293 do
294 var d = self - i
295 if d >= 0 then
296 return d
297 else
298 return -d
299 end
300 end
301
302 redef fun <=>(other)
303 do
304 if self < other then
305 return -1
306 else if other < self then
307 return 1
308 else
309 return 0
310 end
311 end
312
313 redef fun is_between(c, d)
314 do
315 if self < c or d < self then
316 return false
317 else
318 return true
319 end
320 end
321
322 redef fun max(other)
323 do
324 if self < other then
325 return other
326 else
327 return self
328 end
329 end
330
331 redef fun min(c)
332 do
333 if c < self then
334 return c
335 else
336 return self
337 end
338 end
339
340 # The character whose ASCII value is `self`.
341 #
342 # assert 65.ascii == 'A'
343 # assert 10.ascii == '\n'
344 fun ascii: Char is intern
345
346 # Number of digits of an integer in base `b` (plus one if negative)
347 #
348 # assert 123.digit_count(10) == 3
349 # assert 123.digit_count(2) == 7 # 1111011 in binary
350 fun digit_count(b: Int): Int
351 do
352 if b == 10 then return digit_count_base_10
353 var d: Int # number of digits
354 var n: Int # current number
355 # Sign
356 if self < 0 then
357 d = 1
358 n = - self
359 else if self == 0 then
360 return 1
361 else
362 d = 0
363 n = self
364 end
365 # count digits
366 while n > 0 do
367 d += 1
368 n = n / b # euclidian division /
369 end
370 return d
371 end
372
373 # Optimized version for base 10
374 fun digit_count_base_10: Int
375 do
376 var val: Int
377 var result: Int
378 if self < 0 then
379 result = 2
380 val = -self
381 else
382 result = 1
383 val = self
384 end
385 loop
386 if val < 10 then return result
387 if val < 100 then return result+1
388 if val < 1000 then return result+2
389 if val < 10000 then return result+3
390 val = val / 10000
391 result += 4
392 end
393 end
394
395 # Return the corresponding digit character
396 # If 0 <= `self` <= 9, return the corresponding character.
397 # assert 5.to_c == '5'
398 # If 10 <= `self` <= 36, return the corresponding letter [a..z].
399 # assert 15.to_c == 'f'
400 fun to_c: Char
401 do
402 assert self >= 0 and self <= 36 # TODO plan for this
403 if self < 10 then
404 return (self + '0'.ascii).ascii
405 else
406 return (self + ('a'.ascii - 10)).ascii
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 hash do return ascii
435 redef fun ==(o) is intern
436 redef fun !=(o) is intern
437 redef fun output is intern
438
439 redef fun <=(i) is intern
440 redef fun <(i) is intern
441 redef fun >=(i) is intern
442 redef fun >(i) is intern
443
444 redef fun succ is intern
445 redef fun prec is intern
446
447 redef fun distance(c)
448 do
449 var d = self.ascii - c.ascii
450 if d >= 0 then
451 return d
452 else
453 return -d
454 end
455 end
456
457 # If `self` is a digit then return this digit else return -1.
458 #
459 # assert '5'.to_i == 5
460 fun to_i: Int
461 do
462
463 if self == '-' then
464 return -1
465 else if is_digit then
466 return self.ascii - '0'.ascii
467 else
468 return self.to_lower.ascii - 'a'.ascii + 10
469 end
470 end
471
472 # the ascii value of self
473 #
474 # assert 'a'.ascii == 97
475 # assert '\n'.ascii == 10
476 fun ascii: Int is intern
477
478 redef fun +(i) is intern
479 redef fun -(i) is intern
480
481 # Return the lower case version of self.
482 # If self is not a letter, then return self
483 #
484 # assert 'A'.to_lower == 'a'
485 # assert 'a'.to_lower == 'a'
486 # assert '$'.to_lower == '$'
487 fun to_lower: Char
488 do
489 if is_upper then
490 return (ascii + ('a'.distance('A'))).ascii
491 else
492 return self
493 end
494 end
495
496 # Return the upper case version of self.
497 # If self is not a letter, then return self
498 #
499 # assert 'a'.to_upper == 'A'
500 # assert 'A'.to_upper == 'A'
501 # assert '$'.to_upper == '$'
502 fun to_upper: Char
503 do
504 if is_lower then
505 return (ascii - ('a'.distance('A'))).ascii
506 else
507 return self
508 end
509 end
510
511 # Is self a digit? (from '0' to '9')
512 #
513 # assert '0'.is_digit == true
514 # assert '9'.is_digit == true
515 # assert 'a'.is_digit == false
516 fun is_digit : Bool
517 do
518 return self >= '0' and self <= '9'
519 end
520
521 # Is self a lower case letter? (from 'a' to 'z')
522 #
523 # assert 'a'.is_lower == true
524 # assert 'z'.is_lower == true
525 # assert 'A'.is_lower == false
526 # assert '$'.is_lower == false
527 fun is_lower : Bool
528 do
529 return self >= 'a' and self <= 'z'
530 end
531
532 # Is self a upper case letter? (from 'A' to 'Z')
533 #
534 # assert 'A'.is_upper == true
535 # assert 'A'.is_upper == true
536 # assert 'z'.is_upper == false
537 # assert '$'.is_upper == false
538 fun is_upper : Bool
539 do
540 return self >= 'A' and self <= 'Z'
541 end
542
543 # Is self a letter? (from 'A' to 'Z' and 'a' to 'z')
544 #
545 # assert 'A'.is_letter == true
546 # assert 'A'.is_letter == true
547 # assert 'z'.is_letter == true
548 # assert '$'.is_letter == false
549 fun is_letter : Bool
550 do
551 return is_lower or is_upper
552 end
553 end
554
555 # Pointer classes are used to manipulate extern C structures.
556 extern Pointer
557 # Is the address behind this Object at NULL?
558 fun address_is_null: Bool `{ return recv == NULL; `}
559
560 # Free the memory pointed by this pointer
561 fun free `{ free(recv); `}
562 end