aboutsummaryrefslogtreecommitdiffstats
path: root/cppawk-include
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-04-14 20:45:31 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-04-14 20:45:31 -0700
commit186a378870e2ceaad4cb167d0d24d4d0a3a9bb8e (patch)
treea94a21483c8cab57dcd14c998d054b9f76b5372d /cppawk-include
parent80e321e5615e72c3fed5a1986ef4b227d6d1f91f (diff)
downloadcppawk-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.h95
-rw-r--r--cppawk-include/cons.h3
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