X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Flexer%2Fmacro.c;h=6d7decb40faccf0e97e85a40ca04379885c068c4;hb=3c71220834d52d1c4ebdddc9670e911ffdd90852;hp=12e27620c1c23c997c285ef4f755ba00348be44a;hpb=a3fd68bc627bda62cd08e2041b9910f0ee802f97;p=pspp diff --git a/src/language/lexer/macro.c b/src/language/lexer/macro.c index 12e27620c1..6d7decb40f 100644 --- a/src/language/lexer/macro.c +++ b/src/language/lexer/macro.c @@ -722,7 +722,7 @@ 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, struct macro_tokens *exp); + bool *expand, bool *break_, struct macro_tokens *exp); static bool expand_macro_function (struct parse_macro_function_ctx *ctx, @@ -1054,7 +1054,7 @@ 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, &exp); + ctx->vars, ctx->expand, NULL, &exp); macro_tokens_to_representation (&exp, output); macro_tokens_uninit (&exp); macro_tokens_uninit (&mts); @@ -1378,7 +1378,7 @@ 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, - bool *expand, struct macro_tokens *exp) + bool *expand, bool *break_, struct macro_tokens *exp) { const struct macro_token *p = tokens; const struct macro_token *end = tokens + n_tokens; @@ -1453,7 +1453,8 @@ 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, exp); + macro_expand (&mts, nesting_countdown, macros, me, vars, expand, + break_, exp); } return (end_if + 1) - tokens; } @@ -1569,8 +1570,12 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens, { string_map_replace_nocopy (vars, ss_xstrdup (var_name), ss_xstrdup (items.mts[i].representation)); + + bool break_ = false; macro_expand (&inner, nesting_countdown, macros, - me, vars, expand, exp); + me, vars, expand, &break_, exp); + if (break_) + break; } return do_end - tokens + 1; } @@ -1628,8 +1633,12 @@ macro_expand_do (const struct macro_token *tokens, size_t n_tokens, c_dtoastr (index_s, sizeof index_s, 0, 0, index); string_map_replace_nocopy (vars, ss_xstrdup (var_name), xstrdup (index_s)); + + bool break_ = false; macro_expand (&inner, nesting_countdown, macros, - me, vars, expand, exp); + me, vars, expand, &break_, exp); + if (break_) + break; } return do_end - tokens + 1; @@ -1645,7 +1654,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, - bool *expand, struct macro_tokens *exp) + bool *expand, bool *break_, struct macro_tokens *exp) { if (nesting_countdown <= 0) { @@ -1658,7 +1667,8 @@ macro_expand (const struct macro_tokens *mts, struct string_map own_vars = STRING_MAP_INITIALIZER (own_vars); if (!vars) vars = &own_vars; - for (size_t i = 0; i < mts->n; i++) + + for (size_t i = 0; i < mts->n && (!break_ || !*break_); i++) { const struct macro_token *mt = &mts->mts[i]; const struct token *token = &mt->token; @@ -1672,7 +1682,7 @@ 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, exp); + expand, break_, exp); else for (size_t i = 0; i < arg->n; i++) macro_tokens_add (exp, &arg->mts[i]); @@ -1690,7 +1700,7 @@ 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, exp); + expand, break_, exp); else for (size_t k = 0; k < arg->n; k++) macro_tokens_add (exp, &arg->mts[k]); @@ -1701,7 +1711,7 @@ 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, exp); + expand, break_, exp); if (n > 0) { i += n - 1; @@ -1735,7 +1745,7 @@ macro_expand (const struct macro_tokens *mts, { i += retval - 1; macro_expand (&subme->macro->body, nesting_countdown - 1, macros, - subme, NULL, expand, exp); + subme, NULL, expand, break_, exp); macro_expander_destroy (subme); continue; } @@ -1749,6 +1759,17 @@ macro_expand (const struct macro_tokens *mts, continue; } + if (ss_equals_case (token->string, ss_cstr ("!break"))) + { + if (!break_) + printf ("!BREAK outside !DO\n"); + else + { + *break_ = true; + break; + } + } + struct parse_macro_function_ctx ctx = { .input = &mts->mts[i], .n_input = mts->n - i, @@ -1813,7 +1834,7 @@ macro_expander_get_expansion (struct macro_expander *me, struct macro_tokens *ex bool expand = true; macro_expand (&me->macro->body, settings_get_mnest (), - me->macros, me, NULL, &expand, exp); + me->macros, me, NULL, &expand, NULL, exp); #if 0 printf ("expansion:\n");