From 6e61fef8d4447f2d7610ed57009ae842ffe6a272 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 28 Jun 2021 23:41:18 -0700 Subject: [PATCH] work on macro expansion error messages --- src/language/lexer/macro.c | 150 +++++++++++++++++++++++++------------ 1 file changed, 104 insertions(+), 46 deletions(-) diff --git a/src/language/lexer/macro.c b/src/language/lexer/macro.c index 786aeea54a..5f68de3fdd 100644 --- a/src/language/lexer/macro.c +++ b/src/language/lexer/macro.c @@ -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)); } +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); } -- 2.30.2