Merge: SELF type
[nit.git] / lib / standard / kernel.nit
index f64d6c2..a179e9a 100644 (file)
@@ -17,6 +17,10 @@ module kernel
 
 import end # Mark this module is a top level one. (must be only one)
 
+`{
+#include <errno.h>
+`}
+
 ###############################################################################
 # System Classes                                                              #
 ###############################################################################
@@ -26,6 +30,28 @@ import end # Mark this module is a top level one. (must be only one)
 #
 # Currently, Object is also used to collect all top-level methods.
 interface Object
+       # Type of this instance, automatically specialized in every class
+       #
+       # A common use case of the virtual type `SELF` is to type an attribute and
+       # store another instance of the same type as `self`. It can also be used as as
+       # return type to a method producing a copy of `self` or returning an instance
+       # expected to be the exact same type as self.
+       #
+       # This virtual type must be used with caution as it can hinder specialization.
+       # In fact, it imposes strict restrictions on all sub-classes and their usage.
+       # For example, using `SELF` as a return type of a method `foo`
+       # forces all subclasses to ensure that `foo` returns the correct and updated
+       # type.
+       # A dangerous usage take the form of a method typed by `SELF` which creates
+       # and returns a new instance.
+       # If not correctly specialized, this method would break when invoked on a
+       # sub-class.
+       #
+       # A general rule for safe usage of `SELF` is to ensure that inputs typed
+       # `SELF` are stored in attributes typed `SELF` and returned by methods typed
+       # `SELF`, pretty much the same things as you would do with parameter types.
+       type SELF: Object
+
        # The unique object identifier in the class.
        # Unless specific code, you should not use this method.
        # The identifier is used internally to provide a hash value.
@@ -65,12 +91,6 @@ interface Object
        # only and can be removed without any notice
        fun output_class_name is intern 
 
-       # Quit the program with a specific return code
-       protected fun exit(exit_value: Int) is intern
-
-       # Return the global sys object, the only instance of the `Sys` class.
-       protected fun sys: Sys is intern
-
        # The hash code of the object.
        # Assuming that a == b -> a.hash == b.hash
        ##
@@ -84,8 +104,25 @@ end
 class Sys
        # Instructions outside classes implicitly redefine this method.
        fun main do end
+
+       # The entry point for the execution of the whole program.
+       # Its job is to call `main` but some modules may want to refine it
+       # and inject specific work before or after the main part.
+       fun run do main
+
+       # Number of the last error
+       fun errno: Int is extern `{
+               return errno;
+       `}
 end
 
+# Quit the program with a specific return code
+fun exit(exit_value: Int) is intern
+
+# Return the global sys object, the only instance of the `Sys` class.
+fun sys: Sys is intern
+
+
 ###############################################################################
 # Abstract Classes                                                            #
 ###############################################################################
@@ -230,6 +267,14 @@ interface Numeric
 
        # The value of zero in the domain of `self`
        fun zero: OTHER is abstract
+
+       # The value of `val` in the domain of `self`
+       #
+       #     assert 1.0.value_of(2) == 2.0
+       #     assert 1.0.value_of(2.0) == 2.0
+       #     assert 1.value_of(2) == 2
+       #     assert 1.value_of(2.0) == 2
+       fun value_of(val: Numeric): OTHER is abstract
 end
 
 ###############################################################################
@@ -246,7 +291,10 @@ universal Bool
        redef fun ==(b) is intern
        redef fun !=(b) is intern
        redef fun output is intern
-       redef fun hash
+       redef fun hash do return to_i
+
+       # 1 if true and 0 if false
+       fun to_i: Int
        do
                if self then
                        return 1
@@ -264,6 +312,8 @@ universal Float
        redef type OTHER: Float
 
        redef fun object_id is intern
+       redef fun ==(i) is intern
+       redef fun !=(i) is intern
        redef fun output is intern
 
        redef fun <=(i): Bool is intern
@@ -281,6 +331,60 @@ universal Float
        redef fun to_f do return self
 
        redef fun zero do return 0.0
+       redef fun value_of(val) do return val.to_f
+
+       redef fun <=>(other)
+       do
+               if self < other then
+                       return -1
+               else if other < self then
+                       return 1
+               else
+                       return 0
+               end
+       end
+
+       redef fun is_between(c, d)
+       do
+               if self < c or d < self then
+                       return false
+               else
+                       return true
+               end
+       end
+
+       # Compare float numbers with a given precision.
+       #
+       # Because of the loss of precision in floating numbers,
+       # the `==` method is often not the best way to compare them.
+       #
+       # ~~~
+       # assert 0.01.is_approx(0.02, 0.1)   == true
+       # assert 0.01.is_approx(0.02, 0.001) == false
+       # ~~~
+       fun is_approx(other, precision: Float): Bool
+       do
+               assert precision >= 0.0
+               return self <= other + precision and self >= other - precision
+       end
+
+       redef fun max(other)
+       do
+               if self < other then
+                       return other
+               else
+                       return self
+               end
+       end
+
+       redef fun min(c)
+       do
+               if c < self then
+                       return c
+               else
+                       return self
+               end
+       end
 end
 
 # Native integer numbers.
@@ -313,6 +417,7 @@ universal Int
        fun %(i: Int): Int is intern
 
        redef fun zero do return 0
+       redef fun value_of(val) do return val.to_i
 
        # `i` bits shift fo the left (aka <<)
        #
@@ -588,7 +693,10 @@ universal Char
 end
 
 # Pointer classes are used to manipulate extern C structures.
-extern Pointer
+extern class Pointer
        # Is the address behind this Object at NULL?
-       fun address_is_null: Bool `{ return recv == NULL; `}
+       fun address_is_null: Bool is extern "address_is_null"
+
+       # Free the memory pointed by this pointer
+       fun free `{ free(recv); `}
 end