From 88b376ca3d8496aa2a1b24b27b4dd8027557fc57 Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Wed, 10 Jun 2009 09:29:20 -0400 Subject: [PATCH] lib: Split collections into readable and writable Map -> MapRead (r) Map (rw) IndexedCollection -> IndexedCollectionRead (r) IndexedCollection (rw) AbstractArray -> AbstractArrayRead (r) AbstractArray (rw) String -> String (ro) Buffer (rw) Signed-off-by: Jean Privat --- lib/opts.nit | 4 +- lib/standard/abstract_collection.nit | 83 ++++--- lib/standard/array.nit | 173 +++++++------- lib/standard/exec.nit | 4 +- lib/standard/file.nit | 4 +- lib/standard/hash.nit | 10 +- lib/standard/list.nit | 2 +- lib/standard/stream.nit | 28 +-- lib/standard/string.nit | 436 +++++++++++++++++++--------------- src/compiling/compiling.nit | 4 +- src/compiling/compiling_global.nit | 4 +- src/compiling/compiling_methods.nit | 8 +- src/metamodel/partial_order.nit | 4 +- src/metamodel/static_type.nit | 8 +- src/nitc.nit | 2 +- src/nitdoc.nit | 30 +-- src/parser/lexer.nit | 8 +- src/parser/xss/lexer.xss | 8 +- src/syntax/mmbuilder.nit | 9 +- src/utils.nit | 4 +- tests/bench_string_append.nit | 4 +- tests/example_objet.nit | 16 +- tests/example_point.nit | 6 +- tests/example_procedural_string.nit | 4 +- tests/example_string.nit | 2 +- tests/example_time.nit | 4 +- tests/sav/test_symbol.sav | 2 +- tests/shootout_nsieve.nit | 2 +- tests/test_create_more.nit | 4 +- tests/test_isa.nit | 2 +- tests/test_refinement.nit | 2 +- tests/test_string_long.nit | 4 +- 32 files changed, 478 insertions(+), 407 deletions(-) diff --git a/lib/opts.nit b/lib/opts.nit index b9e5ceb..81b9a98 100644 --- a/lib/opts.nit +++ b/lib/opts.nit @@ -57,14 +57,14 @@ class Option # A pretty print for this help meth pretty(off: Int): String do - var text = " " + var text = new Buffer.from(" ") text.append(_names.join(", ")) text.append(" ") var rest = off - text.length if rest > 0 then text.append(" " * rest) text.append(helptext) #text.append(pretty_default) - return text + return text.to_s end meth pretty_default: String diff --git a/lib/standard/abstract_collection.nit b/lib/standard/abstract_collection.nit index 2ece03d..8f0a11d 100644 --- a/lib/standard/abstract_collection.nit +++ b/lib/standard/abstract_collection.nit @@ -227,6 +227,17 @@ special SimpleCollection[E] redef meth remove_all(item) do remove(item) end +interface MapRead[K, E] +special Collection[E] + # Get the item at `key'. + meth [](key: K): E is abstract + + # Is there an item at `key'. + meth has_key(key: K): Bool is abstract + + redef meth iterator: MapIterator[K, E] is abstract +end + # Maps are associative collections: `key' -> `item'. # # The main operator over maps is []. @@ -241,15 +252,10 @@ end # map.has_key(u3) # -> false interface Map[K, E] special RemovableCollection[E] - # Get the item at `key'. - meth [](key: K): E is abstract - +special MapRead[K, E] # Set the`item' at `key'. meth []=(key: K, item: E) is abstract - # Is there an item at `key'. - meth has_key(key: K): Bool is abstract - # Remove the item at `key' meth remove_at(key: K) is abstract @@ -263,8 +269,6 @@ special RemovableCollection[E] i.next end end - - redef meth iterator: MapIterator[K, E] is abstract end # Iterators for Map. @@ -274,35 +278,55 @@ special Iterator[E] meth key: K is abstract # Set a new `item' at `key'. - meth item=(item: E) is abstract + #meth item=(item: E) is abstract end # Indexed collection are ordoned collections. # The first item is 0. The last is `length'-1. -interface IndexedCollection[E] -special Map[Int, E] -special SimpleCollection[E] +interface IndexedCollectionRead[E] +special MapRead[Int, E] # Get the first item. # Is equivalent with `self'[0]. - redef meth first - do + redef meth first + do assert not_empty: not is_empty - return self[0] + return self[0] end - # Set the first item. - # Is equivalent with `self'[0] = `item'. - meth first=(item: E) - do self[0] = item end - # Get the last item. # Is equivalent with `self'[`length'-1]. meth last: E - do + do assert not_empty: not is_empty - return self[length-1] + return self[length-1] end + # Return the index of the first occurence of `item'. + # Return -1 if `item' is not found + meth index_of(item: E): Int + do + var i = iterator + while i.is_ok do + if i.item == item then return i.index + i.next + end + return -1 + end + + redef meth iterator: IndexedIterator[E] is abstract +end + +# Indexed collection are ordoned collections. +# The first item is 0. The last is `length'-1. +interface IndexedCollection[E] +special IndexedCollectionRead[E] +special Map[Int, E] +special SimpleCollection[E] + # Set the first item. + # Is equivalent with `self'[0] = `item'. + meth first=(item: E) + do self[0] = item end + # Set the last item. # Is equivalent with `self'[length-1] = `item'. meth last=(item: E) @@ -334,19 +358,6 @@ special SimpleCollection[E] # The second item become the first. meth shift: E is abstract - # Return the index of the first occurence of `item'. - # Return -1 if `item' is not found - meth index_of(item: E): Int - do - var i = iterator - while i.is_ok do - if i.item == item then return i.index - i.next - end - return -1 - end - - redef meth iterator: IndexedIterator[E] is abstract end # Iterators on indexed collections. @@ -386,7 +397,7 @@ class CoupleMapIterator[K, E] special MapIterator[K, E] redef meth item do return _iter.item.second - redef meth item=(e) do _iter.item.second = e + #redef meth item=(e) do _iter.item.second = e redef meth key do return _iter.item.first diff --git a/lib/standard/array.nit b/lib/standard/array.nit index 78beeb3..1f90388 100644 --- a/lib/standard/array.nit +++ b/lib/standard/array.nit @@ -17,60 +17,13 @@ package array import abstract_collection -# Resizeable one dimention array of objects. -class AbstractArray[E] -special IndexedCollection[E] - meth enlarge(cap: Int) is abstract - +# One dimention array of objects. +class AbstractArrayRead[E] +special IndexedCollectionRead[E] # The current length redef readable attr _length: Int = 0 - - redef meth is_empty do return _length == 0 - - redef meth push(item) do add(item) - - redef meth pop - do - assert not_empty: not is_empty - var r = last - _length -= 1 - return r - end - - redef meth shift - do - assert not_empty: not is_empty - var r = first - var i = 1 - var l = length - while i < l do - self[i-1] = self[i] - i += 1 - end - _length = l - 1 - return r - end - redef meth unshift(item) - do - var i = length - 1 - while i > 0 do - self[i+1] = self[i] - i -= 1 - end - self[0] = item - end - - meth insert(item: E, pos: Int) - do - enlarge(length + 1) - copy_to(pos, length-pos, self, pos + 1) - self[pos] = item - end - - redef meth add(item) do self[length] = item - - redef meth clear do _length = 0 + redef meth is_empty do return _length == 0 redef meth has(item) do @@ -149,30 +102,6 @@ special IndexedCollection[E] return result end - redef meth remove(item) do remove_at(index_of(item)) - - redef meth remove_all(item) - do - var i = index_of(item) - while i >= 0 do - remove_at(i) - i = index_of_from(item, i) - end - end - - redef meth remove_at(i) - do - var l = length - if i >= 0 and i < l then - var j = i + 1 - while j < l do - self[j-1] = self[j] - j += 1 - end - _length = l - 1 - end - end - protected meth copy_to(start: Int, len: Int, dest: AbstractArray[E], new_start: Int) do # TODO native one @@ -211,7 +140,83 @@ special IndexedCollection[E] return true end end - + +# Resizeable one dimention array of objects. +class AbstractArray[E] +special AbstractArrayRead[E] +special IndexedCollection[E] + meth enlarge(cap: Int) is abstract + + redef meth push(item) do add(item) + + redef meth pop + do + assert not_empty: not is_empty + var r = last + _length -= 1 + return r + end + + redef meth shift + do + assert not_empty: not is_empty + var r = first + var i = 1 + var l = length + while i < l do + self[i-1] = self[i] + i += 1 + end + _length = l - 1 + return r + end + + redef meth unshift(item) + do + var i = length - 1 + while i > 0 do + self[i+1] = self[i] + i -= 1 + end + self[0] = item + end + + meth insert(item: E, pos: Int) + do + enlarge(length + 1) + copy_to(pos, length-pos, self, pos + 1) + self[pos] = item + end + + redef meth add(item) do self[length] = item + + redef meth clear do _length = 0 + + redef meth remove(item) do remove_at(index_of(item)) + + redef meth remove_all(item) + do + var i = index_of(item) + while i >= 0 do + remove_at(i) + i = index_of_from(item, i) + end + end + + redef meth remove_at(i) + do + var l = length + if i >= 0 and i < l then + var j = i + 1 + while j < l do + self[j-1] = self[j] + j += 1 + end + _length = l - 1 + end + end +end + # Resizeable one dimention array of objects. # # Arrays have a literal representation. @@ -312,13 +317,13 @@ class ArrayIterator[E] special IndexedIterator[E] redef meth item do return _array[_index] - redef meth item=(e) do _array[_index] = e + # redef meth item=(e) do _array[_index] = e redef meth is_ok do return _index < _array.length redef meth next do _index += 1 - init(a: AbstractArray[E]) + init(a: AbstractArrayRead[E]) do assert not_nil: a != null _array = a @@ -326,7 +331,7 @@ special IndexedIterator[E] end redef readable attr _index: Int = 0 - attr _array: AbstractArray[E] + attr _array: AbstractArrayRead[E] end # Others collections ########################################################## @@ -397,7 +402,7 @@ end # Associative arrays implemented with an array of (key, value) pairs. class ArrayMap[K, E] -special CoupleMap[K, E] +special CoupleMap[K, E] # O(n) redef meth [](key) @@ -418,7 +423,7 @@ special CoupleMap[K, E] _items[i].second = item else _items.push(new Couple[K,E](key, item)) - end + end end # O(n) @@ -511,12 +516,12 @@ special CoupleMap[K, E] # The last positive result given by a index(1) call attr _last_index: Int = 0 - + # Where is the `key' in `_item'? # return -1 if not found private meth index(key: K): Int do - var l = _last_index + var l = _last_index if l < _items.length and _items[l].first == key then return l var i = 0 @@ -532,7 +537,7 @@ special CoupleMap[K, E] # A new empty map. init - do + do _items = new Array[Couple[K,E]] end end diff --git a/lib/standard/exec.nit b/lib/standard/exec.nit index c98a39c..72dd195 100644 --- a/lib/standard/exec.nit +++ b/lib/standard/exec.nit @@ -61,7 +61,7 @@ class Process # Internal code to handle execusion protected init execute(command: String, arguments: Array[String], pipeflags: Int) do - var args = new String + var args = new Buffer var l = 1 # Number of elements in args args.append(command) if arguments != null then @@ -71,7 +71,7 @@ class Process end l += arguments.length end - _data = basic_exec_execute(command.to_cstring, args.to_cstring, l, pipeflags) + _data = basic_exec_execute(command.to_cstring, args.to_s.to_cstring, l, pipeflags) end attr _data: NativeProcess diff --git a/lib/standard/file.nit b/lib/standard/file.nit index 7dbf17a..e6df753 100644 --- a/lib/standard/file.nit +++ b/lib/standard/file.nit @@ -242,7 +242,7 @@ redef class String meth mkdir do var dirs = self.split_with("/") - var path = new String + var path = new Buffer if dirs.is_empty then return if dirs[0].is_empty then # it was a starting / @@ -252,7 +252,7 @@ redef class String if d.is_empty then continue path.append(d) path.add('/') - path.to_cstring.file_mkdir + path.to_s.to_cstring.file_mkdir end end end diff --git a/lib/standard/hash.nit b/lib/standard/hash.nit index 9d68891..af4ebd3 100644 --- a/lib/standard/hash.nit +++ b/lib/standard/hash.nit @@ -336,11 +336,11 @@ special MapIterator[K, V] return _node.second end - redef meth item=(value) - do - assert is_ok - _node.second = value - end + #redef meth item=(value) + #do + # assert is_ok + # _node.second = value + #end redef meth key do diff --git a/lib/standard/list.nit b/lib/standard/list.nit index 5ab2cf3..97caba4 100644 --- a/lib/standard/list.nit +++ b/lib/standard/list.nit @@ -245,7 +245,7 @@ class ListIterator[E] special IndexedIterator[E] redef meth item do return _node.item - redef meth item=(e) do _node.item = e + # redef meth item=(e) do _node.item = e redef meth is_ok do return not _node == null diff --git a/lib/standard/stream.nit b/lib/standard/stream.nit index 9046044..3204e84 100644 --- a/lib/standard/stream.nit +++ b/lib/standard/stream.nit @@ -30,7 +30,7 @@ special IOS # Read at most i bytes meth read(i: Int): String do - var s = new String.with_capacity(i) + var s = new Buffer.with_capacity(i) while i > 0 and not eof do var c = read_char if c >= 0 then @@ -38,31 +38,31 @@ special IOS i -= 1 end end - return s + return s.to_s end # Read a string until the end of the line. meth read_line: String do assert not eof - var s = new String + var s = new Buffer append_line_to(s) - return s + return s.to_s end # Read all the stream until the eof. meth read_all: String do - var s = "" + var s = new Buffer while not eof do var c = read_char if c >= 0 then s.add(c.ascii) end - return s + return s.to_s end # Read a string until the end of the line and append it to `s'. - meth append_line_to(s: String) + meth append_line_to(s: Buffer) do while true do var x = read_char @@ -109,13 +109,13 @@ special IStream redef meth read(i) do - var s = new String.with_capacity(i) + var s = new Buffer.with_capacity(i) var j = _buffer_pos var k = _buffer.length while i > 0 do if j >= k then fill_buffer - if eof then return s + if eof then return s.to_s j = _buffer_pos k = _buffer.length end @@ -126,12 +126,12 @@ special IStream end end _buffer_pos = j - return s + return s.to_s end redef meth read_all do - var s = "" + var s = new Buffer while not eof do var j = _buffer_pos var k = _buffer.length @@ -142,7 +142,7 @@ special IStream _buffer_pos = j fill_buffer end - return s + return s.to_s end redef meth append_line_to(s) @@ -184,7 +184,7 @@ special IStream redef meth eof do return _buffer_pos >= _buffer.length and end_reached # The buffer - attr _buffer: String = null + attr _buffer: Buffer = null # The current position in the buffer attr _buffer_pos: Int = 0 @@ -198,7 +198,7 @@ special IStream # Allocate a `_buffer' for a given `capacity'. protected meth prepare_buffer(capacity: Int) do - _buffer = new String.with_capacity(capacity) + _buffer = new Buffer.with_capacity(capacity) _buffer_pos = 0 # need to read end end diff --git a/lib/standard/string.nit b/lib/standard/string.nit index a9ebc63..3b0065c 100644 --- a/lib/standard/string.nit +++ b/lib/standard/string.nit @@ -20,88 +20,86 @@ intrude import array # String # ############################################################################### -# Strings are arrays of characters. -class String -special AbstractArray[Char] -special Comparable -special StringCapable - - redef type OTHER: String +abstract class AbstractString +special AbstractArrayRead[Char] + readable private attr _items: NativeString redef meth [](index) do return _items[index] - redef meth []=(index, item) + # Create a substring. + # + # "abcd".substring(1, 2) # --> "bc" + # "abcd".substring(-1, 2) # --> "a" + # "abcd".substring(1, 0) # --> "" + # "abcd".substring(2, 5) # --> "cd" + meth substring(from: Int, count: Int): String do - if index == length then - add(item) - return + assert count >= 0 + count += from + if from < 0 then from = 0 + if count > length then count = length + if from < count then + var r = new Buffer.with_capacity(count - from) + while from < count do + r.push(_items[from]) + from += 1 + end + return r.to_s + else + return "" end - assert index >= 0 and index < length - _items[index] = item - end - - redef meth add(c) - do - if _capacity <= length then enlarge(length + 5) - _items[length] = c - _length += 1 end - redef meth enlarge(cap) + # Create a substring with the string beginning at the 'from' position + # + # "abcd".substring(1) # --> "bcd" + # "abcd".substring(-1) # --> "abcd" + # "abcd".substring(2) # --> "cd" + meth substring_from(from: Int): String do - var c = _capacity - if cap <= c then return - while c <= cap do c = c * 2 + 2 - var a = calloc_string(c) - _items.copy_to(a, length, 0, 0) - _items = a - _capacity = c + assert from < length + return substring(from, length - from) end - redef meth append(s) + # is this string a substring of the 'of' string from pos 'pos' + # + # "bc".is_substring("abcd",1) # --> true + # "bc".is_substring("abcd",2) # --> false + meth has_substring(str: String, pos: Int): Bool do - if s isa String then - var sl = s.length - if _capacity < length + sl then enlarge(length + sl) - s.items.copy_to(_items, sl, 0, length) - _length += sl - else - super + var itsindex = str.length - 1 + var myindex = pos + itsindex + var myitems = _items + var itsitems = str._items + if myindex > length or itsindex > myindex then return false + while itsindex > 0 do + if myitems[myindex] != itsitems[itsindex] then return false + myindex -= myindex + itsindex -= itsindex end + return true end - # The concatenation of `self' with `r' - meth +(s: String): String - do - var r = new String.with_capacity(length + s.length) - r.append(self) - r.append(s) - return r - end - - # i repetitions of self - meth *(i: Int): String - do - assert i >= 0 - var r = new String.with_capacity(length * i) - while i > 0 do - r.append(self) - i -= 1 - end - return r - end + # Is this string prefixed by 'prefix' + # + # "abc".is_prefix("abcd") # --> true + # "bc".is_prefix("abcd") # --> false + meth has_prefix(prefix: String): Bool do return has_substring(prefix,0) - # Clone. - redef meth to_s: String do return new String.from(self) + # Is this string suffixed by 'suffix' + # + # "abcd".has_suffix("abc") # --> false + # "abcd".has_suffix("bcd") # --> true + meth has_suffix(suffix: String): Bool do return has_substring(suffix, length - suffix.length) # If `self' contains only digits, return the corresponding integer meth to_i: Int do # Shortcut - return to_cstring.atoi + return to_s.to_cstring.atoi end - # If `self' contains only digits and alpha <= 'f', return the corresponding integer. + # If `self' contains only digits and alpha <= 'f', return the corresponding integer. meth to_hex: Int do return a_to(16) # If `self' contains only digits and letters, return the corresponding integer in a given base @@ -109,7 +107,7 @@ special StringCapable do var i = 0 var neg = false - + for c in self do var v = c.to_i @@ -132,79 +130,185 @@ special StringCapable end end + # String to upper case + meth to_upper: String + do + var s = new Buffer.with_capacity(length) + for i in self do s.add(i.to_upper) + return s.to_s + end + + # String to lower case + meth to_lower : String + do + var s = new Buffer.with_capacity(length) + for i in self do s.add(i.to_lower) + return s.to_s + end + + + redef meth output + do + var i = 0 + while i < length do + _items[i].output + i += 1 + end + end +end + + +class String +special Comparable +special AbstractString + redef type OTHER: String + + # Create a new string from a given char *. + init with_native(nat: NativeString, size: Int) + do + assert size >= 0 + _items = nat + _length = size + end + + # Create a new string from a null terminated char *. + init from_cstring(str: NativeString) + do + var size = str.cstring_length + _items = str + _length = size + end + # Return a null terminated char * meth to_cstring: NativeString do - self[length] = '\0' - _length -= 1 return _items end - # Create a substring. - # - # "abcd".substring(1, 2) # --> "bc" - # "abcd".substring(-1, 2) # --> "a" - # "abcd".substring(1, 0) # --> "" - # "abcd".substring(2, 5) # --> "cd" - meth substring(from: Int, count: Int): String + redef meth ==(o) do - assert count >= 0 - count += from - if from < 0 then from = 0 - if count > length then count = length - if from < count then - var r = new String.with_capacity(count - from) - while from < count do - r.push(_items[from]) - from += 1 + if not o isa String or o is null then return false + assert o isa String + var l = length + if o.length != l then return false + var i = 0 + var it = _items + var oit = o._items + while i < l do + if it[i] != oit[i] then return false + i += 1 + end + return true + end + + redef meth <(s) + do + var i = 0 + var l1 = length + var l2 = s.length + var n1 = _items + var n2 = s._items + while i < l1 and i < l2 do + var c1 = n1[i].ascii + var c2 = n2[i].ascii + if c1 < c2 then + return true + else if c2 < c1 then + return false end - return r + i += 1 + end + if l1 < l2 then + return true else - return "" + return false end end - # Create a substring with the string beginning at the 'from' position - # - # "abcd".substring(1) # --> "bcd" - # "abcd".substring(-1) # --> "abcd" - # "abcd".substring(2) # --> "cd" - meth substring_from(from: Int): String + # The concatenation of `self' with `r' + meth +(s: String): String do - assert from < length - return substring(from, length - from) + var r = new Buffer.with_capacity(length + s.length) + r.append(self) + r.append(s) + return r.to_s end - # is this string a substring of the 'of' string from pos 'pos' - # - # "bc".is_substring("abcd",1) # --> true - # "bc".is_substring("abcd",2) # --> false - meth has_substring(str: String, pos: Int): Bool + # i repetitions of self + meth *(i: Int): String do - var itsindex = str.length - 1 - var myindex = pos + itsindex - var myitems = _items - var itsitems = str._items - if myindex > length or itsindex > myindex then return false - while itsindex > 0 do - if myitems[myindex] != itsitems[itsindex] then return false - myindex -= myindex - itsindex -= itsindex + assert i >= 0 + var r = new Buffer.with_capacity(length * i) + while i > 0 do + r.append(self) + i -= 1 end - return true + return r.to_s end - # Is this string prefixed by 'prefix' - # - # "abc".is_prefix("abcd") # --> true - # "bc".is_prefix("abcd") # --> false - meth has_prefix(prefix: String): Bool do return has_substring(prefix,0) + redef meth to_s do return self +end - # Is this string suffixed by 'suffix' - # - # "abcd".has_suffix("abc") # --> false - # "abcd".has_suffix("bcd") # --> true - meth has_suffix(suffix: String): Bool do return has_substring(suffix, length - suffix.length) +# Strings are arrays of characters. +class Buffer +special AbstractString +special Comparable +special StringCapable +special AbstractArray[Char] + + redef type OTHER: String + + redef meth []=(index, item) + do + if index == length then + add(item) + return + end + assert index >= 0 and index < length + _items[index] = item + end + + redef meth add(c) + do + if _capacity <= length then enlarge(length + 5) + _items[length] = c + _length += 1 + end + + redef meth enlarge(cap) + do + var c = _capacity + if cap <= c then return + while c <= cap do c = c * 2 + 2 + var a = calloc_string(c+1) + _items.copy_to(a, length, 0, 0) + _items = a + _capacity = c + end + + redef meth append(s) + do + if s isa String then + var sl = s.length + if _capacity < length + sl then enlarge(length + sl) + s.items.copy_to(_items, sl, 0, length) + _length += sl + else + super + end + end + + redef meth to_s: String + do + var l = length + var a = calloc_string(l+1) + _items.copy_to(a, l, 0, 0) + + # Ensure the afterlast byte is '\0' to nul-terminated char * + a[length] = '\0' + + return new String.with_native(a, length) + end redef meth <(s) do @@ -247,54 +351,15 @@ special StringCapable do assert cap >= 0 # _items = new NativeString.calloc(cap) - _items = calloc_string(cap) + _items = calloc_string(cap+1) _capacity = cap _length = 0 end - # Create a new string from a given char *. - init with_native(nat: NativeString, size: Int) - do - assert size >= 0 - _items = nat - _capacity = size - _length = size - end - - # Create a new string from a null terminated char *. - init from_cstring(str: NativeString) - do - var size = str.cstring_length - _items = str - _capacity = size + 1 # Since there is a trailing \n - _length = size - end - - # Create a string of `count' chararter `c' - init filled_with(c: Char, count: Int) - do - with_capacity(count) - var i = 0 - while i < count do - _items[i] = c - i += 1 - end - _length = count - end - - redef meth output - do - var i = 0 - while i < length do - _items[i].output - i += 1 - end - end - redef meth ==(o) do - if not o isa String or o is null then return false - assert o isa String + if not o isa Buffer or o is null then return false + assert o isa Buffer var l = length if o.length != l then return false var i = 0 @@ -307,23 +372,6 @@ special StringCapable return true end - # String to upper case - meth to_upper: String - do - var s = new String.with_capacity(length) - for i in self do s.add(i.to_upper) - return s - end - - # String to lower case - meth to_lower : String - do - var s = new String.with_capacity(length) - for i in self do s.add(i.to_lower) - return s - end - - readable private attr _items: NativeString readable private attr _capacity: Int end @@ -342,7 +390,7 @@ redef class Object meth inspect: String do var r = inspect_head - r.add('>') + # r.add('>') return r end @@ -371,7 +419,7 @@ redef class Bool end redef class Int - meth fill_string(s: String, base: Int, signed: Bool) + meth fill_buffer(s: Buffer, base: Int, signed: Bool) # Fill `s' with the digits in base 'base' of `self' (and with the '-' sign if 'signed' and negative). # assume < to_c max const of char do @@ -405,9 +453,9 @@ redef class Int meth to_base(base: Int, signed: Bool): String do var l = digit_count(base) - var s = new String.filled_with(' ', l) - fill_string(s, base, signed) - return s + var s = new Buffer.from(" " * l) + fill_buffer(s, base, signed) + return s.to_s end end @@ -433,9 +481,9 @@ end redef class Char redef meth to_s do - var s = new String.with_capacity(1) + var s = new Buffer.with_capacity(1) s[0] = self - return s + return s.to_s end end @@ -443,9 +491,9 @@ redef class Collection[E] # Concatenate elements. redef meth to_s do - var s = new String + var s = new Buffer for e in self do if e != null then s.append(e.to_s) - return s + return s.to_s end # Concatenate and separate each elements with `sep'. @@ -453,7 +501,7 @@ redef class Collection[E] do if is_empty then return "" - var s = new String # Result + var s = new Buffer # Result # Concat first item var i = iterator @@ -468,7 +516,23 @@ redef class Collection[E] if e != null then s.append(e.to_s) i.next end - return s + return s.to_s + end +end + +redef class Array[E] + # Fast implementation + redef meth to_s + do + var s = new Buffer + var i = 0 + var l = length + while i < l do + var e = self[i] + if e != null then s.append(e.to_s) + i += 1 + end + return s.to_s end end @@ -478,7 +542,7 @@ redef class Map[K,V] do if is_empty then return "" - var s = new String # Result + var s = new Buffer # Result # Concat first item var i = iterator @@ -495,7 +559,7 @@ redef class Map[K,V] if e != null then s.append("{k}{couple_sep}{e}") i.next end - return s + return s.to_s end end diff --git a/src/compiling/compiling.nit b/src/compiling/compiling.nit index a74118b..5af27e8 100644 --- a/src/compiling/compiling.nit +++ b/src/compiling/compiling.nit @@ -48,7 +48,7 @@ redef class MMSrcModule if (native_name + "_nit.h").file_exists then includes.add("-I {native_name.dirname}") end - native_name.append("_nit.c") + native_name += "_nit.c" if native_name.file_exists then files.add(native_name) end @@ -103,7 +103,7 @@ redef class MMSrcModule v.global_analysis = ga v.add_decl("#include ") var native_name = filename.strip_extension(".nit") - native_name.append("_nit.h") + native_name += ("_nit.h") if native_name.file_exists then v.add_decl("#include <{native_name.basename("")}>") declare_class_tables_to_c(v) compile_mod_to_c(v) diff --git a/src/compiling/compiling_global.nit b/src/compiling/compiling_global.nit index 65c6ca0..f883907 100644 --- a/src/compiling/compiling_global.nit +++ b/src/compiling/compiling_global.nit @@ -421,7 +421,7 @@ redef class MMSrcModule for c in local_classes do c.compile_tables_to_c(v) end - var s = "classtable_t TAG2VFT[4] = \{NULL" + var s = new Buffer.from("classtable_t TAG2VFT[4] = \{NULL") for t in ["Int","Char","Bool"] do if has_global_class_named(t.to_symbol) then s.append(", (const classtable_t)VFT_{t}") @@ -430,7 +430,7 @@ redef class MMSrcModule end end s.append("};") - v.add_instr(s) + v.add_instr(s.to_s) end # Declare class table (for _sep.h) diff --git a/src/compiling/compiling_methods.nit b/src/compiling/compiling_methods.nit index 4556ba2..1253a51 100644 --- a/src/compiling/compiling_methods.nit +++ b/src/compiling/compiling_methods.nit @@ -73,12 +73,12 @@ redef class CompilerVisitor # Generate an fprintf to display an error location meth printf_locate_error(node: PNode): String do - var s = "fprintf(stderr, \"" + var s = new Buffer.from("fprintf(stderr, \"") if nmc != null then s.append(" in %s") s.append(" (%s:%d)\\n\", ") if nmc != null then s.append("LOCATE_{nmc.method.cname}, ") s.append("LOCATE_{module.name}, {node.line_number});") - return s + return s.to_s end redef init(module: MMSrcModule) @@ -1194,7 +1194,7 @@ redef class AStringFormExpr do var len = 0 var str = string_text - var res = new String + var res = new Buffer var i = 0 while i < str.length do var c = str[i] @@ -1210,7 +1210,7 @@ redef class AStringFormExpr res.add(c) i = i + 1 end - _cstring = res + _cstring = res.to_s _cstring_length = len end end diff --git a/src/metamodel/partial_order.nit b/src/metamodel/partial_order.nit index 42a0525..4960a51 100644 --- a/src/metamodel/partial_order.nit +++ b/src/metamodel/partial_order.nit @@ -68,7 +68,7 @@ special Collection[E] # Return a dot representation meth to_dot: String do - var s = new String + var s = new Buffer s.append(to_dot_header) for e in _elements do s.append(to_dot_node(e.value)) @@ -77,7 +77,7 @@ special Collection[E] end end s.append("}\n") - return s + return s.to_s end # Called to display the header diff --git a/src/metamodel/static_type.nit b/src/metamodel/static_type.nit index 627fe9e..6cf53b7 100644 --- a/src/metamodel/static_type.nit +++ b/src/metamodel/static_type.nit @@ -122,7 +122,7 @@ class MMSignature redef meth to_s do - var s: String + var s = new Buffer if _params != null and _params.length > 0 then var tmp: String var a = new Array[String].with_capacity(_params.length) @@ -132,14 +132,12 @@ class MMSignature #a.add("{pn}: {p}") a.add(p.to_s) end - s = "({a.join(",")})" - else - s = "" + s.append("({a.join(",")})") end if _return_type != null then s.append(": {_return_type}") end - return s + return s.to_s end # Adapt the signature to a different receiver diff --git a/src/nitc.nit b/src/nitc.nit index 57ce45e..5c65f1f 100644 --- a/src/nitc.nit +++ b/src/nitc.nit @@ -57,7 +57,7 @@ special AbstractCompiler compdir = ".nit_compile" end end - compdir.append(ext_prefix) + compdir += ext_prefix clibdir = opt_clibdir.value if clibdir == null then diff --git a/src/nitdoc.nit b/src/nitdoc.nit index 9f55979..30d29da 100644 --- a/src/nitdoc.nit +++ b/src/nitdoc.nit @@ -425,7 +425,7 @@ special MMEntity redef meth prototype_head(dctx) do - var res = "" + var res = new Buffer var intro_class = known_intro_class(dctx) var is_redef = local_class != intro_class @@ -444,12 +444,13 @@ special MMEntity res.append(" {intro_class.module.html_link(dctx)}::") end end - return res + return res.to_s end redef meth prototype_body(dctx) do - var res = signature.to_html(dctx) + var res = new Buffer + res.append(signature.to_html(dctx)) var s = self if s.node != null then if s.node isa ADeferredMethPropdef then @@ -458,7 +459,7 @@ special MMEntity res.append(" is intern") end end - return res + return res.to_s end redef meth need_doc(dctx) @@ -675,11 +676,11 @@ redef class ADoc # Html transcription of the doc meth to_html: String do - var res = new String + var res = new Buffer for c in n_comment do res.append(c.text.substring_from(1)) end - return res + return res.to_s end # Oneliner transcription of the doc @@ -726,19 +727,19 @@ special MMEntity redef meth prototype_head(dctx) do - var res = "" + var res = new Buffer var ki = known_intro(dctx) var is_redef = ki != self if is_redef then res.append("redef ") if global.visibility_level == 3 then res.append("private ") res.append("class ") if is_redef then res.append("{ki.module.html_link(dctx)}::") - return res + return res.to_s end redef meth prototype_body(dctx) do - var res = "" + var res = new Buffer if arity > 0 then res.append("[") for i in [0..arity[ do @@ -749,7 +750,7 @@ special MMEntity end res.append("]") end - return res + return res.to_s end # Extract the doc of a class @@ -1105,7 +1106,7 @@ redef class MMSignature # Htlm transcription of the signature (with nested links) meth to_html(dctx: DocContext): String do - var res = new String + var res = new Buffer if arity > 0 then res.append("(") res.append(self[0].html_link(dctx)) @@ -1119,7 +1120,7 @@ redef class MMSignature res.append(": ") res.append(return_type.html_link(dctx)) end - return res + return res.to_s end end @@ -1135,7 +1136,8 @@ end redef class MMTypeGeneric redef meth html_link(dctx) do - var res = local_class.html_link(dctx) + var res = new Buffer + res.append(local_class.html_link(dctx)) res.append("[") res.append(params[0].html_link(dctx)) for i in [1..params.length[ do @@ -1143,7 +1145,7 @@ redef class MMTypeGeneric res.append(params[i].html_link(dctx)) end res.append("]") - return res + return res.to_s end end diff --git a/src/parser/lexer.nit b/src/parser/lexer.nit index 8a7fb3d..bc2de48 100644 --- a/src/parser/lexer.nit +++ b/src/parser/lexer.nit @@ -1320,7 +1320,7 @@ class Lexer attr _stream: IStream # Pushback buffer to store unread character - attr _stream_buf: String + attr _stream_buf: Buffer # Number of character stored in the pushback buffer attr _stream_pos: Int @@ -1338,7 +1338,7 @@ class Lexer attr _eof: Bool = false # Current working text read from the input stream - attr _text: String + attr _text: Buffer # Constante state values private meth state_initial: Int do return 0 end @@ -1347,10 +1347,10 @@ class Lexer init(stream: IStream, fname: String) do _filename = fname - _text = new String + _text = new Buffer _stream = stream _stream_pos = -1 - _stream_buf = new String + _stream_buf = new Buffer build_goto_table build_accept_table end diff --git a/src/parser/xss/lexer.xss b/src/parser/xss/lexer.xss index f3b3247..d962dce 100644 --- a/src/parser/xss/lexer.xss +++ b/src/parser/xss/lexer.xss @@ -34,7 +34,7 @@ class Lexer attr _stream: IStream # Pushback buffer to store unread character - attr _stream_buf: String + attr _stream_buf: Buffer # Number of character stored in the pushback buffer attr _stream_pos: Int @@ -52,7 +52,7 @@ class Lexer attr _eof: Bool = false # Current working text read from the input stream - attr _text: String + attr _text: Buffer $ foreach {lexer_data/state} # Constante state values @@ -63,10 +63,10 @@ $ end foreach init(stream: IStream, fname: String) do _filename = fname - _text = new String + _text = new Buffer _stream = stream _stream_pos = -1 - _stream_buf = new String + _stream_buf = new Buffer build_goto_table build_accept_table end diff --git a/src/syntax/mmbuilder.nit b/src/syntax/mmbuilder.nit index 038ab90..b59eaa9 100644 --- a/src/syntax/mmbuilder.nit +++ b/src/syntax/mmbuilder.nit @@ -1055,7 +1055,7 @@ end # Visitor used to build a full method name from multiple tokens private class MethidAccumulator special Visitor - readable attr _name: String + readable attr _name: Buffer = new Buffer redef meth visit(n) do if n isa Token then @@ -1064,11 +1064,6 @@ special Visitor n.visit_all(self) end end - - init - do - _name = new String - end end redef class PMethid @@ -1079,7 +1074,7 @@ redef class PMethid do var accumulator = new MethidAccumulator accumulator.visit(self) - _name = accumulator.name.to_symbol + _name = accumulator.name.to_s.to_symbol super end end diff --git a/src/utils.nit b/src/utils.nit index 1aa727f..f8dbfbd 100644 --- a/src/utils.nit +++ b/src/utils.nit @@ -22,7 +22,7 @@ package utils meth cmangle(symbols: Symbol...): String do var table = once cmangle_table - var res = new String + var res = new Buffer for sym in symbols do if not res.is_empty then res.add('_') @@ -52,7 +52,7 @@ do end end end - return res + return res.to_s end # Build the table that associates character to mangle to string diff --git a/tests/bench_string_append.nit b/tests/bench_string_append.nit index 1856a7a..9f5944f 100644 --- a/tests/bench_string_append.nit +++ b/tests/bench_string_append.nit @@ -22,7 +22,7 @@ end var s = "*" var i = 0 while i < n do - var s2 = "Je dis «" + var s2 = new Buffer.from("Je dis «") s2.append(s) s2.append("» et redis «") s2.append(s) @@ -30,7 +30,7 @@ while i < n do s2.append(s) s2.append(s) s2.append("».\n") - s = s2 + s = s2.to_s i = i + 1 end print("Je dis «Je dis".search_all_in(s).length) diff --git a/tests/example_objet.nit b/tests/example_objet.nit index db8bc4f..cc22a7c 100644 --- a/tests/example_objet.nit +++ b/tests/example_objet.nit @@ -101,9 +101,9 @@ private do # Les variables sont déclarées par "var", leur portée va de leur # déclaration jusqu'au "end" correspondant - var s: String # Là où on calcule le résultat + var s = new Buffer # Là où on calcule le résultat # Les chaînes littérales sont déclarées avec des guillemets - s = "*** Entrepôt " # On initialise "s" + s.append("*** Entrepôt ") # On initialise "s" # puis on concatène des chaînes à "s" s.append(_nom_) # la méthode "append" concatène s.append(" ***\n") @@ -124,7 +124,7 @@ private s.add('\n') # "add" ajoute un caractère à la fin. # Comme en C, les caractères sont entre simples cotes. end - return s + return s.to_s end @@ -218,12 +218,13 @@ private # Si une expression est passée comme valeur initiale d'une # variable, le type statique de la variable est implicitement # celui de l'expression. - var s = "* Rayon : " + var s = new Buffer + s.append("* Rayon : ") # Ici, le type statique de s est implicitement String s.append(_rubrique) s.add('\n') - return s + return s.to_s end meth cherche_produit(n: String): Produit @@ -244,7 +245,8 @@ private redef meth to_s: String do - var s = to_s_head + var s = new Buffer + s.append(to_s_head) # Les boucles en NIT sont des structures puissantes, toutefois # la manipulation des itérateurs peut être facilité par la # structure "for in" @@ -261,7 +263,7 @@ private s.append(p.to_s) s.add('\n') end - return s + return s.to_s end diff --git a/tests/example_point.nit b/tests/example_point.nit index c2363c2..3ab94cb 100644 --- a/tests/example_point.nit +++ b/tests/example_point.nit @@ -47,11 +47,7 @@ private redef meth to_s: String do - var s = "(" - s.append(_x.to_s) - s.add(':') - s.append(_y.to_s) - s.add(')') + var s = "({_x}:{_y})" return s end diff --git a/tests/example_procedural_string.nit b/tests/example_procedural_string.nit index 126fb85..35b7879 100644 --- a/tests/example_procedural_string.nit +++ b/tests/example_procedural_string.nit @@ -18,13 +18,13 @@ meth first_word(s: String): String do - var result = new String + var result = new Buffer var i = 0 while i < s.length and s[i] != ' ' do result.add(s[i]) i = i + 1 end - return result + return result.to_s end print(first_word("Hello world!")) diff --git a/tests/example_string.nit b/tests/example_string.nit index 5371270..006efff 100644 --- a/tests/example_string.nit +++ b/tests/example_string.nit @@ -27,7 +27,7 @@ printn("The value of a is: ", a, ".\n") # Second way: Build a string and display it. # Pro: Eiffel way (rigourous). # Con: Eiffel way (heavy). -var s = "The value of a is: " +var s = new Buffer.from("The value of a is: ") s.append(a.to_s) s.append(".\n") printn(s) diff --git a/tests/example_time.nit b/tests/example_time.nit index ae694d6..9c47159 100644 --- a/tests/example_time.nit +++ b/tests/example_time.nit @@ -39,9 +39,7 @@ class Time # The quantity of tyme in human readable form (h:m) redef meth to_s: String do - var s = hour.to_s # Get the h - s.add(':') - s.append((_min % 60).to_s) # Append the m + var s = "{hour}:{min%60}" return s end diff --git a/tests/sav/test_symbol.sav b/tests/sav/test_symbol.sav index 5ce0902..bc74ec5 100644 --- a/tests/sav/test_symbol.sav +++ b/tests/sav/test_symbol.sav @@ -3,7 +3,7 @@ TotoTataToto1 false false true -false +true 2 false false diff --git a/tests/shootout_nsieve.nit b/tests/shootout_nsieve.nit index a9a3923..0e2542b 100644 --- a/tests/shootout_nsieve.nit +++ b/tests/shootout_nsieve.nit @@ -17,7 +17,7 @@ meth nsieve(n: Int): Int do var count = 0 - var array = new String.with_capacity(n) + var array = new Buffer.with_capacity(n) for i in [0..n[ do array[i] = 'o' end diff --git a/tests/test_create_more.nit b/tests/test_create_more.nit index 1b0fd1c..c1a0252 100644 --- a/tests/test_create_more.nit +++ b/tests/test_create_more.nit @@ -47,9 +47,9 @@ class A do var s = _num.to_s if _attribute == null then - s.add('\n') + s += "\n" else - s.append(_attribute.to_s) + s += _attribute.to_s end return s end diff --git a/tests/test_isa.nit b/tests/test_isa.nit index 5b5ff3b..318a945 100644 --- a/tests/test_isa.nit +++ b/tests/test_isa.nit @@ -28,7 +28,7 @@ print("string:") a = "Bonjour" print(not a isa Int) print(a isa String) -print(a isa AbstractArray[Char]) +print(a isa AbstractArrayRead[Char]) print(not a isa Iterator[Int]) print(not a isa Discrete) print(a isa Object) diff --git a/tests/test_refinement.nit b/tests/test_refinement.nit index 4f39f68..ad05e55 100644 --- a/tests/test_refinement.nit +++ b/tests/test_refinement.nit @@ -70,7 +70,7 @@ do print(a) end -var b = "ab" +var b = new Buffer.from("ab") do print(b) b.add('c') diff --git a/tests/test_string_long.nit b/tests/test_string_long.nit index 0429f07..94324a3 100644 --- a/tests/test_string_long.nit +++ b/tests/test_string_long.nit @@ -16,8 +16,8 @@ var s = "Bonjour !\n" -var r = new String.with_capacity(50) -var r2 = "" +var r = new Buffer.with_capacity(50) +var r2 = new Buffer var i = 0 while i < 5000 do -- 1.7.9.5