/
ColdWeb-0.2/
ColdWeb-0.2/root/
parent $root
object $list

method to_string
    arg list, [sep];
    var str, part;
    
    if (!list)
        return "";
    sep = [@sep, " "][1];
    str = tostr(list[1]);
    for part in (delete(list, 1))
        str = str + sep + tostr(part);
    return str;
.

method to_english
    arg list, [options];
    var empty, and, sep;
    
    empty = [@options, "nothing"][1];
    switch (listlen(list)) {
        case 0:
            return empty;
        case 1:
            return tostr(list[1]);
    }
    and = [@options, " and ", " and "][2];
    sep = [@options, ", ", ", ", ", "][3];
    return .to_string(delete(list, listlen(list)), sep) + and + tostr(list[listlen(list)]);
.

method map
    arg list, method, [args];
    var out, x;
    
    // call 'method on each object, return results.
    out = [];
    for x in (list)
        out = [@out, x.(method)(@args)];
    return out;
.

method filter
    arg list, method, [args];
    var out, x;
    
    // similar to .map, but returns a list of objects which returned a
    // true value from 'method.
    out = [];
    for x in (list) {
        if (x.(method)(@args))
            out = [@out, x];
    }
    return out;
.

method sort
    arg list, [sortby];
    
    // calls ._sort().  Does not set an element to sort by yet, but should
    // eventually will have to fix.
    return ._sort(list, 1, listlen(list));
.

method _sort
    arg lst, x, y;
    var p, i, j;
    
    switch (y - x + 1) {
        case 0, 1:
            return lst;
        case 2:
            if (lst[x] <= lst[y])
                return lst;
            p = lst[x];
            lst = replace(lst, x, lst[y]);
            lst = replace(lst, y, p);
            return lst;
        case 3:
            if (lst[x] <= lst[x + 1]) {
                if (lst[x + 1] <= lst[y]) {
                } else if (lst[x] <= lst[y]) {
                    p = lst[x + 1];
                    lst = replace(lst, x + 1, lst[y]);
                    lst = replace(lst, y, p);
                } else {
                    p = lst[x];
                    lst = replace(lst, x, lst[y]);
                    lst = replace(lst, y, lst[x + 1]);
                    lst = replace(lst, x + 1, p);
                }
            } else if (lst[x] <= lst[y]) {
                p = lst[x];
                lst = replace(lst, x, lst[x + 1]);
                lst = replace(lst, x + 1, p);
            } else if (lst[x + 1] <= lst[y]) {
                p = lst[x];
                lst = replace(lst, x, lst[x + 1]);
                lst = replace(lst, x + 1, lst[y]);
                lst = replace(lst, y, p);
            } else {
                p = lst[x];
                lst = replace(lst, x, lst[y]);
                lst = replace(lst, y, p);
            }
            return lst;
    }
    p = lst[x];
    i = x;
    j = y;
    while (1) {
        while (i < j && p <= lst[j])
            j = j - 1;
        if (i == j)
            break;
        lst = replace(lst, i, lst[j]);
        i = i + 1;
        while (i < j && p >= lst[i])
            i = i + 1;
        if (i == j)
            break;
        lst = replace(lst, j, lst[i]);
        j = j - 1;
    }
    lst = replace(lst, i, p);
    lst = ._sort(lst, x, i - 1);
    lst = ._sort(lst, i + 1, y);
    return lst;
.

method columnize
    arg list, cols, [rest];
    var width, lines, line, separator, linelength, curcol;
    
    // turn [...] into ".   .   ."
    // rest[1]==separator; rest[2]==linelength
    separator = [@rest, "   "][1];
    linelength = [@rest, 78, 78][2];
    width = linelength / cols - strlen(separator);
    lines = [];
    while (list) {
        line = pad(list[1], width);
        list = sublist(list, 2);
        for curcol in [2 .. cols] {
            if (list) {
                line = line + separator + pad(list[1], width);
                list = sublist(list, 2);
            }
        }
        lines = [@lines, line];
    }
    return lines;
.

method reverse
    arg list;
    var elm, reversed;
    
    // .reverse(list)
    // -> list with its elements reversed
    reversed = [];
    for elm in (list)
        reversed = [elm, @reversed];
    return reversed;
.

method compress
    arg list;
    var out, last, x;
    
    // [a,a,b,b,c,c,d,d] => [a,b,c,d]
    // removes duplicate entries in a list
    out = [];
    for x in (list) {
        if (!(x in out))
            out = [@out, x];
    }
    return out;
.

method last
    arg list;
    
    return list[listlen(list)];
.

method count
    arg elem, list;
    var count;
    
    // count of elem in list
    while (elem in list) {
        count = count + 1;
        list = sublist(list, (elem in list) + 1);
    }
    return count;
.

method numbered_text
    arg text;
    var line;
    
    // receives a list of strings, returns that list with line numbers pre-pended
    for line in [1 .. listlen(text)]
        text = replace(text, line, (line < 10 ? " " | "") + tostr(line) + ": " + text[line]);
    return text;
.

method slice
    arg big_list, element;
    var list, ret_list;
    
    // Return elementh' element of all lists in big_list
    // No type or length checking done for speed purposes.
    ret_list = [];
    for list in (big_list)
        ret_list = [@ret_list, list[element]];
    return ret_list;
.

method swap
    arg list, a, b;
    var holder;
    
    // swap elements at indexes a and b
    holder = (> list[a] <);
    list = (> replace(list, a, list[b]) <);
    list = replace(list, b, holder);
    return list;
.

method max
    arg list;
    
    // return greatest element of list (no type checking performed)
    // if list is [], returns 0
    while (listlen(list) > 1) {
        if (list[1] > list[2])
            list = delete(list, 2);
        else
            list = delete(list, 1);
    }
    return [@list, 0][1];
.

method min
    arg list;
    
    // return least element of list (no type checking performed)
    // if list is [], returns 0
    while (listlen(list) > 1) {
        if (list[1] < list[2])
            list = delete(list, 2);
        else
            list = delete(list, 1);
    }
    return [@list, 0][1];
.

method swapsort
    arg list, [sort_by];
    var bot_elem, cur_elem, elem, compare;
    
    // note: iterative implementation allows sorts of extra-long lists
    elem = [@sort_by, 1];
    compare = [@sort_by, 'gt, 'lt][2];
    for bot_elem in [1 .. listlen(list)] {
        for cur_elem in [bot_elem + 1 .. listlen(list)] {
            if (._swap_compare(list[bot_elem], list[cur_elem], compare, elem))
                list = $list.swap(list, bot_elem, cur_elem);
        }
    }
    return list;
.

method _swap_compare
    arg elem1, elem2, compare, [elem];
    
    elem = [@elem, 1][1];
    switch (compare) {
        case 'lt:
            return elem1[elem] < elem2[elem];
        case 'gt:
            return elem1[elem] > elem2[elem];
        default:
            return 0;
    }
.

method heapsort
    arg list, [sort_by];
    var heap, sort_type, sort_elem;
    
    sort_elem = [@sort_by, 1][1];
    sort_type = [@sort_by, 'gt, 'gt][2];
    switch (sort_type) {
        case 'gt:
            heap = $small_first_heap_class.new(list, sort_elem);
        default:
            return list;
    }
    list = [];
    while (heap.length()) {
        list = heap.element(1);
        heap = heap.del(1);
    }
    return list;
.

method flatten
    arg list;
    var toret, elem;
    
    // [[[x], x], x]   =>   [x, x, x]
    toret = [];
    for elem in (list) {
        if (type(elem) == 'list)
            toret = toret + .flatten(elem);
        else
            toret = toret + [elem];
    }
    return toret;
.

method sum
    arg ints;
    var ret;
    
    // returns a sum of each integer in the list.
    ret = 0;
    while (ints) {
        ret = ret + ints[1];
        ints = delete(ints, 1);
    }
    return ret;
.

method non_alphanumeric
    // returns nun-alphanumeric in a list of characters
    return ["!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "+", "-", "=", "~", "`", "'", "{", "}", "[", "]", "|", "/", "?", "\"", "\\", ",", ".", "<", ">", ";", ":", " "];
.

method numbers
    // returns a list of numbers
    return ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
.

method alphabet
    //returns the alphabet in a list
    return ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];
.

method to_buffer
    arg list;
    
    // assumes this is a list of strings (for now)
    return buffer_from_strings(list);
.

method delete
    arg [args];
    
    return (> delete(@args) <);
.

method replace
    arg [args];
    
    return (> replace(@args) <);
.

method chop
    arg list, [count];
    
    // chops the last <count> elements off the list.
    // return [] if count is longer then the list.
    count = count || 1;
    return (| sublist(list, 1, listlen(list) - count) |) || [];
.

method length
    arg l;
    
    return listlen(l);
.

method union
    arg [args];
    
    return (> union(@args) <);
.

method sublist
    arg [args];
    
    return (> sublist(@args) <);
.

method del
    arg list, element;
    
    return (> setremove(list, element) <);
.

method add
    arg list, element;
    
    return (> setadd(list, element) <);
.