From 15c8f96cf1931d6df3e6e4fb3f11fae4a1dd243a Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 30 May 2021 23:00:12 -0700 Subject: [PATCH] Keyword arguments work. --- src/language/lexer/macro.c | 5 +- tests/language/control/define.at | 146 ++++++++++++++++++++++++++++++- 2 files changed, 148 insertions(+), 3 deletions(-) diff --git a/src/language/lexer/macro.c b/src/language/lexer/macro.c index fd5ac452cf..d67278c51c 100644 --- a/src/language/lexer/macro.c +++ b/src/language/lexer/macro.c @@ -535,10 +535,13 @@ me_enclose (struct macro_expander *me, const struct macro_token *mt) static const struct macro_param * macro_find_parameter_by_name (const struct macro *m, struct substring name) { + if (ss_first (name) == '!') + ss_advance (&name, 1); + for (size_t i = 0; i < m->n_params; i++) { const struct macro_param *p = &m->params[i]; - struct substring p_name = ss_cstr (p->name); + struct substring p_name = ss_cstr (p->name + 1); if (!utf8_strncasecmp (p_name.string, p_name.length, name.string, name.length)) return p; diff --git a/tests/language/control/define.at b/tests/language/control/define.at index 0211c71785..a24ffb33c3 100644 --- a/tests/language/control/define.at +++ b/tests/language/control/define.at @@ -16,6 +16,18 @@ dnl along with this program. If not, see . dnl AT_BANNER([DEFINE]) +m4_define([PSPP_CHECK_MACRO_EXPANSION], + [AT_SETUP([macro expansion - $1]) + AT_DATA([define.sps], [$2 +DEBUG EXPAND. +$3 +]) + AT_DATA([expout], [$4 +]) + AT_CHECK([pspp --testing-mode define.sps | sed '/^$/d'], [$6 +], [expout]) + AT_CLEANUP]) + AT_SETUP([simple macro expansion]) AT_DATA([define.sps], [dnl DEFINE !macro() @@ -40,8 +52,18 @@ m(n, o). "x "" y". ]) AT_CLEANUP - -AT_SETUP([macro expansion with arguments]) + +PSPP_CHECK_MACRO_EXPANSION([one !TOKENS(1) positional argument], + [DEFINE !t1(!positional !tokens(1)) t1 (!1) !ENDDEFINE.], + [!t1 a. +!t1 b. +!t1 a b.], + [t1(a) +t1(b) +t1(a) +note: unexpanded token "b"]) + +AT_SETUP([macro expansion with positional arguments]) AT_DATA([define.sps], [dnl DEFINE !title(!positional !tokens(1)) !1 !ENDDEFINE. DEFINE !t1(!positional !tokens(1)) t1 (!1) !ENDDEFINE. @@ -61,6 +83,12 @@ DEFINE !cmd2(!positional !cmdend cmd2(!1, !2) !ENDDEFINE. +DEFINE !p(!positional !tokens(1) + /!positional !tokens(1) + /!positional !tokens(1)) +p(!1, !2, !3) +!ENDDEFINE. + DEBUG EXPAND. !title "!TOKENS(1) argument." !t1 a. @@ -90,6 +118,10 @@ DEBUG EXPAND. !cmd 1 2 3 4. !cmd2 5 6. 7. + +!title "Three !TOKENS(1) arguments." +!p a b c. +!p 1 -2 -3. ]) AT_CHECK([pspp --testing-mode define.sps], [0], [dnl "!TOKENS(1) argument." @@ -139,5 +171,115 @@ e(a b) cmd(1 2 3 4) cmd2(5 6, 7) + +"Three !TOKENS(1) arguments." + +p(a, b, c) + +p(1, -2, -3) +]) +AT_CLEANUP + +AT_SETUP([macro expansion with positional arguments - negative]) +AT_DATA([define.sps], [dnl +DEFINE !title(!positional !tokens(1)) !1 !ENDDEFINE. +DEFINE !p(!positional !tokens(1) + /!positional !tokens(1) + /!positional !tokens(1)) +(!1, !2, !3) +!ENDDEFINE. + +DEFINE !ce(!positional !charend('/')) ce(!1) !ENDDEFINE. + +DEFINE !enc1(!positional !enclose('{', '}')) enc1(!1) !ENDDEFINE. +DEBUG EXPAND. +!title "Too few tokens for !TOKENS." +!p a b. +!p a. +!p. + +!title "Missing charend delimiter." +!ce a b c. + +!title "Missing start delimiter." +!enc1 a b c. + +!title "Missing end delimiter." +!enc1{a b c. +]) +AT_CHECK([pspp --testing-mode define.sps], [1], [dnl +"Too few tokens for !TOKENS." + +define.sps:13: error: DEBUG EXPAND: Unexpected end of command reading +argument !3 to macro !p. + +note: unexpanded token "!p" + +note: unexpanded token "a" + +note: unexpanded token "b" + +define.sps:14: error: DEBUG EXPAND: Unexpected end of command reading +argument !2 to macro !p. + +note: unexpanded token "!p" + +note: unexpanded token "a" + +define.sps:15: error: DEBUG EXPAND: Unexpected end of command reading +argument !1 to macro !p. + +note: unexpanded token "!p" + +"Missing charend delimiter." + +define.sps:18: error: DEBUG EXPAND: Unexpected end of command reading +argument !1 to macro !ce. + +note: unexpanded token "!ce" + +note: unexpanded token "a" + +note: unexpanded token "b" + +note: unexpanded token "c" + +"Missing start delimiter." + +define.sps:21: error: DEBUG EXPAND: Found `a' while expecting `{' reading +argument !1 to macro !enc1. + +note: unexpanded token "!enc1" + +note: unexpanded token "a" + +note: unexpanded token "b" + +note: unexpanded token "c" + +"Missing end delimiter." + +define.sps:24: error: DEBUG EXPAND: Unexpected end of command reading +argument !1 to macro !enc1. + +note: unexpanded token "!enc1" + +note: unexpanded token "{" + +note: unexpanded token "a" + +note: unexpanded token "b" + +note: unexpanded token "c" ]) AT_CLEANUP + +PSPP_CHECK_MACRO_EXPANSION([one !TOKENS(1) keyword argument], + [DEFINE !k(arg1 = !TOKENS(1)) k(!arg1) !ENDDEFINE.], + [!k arg1=x. +!k arg1=x y. +!k.], + [k(x) +k(x) +note: unexpanded token "y" +k( )]) \ No newline at end of file -- 2.30.2