lib: add Float::is_approx to compare floats
[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 #include <errno.h>
22 `}
23
24 ###############################################################################
25 # System Classes #
26 ###############################################################################
27
28 # The root of the class hierarchy.
29 # Each class implicitly specialize Object.
30 #
31 # Currently, Object is also used to collect all top-level methods.
32 interface Object
33 # The unique object identifier in the class.
34 # Unless specific code, you should not use this method.
35 # The identifier is used internally to provide a hash value.
36 fun object_id: Int is intern
37
38 # Return true if `self` and `other` have the same dynamic type.
39 # Unless specific code, you should not use this method.
40 fun is_same_type(other: Object): Bool is intern
41
42 # Return true if `self` and `other` are the same instance.
43 # Unless specific code, you should use `==` instead.
44 fun is_same_instance(other: nullable Object): Bool is intern
45
46 # Have `self` and `other` the same value?
47 ##
48 # The exact meaning of "same value" is let to the subclasses.
49 # Implicitly, the default implementation, is `is_same_instance`
50 fun ==(other: nullable Object): Bool do return self.is_same_instance(other)
51
52 # Have `self` and `other` different values?
53 ##
54 # != is equivalent with "not ==".
55 fun !=(other: nullable Object): Bool do return not (self == other)
56
57 # Display self on stdout (debug only).
58 # This method MUST not be used by programs, it is here for debugging
59 # only and can be removed without any notice
60 fun output
61 do
62 '<'.output
63 object_id.output
64 '>'.output
65 end
66
67 # Display class name on stdout (debug only).
68 # This method MUST not be used by programs, it is here for debugging
69 # only and can be removed without any notice
70 fun output_class_name is intern
71
72 # The hash code of the object.
73 # Assuming that a == b -> a.hash == b.hash
74 ##
75 # Without redefinition, it is based on the `object_id` of the instance.
76 fun hash: Int do return object_id / 8
77 end
78
79 # The main class of the program.
80 # `Sys` is a singleton class, its only instance is `sys` defined in `Object`.
81 # `sys` is used to invoke methods on the program on the system.
82 class Sys
83 # Instructions outside classes implicitly redefine this method.
84 fun main do end
85
86 # The entry point for the execution of the whole program.
87 # Its job is to call `main` but some modules may want to refine it
88 # and inject specific work before or after the main part.
89 fun run do main
90
91 # Number of the last error
92 fun errno: Int is extern `{
93 return errno;
94 `}
95 end
96
97 # Quit the program with a specific return code
98 fun exit(exit_value: Int) is intern
99
100 # Return the global sys object, the only instance of the `Sys` class.
101 fun sys: Sys is intern
102
103
104 ###############################################################################
105 # Abstract Classes #
106 ###############################################################################
107
108 # The ancestor of class where objects are in a total order.
109 # In order to work, the method '<' has to be redefined.
110 interface Comparable
111 # What `self` can be compared to?
112 type OTHER: Comparable
113
114 # Is `self` lesser than `other`?
115 fun <(other: OTHER): Bool is abstract
116
117 # not `other` < `self`
118 # Note, the implementation must ensure that: `(x<=y) == (x<y or x==y)`
119 fun <=(other: OTHER): Bool do return not other < self
120
121 # not `self` < `other`
122 # Note, the implementation must ensure that: `(x>=y) == (x>y or x==y)`
123 fun >=(other: OTHER): Bool do return not self < other
124
125 # `other` < `self`
126 fun >(other: OTHER): Bool do return other < self
127
128 # -1 if <, +1 if > and 0 otherwise
129 # Note, the implementation must ensure that: (x<=>y == 0) == (x==y)
130 fun <=>(other: OTHER): Int
131 do
132 if self < other then
133 return -1
134 else if other < self then
135 return 1
136 else
137 return 0
138 end
139 end
140
141 # c <= self <= d
142 fun is_between(c: OTHER, d: OTHER): Bool
143 do
144 return c <= self and self <= d
145 end
146
147 # The maximum between `self` and `other` (prefers `self` if equals).
148 fun max(other: OTHER): OTHER
149 do
150 if self < other then
151 return other
152 else
153 return self
154 end
155 end
156
157 # The minimum between `self` and `c` (prefer `self` if equals)
158 fun min(c: OTHER): OTHER
159 do
160 if c < self then
161 return c
162 else
163 return self
164 end
165 end
166 end
167
168 # Discrete total orders.
169 interface Discrete
170 super Comparable
171
172 redef type OTHER: Discrete
173
174 # The next element.
175 fun successor(i: Int): OTHER is abstract
176
177 # The previous element.
178 fun predecessor(i: Int): OTHER is abstract
179
180 # The distance between self and d.
181 #
182 # assert 10.distance(15) == 5
183 # assert 'Z'.distance('A') == 25
184 fun distance(d: OTHER): Int
185 do
186 var cursor: OTHER
187 var stop: OTHER
188 if self < d then
189 cursor = self
190 stop = d
191 else if self > d then
192 cursor = d
193 stop = self
194 else
195 return 0
196 end
197
198 var nb = 0
199 while cursor < stop do
200 cursor = cursor.successor(1)
201 nb += 1
202 end
203 return nb
204 end
205 end
206
207 # A numeric value supporting mathematical operations
208 interface Numeric
209 super Comparable
210
211 redef type OTHER: Numeric
212
213 # Addition of `self` with `i`
214 fun +(i: OTHER): OTHER is abstract
215
216 # Substraction of `i` from `self`
217 fun -(i: OTHER): OTHER is abstract
218
219 # Inverse of `self`
220 fun -: OTHER is abstract
221
222 # Multiplication of `self` with `i`
223 fun *(i: OTHER): OTHER is abstract
224
225 # Division of `self` with `i`
226 fun /(i: OTHER): OTHER is abstract
227
228 # The integer part of `self`.
229 #
230 # assert (0.0).to_i == 0
231 # assert (0.9).to_i == 0
232 # assert (-0.9).to_i == 0
233 # assert (9.9).to_i == 9
234 # assert (-9.9).to_i == -9
235 fun to_i: Int is abstract
236
237 # The float equivalent of `self`
238 #
239 # assert 5.to_f == 5.0
240 # assert 5.to_f != 5 # Float and Int are not equals
241 fun to_f: Float is abstract
242
243 # Is this the value of zero in its domain?
244 fun is_zero: Bool do return self == zero
245
246 # The value of zero in the domain of `self`
247 fun zero: OTHER is abstract
248
249 # The value of `val` in the domain of `self`
250 #
251 # assert 1.0.value_of(2) == 2.0
252 # assert 1.0.value_of(2.0) == 2.0
253 # assert 1.value_of(2) == 2
254 # assert 1.value_of(2.0) == 2
255 fun value_of(val: Numeric): OTHER is abstract
256 end
257
258 ###############################################################################
259 # Native classes #
260 ###############################################################################
261
262 # Native Booleans.
263 # `true` and `false` are the only instances.
264 # Boolean are manipulated trough three special operators:
265 # `and`, `or`, `not`.
266 # Booleans are mainly used by conditional statement and loops.
267 universal Bool
268 redef fun object_id is intern
269 redef fun ==(b) is intern
270 redef fun !=(b) is intern
271 redef fun output is intern
272 redef fun hash do return to_i
273
274 # 1 if true and 0 if false
275 fun to_i: Int
276 do
277 if self then
278 return 1
279 else
280 return 0
281 end
282 end
283 end
284
285 # Native floating point numbers.
286 # Corresponds to C float.
287 universal Float
288 super Numeric
289
290 redef type OTHER: Float
291
292 redef fun object_id is intern
293 redef fun ==(i) is intern
294 redef fun !=(i) is intern
295 redef fun output is intern
296
297 redef fun <=(i): Bool is intern
298 redef fun <(i): Bool is intern
299 redef fun >=(i): Bool is intern
300 redef fun >(i): Bool is intern
301
302 redef fun +(i) is intern
303 redef fun - is intern
304 redef fun -(i) is intern
305 redef fun *(i) is intern
306 redef fun /(i) is intern
307
308 redef fun to_i is intern
309 redef fun to_f do return self
310
311 redef fun zero do return 0.0
312 redef fun value_of(val) do return val.to_f
313
314 redef fun <=>(other)
315 do
316 if self < other then
317 return -1
318 else if other < self then
319 return 1
320 else
321 return 0
322 end
323 end
324
325 redef fun is_between(c, d)
326 do
327 if self < c or d < self then
328 return false
329 else
330 return true
331 end
332 end
333
334 # Compare float numbers with a given precision.
335 #
336 # Because of the loss of precision in floating numbers,
337 # the `==` method is often not the best way to compare them.
338 #
339 # ~~~
340 # assert 0.01.is_approx(0.02, 0.1) == true
341 # assert 0.01.is_approx(0.02, 0.001) == false
342 # ~~~
343 fun is_approx(other, precision: Float): Bool
344 do
345 assert precision >= 0.0
346 return self <= other + precision and self >= other - precision
347 end
348
349 redef fun max(other)
350 do
351 if self < other then
352 return other
353 else
354 return self
355 end
356 end
357
358 redef fun min(c)
359 do
360 if c < self then
361 return c
362 else
363 return self
364 end
365 end
366 end
367
368 # Native integer numbers.
369 # Correspond to C int.
370 universal Int
371 super Discrete
372 super Numeric
373
374 redef type OTHER: Int
375
376 redef fun successor(i) do return self + i
377 redef fun predecessor(i) do return self - i
378
379 redef fun object_id is intern
380 redef fun hash do return self
381 redef fun ==(i) is intern
382 redef fun !=(i) is intern
383 redef fun output is intern
384
385 redef fun <=(i) is intern
386 redef fun <(i) is intern
387 redef fun >=(i) is intern
388 redef fun >(i) is intern
389 redef fun +(i) is intern
390
391 redef fun - is intern
392 redef fun -(i) is intern
393 redef fun *(i) is intern
394 redef fun /(i) is intern
395 fun %(i: Int): Int is intern
396
397 redef fun zero do return 0
398 redef fun value_of(val) do return val.to_i
399
400 # `i` bits shift fo the left (aka <<)
401 #
402 # assert 5.lshift(1) == 10
403 fun lshift(i: Int): Int is intern
404
405 # `i` bits shift fo the right (aka >>)
406 #
407 # assert 5.rshift(1) == 2
408 fun rshift(i: Int): Int is intern
409
410 redef fun to_i do return self
411 redef fun to_f is intern
412
413 redef fun distance(i)
414 do
415 var d = self - i
416 if d >= 0 then
417 return d
418 else
419 return -d
420 end
421 end
422
423 redef fun <=>(other)
424 do
425 if self < other then
426 return -1
427 else if other < self then
428 return 1
429 else
430 return 0
431 end
432 end
433
434 redef fun is_between(c, d)
435 do
436 if self < c or d < self then
437 return false
438 else
439 return true
440 end
441 end
442
443 redef fun max(other)
444 do
445 if self < other then
446 return other
447 else
448 return self
449 end
450 end
451
452 redef fun min(c)
453 do
454 if c < self then
455 return c
456 else
457 return self
458 end
459 end
460
461 # The character whose ASCII value is `self`.
462 #
463 # assert 65.ascii == 'A'
464 # assert 10.ascii == '\n'
465 fun ascii: Char is intern
466
467 # Number of digits of an integer in base `b` (plus one if negative)
468 #
469 # assert 123.digit_count(10) == 3
470 # assert 123.digit_count(2) == 7 # 1111011 in binary
471 fun digit_count(b: Int): Int
472 do
473 if b == 10 then return digit_count_base_10
474 var d: Int # number of digits
475 var n: Int # current number
476 # Sign
477 if self < 0 then
478 d = 1
479 n = - self
480 else if self == 0 then
481 return 1
482 else
483 d = 0
484 n = self
485 end
486 # count digits
487 while n > 0 do
488 d += 1
489 n = n / b # euclidian division /
490 end
491 return d
492 end
493
494 # Optimized version for base 10
495 fun digit_count_base_10: Int
496 do
497 var val: Int
498 var result: Int
499 if self < 0 then
500 result = 2
501 val = -self
502 else
503 result = 1
504 val = self
505 end
506 loop
507 if val < 10 then return result
508 if val < 100 then return result+1
509 if val < 1000 then return result+2
510 if val < 10000 then return result+3
511 val = val / 10000
512 result += 4
513 end
514 end
515
516 # Return the corresponding digit character
517 # If 0 <= `self` <= 9, return the corresponding character.
518 # assert 5.to_c == '5'
519 # If 10 <= `self` <= 36, return the corresponding letter [a..z].
520 # assert 15.to_c == 'f'
521 fun to_c: Char
522 do
523 assert self >= 0 and self <= 36 # TODO plan for this
524 if self < 10 then
525 return (self + '0'.ascii).ascii
526 else
527 return (self + ('a'.ascii - 10)).ascii
528 end
529 end
530
531 # The absolute value of self
532 #
533 # assert (-10).abs == 10
534 # assert 10.abs == 10
535 # assert 0.abs == 0
536 fun abs: Int
537 do
538 if self >= 0
539 then
540 return self
541 else
542 return -1 * self
543 end
544 end
545 end
546
547 # Native characters.
548 # Characters are denoted with simple quote.
549 # eg. `'a'` or `'\n'`.
550 universal Char
551 super Discrete
552 redef type OTHER: Char
553
554 redef fun object_id is intern
555 redef fun hash do return ascii
556 redef fun ==(o) is intern
557 redef fun !=(o) is intern
558 redef fun output is intern
559
560 redef fun <=(i) is intern
561 redef fun <(i) is intern
562 redef fun >=(i) is intern
563 redef fun >(i) is intern
564
565 redef fun successor(i) is intern
566 redef fun predecessor(i) is intern
567
568 redef fun distance(c)
569 do
570 var d = self.ascii - c.ascii
571 if d >= 0 then
572 return d
573 else
574 return -d
575 end
576 end
577
578 # If `self` is a digit then return this digit else return -1.
579 #
580 # assert '5'.to_i == 5
581 fun to_i: Int
582 do
583
584 if self == '-' then
585 return -1
586 else if is_digit then
587 return self.ascii - '0'.ascii
588 else
589 return self.to_lower.ascii - 'a'.ascii + 10
590 end
591 end
592
593 # the ascii value of self
594 #
595 # assert 'a'.ascii == 97
596 # assert '\n'.ascii == 10
597 fun ascii: Int is intern
598
599 # Return the lower case version of self.
600 # If self is not a letter, then return self
601 #
602 # assert 'A'.to_lower == 'a'
603 # assert 'a'.to_lower == 'a'
604 # assert '$'.to_lower == '$'
605 fun to_lower: Char
606 do
607 if is_upper then
608 return (ascii + ('a'.distance('A'))).ascii
609 else
610 return self
611 end
612 end
613
614 # Return the upper case version of self.
615 # If self is not a letter, then return self
616 #
617 # assert 'a'.to_upper == 'A'
618 # assert 'A'.to_upper == 'A'
619 # assert '$'.to_upper == '$'
620 fun to_upper: Char
621 do
622 if is_lower then
623 return (ascii - ('a'.distance('A'))).ascii
624 else
625 return self
626 end
627 end
628
629 # Is self a digit? (from '0' to '9')
630 #
631 # assert '0'.is_digit == true
632 # assert '9'.is_digit == true
633 # assert 'a'.is_digit == false
634 fun is_digit : Bool
635 do
636 return self >= '0' and self <= '9'
637 end
638
639 # Is self a lower case letter? (from 'a' to 'z')
640 #
641 # assert 'a'.is_lower == true
642 # assert 'z'.is_lower == true
643 # assert 'A'.is_lower == false
644 # assert '$'.is_lower == false
645 fun is_lower : Bool
646 do
647 return self >= 'a' and self <= 'z'
648 end
649
650 # Is self a upper case letter? (from 'A' to 'Z')
651 #
652 # assert 'A'.is_upper == true
653 # assert 'A'.is_upper == true
654 # assert 'z'.is_upper == false
655 # assert '$'.is_upper == false
656 fun is_upper : Bool
657 do
658 return self >= 'A' and self <= 'Z'
659 end
660
661 # Is self a letter? (from 'A' to 'Z' and 'a' to 'z')
662 #
663 # assert 'A'.is_letter == true
664 # assert 'A'.is_letter == true
665 # assert 'z'.is_letter == true
666 # assert '$'.is_letter == false
667 fun is_letter : Bool
668 do
669 return is_lower or is_upper
670 end
671 end
672
673 # Pointer classes are used to manipulate extern C structures.
674 extern class Pointer
675 # Is the address behind this Object at NULL?
676 fun address_is_null: Bool is extern "address_is_null"
677
678 # Free the memory pointed by this pointer
679 fun free `{ free(recv); `}
680 end