@@@ major overhaul, new primitives
[mLib] / utils / t / control-test.c
index 51a9adf..d69572b 100644 (file)
@@ -53,27 +53,47 @@ static void check_step(int s, const char *where)
 static void laststep(int s, const char *where)
   { check_step(s, where); step = 0; }
 
+#define FORELSE(head)                                                  \
+                       MC_GOTO(top)                                    \
+  MC_LABEL(out)                MC_ACT({ ; })                                   \
+  MC_LABEL(top)                ALLOWELSE(els)                                  \
+                       AFTER(outer, { GOELSE(els); })                  \
+                       for (head)                                      \
+                         WRAP(inner, { ; },                            \
+                                     { ; },                            \
+                                     { MC_GOTO(out); })
+
 #define FOR_FIZZBUZZ(var, base, limit)                                 \
-       FIRSTBRANCH(fizzbuzz0) GOBRANCH(fizzbuzz2);                     \
-       MIDBRANCH(fizzbuzz1) ;                                          \
-       LASTBRANCH(fizzbuzz2)                                           \
-       DECL(fizzbuzz3, int _i = base COMMA _limit = limit)             \
-         for (; _i < _limit; _i++)                                     \
-           DECL(fizzbuzz4, char _buf[24])                              \
-           DECL(fizzbuzz5, const char *var)                            \
-           WRAP(fizzbuzz6, {                                           \
-             switch (_i%15) {                                          \
-               case 0: var = "fizzbuzz"; break;                        \
-               case 3: case 6: case 9: case 12: var = "fizz"; break;   \
-               case 5: case 10: var = "buzz"; break;                   \
-               default: sprintf(_buf, "%d", _i); var = _buf; break;    \
-             }                                                         \
-           },                                                          \
-           { ; },                                                      \
-           { GOBRANCH(fizzbuzz1); })
+                       MC_GOTO(top)                                    \
+  MC_LABEL(out)                MC_ACT({ ; })                                   \
+  MC_LABEL(top)                DECL(bounds,                                    \
+                            int _i = base COMMA _limit = limit)        \
+                       for (; _i < _limit; _i++)                       \
+                         DECL(buf, char _buf[24])                      \
+                         DECL(var, const char *var)                    \
+                         WRAP(wrap, {                                  \
+                           switch (_i%15) {                            \
+                             case 0:                                   \
+                               var = "fizzbuzz";                       \
+                               break;                                  \
+                             case 3: case 6: case 9: case 12:          \
+                               var = "fizz";                           \
+                               break;                                  \
+                             case 5: case 10:                          \
+                               var = "buzz";                           \
+                               break;                                  \
+                             default:                                  \
+                               sprintf(_buf, "%d", _i); var = _buf;    \
+                               break;                                  \
+                           }                                           \
+                         },                                            \
+                         { ; },                                        \
+                         { MC_GOTO(out); })
 
 int main(void)
 {
+  int i;
+
   BEFORE(before0, { STEP(0); }) STEP(1);
   AFTER(after0, { STEP(3); }) STEP(2);
   LASTSTEP(4);
@@ -89,9 +109,43 @@ int main(void)
   }
   LASTSTEP(3);
 
+  FORELSE (i = 0; i < 10; i++) {
+    STEP(i);
+    if (i == 7) break;
+  } else
+    MISSTEP;
+  LASTSTEP(8);
+
+  FORELSE (i = 0; i < 10; i++) {
+    STEP(i);
+    if (i == 12) break;
+  } else
+    STEP(10);
+  LASTSTEP(11);
+
+#define TEST                                                           \
+                       MC_ACT({ STEP(0); MC_GOTO(in_plain); })         \
+  MC_LABEL(done_plain) MC_ACT({ STEP(5); GOELSE(elsie); })             \
+  MC_LABEL(in_plain)   WRAP(outer_wrap, { STEP(1); },                  \
+                                        { STEP(7); },                  \
+                                        { MISSTEP; })                  \
+                       ALLOWELSE(elsie)                                \
+                         WRAP(inner_wrap, { STEP(2); },                \
+                                          { STEP(4);                   \
+                                            MC_GOTO(done_plain); },    \
+                                          { MISSTEP; })                \
+                         STEP(3);                                      \
+                       else                                            \
+                         STEP(6);                                      \
+                       LASTSTEP(8);
+  TEST
+#undef TEST
+
+#if __STDC_VERSION__ >= 199901 || defined(__cplusplus)
   STEP(0);
-  DECL(decl0, int i = 1) STEP(i);
+  DECL(decl0, int j = 1) STEP(j);
   LASTSTEP(2);
+#endif
 
   FOR_FIZZBUZZ(fb, 19, 32) printf("%s\n", fb);