work on macro expansion error messages
authorBen Pfaff <blp@cs.stanford.edu>
Tue, 29 Jun 2021 06:41:18 +0000 (23:41 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 29 Jun 2021 06:41:18 +0000 (23:41 -0700)
src/language/lexer/macro.c

index 786aeea54a3429645dff5094fd644a37348e0bd2..5f68de3fdd289b22a052d5e97f51f66894bdec0a 100644 (file)
@@ -423,6 +423,13 @@ macro_set_add (struct macro_set *set, struct macro *m)
   hmap_insert (&set->macros, &m->hmap_node, hash_macro_name (m->name));
 }
 \f
+struct macro_expansion_stack
+  {
+    const struct macro_expansion_stack *next;
+    const char *name;
+  };
+
+
 enum me_state
   {
     /* Error state. */
@@ -758,6 +765,7 @@ struct parse_macro_function_ctx
     int nesting_countdown;
     const struct macro_set *macros;
     const struct macro_expander *me;
+    const struct macro_expansion_stack *stack;
     struct string_map *vars;
     bool *expand;
   };
@@ -766,7 +774,9 @@ static void
 macro_expand (const struct macro_tokens *,
               int nesting_countdown, const struct macro_set *,
               const struct macro_expander *, struct string_map *vars,
-              bool *expand, bool *break_, struct macro_tokens *exp);
+              const struct macro_expansion_stack *stack,
+              bool *expand, bool *break_,
+              struct macro_tokens *exp);
 
 static bool
 expand_macro_function (struct parse_macro_function_ctx *ctx,
@@ -842,6 +852,7 @@ parse_function_arg (struct parse_macro_function_ctx *ctx,
         .nesting_countdown = ctx->nesting_countdown,
         .macros = ctx->macros,
         .me = ctx->me,
+        .stack = ctx->stack,
         .vars = ctx->vars,
         .expand = ctx->expand,
       };
@@ -1098,7 +1109,11 @@ expand_macro_function (struct parse_macro_function_ctx *ctx,
                                 SEG_MODE_INTERACTIVE /* XXX */);
       struct macro_tokens exp = { .n = 0 };
       macro_expand (&mts, ctx->nesting_countdown - 1, ctx->macros, ctx->me,
-                    ctx->vars, ctx->expand, NULL, &exp);
+                    ctx->vars,
+                    &(struct macro_expansion_stack) {
+                      .name = "!EVAL",
+                      .next = ctx->stack,
+                    }, ctx->expand, NULL, &exp);
       macro_tokens_to_representation (&exp, output, NULL, NULL);
       macro_tokens_uninit (&exp);
       macro_tokens_uninit (&mts);
@@ -1122,6 +1137,7 @@ struct expr_context
     int nesting_countdown;
     const struct macro_set *macros;
     const struct macro_expander *me;
+    const struct macro_expansion_stack *stack;
     struct string_map *vars;
     bool *expand;
   };
@@ -1161,6 +1177,7 @@ macro_evaluate_literal (const struct expr_context *ctx,
     .nesting_countdown = ctx->nesting_countdown,
     .macros = ctx->macros,
     .me = ctx->me,
+    .stack = ctx->stack,
     .vars = ctx->vars,
     .expand = ctx->expand,
   };
@@ -1354,13 +1371,15 @@ macro_evaluate_or (const struct expr_context *ctx,
 static char *
 macro_evaluate_expression (const struct macro_token **tokens, size_t n_tokens,
                            int nesting_countdown, const struct macro_set *macros,
-                           const struct macro_expander *me, struct string_map *vars,
-                           bool *expand)
+                           const struct macro_expander *me,
+                           const struct macro_expansion_stack *stack,
+                           struct string_map *vars, bool *expand)
 {
   const struct expr_context ctx = {
     .nesting_countdown = nesting_countdown,
     .macros = macros,
     .me = me,
+    .stack = stack,
     .vars = vars,
     .expand = expand,
   };
@@ -1370,11 +1389,13 @@ macro_evaluate_expression (const struct macro_token **tokens, size_t n_tokens,
 static bool
 macro_evaluate_number (const struct macro_token **tokens, size_t n_tokens,
                        int nesting_countdown, const struct macro_set *macros,
-                       const struct macro_expander *me, struct string_map *vars,
+                       const struct macro_expander *me,
+                       const struct macro_expansion_stack *stack,
+                       struct string_map *vars,
                        bool *expand, double *number)
 {
   char *s = macro_evaluate_expression (tokens, n_tokens, nesting_countdown,
-                                       macros, me, vars, expand);
+                                       macros, me, stack, vars, expand);
   if (!s)
     return false;
 
@@ -1421,7 +1442,9 @@ find_ifend_clause (const struct macro_token *p, const struct macro_token *end)
 static size_t
 macro_expand_if (const struct macro_token *tokens, size_t n_tokens,
                  int nesting_countdown, const struct macro_set *macros,
-                 const struct macro_expander *me, struct string_map *vars,
+                 const struct macro_expander *me,
+                 const struct macro_expansion_stack *stack,
+                 struct string_map *vars,
                  bool *expand, bool *break_, struct macro_tokens *exp)
 {
   const struct macro_token *p = tokens;
@@ -1432,8 +1455,8 @@ macro_expand_if (const struct macro_token *tokens, size_t n_tokens,
 
   p++;
   char *result = macro_evaluate_expression (&p, end - p,
-                                            nesting_countdown, macros, me, vars,
-                                            expand);
+                                            nesting_countdown, macros, me,
+                                            stack, vars, expand);
   if (!result)
     return 0;
   bool b = strcmp (result, "0");
@@ -1497,17 +1520,47 @@ 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, macros, me, vars, expand,
-                    break_, exp);
+      macro_expand (&mts, nesting_countdown, macros, me, vars,
+                    &(struct macro_expansion_stack) {
+                      .name = "!IF",
+                      .next = stack,
+                    },
+                    expand, break_, exp);
     }
   return (end_if + 1) - tokens;
 }
 
+static void PRINTF_FORMAT (2, 3)
+macro_error (const struct macro_expansion_stack *stack,
+             const char *format, ...)
+{
+  va_list args;
+  va_start (args, format);
+  char *s = xvasprintf (format, args);
+  va_end (args);
+
+  /* foo.sps:12: While expanding macro 'innermost',
+     foo.sps:23: inside expansion of 'next_inner',
+     foo.sps:34: inside expansion of 'next_inner2',
+     foo.sps:45: inside expansion of 'outermost':
+     error. */
+  struct string header = DS_EMPTY_INITIALIZER;
+  ds_put_format (&header, "While expanding \"%s\"", stack->name);
+  while ((stack = stack->next) != NULL)
+    ds_put_format (&header, ", inside expansion of \"%s\"", stack->name);
+
+  msg (SE, "%s: %s", ds_cstr (&header), s);
+
+  ds_destroy (&header);
+  free (s);
+}
+
 static size_t
 macro_parse_let (const struct macro_token *tokens, size_t n_tokens,
                  int nesting_countdown, const struct macro_set *macros,
-                 const struct macro_expander *me, struct string_map *vars,
-                 bool *expand)
+                 const struct macro_expander *me,
+                 const struct macro_expansion_stack *stack,
+                 struct string_map *vars, bool *expand)
 {
   const struct macro_token *p = tokens;
   const struct macro_token *end = tokens + n_tokens;
@@ -1518,7 +1571,7 @@ macro_parse_let (const struct macro_token *tokens, size_t n_tokens,
 
   if (p >= end || p->token.type != T_MACRO_ID)
     {
-      printf ("expected macro variable name following !LET\n");
+      macro_error (stack, "expected macro variable name following !LET");
       return 0;
     }
   const struct substring var_name = p->token.string;
@@ -1538,8 +1591,8 @@ macro_parse_let (const struct macro_token *tokens, size_t n_tokens,
   p++;
 
   char *value = macro_evaluate_expression (&p, end - p,
-                                           nesting_countdown, macros, me, vars,
-                                           expand);
+                                           nesting_countdown, macros, me, stack,
+                                           vars, expand);
   if (!value)
     return 0;
 
@@ -1572,7 +1625,9 @@ find_doend (const struct macro_token *p, const struct macro_token *end)
 static size_t
 macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
                  int nesting_countdown, const struct macro_set *macros,
-                 const struct macro_expander *me, struct string_map *vars,
+                 const struct macro_expander *me,
+                 const struct macro_expansion_stack *stack,
+                 struct string_map *vars,
                  bool *expand, struct macro_tokens *exp)
 {
   const struct macro_token *p = tokens;
@@ -1596,14 +1651,17 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
     }
   p++;
 
+  struct macro_expansion_stack next_stack = {
+    .name = "!DO", .next = stack,
+  };
   int miterate = settings_get_miterate ();
   if (p < end && p->token.type == T_MACRO_ID
       && ss_equals_case (p->token.string, ss_cstr ("!IN")))
     {
       p++;
       char *list = macro_evaluate_expression (&p, end - p,
-                                              nesting_countdown, macros, me, vars,
-                                              expand);
+                                              nesting_countdown, macros, me,
+                                              &next_stack, vars, expand);
       if (!list)
         return 0;
 
@@ -1635,7 +1693,7 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
 
           bool break_ = false;
           macro_expand (&inner, nesting_countdown, macros,
-                        me, vars, expand, &break_, exp);
+                        me, vars, &next_stack, expand, &break_, exp);
           if (break_)
             break;
         }
@@ -1646,7 +1704,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, macros, me,
-                                  vars, expand, &first))
+                                  &next_stack, vars, expand, &first))
         return 0;
 
       if (p >= end || p->token.type != T_MACRO_ID
@@ -1659,7 +1717,7 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
 
       double last;
       if (!macro_evaluate_number (&p, end - p, nesting_countdown, macros, me,
-                                  vars, expand, &last))
+                                  &next_stack, vars, expand, &last))
         return 0;
 
       double by = 1.0;
@@ -1668,7 +1726,7 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
         {
           p++;
           if (!macro_evaluate_number (&p, end - p, nesting_countdown, macros, me,
-                                      vars, expand, &by))
+                                      &next_stack, vars, expand, &by))
             return 0;
 
           if (by == 0.0)
@@ -1707,7 +1765,7 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens,
 
               bool break_ = false;
               macro_expand (&inner, nesting_countdown, macros,
-                            me, vars, expand, &break_, exp);
+                            me, vars, &next_stack, expand, &break_, exp);
               if (break_)
                 break;
             }
@@ -1726,6 +1784,7 @@ static void
 macro_expand (const struct macro_tokens *mts,
               int nesting_countdown, const struct macro_set *macros,
               const struct macro_expander *me, struct string_map *vars,
+              const struct macro_expansion_stack *stack,
               bool *expand, bool *break_, struct macro_tokens *exp)
 {
   if (nesting_countdown <= 0)
@@ -1754,7 +1813,10 @@ macro_expand (const struct macro_tokens *mts,
               //macro_tokens_print (arg, stdout);
               if (*expand && param->expand_arg)
                 macro_expand (arg, nesting_countdown, macros, NULL, NULL,
-                              expand, break_, exp);
+                              &(struct macro_expansion_stack) {
+                                .name = param->name,
+                                .next = stack,
+                              }, expand, break_, exp);
               else
                 for (size_t i = 0; i < arg->n; i++)
                   macro_tokens_add (exp, &arg->mts[i]);
@@ -1772,7 +1834,10 @@ macro_expand (const struct macro_tokens *mts,
                   const struct macro_tokens *arg = me->args[j];
                   if (*expand && param->expand_arg)
                     macro_expand (arg, nesting_countdown, macros, NULL, NULL,
-                                  expand, break_, exp);
+                                  &(struct macro_expansion_stack) {
+                                    .name = "!*",
+                                    .next = stack,
+                                  }, expand, break_, exp);
                   else
                     for (size_t k = 0; k < arg->n; k++)
                       macro_tokens_add (exp, &arg->mts[k]);
@@ -1782,8 +1847,8 @@ macro_expand (const struct macro_tokens *mts,
             }
 
           size_t n = macro_expand_if (&mts->mts[i], mts->n - i,
-                                      nesting_countdown, macros, me, vars,
-                                      expand, break_, exp);
+                                      nesting_countdown, macros, me, stack,
+                                      vars, expand, break_, exp);
           if (n > 0)
             {
               i += n - 1;
@@ -1817,7 +1882,11 @@ macro_expand (const struct macro_tokens *mts,
             {
               i += retval - 1;
               macro_expand (&subme->macro->body, nesting_countdown - 1, macros,
-                            subme, NULL, expand, break_, exp);
+                            subme, NULL,
+                            &(struct macro_expansion_stack) {
+                              .name = subme->macro->name,
+                              .next = stack,
+                            }, expand, break_, exp);
               macro_expander_destroy (subme);
               continue;
             }
@@ -1848,6 +1917,7 @@ macro_expand (const struct macro_tokens *mts,
         .nesting_countdown = nesting_countdown,
         .macros = macros,
         .me = me,
+        .stack = stack,
         .vars = vars,
         .expand = expand,
       };
@@ -1865,8 +1935,8 @@ macro_expand (const struct macro_tokens *mts,
         }
 
       size_t n = macro_parse_let (&mts->mts[i], mts->n - i,
-                                  nesting_countdown, macros, me, vars,
-                                  expand);
+                                  nesting_countdown, macros, me, stack,
+                                  vars, expand);
       if (n > 0)
         {
           i += n - 1;
@@ -1874,7 +1944,7 @@ macro_expand (const struct macro_tokens *mts,
         }
 
       n = macro_expand_do (&mts->mts[i], mts->n - i,
-                           nesting_countdown, macros, me, vars,
+                           nesting_countdown, macros, me, stack, vars,
                            expand, exp);
       if (n > 0)
         {
@@ -1896,21 +1966,9 @@ macro_expand (const struct macro_tokens *mts,
 void
 macro_expander_get_expansion (struct macro_expander *me, struct macro_tokens *exp)
 {
-#if 0
-  for (size_t i = 0; i < me->macro->n_params; i++)
-    {
-      printf ("%s:\n", me->macro->params[i].name);
-      macro_tokens_print (me->args[i], stdout);
-    }
-#endif
-
   bool expand = true;
+  struct macro_expansion_stack stack = { .name = me->macro->name };
   macro_expand (&me->macro->body, settings_get_mnest (),
-                me->macros, me, NULL, &expand, NULL, exp);
-
-#if 0
-  printf ("expansion:\n");
-  macro_tokens_print (exp, stdout);
-#endif
+                me->macros, me, NULL, &stack, &expand, NULL, exp);
 }