Keyword arguments work.
authorBen Pfaff <blp@cs.stanford.edu>
Mon, 31 May 2021 06:00:12 +0000 (23:00 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Mon, 31 May 2021 06:00:12 +0000 (23:00 -0700)
src/language/lexer/macro.c
tests/language/control/define.at

index fd5ac452cff3a0421902d40b4321e8bf98d56347..d67278c51cd4066aa3c99f973e4a0de98db4063e 100644 (file)
@@ -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;
index 0211c71785511c75f647ebe47fec7ac5c7ee2a7b..a24ffb33c3dd3bdf55a085c3dd8c4440d873777f 100644 (file)
@@ -16,6 +16,18 @@ dnl along with this program.  If not, see <http://www.gnu.org/licenses/>.
 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])
+\f
+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"])
+\f
+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
+\f
+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
+\f
+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