summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2023-03-12 13:30:15 +0100
committerTyge Løvset <[email protected]>2023-03-12 13:30:15 +0100
commitc9be5f66a481bd040b36a25314f6589dd939daa5 (patch)
treed71cc01f17fabc526a72219c225b015b4130c8b3
parent1ac8bb4ff664baa838b44ed6bf62225766f000c5 (diff)
downloadSTC-modified-c9be5f66a481bd040b36a25314f6589dd939daa5.tar.gz
STC-modified-c9be5f66a481bd040b36a25314f6589dd939daa5.zip
Safer state machine in coroutine.h (internal).
Removed c_forwhile() macro. Redundant, use c_forfilter(). Removed find and eq in cspan (use general c_find_if() instead for search).
-rw-r--r--README.md1
-rw-r--r--docs/ccommon_api.md16
-rw-r--r--include/stc/algo/coroutine.h9
-rw-r--r--include/stc/algo/crange.h6
-rw-r--r--include/stc/algo/filter.h13
-rw-r--r--include/stc/ccommon.h5
-rw-r--r--include/stc/cspan.h21
-rw-r--r--include/stc/priv/altnames.h1
-rw-r--r--misc/examples/forfilter.c36
-rw-r--r--misc/examples/forloops.c20
-rw-r--r--misc/examples/list.c11
-rw-r--r--misc/examples/prime.c6
-rw-r--r--src/checkauto.l1
13 files changed, 66 insertions, 80 deletions
diff --git a/README.md b/README.md
index f74ee916..c214413b 100644
--- a/README.md
+++ b/README.md
@@ -547,7 +547,6 @@ STC is generally very memory efficient. Type sizes:
## API changes summary V4.0
- Added **cregex** with documentation - powerful regular expressions.
- Added: `c_forfilter`: container iteration with "piped" filtering using && operator. 4 built-in filters.
-- Added: `c_forwhile`: *c_foreach* container iteration with extra predicate.
- Added: **crange**: number generator type, which can be iterated (e.g. with *c_forfilter*).
- Added back **coption** - command line argument parsing.
- New + renamed loop iteration/scope macros:
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md
index 8dcb2ff3..ff75d83d 100644
--- a/docs/ccommon_api.md
+++ b/docs/ccommon_api.md
@@ -176,7 +176,7 @@ Iterate containers with stop-criteria and chained range filtering.
| Usage | Description |
|:----------------------------------------------------|:---------------------------------------|
| `c_forfilter (it, ctype, container, filter)` | Filter out items in chain with && |
-| `c_forwhile (it, ctype, start, pred)` | Iterate until pred is false |
+| `c_forfilter_it (it, ctype, startit, filter)` | Filter from startit position |
| Built-in filter | Description |
|:----------------------------------|:-------------------------------------|
@@ -203,10 +203,10 @@ int main() {
crange R = crange_make(1001, INT32_MAX, 2);
c_forfilter (i, crange, R,
- isPrime(*i.ref)
- && c_flt_skip(i, 24)
- && c_flt_count(i) % 15 == 1
- && c_flt_take(i, 10))
+ isPrime(*i.ref) &&
+ c_flt_skip(i, 24) &&
+ c_flt_count(i) % 15 == 1 &&
+ c_flt_take(i, 10))
printf(" %lld", *i.ref);
puts("");
}
@@ -237,9 +237,9 @@ c_forfilter (i, crange, r1, isPrime(*i.ref))
// 2. The 11 first primes:
printf("2");
-c_forfilter (i, crange, crange_obj(3, INT64_MAX, 2)
- , isPrime(*i.ref)
- && c_flt_take(10))
+c_forfilter (i, crange, crange_obj(3, INT64_MAX, 2),
+ isPrime(*i.ref) &&
+ c_flt_take(10))
printf(" %lld", *i.ref);
// 2 3 5 7 11 13 17 19 23 29 31
```
diff --git a/include/stc/algo/coroutine.h b/include/stc/algo/coroutine.h
index 1c849d49..1dd82720 100644
--- a/include/stc/algo/coroutine.h
+++ b/include/stc/algo/coroutine.h
@@ -68,12 +68,11 @@ enum {
#define cco_begin(ctx) \
int *_state = &(ctx)->cco_state; \
switch (*_state) { \
- case cco_state_done: \
case 0:
#define cco_end(retval) \
*_state = cco_state_done; break; \
- default: goto _cco_final_; /* never happens */ \
+ default: assert(0); goto _cco_final_; \
} \
return retval
@@ -109,4 +108,10 @@ enum {
if (*_state > 0) *_state = cco_state_final; \
} while (0)
+#define cco_reset(ctx) \
+ do { \
+ int* _state = &(ctx)->cco_state; \
+ if (*_state == cco_state_final) *_state = 0; \
+ } while (0)
+
#endif
diff --git a/include/stc/algo/crange.h b/include/stc/algo/crange.h
index 4fc957b6..ca06c258 100644
--- a/include/stc/algo/crange.h
+++ b/include/stc/algo/crange.h
@@ -34,9 +34,9 @@ int main()
// use a temporary crange object.
int a = 100, b = INT32_MAX;
- c_forfilter (i, crange, crange_obj(a, b, 8)
- , i.index > 10
- && c_flt_take(i, 3))
+ c_forfilter (i, crange, crange_obj(a, b, 8),
+ c_flt_skip(i, 10) &&
+ c_flt_take(i, 3))
printf(" %lld", *i.ref);
puts("");
}
diff --git a/include/stc/algo/filter.h b/include/stc/algo/filter.h
index a5e11b64..5e3125b1 100644
--- a/include/stc/algo/filter.h
+++ b/include/stc/algo/filter.h
@@ -35,10 +35,10 @@ int main()
printf(" %d", *i.ref);
puts("");
- c_forfilter (i, cstack_int, stk
- , c_flt_skipwhile(i, *i.ref < 3)
- && (*i.ref & 1) == 0 // even only
- && c_flt_take(i, 2)) // break after 2
+ c_forfilter (i, cstack_int, stk,
+ c_flt_skipwhile(i, *i.ref < 3) &&
+ (*i.ref & 1) == 0 && // even only
+ c_flt_take(i, 2)) // break after 2
printf(" %d", *i.ref);
puts("");
}
@@ -57,8 +57,11 @@ int main()
#define c_flt_last(i) (i).b.s1[(i).b.s1top - 1]
#define c_forfilter(i, C, cnt, filter) \
+ c_forfilter_it(i, C, C##_begin(&cnt), filter)
+
+#define c_forfilter_it(i, C, start, filter) \
for (struct {struct _flt_base b; C##_iter it; C##_value *ref;} \
- i = {.it=C##_begin(&cnt), .ref=i.it.ref} ; !i.b.done & (i.it.ref != NULL) ; \
+ i = {.it=start, .ref=i.it.ref} ; !i.b.done & (i.it.ref != NULL) ; \
C##_next(&i.it), i.ref = i.it.ref, i.b.s1top=0, i.b.s2top=0) \
if (!(filter)) ; else
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h
index de230910..33446982 100644
--- a/include/stc/ccommon.h
+++ b/include/stc/ccommon.h
@@ -178,11 +178,6 @@ STC_INLINE char* cstrnstrn(const char *str, const char *needle,
for (C##_iter it = start, *_endref = (C##_iter*)(finish).ref \
; it.ref != (C##_value*)_endref; C##_next(&it))
-#define c_forwhile(i, C, cnt, cond) \
- for (struct {C##_iter it; C##_value *ref; intptr_t index;} \
- i = {.it=C##_begin(&cnt), .ref=i.it.ref}; i.it.ref && (cond) \
- ; C##_next(&i.it), i.ref = i.it.ref, ++i.index)
-
#define c_forpair(key, val, C, cnt) /* structured binding */ \
for (struct {C##_iter it; const C##_key* key; C##_mapped* val;} _ = {.it=C##_begin(&cnt)} \
; _.it.ref && (_.key = &_.it.ref->first, _.val = &_.it.ref->second) \
diff --git a/include/stc/cspan.h b/include/stc/cspan.h
index 00313540..d5482200 100644
--- a/include/stc/cspan.h
+++ b/include/stc/cspan.h
@@ -48,9 +48,9 @@ int demo2() {
puts("");
c_forfilter (i, Intspan, span,
- , c_flt_skipwhile(i, *i.ref < 25)
- && (*i.ref & 1) == 0 // even only
- && c_flt_take(i, 2)) // break after 2
+ c_flt_skipwhile(i, *i.ref < 25) &&
+ (*i.ref & 1) == 0 && // even only
+ c_flt_take(i, 2)) // break after 2
printf(" %d", *i.ref);
puts("");
}
@@ -65,9 +65,6 @@ int demo2() {
using_cspan_3(Self, T, 1)
#define using_cspan_3(Self, T, RANK) \
- using_cspan_4(Self, T, RANK, c_default_eq)
-
-#define using_cspan_4(Self, T, RANK, i_eq) \
typedef T Self##_value; typedef T Self##_raw; \
typedef struct { \
Self##_value *data; \
@@ -99,18 +96,6 @@ int demo2() {
it->ref += _cspan_next##RANK(RANK, it->pos, it->_s->shape, it->_s->stride.d); \
if (it->pos[0] == it->_s->shape[0]) it->ref = NULL; \
} \
- STC_INLINE bool Self##_eq(const Self* x, const Self* y) { \
- if (memcmp(x->shape, y->shape, sizeof x->shape)) return false; \
- Self##_iter i = Self##_begin(x), j = Self##_begin(y); \
- for (; i.ref; Self##_next(&i), Self##_next(&j)) \
- if (!(i_eq(i.ref, j.ref))) return false; \
- return true; \
- } \
- STC_INLINE Self##_iter Self##_find(const Self* self, Self##_raw raw) { \
- Self##_iter i = Self##_begin(self); \
- for (; i.ref; Self##_next(&i)) if (i_eq(i.ref, &raw)) return i; \
- return i; \
- } \
struct stc_nostruct
#define using_cspan2(Self, T) using_cspan_3(Self, T, 1); using_cspan_3(Self##2, T, 2)
diff --git a/include/stc/priv/altnames.h b/include/stc/priv/altnames.h
index b10c7a11..8fa326f1 100644
--- a/include/stc/priv/altnames.h
+++ b/include/stc/priv/altnames.h
@@ -23,7 +23,6 @@
#define c_FORLIST c_forlist
#define c_FORRANGE c_forrange
#define c_FOREACH c_foreach
-#define c_FORWHILE c_forwhile
#define c_FORPAIR c_forpair
#define c_FORFILTER c_forfilter
#define c_FORMATCH c_formatch
diff --git a/misc/examples/forfilter.c b/misc/examples/forfilter.c
index 2be975a6..cd6d59cc 100644
--- a/misc/examples/forfilter.c
+++ b/misc/examples/forfilter.c
@@ -32,13 +32,13 @@ void demo1(void)
puts("");
int res, sum = 0;
- c_forfilter (i, IVec, vec
- , c_flt_skipwhile(i, *i.ref != 80)
- && c_flt_skip(i, 1)
- && c_flt_skipwhile(i, *i.ref != 80)
- && flt_isEven(i)
- && flt_skipValue(i, 80)
- && c_flt_take(i, 5) // short-circuit
+ c_forfilter (i, IVec, vec,
+ c_flt_skipwhile(i, *i.ref != 80) &&
+ c_flt_skip(i, 1) &&
+ c_flt_skipwhile(i, *i.ref != 80) &&
+ flt_isEven(i) &&
+ flt_skipValue(i, 80) &&
+ c_flt_take(i, 5) // short-circuit
){
sum += res = flt_square(i);
printf(" %d", res);
@@ -65,10 +65,10 @@ void demo2(void)
c_auto (IVec, vector) {
puts("demo2:");
crange R = crange_make(INT64_MAX);
- c_forfilter (x, crange, R
- , c_flt_skipwhile(x, *x.ref != 11)
- && *x.ref % 2 != 0
- && c_flt_take(x, 5))
+ c_forfilter (x, crange, R,
+ c_flt_skipwhile(x, *x.ref != 11) &&
+ *x.ref % 2 != 0 &&
+ c_flt_take(x, 5))
IVec_push(&vector, (int)(*x.ref * *x.ref));
c_foreach (x, IVec, vector)
printf(" %d", *x.ref);
@@ -97,7 +97,7 @@ void demo3(void)
SVec_push(&words, *w.ref);
c_forfilter (w, SVec, words,
- csview_contains(*w.ref, "i"))
+ csview_contains(*w.ref, "i"))
SVec_push(&words_containing_i, *w.ref);
puts("demo3:");
@@ -127,12 +127,12 @@ void demo5(void)
#define flt_mid_decade(i) ((*i.ref % 10) != 0)
puts("demo5:");
crange R = crange_make(1963, INT32_MAX);
- c_forfilter (i, crange, R
- , c_flt_skip(i,15)
- && c_flt_skipwhile(i, flt_mid_decade(i))
- && c_flt_skip(i,30)
- && flt_even(i)
- && c_flt_take(i,5))
+ c_forfilter (i, crange, R,
+ c_flt_skip(i,15) &&
+ c_flt_skipwhile(i, flt_mid_decade(i)) &&
+ c_flt_skip(i,30) &&
+ flt_even(i) &&
+ c_flt_take(i,5))
printf(" %lld", *i.ref);
puts("");
}
diff --git a/misc/examples/forloops.c b/misc/examples/forloops.c
index 707e8285..144ec637 100644
--- a/misc/examples/forloops.c
+++ b/misc/examples/forloops.c
@@ -60,20 +60,20 @@ int main()
c_forpair (key, val, IMap, map)
printf(" (%d %d)", *_.key, *_.val);
- puts("\n\nc_forwhile:");
- c_forwhile (i, IVec, IVec_begin(&vec), i.index < 3)
+ puts("\n\nc_forfilter 1:");
+ c_forfilter (i, IVec, vec, c_flt_take(i, 3))
printf(" %d", *i.ref);
#define isOdd(i) (*i.ref & 1)
- puts("\n\nc_forfilter:");
- c_forfilter (i, IVec, vec
- , c_flt_skipwhile(i, *i.ref != 65)
- && c_flt_takewhile(i, *i.ref != 280)
- && c_flt_skipwhile(i, isOdd(i))
- && isOdd(i)
- && c_flt_skip(i, 2)
- && c_flt_take(i, 2))
+ puts("\n\nc_forfilter 2:");
+ c_forfilter (i, IVec, vec,
+ c_flt_skipwhile(i, *i.ref != 65) &&
+ c_flt_takewhile(i, *i.ref != 280) &&
+ c_flt_skipwhile(i, isOdd(i)) &&
+ isOdd(i) &&
+ c_flt_skip(i, 2) &&
+ c_flt_take(i, 2))
printf(" %d", *i.ref);
puts("");
// 189
diff --git a/misc/examples/list.c b/misc/examples/list.c
index b345bd16..c12d67e9 100644
--- a/misc/examples/list.c
+++ b/misc/examples/list.c
@@ -1,11 +1,12 @@
#include <stdio.h>
#include <time.h>
+#include <stc/calgo.h>
+#include <stc/crandom.h>
#define i_val double
#define i_tag fx
#define i_extern // include sort function
#include <stc/clist.h>
-#include <stc/crandom.h>
int main() {
const int n = 1000000;
@@ -24,8 +25,8 @@ int main() {
sum += *i.ref;
printf("sum %f\n\n", sum);
- c_forwhile (i, clist_fx, clist_fx_begin(&list), i.index < 10)
- printf("%8d: %10f\n", (int)i.index, *i.ref);
+ c_forfilter (i, clist_fx, list, c_flt_take(i, 10))
+ printf("%8d: %10f\n", c_flt_last(i), *i.ref);
puts("sort");
clist_fx_sort(&list); // mergesort O(n*log n)
@@ -37,8 +38,8 @@ int main() {
last = *i.ref;
}
- c_forwhile (i, clist_fx, clist_fx_begin(&list), i.index < 10)
- printf("%8d: %10f\n", (int)i.index, *i.ref);
+ c_forfilter (i, clist_fx, list, c_flt_take(i, 10))
+ printf("%8d: %10f\n", c_flt_last(i), *i.ref);
puts("");
clist_fx_clear(&list);
diff --git a/misc/examples/prime.c b/misc/examples/prime.c
index 59ee336c..16a59774 100644
--- a/misc/examples/prime.c
+++ b/misc/examples/prime.c
@@ -43,9 +43,9 @@ int main(void)
puts("Show the last 50 primes using a temporary crange generator:");
crange R = crange_make(n - 1, 0, -2);
- c_forfilter (i, crange, R
- , cbits_test(&primes, *i.ref>>1)
- && c_flt_take(i, 50)) {
+ c_forfilter (i, crange, R,
+ cbits_test(&primes, *i.ref>>1) &&
+ c_flt_take(i, 50)) {
printf("%lld ", *i.ref);
if (c_flt_last(i) % 10 == 0) puts("");
}
diff --git a/src/checkauto.l b/src/checkauto.l
index ab71403c..349da70b 100644
--- a/src/checkauto.l
+++ b/src/checkauto.l
@@ -35,7 +35,6 @@ c_foreach |
c_forpair |
c_forrange |
c_forfilter |
-c_forwhile |
c_formatch |
c_fortoken |
for |