Move break_ into macro_expander.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 4 Jul 2021 21:35:38 +0000 (14:35 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 4 Jul 2021 21:35:38 +0000 (14:35 -0700)
src/language/lexer/macro.c

index 82e71bb93ec0eb85bd6dbe37767ded850f8a6a26..31bacec52d7ea29b4cc036ebb492ac24dfd55435 100644 (file)
@@ -872,6 +872,7 @@ struct macro_expander
     enum segmenter_mode segmenter_mode;
     struct stringi_map *vars;
     bool *expand;
+    bool *break_;
     int nesting_countdown;
   };
 
@@ -900,8 +901,8 @@ struct parse_macro_function_ctx
 
 static void
 macro_expand (const struct macro_tokens *, const struct macro_expander *,
-              const struct macro_expansion_stack *stack,
-              bool *break_, struct macro_tokens *exp);
+              const struct macro_expansion_stack *,
+              struct macro_tokens *);
 
 static bool
 expand_macro_function (struct parse_macro_function_ctx *ctx,
@@ -1245,11 +1246,13 @@ expand_macro_function (struct parse_macro_function_ctx *ctx,
       macro_tokens_from_string__ (&mts, ss_cstr (args.strings[0]),
                                   ctx->me->segmenter_mode, ctx->stack);
       struct macro_tokens exp = { .n = 0 };
-      macro_expand (&mts, ctx->me,
+      struct macro_expander subme = *ctx->me;
+      subme.break_ = NULL;
+      macro_expand (&mts, &subme,
                     &(struct macro_expansion_stack) {
                       .name = "!EVAL",
                       .next = ctx->stack,
-                    }, NULL, &exp);
+                    }, &exp);
       macro_tokens_to_representation (&exp, output, NULL, NULL);
       macro_tokens_uninit (&exp);
       macro_tokens_uninit (&mts);
@@ -1573,7 +1576,7 @@ static size_t
 macro_expand_if (const struct macro_token *tokens, size_t n_tokens,
                  const struct macro_expander *me,
                  const struct macro_expansion_stack *stack,
-                 bool *break_, struct macro_tokens *exp)
+                 struct macro_tokens *exp)
 {
   const struct macro_token *p = tokens;
   const struct macro_token *end = tokens + n_tokens;
@@ -1653,7 +1656,7 @@ macro_expand_if (const struct macro_token *tokens, size_t n_tokens,
                       .name = "!IF",
                       .next = stack,
                     },
-                    break_, exp);
+                    exp);
     }
   return (end_if + 1) - tokens;
 }
@@ -1784,7 +1787,12 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
         .mts = CONST_CAST (struct macro_token *, p),
         .n = do_end - p
       };
-      for (size_t i = 0; i < items.n; i++)
+
+      bool break_ = false;
+      struct macro_expander subme = *me;
+      subme.break_ = &break_;
+
+      for (size_t i = 0; i < items.n && !break_; i++)
         {
           if (i >= miterate)
             {
@@ -1798,10 +1806,7 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
           stringi_map_replace_nocopy (me->vars, ss_xstrdup (var_name),
                                       ss_xstrdup (items.mts[i].representation));
 
-          bool break_ = false;
-          macro_expand (&inner, me, &next_stack, &break_, exp);
-          if (break_)
-            break;
+          macro_expand (&inner, &subme, &next_stack, exp);
         }
       return do_end - tokens + 1;
     }
@@ -1848,11 +1853,15 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
         .n = do_end - p
       };
 
+      bool break_ = false;
+      struct macro_expander subme = *me;
+      subme.break_ = &break_;
+
       if ((by > 0 && first <= last) || (by < 0 && first >= last))
         {
           int i = 0;
           for (double index = first;
-               by > 0 ? (index <= last) : (index >= last);
+               by > 0 ? (index <= last) : (index >= last) && !break_;
                index += by)
             {
               if (i++ > miterate)
@@ -1870,10 +1879,7 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
               stringi_map_replace_nocopy (me->vars, ss_xstrdup (var_name),
                                           xstrdup (index_s));
 
-              bool break_ = false;
-              macro_expand (&inner, me, &next_stack, &break_, exp);
-              if (break_)
-                break;
+              macro_expand (&inner, &subme, &next_stack, exp);
             }
         }
 
@@ -1891,7 +1897,7 @@ static void
 macro_expand (const struct macro_tokens *mts,
               const struct macro_expander *me,
               const struct macro_expansion_stack *stack,
-              bool *break_, struct macro_tokens *exp)
+              struct macro_tokens *exp)
 {
   if (me->nesting_countdown <= 0)
     {
@@ -1903,7 +1909,7 @@ macro_expand (const struct macro_tokens *mts,
       return;
     }
 
-  for (size_t i = 0; i < mts->n && (!break_ || !*break_); i++)
+  for (size_t i = 0; i < mts->n && (!me->break_ || !*me->break_); i++)
     {
       const struct macro_token *mt = &mts->mts[i];
       const struct token *token = &mt->token;
@@ -1913,7 +1919,8 @@ macro_expand (const struct macro_tokens *mts,
             me->macro, token->string);
           if (param)
             {
-              const struct macro_tokens *arg = me->args[param - me->macro->params];
+              const struct macro_tokens *arg
+                = me->args[param - me->macro->params];
               if (*me->expand && param->expand_arg)
                 {
                   struct stringi_map vars = STRINGI_MAP_INITIALIZER (vars);
@@ -1923,13 +1930,14 @@ macro_expand (const struct macro_tokens *mts,
                     .args = NULL,
                     .segmenter_mode = me->segmenter_mode,
                     .expand = me->expand,
+                    .break_ = NULL,
                     .vars = &vars,
                     .nesting_countdown = me->nesting_countdown,
                   };
                   macro_expand (arg, &subme, &(struct macro_expansion_stack) {
                                   .name = param->name,
                                   .next = stack,
-                                }, break_, exp);
+                                }, exp);
                   stringi_map_destroy (&vars);
                 }
               else
@@ -1956,6 +1964,7 @@ macro_expand (const struct macro_tokens *mts,
                         .args = NULL,
                         .segmenter_mode = me->segmenter_mode,
                         .expand = me->expand,
+                        .break_ = NULL,
                         .vars = &vars,
                         .nesting_countdown = me->nesting_countdown,
                       };
@@ -1963,7 +1972,7 @@ macro_expand (const struct macro_tokens *mts,
                                     &(struct macro_expansion_stack) {
                                       .name = "!*",
                                       .next = stack,
-                                    }, break_, exp);
+                                    }, exp);
                       stringi_map_destroy (&vars);
                     }
                   else
@@ -1975,7 +1984,7 @@ macro_expand (const struct macro_tokens *mts,
             }
 
           size_t n = macro_expand_if (&mts->mts[i], mts->n - i, me, stack,
-                                      break_, exp);
+                                      exp);
           if (n > 0)
             {
               i += n - 1;
@@ -2017,6 +2026,7 @@ macro_expand (const struct macro_tokens *mts,
                 .args = submc->args,
                 .segmenter_mode = me->segmenter_mode,
                 .expand = me->expand,
+                .break_ = NULL,
                 .vars = &vars,
                 .nesting_countdown = me->nesting_countdown - 1,
               };
@@ -2027,7 +2037,7 @@ macro_expand (const struct macro_tokens *mts,
                               .first_line = submc->macro->first_line,
                               .last_line = submc->macro->last_line,
                               .next = stack,
-                            }, break_, exp);
+                            }, exp);
               macro_call_destroy (submc);
               stringi_map_destroy (&vars);
               continue;
@@ -2044,11 +2054,11 @@ macro_expand (const struct macro_tokens *mts,
 
       if (ss_equals_case (token->string, ss_cstr ("!break")))
         {
-          if (!break_)
+          if (!me->break_)
             macro_error (stack, mt, _("!BREAK outside !DO."));
           else
             {
-              *break_ = true;
+              *me->break_ = true;
               break;
             }
         }
@@ -2109,6 +2119,7 @@ macro_call_expand (struct macro_call *mc, enum segmenter_mode segmenter_mode,
     .args = mc->args,
     .segmenter_mode = segmenter_mode,
     .expand = &expand,
+    .break_ = NULL,
     .vars = &vars,
     .nesting_countdown = settings_get_mnest (),
   };
@@ -2119,7 +2130,7 @@ macro_call_expand (struct macro_call *mc, enum segmenter_mode segmenter_mode,
     .first_line = mc->macro->first_line,
     .last_line = mc->macro->last_line,
   };
-  macro_expand (&mc->macro->body, &me, &stack, NULL, exp);
+  macro_expand (&mc->macro->body, &me, &stack, exp);
 
   stringi_map_destroy (&vars);
 }