work on macro function parsing
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 4 Jul 2021 23:20:57 +0000 (16:20 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 4 Jul 2021 23:20:57 +0000 (16:20 -0700)
src/language/lexer/macro.c

index 0d74bae00ce50c5d5d42dcf0fd3432966dd72eee..9ae83d1437b43d591bf4901222fc36a7c29cfd08 100644 (file)
@@ -882,21 +882,6 @@ struct macro_expander
     struct macro_tokens **args;
   };
 
-/* Each argument to a macro function is one of:
-
-       - A quoted string or other single literal token.
-
-       - An argument to the macro being expanded, e.g. !1 or a named argument.
-
-       - !*.
-
-       - A function invocation.
-
-   Each function invocation yields a character sequence to be turned into a
-   sequence of tokens.  The case where that character sequence is a single
-   quoted string is an important special case.
-*/
-
 static void
 macro_expand (const struct macro_tokens *, const struct macro_expander *,
               struct macro_tokens *);
@@ -906,23 +891,39 @@ expand_macro_function (const struct macro_expander *me,
                        const struct macro_token *input, size_t n_input,
                        struct string *output, size_t *input_consumed);
 
-/* Returns true if the pair of tokens starting at offset OFS within MTS are !*,
-   false otherwise. */
+/* Returns true if the N tokens within MTS start with !*, false otherwise. */
 static bool
-is_bang_star (const struct macro_token *mts, size_t n, size_t ofs)
+is_bang_star (const struct macro_token *mts, size_t n)
 {
-  return (ofs + 1 < n
-          && mts[ofs].token.type == T_MACRO_ID
-          && ss_equals (mts[ofs].token.string, ss_cstr ("!"))
-          && mts[ofs + 1].token.type == T_ASTERISK);
+  return (n > 1
+          && mts[0].token.type == T_MACRO_ID
+          && ss_equals (mts[0].token.string, ss_cstr ("!"))
+          && mts[1].token.type == T_ASTERISK);
 }
 
+/* Parses one function argument from the N_INPUT tokens in INPUT
+   Each argument to a macro function is one of:
+
+       - A quoted string or other single literal token.
+
+       - An argument to the macro being expanded, e.g. !1 or a named argument.
+
+       - !*.
+
+       - A function invocation.
+
+   Each function invocation yields a character sequence to be turned into a
+   sequence of tokens.  The case where that character sequence is a single
+   quoted string is an important special case.
+*/
 static size_t
 parse_function_arg (const struct macro_expander *me,
                     const struct macro_token *input, size_t n_input,
-                    size_t i, struct string *farg)
+                    struct string *farg)
 {
-  const struct token *token = &input[i].token;
+  assert (n_input > 0);
+
+  const struct token *token = &input[0].token;
   if (token->type == T_MACRO_ID && me->macro)
     {
       const struct macro_param *param = macro_find_parameter_by_name (
@@ -940,7 +941,7 @@ parse_function_arg (const struct macro_expander *me,
           return 1;
         }
 
-      if (is_bang_star (input, n_input, i))
+      if (is_bang_star (input, n_input))
         {
           for (size_t i = 0; i < me->macro->n_params; i++)
             {
@@ -968,12 +969,12 @@ parse_function_arg (const struct macro_expander *me,
         }
 
       size_t subinput_consumed;
-      if (expand_macro_function (me, &input[i], n_input - i,
+      if (expand_macro_function (me, input, n_input,
                                  farg, &subinput_consumed))
         return subinput_consumed;
     }
 
-  ds_put_substring (farg, input[i].representation);
+  ds_put_substring (farg, input[0].representation);
   return 1;
 }
 
@@ -1017,7 +1018,7 @@ parse_macro_function (const struct macro_expander *me,
         }
 
       struct string s = DS_EMPTY_INITIALIZER;
-      i += parse_function_arg (me, tokens, n_tokens, i, &s);
+      i += parse_function_arg (me, tokens + i, n_tokens - i, &s);
       if (i >= n_tokens)
         {
           ds_destroy (&s);
@@ -1301,7 +1302,7 @@ macro_evaluate_literal (const struct macro_expander *me,
 
   struct string function_output = DS_EMPTY_INITIALIZER;
   size_t function_consumed = parse_function_arg (me, p, end - p,
-                                                 0, &function_output);
+                                                 &function_output);
   struct string unquoted = DS_EMPTY_INITIALIZER;
   if (unquote_string (ds_cstr (&function_output), me->segmenter_mode,
                       &unquoted))
@@ -1919,7 +1920,7 @@ macro_expand (const struct macro_tokens *mts,
               continue;
             }
 
-          if (is_bang_star (mts->mts, mts->n, i))
+          if (is_bang_star (mts->mts + i, mts->n - i))
             {
               for (size_t j = 0; j < me->macro->n_params; j++)
                 {