• cppawk: parallel/product iteration syntax.

    From Kaz Kylheku@480-992-1380@kylheku.com to comp.lang.awk on Wed Mar 30 19:18:44 2022
    From Newsgroup: comp.lang.awk

    I didn't suspect C99 preprocessing would be up to this, but, lo and behold:

    ./cppawk '
    #include <loop.h>

    BEGIN {
    $0 = "o p q r s t u v w x y z" # set fields

    split("! @ # $ % ^ & * ( )", arr) # init array

    loop (range(i, 1, 10),
    from(x, 5),
    from_step(y, 100, 5),
    str(j, ch, "abcdefghijklmn"),
    fields(f),
    keys(k, arr))
    {
    print i, x, y, ch, f, k, arr[k]
    }
    }'
    1 5 100 a o 1 !
    2 6 105 a p 2 @
    3 7 110 b q 3 #
    4 8 115 c r 4 $
    5 9 120 d s 5 %
    6 10 125 e t 6 ^
    7 11 130 f u 7 &
    8 12 135 g v 8 *
    9 13 140 h w 9 (
    10 14 145 i x 10 )

    Cross-producing loop:

    $ ./cppawk '
    #include <loop.h>

    BEGIN {
    $0 = "a b c" # set fields

    split("X Y", arr) # init array

    loop_cross (fields(f),
    keys(k, arr),
    range(i, 1, 3))
    {
    print f, arr[k], i
    }
    }'
    a X 1
    a X 2
    a X 3
    a Y 1
    a Y 2
    a Y 3
    b X 1
    b X 2
    b X 3
    b Y 1
    b Y 2
    b Y 3
    c X 1
    c X 2
    c X 3
    c Y 1
    c Y 2
    c Y 3

    The loop clauses are user-definable, and easily so; I'm going to have documentation on exactly how to do that.

    For instance, the clause range(index, from, to) is entirely defined in
    these three simple lines of code in <loop.h>, which are entirely
    isolated from the complexity of loop and loop_cross:

    #define __init_range(idx, from, to) (idx = (from))
    #define __test_range(idx, from, to) (idx <= (to))
    #define __step_range(idx, from, to) (idx++)
    --- Synchronet 3.19c-Linux NewsLink 1.113
  • From Kaz Kylheku@480-992-1380@kylheku.com to comp.lang.awk on Wed Mar 30 21:38:03 2022
    From Newsgroup: comp.lang.awk

    On 2022-03-30, Kaz Kylheku <480-992-1380@kylheku.com> wrote:
    The loop clauses are user-definable, and easily so; I'm going to have documentation on exactly how to do that.

    For instance, the clause range(index, from, to) is entirely defined in
    these three simple lines of code in <loop.h>, which are entirely
    isolated from the complexity of loop and loop_cross:

    #define __init_range(idx, from, to) (idx = (from))
    #define __test_range(idx, from, to) (idx <= (to))
    #define __step_range(idx, from, to) (idx++)

    E.g. let's make a clause "sfixes"
    that loops over string suffixes, e.g "abc" "bc" "c"

    ./cppawk '
    #include <loop.h>

    // user-defined "sfixes" loop clause

    #define __init_sfixes(idx, ch, str) (idx = 1)
    #define __test_sfixes(idx, ch, str) (idx <= length(str) && \
    ((ch = substr(str, idx)) || 1))
    #define __step_sfixes(idx, ch, str) (idx++)

    // use it

    BEGIN {
    loop (sfixes(i, sf, "abcd"))
    print i, sf
    }'
    1 abcd
    2 bcd
    3 cd
    4 d

    Or how about controling the length of the string slices.

    No, how about completely controlling the string slice and just binding
    the variable:

    No, let's first make a general clause "let" to set a arbitrary variable
    on each iteration of the loop.


    ./cppawk '
    #include <loop.h>

    // user-defined "let" loop clause

    #define __init_let(var, expr) 0
    #define __test_let(var, expr) ((var = (expr)) || 1)
    #define __step_let(var, expr) 0

    BEGIN {
    loop (range(i, 1, 10),
    range_step(j, 1, 10, 2),
    let(ch, substr("abcdefghijklmn", i, j)))
    {
    print i, j, ch
    }
    }
    '
    1 1 a
    2 3 bcd
    3 5 cdefg
    4 7 defghij
    5 9 efghijklm


    How about general "first_then_until" stepping clause.

    ./cppawk '
    #include <loop.h>

    // user-defined "first_then_until" loop clause

    #define __init_first_then_until(var, first, then, until) (var = (first)) #define __test_first_then_until(var, first, then, until) (!(until))
    #define __step_first_then_until(var, first, then, until) (var = (then))

    BEGIN {
    loop (first_then_until(i, 1, i * 2, i >= 60),
    first_then_until(s, "x", s s, 0))
    {
    print i, s
    }
    }
    '
    1 x
    2 xx
    4 xxxx
    8 xxxxxxxx
    16 xxxxxxxxxxxxxxxx
    32 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    --- Synchronet 3.19c-Linux NewsLink 1.113
  • From Kaz Kylheku@480-992-1380@kylheku.com to comp.lang.awk on Wed Mar 30 23:19:57 2022
    From Newsgroup: comp.lang.awk

    On 2022-03-30, Kaz Kylheku <480-992-1380@kylheku.com> wrote:
    BEGIN {
    loop (first_then_until(i, 1, i * 2, i >= 60),
    first_then_until(s, "x", s s, 0))
    {
    print i, s
    }
    }
    '
    1 x
    2 xx
    4 xxxx
    8 xxxxxxxx
    16 xxxxxxxxxxxxxxxx
    32 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    List collection. (Poor implementation: the framework will have to
    adjusted to make it possible in a better way):

    ./cppawk '
    #include <loop.h>
    #include <cons.h> // Lisp-inspired data structure framework.

    #define __init_collect(tmp, var, expr) (tmp = list_begin())
    #define __test_collect(tmp, var, expr) ((tmp = list_add(tmp, expr)) && \
    (var = list_end(tmp))) || 1
    #define __step_collect(tmp, var, expr) 1

    BEGIN {
    loop (range(i, 1, 10),
    collect(tmp, lst, i))
    {
    print i
    }

    print sexp(lst)

    dolist (i, lst)
    print i, i * 10
    }
    '
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    (1 2 3 4 5 6 7 8 9 10)
    1 10
    2 20
    3 30
    4 40
    5 50
    6 60
    7 70
    8 80
    9 90
    10 100
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

    --- Synchronet 3.19c-Linux NewsLink 1.113