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

index b7962cd35b0b54e6634029c6bbb682e8371f7ffc..0a5dfb86cca615c7612336aba2deac7ca0289afd 100644 (file)
@@ -32,7 +32,7 @@
 #include "libpspp/message.h"
 #include "libpspp/str.h"
 #include "libpspp/string-array.h"
-#include "libpspp/string-map.h"
+#include "libpspp/stringi-map.h"
 #include "libpspp/stringi-set.h"
 
 #include "gl/c-ctype.h"
@@ -870,6 +870,7 @@ struct macro_expander
     const struct macro *macro;
     struct macro_tokens **args;
     enum segmenter_mode segmenter_mode;
+    struct stringi_map *vars;
     bool *expand;
   };
 
@@ -894,13 +895,12 @@ struct parse_macro_function_ctx
     int nesting_countdown;
     const struct macro_expander *me;
     const struct macro_expansion_stack *stack;
-    struct string_map *vars;
     bool *expand;
   };
 
 static void
 macro_expand (const struct macro_tokens *, int nesting_countdown,
-              const struct macro_expander *, struct string_map *vars,
+              const struct macro_expander *,
               const struct macro_expansion_stack *stack,
               bool *break_, struct macro_tokens *exp);
 
@@ -960,16 +960,13 @@ parse_function_arg (struct parse_macro_function_ctx *ctx,
           return 2;
         }
 
-      if (ctx->vars)
+      const char *value = stringi_map_find__ (ctx->me->vars,
+                                              token->string.string,
+                                              token->string.length);
+      if (value)
         {
-          const char *value = string_map_find__ (ctx->vars,
-                                                 token->string.string,
-                                                 token->string.length);
-          if (value)
-            {
-              ds_put_cstr (farg, value);
-              return 1;
-            }
+          ds_put_cstr (farg, value);
+          return 1;
         }
 
       struct parse_macro_function_ctx subctx = {
@@ -978,7 +975,6 @@ parse_function_arg (struct parse_macro_function_ctx *ctx,
         .nesting_countdown = ctx->nesting_countdown,
         .me = ctx->me,
         .stack = ctx->stack,
-        .vars = ctx->vars,
       };
       size_t subinput_consumed;
       if (expand_macro_function (&subctx, farg, &subinput_consumed))
@@ -1251,7 +1247,7 @@ 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->nesting_countdown - 1, ctx->me, ctx->vars,
+      macro_expand (&mts, ctx->nesting_countdown - 1, ctx->me,
                     &(struct macro_expansion_stack) {
                       .name = "!EVAL",
                       .next = ctx->stack,
@@ -1279,7 +1275,6 @@ struct expr_context
     int nesting_countdown;
     const struct macro_expander *me;
     const struct macro_expansion_stack *stack;
-    struct string_map *vars;
   };
 
 static char *macro_evaluate_or (const struct expr_context *ctx,
@@ -1324,7 +1319,6 @@ macro_evaluate_literal (const struct expr_context *ctx,
     .nesting_countdown = ctx->nesting_countdown,
     .me = ctx->me,
     .stack = ctx->stack,
-    .vars = ctx->vars,
   };
   struct string function_output = DS_EMPTY_INITIALIZER;
   size_t function_consumed = parse_function_arg (&fctx, 0, &function_output);
@@ -1520,14 +1514,12 @@ static char *
 macro_evaluate_expression (const struct macro_token **tokens, size_t n_tokens,
                            int nesting_countdown,
                            const struct macro_expander *me,
-                           const struct macro_expansion_stack *stack,
-                           struct string_map *vars)
+                           const struct macro_expansion_stack *stack)
 {
   const struct expr_context ctx = {
     .nesting_countdown = nesting_countdown,
     .me = me,
     .stack = stack,
-    .vars = vars,
   };
   return macro_evaluate_or (&ctx, tokens, *tokens + n_tokens);
 }
@@ -1537,10 +1529,10 @@ macro_evaluate_number (const struct macro_token **tokens, size_t n_tokens,
                        int nesting_countdown,
                        const struct macro_expander *me,
                        const struct macro_expansion_stack *stack,
-                       struct string_map *vars, double *number)
+                       double *number)
 {
   char *s = macro_evaluate_expression (tokens, n_tokens, nesting_countdown,
-                                       me, stack, vars);
+                                       me, stack);
   if (!s)
     return false;
 
@@ -1589,7 +1581,6 @@ static size_t
 macro_expand_if (const struct macro_token *tokens, size_t n_tokens,
                  int nesting_countdown, const struct macro_expander *me,
                  const struct macro_expansion_stack *stack,
-                 struct string_map *vars,
                  bool *break_, struct macro_tokens *exp)
 {
   const struct macro_token *p = tokens;
@@ -1600,7 +1591,7 @@ macro_expand_if (const struct macro_token *tokens, size_t n_tokens,
 
   p++;
   char *result = macro_evaluate_expression (&p, end - p, nesting_countdown,
-                                            me, stack, vars);
+                                            me, stack);
   if (!result)
     return 0;
   bool b = strcmp (result, "0");
@@ -1667,7 +1658,7 @@ macro_expand_if (const struct macro_token *tokens, size_t n_tokens,
         .mts = CONST_CAST (struct macro_token *, start),
         .n = n,
       };
-      macro_expand (&mts, nesting_countdown, me, vars,
+      macro_expand (&mts, nesting_countdown, me,
                     &(struct macro_expansion_stack) {
                       .name = "!IF",
                       .next = stack,
@@ -1680,8 +1671,7 @@ macro_expand_if (const struct macro_token *tokens, size_t n_tokens,
 static size_t
 macro_parse_let (const struct macro_token *tokens, size_t n_tokens,
                  int nesting_countdown, const struct macro_expander *me,
-                 const struct macro_expansion_stack *stack,
-                 struct string_map *vars)
+                 const struct macro_expansion_stack *stack)
 {
   const struct macro_token *p = tokens;
   const struct macro_token *end = tokens + n_tokens;
@@ -1717,11 +1707,11 @@ macro_parse_let (const struct macro_token *tokens, size_t n_tokens,
   p++;
 
   char *value = macro_evaluate_expression (&p, end - p, nesting_countdown,
-                                           me, stack, vars);
+                                           me, stack);
   if (!value)
     return 0;
 
-  string_map_replace_nocopy (vars, ss_xstrdup (var_name), value);
+  stringi_map_replace_nocopy (me->vars, ss_xstrdup (var_name), value);
   return p - tokens;
 }
 
@@ -1752,7 +1742,7 @@ static size_t
 macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
                  int nesting_countdown, const struct macro_expander *me,
                  const struct macro_expansion_stack *stack,
-                 struct string_map *vars, struct macro_tokens *exp)
+                 struct macro_tokens *exp)
 {
   const struct macro_token *p = tokens;
   const struct macro_token *end = tokens + n_tokens;
@@ -1786,7 +1776,7 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
     {
       p++;
       char *list = macro_evaluate_expression (&p, end - p, nesting_countdown,
-                                              me, &next_stack, vars);
+                                              me, &next_stack);
       if (!list)
         return 0;
 
@@ -1817,12 +1807,12 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
                            miterate);
               break;
             }
-          string_map_replace_nocopy (vars, ss_xstrdup (var_name),
-                                     ss_xstrdup (items.mts[i].representation));
+          stringi_map_replace_nocopy (me->vars, ss_xstrdup (var_name),
+                                      ss_xstrdup (items.mts[i].representation));
 
           bool break_ = false;
           macro_expand (&inner, nesting_countdown,
-                        me, vars, &next_stack, &break_, exp);
+                        me, &next_stack, &break_, exp);
           if (break_)
             break;
         }
@@ -1833,7 +1823,7 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
       p++;
       double first;
       if (!macro_evaluate_number (&p, end - p, nesting_countdown,
-                                  me, &next_stack, vars, &first))
+                                  me, &next_stack, &first))
         return 0;
 
       if (p >= end || p->token.type != T_MACRO_ID
@@ -1847,7 +1837,7 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
 
       double last;
       if (!macro_evaluate_number (&p, end - p, nesting_countdown,
-                                  me, &next_stack, vars, &last))
+                                  me, &next_stack, &last))
         return 0;
 
       double by = 1.0;
@@ -1856,7 +1846,7 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
         {
           p++;
           if (!macro_evaluate_number (&p, end - p, nesting_countdown,
-                                      me, &next_stack, vars, &by))
+                                      me, &next_stack, &by))
             return 0;
 
           if (by == 0.0)
@@ -1893,12 +1883,12 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
 
               char index_s[DBL_BUFSIZE_BOUND];
               c_dtoastr (index_s, sizeof index_s, 0, 0, index);
-              string_map_replace_nocopy (vars, ss_xstrdup (var_name),
-                                         xstrdup (index_s));
+              stringi_map_replace_nocopy (me->vars, ss_xstrdup (var_name),
+                                          xstrdup (index_s));
 
               bool break_ = false;
               macro_expand (&inner, nesting_countdown,
-                            me, vars, &next_stack, &break_, exp);
+                            me, &next_stack, &break_, exp);
               if (break_)
                 break;
             }
@@ -1916,7 +1906,7 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
 
 static void
 macro_expand (const struct macro_tokens *mts, int nesting_countdown,
-              const struct macro_expander *me, struct string_map *vars,
+              const struct macro_expander *me,
               const struct macro_expansion_stack *stack,
               bool *break_, struct macro_tokens *exp)
 {
@@ -1930,10 +1920,6 @@ macro_expand (const struct macro_tokens *mts, int nesting_countdown,
       return;
     }
 
-  struct string_map own_vars = STRING_MAP_INITIALIZER (own_vars);
-  if (!vars)
-    vars = &own_vars;
-
   for (size_t i = 0; i < mts->n && (!break_ || !*break_); i++)
     {
       const struct macro_token *mt = &mts->mts[i];
@@ -1947,18 +1933,21 @@ macro_expand (const struct macro_tokens *mts, int nesting_countdown,
               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);
                   struct macro_expander subme = {
                     .macros = me->macros,
                     .macro = NULL,
                     .args = NULL,
                     .segmenter_mode = me->segmenter_mode,
                     .expand = me->expand,
+                    .vars = &vars,
                   };
-                  macro_expand (arg, nesting_countdown, &subme, NULL,
+                  macro_expand (arg, nesting_countdown, &subme,
                                 &(struct macro_expansion_stack) {
                                   .name = param->name,
                                   .next = stack,
                                 }, break_, exp);
+                  stringi_map_destroy (&vars);
                 }
               else
                 for (size_t i = 0; i < arg->n; i++)
@@ -1977,18 +1966,21 @@ macro_expand (const struct macro_tokens *mts, int nesting_countdown,
                   const struct macro_tokens *arg = me->args[j];
                   if (*me->expand && param->expand_arg)
                     {
+                      struct stringi_map vars = STRINGI_MAP_INITIALIZER (vars);
                       struct macro_expander subme = {
                         .macros = me->macros,
                         .macro = NULL,
                         .args = NULL,
                         .segmenter_mode = me->segmenter_mode,
                         .expand = me->expand,
+                        .vars = &vars,
                       };
-                      macro_expand (arg, nesting_countdown, &subme, NULL,
+                      macro_expand (arg, nesting_countdown, &subme,
                                     &(struct macro_expansion_stack) {
                                       .name = "!*",
                                       .next = stack,
                                     }, break_, exp);
+                      stringi_map_destroy (&vars);
                     }
                   else
                     for (size_t k = 0; k < arg->n; k++)
@@ -2000,7 +1992,7 @@ macro_expand (const struct macro_tokens *mts, int nesting_countdown,
 
           size_t n = macro_expand_if (&mts->mts[i], mts->n - i,
                                       nesting_countdown, me, stack,
-                                      vars, break_, exp);
+                                      break_, exp);
           if (n > 0)
             {
               i += n - 1;
@@ -2008,10 +2000,11 @@ macro_expand (const struct macro_tokens *mts, int nesting_countdown,
             }
         }
 
-      if (token->type == T_MACRO_ID && vars)
+      if (token->type == T_MACRO_ID)
         {
-          const char *value = string_map_find__ (vars, token->string.string,
-                                                 token->string.length);
+          const char *value = stringi_map_find__ (me->vars,
+                                                  token->string.string,
+                                                  token->string.length);
           if (value)
             {
               macro_tokens_from_string__ (exp, ss_cstr (value),
@@ -2034,15 +2027,17 @@ macro_expand (const struct macro_tokens *mts, int nesting_countdown,
           if (retval > 0)
             {
               i += retval - 1;
+              struct stringi_map vars = STRINGI_MAP_INITIALIZER (vars);
               struct macro_expander subme = {
                 .macros = submc->macros,
                 .macro = submc->macro,
                 .args = submc->args,
                 .segmenter_mode = me->segmenter_mode,
                 .expand = me->expand,
+                .vars = &vars,
               };
               macro_expand (&submc->macro->body, nesting_countdown - 1,
-                            &subme, NULL, &(struct macro_expansion_stack) {
+                            &subme, &(struct macro_expansion_stack) {
                               .name = submc->macro->name,
                               .file_name = submc->macro->file_name,
                               .first_line = submc->macro->first_line,
@@ -2050,6 +2045,7 @@ macro_expand (const struct macro_tokens *mts, int nesting_countdown,
                               .next = stack,
                             }, break_, exp);
               macro_call_destroy (submc);
+              stringi_map_destroy (&vars);
               continue;
             }
 
@@ -2079,7 +2075,6 @@ macro_expand (const struct macro_tokens *mts, int nesting_countdown,
         .nesting_countdown = nesting_countdown,
         .me = me,
         .stack = stack,
-        .vars = vars,
       };
       struct string function_output = DS_EMPTY_INITIALIZER;
       size_t function_consumed;
@@ -2096,7 +2091,7 @@ macro_expand (const struct macro_tokens *mts, int nesting_countdown,
 
       size_t n = macro_parse_let (&mts->mts[i], mts->n - i,
                                   nesting_countdown,
-                                  me, stack, vars);
+                                  me, stack);
       if (n > 0)
         {
           i += n - 1;
@@ -2104,7 +2099,7 @@ macro_expand (const struct macro_tokens *mts, int nesting_countdown,
         }
 
       n = macro_expand_do (&mts->mts[i], mts->n - i, nesting_countdown, me,
-                           stack, vars, exp);
+                           stack, exp);
       if (n > 0)
         {
           i += n - 1;
@@ -2118,8 +2113,6 @@ macro_expand (const struct macro_tokens *mts, int nesting_countdown,
       else
         macro_tokens_add (exp, mt);
     }
-  if (vars == &own_vars)
-    string_map_destroy (&own_vars);
 }
 
 void
@@ -2129,12 +2122,14 @@ macro_call_expand (struct macro_call *mc, enum segmenter_mode segmenter_mode,
   assert (mc->state == MC_FINISHED);
 
   bool expand = true;
+  struct stringi_map vars = STRINGI_MAP_INITIALIZER (vars);
   struct macro_expander me = {
     .macros = mc->macros,
     .macro = mc->macro,
     .args = mc->args,
     .segmenter_mode = segmenter_mode,
     .expand = &expand,
+    .vars = &vars,
   };
 
   struct macro_expansion_stack stack = {
@@ -2144,6 +2139,8 @@ macro_call_expand (struct macro_call *mc, enum segmenter_mode segmenter_mode,
     .last_line = mc->macro->last_line,
   };
   macro_expand (&mc->macro->body, settings_get_mnest (),
-                &me, NULL, &stack, NULL, exp);
+                &me, &stack, NULL, exp);
+
+  stringi_map_destroy (&vars);
 }