X-Git-Url: http://nitlanguage.org diff --git a/lib/standard/kernel.nit b/lib/standard/kernel.nit index 9dbdc25..dfff892 100644 --- a/lib/standard/kernel.nit +++ b/lib/standard/kernel.nit @@ -26,6 +26,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. @@ -40,13 +62,13 @@ interface Object fun is_same_instance(other: nullable Object): Bool is intern # Have `self` and `other` the same value? - ## + # # The exact meaning of "same value" is let to the subclasses. # Implicitly, the default implementation, is `is_same_instance` fun ==(other: nullable Object): Bool do return self.is_same_instance(other) # Have `self` and `other` different values? - ## + # # != is equivalent with "not ==". fun !=(other: nullable Object): Bool do return not (self == other) @@ -65,15 +87,9 @@ 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 - ## + # # Without redefinition, it is based on the `object_id` of the instance. fun hash: Int do return object_id / 8 end @@ -84,8 +100,23 @@ 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 "sys_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 # ############################################################################### @@ -189,6 +220,25 @@ interface Discrete end end +# Something that can be cloned +# +# This interface introduces the `clone` method used to duplicate an instance +# Its specific semantic is let to the subclasses. +interface Cloneable + # Duplicate `self` + # + # The specific semantic of this method is let to the subclasses; + # Especially, if (and how) attributes are cloned (depth vs. shallow). + # + # As a rule of thumb, the principle of least astonishment should + # be used to guide the semantic. + # + # Note that as the returned clone depends on the semantic, + # the `==` method, if redefined, should ensure the equality + # between an object and its clone. + fun clone: SELF is abstract +end + # A numeric value supporting mathematical operations interface Numeric super Comparable @@ -224,6 +274,20 @@ interface Numeric # assert 5.to_f == 5.0 # assert 5.to_f != 5 # Float and Int are not equals fun to_f: Float is abstract + + # Is this the value of zero in its domain? + fun is_zero: Bool do return self == zero + + # 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 ############################################################################### @@ -232,15 +296,20 @@ end # Native Booleans. # `true` and `false` are the only instances. +# # Boolean are manipulated trough three special operators: -# `and`, `or`, `not`. +# `and`, `or`, `not`. +# # Booleans are mainly used by conditional statement and loops. universal Bool redef fun object_id is intern 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 @@ -258,6 +327,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 @@ -273,6 +344,62 @@ universal Float redef fun to_i is intern 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. @@ -302,8 +429,18 @@ universal Int redef fun -(i) is intern redef fun *(i) is intern redef fun /(i) is intern + + # Modulo of `self` with `i`. + # + # Finds the remainder of division of `self` by `i`. + # + # assert 5 % 2 == 1 + # assert 10 % 2 == 0 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 <<) # # assert 5.lshift(1) == 10 @@ -367,8 +504,8 @@ universal Int # The character whose ASCII value is `self`. # - # assert 65.ascii == 'A' - # assert 10.ascii == '\n' + # assert 65.ascii == 'A' + # assert 10.ascii == '\n' fun ascii: Char is intern # Number of digits of an integer in base `b` (plus one if negative) @@ -575,10 +712,29 @@ universal Char do return is_lower or is_upper end + + # Is self a whitespace character? + # + # These correspond to the "Other" and "Separator" groups of the Unicode. + # + # In the ASCII encoding, this is those <= to space (0x20) plus delete (0x7F). + # + # assert 'A'.is_whitespace == false + # assert ','.is_whitespace == false + # assert ' '.is_whitespace == true + # assert '\t'.is_whitespace == true + fun is_whitespace: Bool + do + var i = ascii + return i <= 0x20 or i == 0x7F + end 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 is extern "free" end