# You are allowed to redistribute it and sell it, alone or is a part of
# another product.
-# This module define several abtract collection classes.
+# This module define several abstract collection classes.
package abstract_collection
import kernel
#
# Instances of this class offers an iterator method.
#
-# Colections instances can use the "for" structure:
+# Collections instances can use the "for" structure:
# var x: Collection[U]
# ...
# for u in x do
fun length: Int is abstract
# Is `item' in the collection ?
- # Comparaisons are done with ==
+ # Comparisons are done with ==
fun has(item: E): Bool is abstract
# Is the collection contain only `item' ?
- # Comparaisons are done with ==
+ # Comparisons are done with ==
# Return true if the collection is empty.
fun has_only(item: E): Bool is abstract
- # How many occurences of `item' are in the collection ?
- # Comparaisons are done with ==
+ # How many occurrences of `item' are in the collection ?
+ # Comparisons are done with ==
fun count(item: E): Int is abstract
# Return one the item of the collection
# Abstract sets.
#
-# Set contains contains only one element with the same value (according to =).
-# var s : Set[E]
+# Set contains contains only one element with the same value (according to ==).
+# var s: Set[E]
# var a = "Hello"
-# var b = "Hello"
+# var b = "Hel" + "lo"
# ...
# s.add(a)
# s.has(b) # --> true
redef fun remove_all(item) do remove(item)
end
+# MapRead are abstract associative collections: `key' -> `item'.
interface MapRead[K: Object, E]
# Get the item at `key'.
fun [](key: K): E is abstract
end
end
- # Return the point of view of self on the values only
+ # Return the point of view of self on the values only.
+ # Note that `self' and `values' are views on the same data;
+ # therefore any modification of one is visible on the other.
fun values: Collection[E] is abstract
- # Return the point of view of self on the keys only
+ # Return the point of view of self on the keys only.
+ # Note that `self' and `keys' are views on the same data;
+ # therefore any modification of one is visible on the other.
fun keys: Collection[E] is abstract
- # Is there no item in the collection ?
+ # Is there no item in the collection?
fun is_empty: Bool is abstract
# Number of items in the collection.
# map[u2] = v2 # Associate 'v2' to 'u2'
# map[u1] # -> v1
# map[u2] # -> v2
-# map.has_key(u1) # -> true
-# map.has_key(u3) # -> false
+#
+# Instances of maps can be used with the for structure
+#
+# for key, value in map do ..
+#
+# The keys and values in the map can also be manipulated directly with the `keys' and `values' methods.
+#
+# map.keys.has(u1) # -> true
+# map.keys.has(u3) # -> false
+# map.values.has(v1) # -> true
+# map.values.has(v3) # -> false
+#
interface Map[K: Object, E]
super MapRead[K, E]
# Set the`item' at `key'.
redef fun item do return self.iterator.item
end
-# Indexed collection are ordoned collections.
+# Sequences are indexed collections.
# The first item is 0. The last is `length'-1.
interface SequenceRead[E]
super Collection[E]
return self[0]
end
+ # Return the index=th element of the sequence.
+ # The first element is 0 and the last if `length-1'
+ # If index is invalid, the program aborts
fun [](index: Int): E is abstract
# Get the last item.
return self[length-1]
end
- # Return the index of the first occurence of `item'.
+ # Return the index of the first occurrence of `item'.
# Return -1 if `item' is not found
+ # Comparison is done with ==
fun index_of(item: E): Int
do
var i = iterator
redef fun iterator: IndexedIterator[E] is abstract
end
-# Indexed collection are ordoned collections.
+# Sequence are indexed collection.
# The first item is 0. The last is `length'-1.
interface Sequence[E]
super SequenceRead[E]
super SimpleCollection[E]
+
# Set the first item.
# Is equivalent with `self'[0] = `item'.
fun first=(item: E)
fun index: Int is abstract
end
-# Associatives arrays that internally uses couples to represent each (key, value) pairs.
+# Associative arrays that internally uses couples to represent each (key, value) pairs.
interface CoupleMap[K: Object, E]
super Map[K, E]
# Return the couple of the corresponding key
import abstract_collection
-# One dimention array of objects.
+# One dimension array of objects.
class AbstractArrayRead[E]
super SequenceRead[E]
- # The current length
+
redef readable var _length: Int = 0
redef fun is_empty do return _length == 0
redef fun index_of(item) do return index_of_from(item, 0)
+ # The index of the last occurrence of an element.
+ # Return -1 if not found.
fun last_index_of(item: E): Int do return last_index_of_from(item, length-1)
+ # The index of the first occurrence of an element starting from pos.
+ # Return -1 if not found.
fun index_of_from(item: E, pos: Int): Int
do
var i = pos
return -1
end
+ # The index of the last occurrence of an element starting from pos.
+ # Return -1 if not found.
fun last_index_of_from(item: E, pos: Int): Int
do
var i = pos
return -1
end
+ # Return a new array that is the reverse of `self'
+ #
+ # [1,2,3].reversed # -> [3, 2, 1]
fun reversed: Array[E]
do
var cmp = _length
return result
end
+ # Copy a portion of `self' to an other array.
+ #
+ # var a = [1, 2, 3, 4]
+ # var b = [10, 20, 30, 40, 50]
+ # a.copy_to(1, 2, b, 2)
+ # b # -> [10, 20, 2, 3, 50]
protected fun copy_to(start: Int, len: Int, dest: AbstractArray[E], new_start: Int)
do
# TODO native one
end
end
-# Resizeable one dimention array of objects.
+# Resizable one dimension array of objects.
class AbstractArray[E]
super AbstractArrayRead[E]
super Sequence[E]
+
+ # Force the capacity to be at least `cap'.
+ # The capacity of the array is an internal information.
+ # However, this method can be used to prepare a large amount of add
fun enlarge(cap: Int) is abstract
redef fun push(item) do add(item)
self[0] = item
end
+ # Insert an element at a given position, following elements are shifted.
+ #
+ # var a= [10, 20, 30, 40]
+ # a.insert(100, 2)
+ # a # -> [10, 20, 100, 30, 40]
fun insert(item: E, pos: Int)
do
enlarge(length + 1)
end
end
- fun swap_at( a : Int, b : Int )
+ # Invert two elements in the array
+ #
+ # var a = [10, 20, 30, 40]
+ # a.swap_at(1, 3)
+ # a # -> [10, 40, 30, 20]
+ fun swap_at(a: Int,b: Int)
do
var e = self[a]
self[a] = b
end
end
-# Resizeable one dimention array of objects.
+# Resizable one dimension array of objects.
#
# Arrays have a literal representation.
# a = [12, 32, 8]
class Array[E]
super AbstractArray[E]
super ArrayCapable[E]
+
redef fun iterate
!each(e: E)
do
# An `Iterator' on `AbstractArray'
class ArrayIterator[E]
super IndexedIterator[E]
+
redef fun item do return _array[_index]
# redef fun item=(e) do _array[_index] = e
# A set implemented with an Array.
class ArraySet[E: Object]
super Set[E]
+
# The stored elements.
var _array: Array[E]
redef fun iterator do return new ArraySetIterator[E](_array.iterator)
- # Assume the capacitydd is at least `cap'.
+ # Assume the capacity is at least `cap'.
fun enlarge(cap: Int) do _array.enlarge(cap)
private fun remove_at(i: Int)
# A HashCollection is an array of HashNode[K] indexed by the K hash value
private class HashCollection[K: Object, N: HashNode[K]]
super ArrayCapable[nullable N]
+
var _array: nullable NativeArray[nullable N] = null # Used to store items
var _capacity: Int = 0 # Size of _array
var _length: Int = 0 # Number of items in the map
_last_accessed_key = null
end
+ # Clear the whole structure
fun raz
do
var i = _capacity - 1
_last_accessed_key = null
end
+ # Force a capacity
fun enlarge(cap: Int)
do
var old_cap = _capacity
end
end
+# A map implemented with a hash table.
+# Keys of such a map cannot be null and require a working `hash' method
class HashMap[K: Object, V]
super Map[K, V]
super HashCollection[K, HashMapNode[K, V]]
redef var values: HashMapValues[K, V] = new HashMapValues[K, V](self)
end
+# View of the keys of a HashMap
class HashMapKeys[K: Object, V]
super RemovableCollection[K]
# The original map
redef fun remove_all(key) do self.map.remove_node(key)
end
+# View of the values of a Map
class HashMapValues[K: Object, V]
super RemovableCollection[V]
# The original map
end
end
-class HashMapNode[K: Object, V]
+private class HashMapNode[K: Object, V]
super HashNode[K]
redef type N: HashMapNode[K, V]
var _value: V
end
end
+# A `Set' implemented with a hash table.
+# Keys of such a map cannot be null and require a working `hash' method
class HashSet[E: Object]
super Set[E]
super HashCollection[E, HashSetNode[E]]
end
end
-class HashSetNode[E: Object]
+private class HashSetNode[E: Object]
super HashNode[E]
redef type N: HashSetNode[E]
import abstract_collection
-# Range of discrete objects.
+# Range of discrete objects.
class Range[E: Discrete]
super Collection[E]
class IteratorRange[E: Discrete]
# Iterator on ranges.
super Iterator[E]
- var _range: Range[E]
+ var _range: Range[E]
redef readable var _item: E
redef fun is_ok do return _item < _range.after
# TODO prevoir une structure pour recup tout un environ, le modifier et le passer a process
redef class Symbol
- # Return environement valued for this symbol
+ # Return environement value for this symbol
+ # If there is no such environement value, then return ""
fun environ: String
do
var res = to_s.to_cstring.get_environ
end
redef class NativeString
-# Refinned to add environement bindings
private fun get_environ: NativeString is extern "string_NativeString_NativeString_get_environ_0"
end
super BufferedIStream
# Misc
+ # Open the same file again.
+ # The original path is reused, therefore the reopened file can be a different file.
fun reopen
do
if not eof then close
_end_reached = true
end
- # Fill the internal read buffer. Needed by read operations.
redef fun fill_buffer
do
var nb = _file.io_read(_buffer._items, _buffer._capacity)
super FStream
super OStream
- # Write a string.
redef fun write(s)
do
assert _writable
fun file_stat: FileStat do return to_cstring.file_stat
+ # Remove a file, return true if success
fun file_delete: Bool do return to_cstring.file_delete
+ # remove the trailing extension "ext"
fun strip_extension(ext: String): String
do
if has_suffix(ext) then
return self
end
+ # Extract the basename of a path and remove the extension
fun basename(ext: String): String
do
var pos = last_index_of_from('/', _length - 1)
return n.strip_extension(ext)
end
+ # Extract the dirname of a path
fun dirname: String
do
var pos = last_index_of_from('/', _length - 1)
end
end
- fun file_path: String
- do
- var l = _length
- var pos = last_index_of_from('/', l - 1)
- if pos >= 0 then
- return substring(0, pos)
- end
- return "."
- end
-
# Create a directory (and all intermediate directories if needed)
fun mkdir
do
end
end
+ # Return right-most extension (without the dot)
fun file_extension : nullable String
do
var last_slash = last_index_of('.')
###############################################################################
# The root of the class hierarchy.
-# Each class implicitely specialize Object.
+# Each class implicitly specialize Object.
+#
+# Currently, Object is also used to collect all top-level methods.
interface Object
- # The unique object identifier in the class
+ # 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.
fun object_id: Int is intern
- # Return true is `self' and `other' have the same dynamic type
+ # Return true is `self' and `other' have the same dynamic type.
+ # Unless specific code, you should not use this method.
fun is_same_type(other: Object): Bool is intern
# Have `self' and `other' the same value?
##
- # Implicitely, the default implementation, is ==
+ # The exact meaning of "same value" is let to the subclasses.
+ # Implicitly, the default implementation, is ==
fun ==(other: nullable Object): Bool do return self is other
# Have `self' and `other' different values?
##
- # != is equivament with "not =".
+ # != is equivalent with "not =".
fun !=(other: nullable Object): Bool do return not (self == other)
# Display self on stdout (debug only).
+ # This method MUST not be used by programs, it is here for debugging only and can be removed without any notice
fun output
do
'<'.output
end
# Display class name on stdout (debug only).
+ # This method MUST not be used by programs, it is here for debugging only and can be removed without any notice
fun output_class_name is intern
- protected fun exit(exit_value: Int) is intern # Quit the program.
- protected fun sys: Sys is intern # The global sys object
+ # 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
end
# The main class of the program.
+# `Sys' is a singleton class, its only instance is `sys' defined in `Object'.
+# `sys' is used to invoke methods on the program on the system.
class Sys
- # Instructions outside classes implicetely redefine this method.
+ # Instructions outside classes implicitly redefine this method.
fun main do end
end
# The ancestor of class where objects are in a total order.
# In order to work, the method '<' has to be redefined.
interface Comparable
+ # What `self' can be compared to?
type OTHER: Comparable
- # Is `self' lesser than `other'
+ # Is `self' lesser than `other'?
fun <(other: OTHER): Bool is abstract
# not `other' < `self'
+ # Note, the implementation must ensure that: (x<=y) == (x<y or x==y)
fun <=(other: OTHER): Bool do return not other < self
# not `self' < `other'
+ # Note, the implementation must ensure that: (x>=y) == (x>y or x==y)
fun >=(other: OTHER): Bool do return not self < other
# `other' < `self'
fun >(other: OTHER): Bool do return other < self
# -1 if <, +1 if > and 0 otherwise
+ # Note, the implementation must ensure that: (x<=>y == 0) == (x==y)
fun <=>(other: OTHER): Int
do
if self < other then
# Native classes #
###############################################################################
-# Native booleans.
+# Native Booleans.
# `true' and `false' are the only instances.
-# Boolean are manipulated trought three special operators:
+# Boolean are manipulated trough three special operators:
# `and', `or', `not'.
# Booleans are mainly used by conditional statement and loops.
universal Bool
# The character whose ASCII value is `self'.
fun ascii: Char is intern
- # Number of digits of an integer in base `b' plus one if negative)
+ # Number of digits of an integer in base `b' (plus one if negative)
fun digit_count(b: Int): Int
do
var d: Int # number of digits
# count digits
while n > 0 do
d += 1
- n = n / b # euclidian division /
+ n = n / b # euclidian division /
end
return d
end
end
end
- # Executre 'each' for each integer in [self..last]
+ # Execute 'each' for each integer in [self..last]
fun enumerate_to(last: Int)
!each(i: Int)
do
end
end
- # Executre 'each' for each integer in [self..after[
+ # Execute 'each' for each integer in [self..after[
fun enumerate_before(after: Int)
!each(i: Int)
do
end
end
- fun abs : Int
+ # The absolute value of self
+ fun abs: Int
do
if self >= 0
then
end
end
- # If `self' is a digit then return this digit.
+ # If `self' is a digit then return this digit else return -1.
fun to_i: Int
do
redef fun +(i) is intern
redef fun -(i) is intern
- # Char to lower case
- fun to_lower : Char
+ # Return the lower case version of self.
+ # If self is not a letter, then return self
+ fun to_lower: Char
do
if is_upper then
return (ascii + ('a'.distance('A'))).ascii
end
end
- # Char to upper case
- fun to_upper : Char
+ # Return the upper case version of self.
+ # If self is not a letter, then return self
+ fun to_upper: Char
do
if is_lower then
return (ascii - ('a'.distance('A'))).ascii
end
end
+ # Is self a digit? (from '0' to '9')
fun is_digit : Bool
do
return self >= '0' and self <= '9'
end
+ # Is self a lower case letter? (from 'a' to 'z')
fun is_lower : Bool
do
return self >= 'a' and self <= 'z'
end
+ # Is self a upper case letter? (from 'A' to 'Z')
fun is_upper : Bool
do
return self >= 'A' and self <= 'Z'
end
+ # Is self a letter? (from 'A' to 'Z' and 'a' to 'z')
fun is_letter : Bool
do
return is_lower or is_upper
end
redef class Collection[ E ]
+ # Return a random element in the collection
fun rand : nullable E
do
if is_empty then return null
# String #
###############################################################################
+# Common subclass for String and Buffer
abstract class AbstractString
super AbstractArrayRead[Char]
+
readable private var _items: NativeString
redef fun [](index) do return _items[index]
class String
super Comparable
super AbstractString
+
redef type OTHER: String
# Create a new string from a given char *.
redef class Object
# fun class_name: String is extern intern # The name of the class
- # User redeable representation of `self'.
+ # User readable representation of `self'.
fun to_s: String do return inspect
# The class name of the object in NativeString format.
# FIXME: real type information is not available at runtime. Therefore, for instance, an instance of List[Bool] has just "List" for classname
fun class_name: String do return new String.from_cstring(native_class_name)
- # Developper readable representation of `self'.
+ # Developer readable representation of `self'.
# Usualy, it uses the form "<CLASSNAME:#OBJECTID bla bla bla>"
fun inspect: String
do
end
# Return "CLASSNAME:#OBJECTID".
- # This fuction is mainly used with the redefinition of the inspect method
+ # This function is mainly used with the redefinition of the inspect method
protected fun inspect_head: String
do
return "{class_name}:#{object_id.to_hex}"
redef class Map[K,V]
# Concatenate couple of 'key value' separate by 'couple_sep' and separate each couple with `sep'.
- fun map_join(sep: String, couple_sep: String): String
+ fun join(sep: String, couple_sep: String): String
do
if is_empty then return ""
end
###############################################################################
-# Native classe #
+# Native classes #
###############################################################################
# Native strings are simple C char *
# Return null if not found.
fun search_in(s: String, from: Int): nullable Match is abstract
- # Search all `self' occucences into `s'.
+ # Search all `self' occurrences into `s'.
fun search_all_in(s: String): Array[Match]
do
var res = new Array[Match] # Result
# see also http://www.cs.utexas.edu/users/moore/best-ideas/string-searching/index.html
class BM_Pattern
super Pattern
+
redef fun to_s do return _motif
- # boyer-moore search gives the position of the first occurence of a pattern starting at position `from'
+ # boyer-moore search gives the position of the first occurrence of a pattern starting at position `from'
redef fun search_index_in(s, from)
do
assert from >= 0
# The starting position in the string
readable var _from: Int
- # The length of the mathching part
+ # The length of the matching part
readable var _length: Int
# The position of the first character just after the matching part.
# May be out of the base string
fun after: Int do return _from + _length
- # The contents of the mathing part
+ # The contents of the matching part
redef fun to_s do return _string.substring(_from, _length)
# Matches `len' characters of `s' from `f'.
redef class Char
super Pattern
+
redef fun search_index_in(s, from)
do
var stop = s.length
redef class String
super Pattern
+
redef fun search_index_in(s, from)
do
assert from >= 0
end
end
- # Like `search_from' but from the first chararter.
+ # Like `search_from' but from the first character.
fun search(p: Pattern): nullable Match do return p.search_in(self, 0)
# Search the given pattern into self from a.
# Return null if not found.
fun search_from(p: Pattern, from: Int): nullable Match do return p.search_in(self, from)
- # Search all occurences of p into self.
+ # Search all occurrences of p into self.
#
# var a = new Array[Int]
# for i in "hello world".searches('o') do