From 286a3ec5b3fde58021342c1f1897eb2c41a2d14c Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 10 Jun 2021 23:00:05 -0700 Subject: [PATCH] !EVAL --- doc/flow-control.texi | 3 ++- src/language/lexer/macro.c | 21 +++++++++++++------- tests/language/control/define.at | 34 +++++++++++++++++++++++++++++--- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/doc/flow-control.texi b/doc/flow-control.texi index 7a95758a78..f0bf4fe10b 100644 --- a/doc/flow-control.texi +++ b/doc/flow-control.texi @@ -492,7 +492,8 @@ extends to the end of @var{arg}. @example !SUBSTR(banana, 3) @expansion{} nana !SUBSTR(banana, 3, 3) @expansion{} nan -!SUBSTR("banana", 3) @expansion{} anana" +!SUBSTR("banana", 3) @expansion{} @r{error (@code{anana"} is not a valid token)} +!SUBSTR(!UNQUOTE("banana"), 3) @expansion{} nana !SUBSTR("banana", 3, 3) @expansion{} ana !SUBSTR(banana, 3, 0) @expansion{} @r{empty} diff --git a/src/language/lexer/macro.c b/src/language/lexer/macro.c index 95d86a6e96..e900a5e7d1 100644 --- a/src/language/lexer/macro.c +++ b/src/language/lexer/macro.c @@ -142,6 +142,7 @@ macro_tokens_from_string (struct macro_tokens *mts, const struct substring src, { if (token->type != SCAN_SKIP) { + printf ("error\n"); /* XXX report error */ } } @@ -995,6 +996,19 @@ expand_macro_function (struct parse_macro_function_ctx *ctx, free (upper); ds_destroy (&tmp); } + else if (parse_macro_function (ctx, &args, ss_cstr ("!eval"), 1, 1, + input_consumed)) + { + struct macro_tokens mts = { .n = 0 }; + macro_tokens_from_string (&mts, ss_cstr (args.strings[0]), + SEG_MODE_INTERACTIVE /* XXX */); + struct macro_tokens exp = { .n = 0 }; + macro_expand (&mts, ctx->nesting_countdown - 1, ctx->macros, + ctx->me, ctx->expand, &exp); + macro_tokens_to_representation (&exp, output); + macro_tokens_uninit (&exp); + macro_tokens_uninit (&mts); + } else if (ctx->n_input > 0 && ctx->input[0].token.type == T_MACRO_ID && ss_equals_case (ctx->input[0].token.string, ss_cstr ("!null"))) @@ -1015,13 +1029,6 @@ macro_expand (const struct macro_tokens *mts, const struct macro_expander *me, bool *expand, struct macro_tokens *exp) { - /* Macro expansion: - - - Macro names in macro bodies are not expanded by default. !EVAL() - expands them. - - - Macro names in arguments to macro invocations (outside of macro bodies) - are expanded by default, unless !NOEXPAND. */ if (nesting_countdown <= 0) { printf ("maximum nesting level exceeded\n"); diff --git a/tests/language/control/define.at b/tests/language/control/define.at index fce0e3f832..bf5e2c4ae1 100644 --- a/tests/language/control/define.at +++ b/tests/language/control/define.at @@ -391,6 +391,32 @@ xy. 1234. 123.]) +dnl Keep this test in sync with the examples for !EVAL in the manual. +PSPP_CHECK_MACRO_EXPANSION([!EVAL], + [DEFINE !vars() a b c !ENDDEFINE. +DEFINE !e() +!vars. +!QUOTE(!vars). +!EVAL(!vars). +!QUOTE(!EVAL(!vars)). +!ENDDEFINE +DEFINE !e2(!positional !enclose('(',')')) +!1. +!QUOTE(!1). +!EVAL(!1). +!QUOTE(!EVAL(!1)). +!ENDDEFINE], + [!e. +!e2(!vars)], + [a b c. +'!vars'. +a b c. +'a b c'. +a b c. +'!vars'. +a b c. +'a b c'.]) + dnl Keep this test in sync with the examples for !HEAD in the manual. PSPP_CHECK_MACRO_EXPANSION([!HEAD], [DEFINE !h() @@ -476,16 +502,18 @@ PSPP_CHECK_MACRO_EXPANSION([!SUBSTR], !SUBSTR(banana, 3). !SUBSTR(banana, 3, 3). !SUBSTR("banana", 3). +!SUBSTR(!UNQUOTE("banana"), 3). !SUBSTR("banana", 3, 3). !SUBSTR(banana, 3, 0). !SUBSTR(banana, 3, 10). !SUBSTR(banana, 10, 3). !ENDDEFINE.], [!s.], - [nana. + [error +nana. nan. -anana". dnl" - +anana. +nana. ana. . nana. -- 2.30.2