[Gd-chatter] r11685 - trunk/libraries/strings

cgay at gwydiondylan.org cgay at gwydiondylan.org
Tue Feb 19 00:30:59 CET 2008


Author: cgay
Date: Tue Feb 19 00:30:59 2008
New Revision: 11685

Modified:
   trunk/libraries/strings/library.dylan
   trunk/libraries/strings/strings.dylan
Log:
job: 7372
Use new common-dylan split implementation.

Modified: trunk/libraries/strings/library.dylan
==============================================================================
--- trunk/libraries/strings/library.dylan	(original)
+++ trunk/libraries/strings/library.dylan	Tue Feb 19 00:30:59 2008
@@ -58,8 +58,6 @@
   // Creation/modification/conversion
   create
     substring,
-    join,
-    split,
     trim,
     replace,
     replace!,
@@ -86,8 +84,7 @@
 //
 define module strings-implementation
   use strings;            // Use API module
-  use common-dylan,
-    exclude: { split };
+  use common-dylan;
   use streams,
     import: { \with-output-to-string,
               write,
@@ -100,10 +97,4 @@
               <case-sensitive-character-set>,
               <case-insensitive-character-set>,
               <byte-character-table> };
-  use regular-expressions,
-    import: { <regex>,
-              regex-search,
-              match-group,
-              group-start,
-              group-end };
 end module strings-implementation;

Modified: trunk/libraries/strings/strings.dylan
==============================================================================
--- trunk/libraries/strings/strings.dylan	(original)
+++ trunk/libraries/strings/strings.dylan	Tue Feb 19 00:30:59 2008
@@ -779,220 +779,6 @@
   int
 end method digit-to-integer;
 
-// ----------------------------------------------------------------------
-define open generic join
-    (items :: <sequence>, separator :: <sequence>, #key key, conjunction)
- => (joined :: <sequence>);
-
-// join(range(from: 1, to: 3), ", ",
-//      key: integer-to-string,
-//      conjunction: " and ");
-// => "1, 2 and 3"
-
-define method join
-    (sequences :: <sequence>, separator :: <sequence>,
-     #key key :: <function> = identity,
-          conjunction :: false-or(<sequence>))
- => (joined :: <sequence>)
-  let length :: <integer> = sequences.size;
-  if (length == 0)
-    error("Attempt to join an empty sequence.")
-  elseif (length == 1)
-    key(sequences[0])
-  else
-    let result-size :: <integer>
-      = (reduce(method (len, seq)
-                  len + seq.size
-                end,
-                0,
-                sequences)
-           + (separator.size * (length - 1))
-           + if (conjunction)
-               // the last separator is replaced by the conjunction
-               conjunction.size - separator.size
-             else
-               0
-             end);
-    let first = key(sequences[0]);   // don't call key > once on sequences[0]
-    let result = make(object-class(first), size: result-size);
-    let result-index :: <integer> = 0;
-    local method copy-to-result (seq :: <sequence>)
-            result := replace-subsequence!(result, seq, start: result-index);
-            result-index := result-index + seq.size;
-          end;
-    copy-to-result(first);
-    let max-index :: <integer> = length - 1;
-    for (i :: <integer> from 1 to max-index)
-      let seq :: <sequence> = sequences[i];
-      copy-to-result(if(conjunction & i == max-index)
-                       conjunction
-                     else
-                       separator
-                     end);
-      copy-to-result(key(seq));
-    end;
-    result
-  end if
-end method join;
-    
-
-
-// In common-dylan library...
-// Split a sequence into parts at each occurrance of the 'separator'
-// and return a sequence containing the parts.  The sequence is
-// searched from beginning to end for the given 'separator' and stops
-// when it reaches the end of 'sequence' or when the size of the
-// result reaches 'count' elements.  The meaning of the 'start' and
-// 'end' parameters may differ for different methods, but the intent
-// is that it be the same as if you passed in the subsequence delimited
-// by 'start' and 'end'.  See the individual methods for details.
-//
-define generic split
-    (sequence :: <sequence>, separator :: <object>,
-     #key start :: <integer> = 0,
-          end: _end :: false-or(<integer>),
-          count :: false-or(<integer>))
- => (parts :: <sequence>);
-
-// In common-dylan library
-
-// This is in some sense the most basic method, since others can be
-// implemented in terms of it.  The 'separator' function must accept
-// three arguments: (1) the sequence in which to search for a
-// separator, (2) the start index in that sequence at which to begin
-// searching, and (3) the index at which to stop searching, or #f to
-// search the entire sequence.  The 'separator' function must return
-// #f to indicate that no separator was found, or two values: the
-// start and end indices of the separator in the given sequence.  The
-// initial start and end indices passed to the 'separator' function
-// are the same as the 'start' and 'end' arguments passed to this
-// method.  The 'separator' function should stay within the given
-// bounds whenever possible.  (In particular it may not always be
-// possible when the separator is a regex.)
-define method split
-    (seq :: <sequence>, find-separator :: <function>,
-     #key start :: <integer> = 0,
-          end: _end :: false-or(<integer>),
-          count :: false-or(<integer>))
- => (parts :: <sequence>)
-  let bpos = start;
-  let epos :: <integer> = _end | seq.size;
-  let parts = list();           // likely to be short
-  // The use of epos below is an efficiency hack, but having more than
-  // epos splits is impossible so it works.
-  let max-parts :: <integer> = count | epos;
-  let num-parts :: <integer> = 0;
-  let separator-end = #f;
-  while (bpos & bpos < epos & num-parts < max-parts)
-    let (sep-start, sep-end) = find-separator(seq, bpos, epos);
-    if (sep-start)
-      parts := add!(parts, copy-sequence(seq, start: bpos, end: sep-start));
-      separator-end := sep-end;
-      num-parts := num-parts + 1;
-    end;
-    bpos := sep-end;  // may be #f and terminate loop
-  end while;
-  parts := add!(parts, if (separator-end)
-                         copy-sequence(seq, start: separator-end, end: epos)
-                       else
-                         seq
-                       end);
-  reverse!(parts)
-end method split;
-
-// In common-dylan library
-// Splits seq around occurrances of the separator subsequence.
-// Works for the relatively common case where seq and separator
-// are both <string>s.
-define method split
-    (seq :: <sequence>, separator :: <sequence>,
-     #key start :: <integer> = 0,
-          end: _end :: false-or(<integer>),
-          count :: false-or(<integer>))
- => (parts :: <sequence>)
-  local method find-string (seq :: <sequence>,
-                            bpos :: <integer>,
-                            epos :: false-or(<integer>))
-          // Note that this only splits on the separator sequence if it is
-          // entirely contained between the start and end positions.
-          let epos :: <integer> = epos | seq.size;
-          let max-separator-start :: <integer> = epos - separator.size;
-          block (exit-loop)
-            for (seq-index from bpos to max-separator-start)
-              if (looking-at?(separator, seq, seq-index))
-                exit-loop(seq-index, seq-index + separator.size);
-              end;
-            end;
-            #f      // separator not found
-          end
-        end;
-  split(seq, find-string, start: start, end: _end, count: count);
-end method split;
-
-// In common-dylan library
-// Split on a given object.
-// Covers the (<string>, <character>) case, for example.
-define method split
-    (seq :: <sequence>, separator :: <object>,
-     #key start :: <integer> = 0,
-          end: _end :: false-or(<integer>),
-          count :: false-or(<integer>))
- => (parts :: <sequence>)
-  local method find-pos (seq :: <sequence>,
-                         bpos :: <integer>,
-                         epos :: false-or(<integer>))
-          // Unfortunately common-dylan's position function doesn't accept
-          // start and end parameters so we have to write our own.
-          block (exit-loop)
-            for (i from bpos below epos)
-              // Should this use = or ==?
-              // How should we provide case-insensitive comparisons?
-              if (seq[i] = separator)
-                exit-loop(i, i + 1)
-              end;
-            end;
-            #f
-          end block
-        end method;
-  split(seq, find-pos, start: start, end: _end, count: count);
-end method split;
-
-// In regular-expressions library
-define method split
-    (seq :: <string>, separator :: <regex>,
-     #key start :: <integer> = 0,
-          end: _end :: false-or(<integer>),
-          count :: false-or(<integer>))
- => (parts :: <sequence>)
-  local method find-regex (seq :: <string>,
-                           bpos :: <integer>,
-                           epos :: false-or(<integer>))
-          let match = regex-search(separator, seq, start: bpos, end: epos);
-          if (match)
-            let (ignore, match-start, match-end) = match-group(match, 0);
-            values(match-start, match-end)
-          else
-            #f
-          end
-        end method find-regex;
-  split(seq, find-regex, start: start, end: _end, count: count)
-end method split;
-
-// todo -- should this be exported?
-define method looking-at?
-    (pattern :: <byte-string>, big :: <byte-string>, bpos :: <integer>)
- => (result :: <boolean>)
-  block (return)
-    let len :: <integer> = big.size;
-    for (char in pattern, pos from bpos)
-      if (pos >= len | char ~== big[pos])
-        return(#f)
-      end if;
-    end for;
-    #t
-  end
-end method looking-at?;
-
 define sealed method count-matches
     (source :: <byte-string>, pattern :: <byte-string>,
      #key test :: <function> = \==,



More information about the chatter mailing list