;; Help function for "split" that generates a literal string from a ;; list of ASCII ordinal values. You can use this to easily generate ;; the standard list of white space characters as follows: ;; ;; split.ord_to_str [32 9 10 13 12] ;; to split.ord_to_str :lst output apply "word map [char ?] :lst end ;; Split the string "s" into words using the characters in the string ;; "delims" as delimiters. By default most of the standard "C" locale ;; white space characters are used which include space, tab, newline, ;; carriage return, and form feed. Return the resulting list of ;; words. If "allow_empty_parts" is true, empty strings will be ;; inserted into the returned list for each pair of consecutive ;; delimiters in "s". If "allow_empty_parts" is false, consecutive ;; delimiters in "s" will be treated as if only one delimiter were ;; present in "s". to split :s ~ [:delims split.ord_to_str [32 9 10 13 12]] ~ [:allow_empty_parts "false] ~ [:curr []] ~ [:acc []] ~ [:pc []] ;; Check for the base case. If there are characters in "curr", ;; copy them to the accumulator before returning the accumulator. ;; Also, if the previous character "pc" before the end-of-string ;; was a separator and "allow_empty_parts" is true, the ;; end-of-string counts as an implicit separator, and an empty ;; part needs to be appended. if emptyp :s ~ [ifelse (or (not emptyp :curr) (and :allow_empty_parts (memberp :pc :delims))) [output reverse (fput (apply "word (reverse :curr)) :acc)] [output reverse :acc]] ;; Check if this character is a delimiter. If so, add the list of ;; characters in "curr" that represent the current word on the ;; accumulator. Note that "curr" is a list not a word. It is ;; done this way so that "word" only has to be called once which ;; is more efficient for long strings. Also note that the ;; characters in "curr" are added in reverse order. So "curr" ;; must be reversed before applying "word". if memberp (first :s) :delims ~ [ifelse (or (not emptyp :curr) :allow_empty_parts) [output (split (bf :s) :delims :allow_empty_parts [] (fput (apply "word (reverse :curr)) :acc) (first :s))] [output (split (bf :s) :delims :allow_empty_parts [] :acc (first :s))]] ;; Iterate until a delimiter is found or "s" is empty. output (split (bf :s) :delims :allow_empty_parts (fput (first :s) :curr) :acc (first :s)) end