diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-04-14 20:45:31 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-04-14 20:45:31 -0700 |
commit | 186a378870e2ceaad4cb167d0d24d4d0a3a9bb8e (patch) | |
tree | a94a21483c8cab57dcd14c998d054b9f76b5372d /cppawk-include | |
parent | 80e321e5615e72c3fed5a1986ef4b227d6d1f91f (diff) | |
download | cppawk-186a378870e2ceaad4cb167d0d24d4d0a3a9bb8e.tar.gz cppawk-186a378870e2ceaad4cb167d0d24d4d0a3a9bb8e.tar.bz2 cppawk-186a378870e2ceaad4cb167d0d24d4d0a3a9bb8e.zip |
cons: add ldiff, last and butlast.
Diffstat (limited to 'cppawk-include')
-rw-r--r-- | cppawk-include/cons-priv.h | 95 | ||||
-rw-r--r-- | cppawk-include/cons.h | 3 |
2 files changed, 93 insertions, 5 deletions
diff --git a/cppawk-include/cons-priv.h b/cppawk-include/cons-priv.h index 85bbe42..4c0a767 100644 --- a/cppawk-include/cons-priv.h +++ b/cppawk-include/cons-priv.h @@ -93,9 +93,13 @@ !__endp(__g(i)) && ((item = __car(__g(i))) || 1); \ __prog(__g(i) = __cdr(__g(i)), index++)) +#define __doconses(iter, list) \ + for (iter = list; __consp(iter); iter = __cdr(iter)) + #define __list_begin() "" #define __list_add(stk, item) __pack(stk, item) -#define __list_end(stk) __unpack(stk) +#define __list_end(stk) __unpack(stk, __nil) +#define __list_end_atom(stk, atom) __unpack(stk, atom) #define __bag_init_first(x) (x = __list_begin()) #define __bag_init_next(p, x) (p || 1) && __bag_init_first(x) @@ -417,11 +421,9 @@ function __pack(__stk, __item) return length(__item) ":" __item __stk } -function __unpack(__stk, - __col, __out) +function __unpack(__stk, __out, + __col) { - __out = __nil - while (__stk != "") { __col = match(__stk, /:/) if (__col == 0) @@ -701,6 +703,89 @@ function __nthcdr(__pos, __lst) return __lst } +function __ldiff(__main, __tail, + __out, __iter) +{ + if (__null(main)) + return nil + + if (__null(tail)) + return __main + + __out = __list_begin() + + __doconses (__iter, __main) { + if (__iter == __tail) + break + __out = __list_add(__out, __car(__iter)) + } + + if (__atom(__iter) && __iter != __tail) + return __list_end_atom(__out, __iter) + + return __list_end(__out) +} + +function __last(__lst, __n, + __circbuf, __i) +{ + if (!__present(__n)) + __n = 1 + else if (__n < 0) + __error("last: number argument %s must be non-negative", __n) + + if (__n == 0) { + __doconses (__iter, __lst) + ; // nothing + return __iter + } + + delete __circbuf + + __i = 0 + + __n++ + + __doconses (__iter, __lst) + __circbuf[__i++ % __n] = __iter + + __i = (__i + 1) % __n + + return (__i in __circbuf) ? __circbuf[__i] : __lst +} + +function __butlast(__lst, __n, + __circbuf, __i, __out) +{ + if (!__present(__n)) + __n = 1 + else if (__n < 0) + __error("butlast: number argument %s must be non-negative", __n) + + __out = __list_begin() + + if (__n == 0) { + __doconses (__iter, __lst) + __out = __list_add(__out, __car(__iter)) + return __list_end(__out) + } + + delete __circbuf + + __i = 0 + + __n++ + + __doconses (__iter, __lst) { + __circbuf[__i++ % __n] = __out + __out = __list_add(__out, __car(__iter)) + } + + __i = (__i + 1) % __n + + return (__i in __circbuf) ? __list_end(__circbuf[__i]) : __nil +} + function __iota(__from, __to, __step, __i, __out) { diff --git a/cppawk-include/cons.h b/cppawk-include/cons.h index 0087930..2cf579f 100644 --- a/cppawk-include/cons.h +++ b/cppawk-include/cons.h @@ -78,6 +78,9 @@ #define position __position #define nth __nth #define nthcdr __nthcdr +#define ldiff __ldiff +#define last __last +#define butlast __butlast #define iota __iota #define uniq __uniq #define mapcar __mapcar |