Turn !* into a single token, for macro expansion purposes.
authorBen Pfaff <blp@cs.stanford.edu>
Thu, 22 Jul 2021 05:48:07 +0000 (22:48 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Thu, 22 Jul 2021 06:04:57 +0000 (23:04 -0700)
src/language/lexer/macro.c
src/language/lexer/segment.c
tests/language/lexer/scan.at
tests/language/lexer/segment.at

index 22e92ca05e911c32e289aaedf081a664d4fb2c46..ab1e78efcf0e3b691c9a55ca1591182536e23175 100644 (file)
@@ -897,16 +897,6 @@ expand_macro_function (const struct macro_expander *me,
                        const struct macro_token *input, size_t n_input,
                        struct string *output);
 
-/* Returns true if the N tokens within MTS start with !*, false otherwise. */
-static bool
-is_bang_star (const struct macro_token *mts, size_t n)
-{
-  return (n > 1
-          && mts[0].token.type == T_MACRO_ID
-          && ss_equals (mts[0].token.string, ss_cstr ("!"))
-          && mts[1].token.type == T_ASTERISK);
-}
-
 /* Parses one function argument from the N_INPUT tokens in INPUT
    Each argument to a macro function is one of:
 
@@ -941,7 +931,7 @@ parse_function_arg (const struct macro_expander *me,
           return 1;
         }
 
-      if (is_bang_star (input, n_input))
+      if (ss_equals (token->string, ss_cstr ("!*")))
         {
           for (size_t i = 0; i < me->macro->n_params; i++)
             {
@@ -951,7 +941,7 @@ parse_function_arg (const struct macro_expander *me,
                 ds_put_byte (farg, ' ');
               macro_tokens_to_syntax (me->args[i], farg, NULL, NULL);
             }
-          return 2;
+          return 1;
         }
 
       const char *var = stringi_map_find__ (me->vars,
@@ -1998,11 +1988,11 @@ macro_expand__ (const struct macro_token *mts, size_t n,
           macro_expand_arg (me, param - me->macro->params, exp);
           return 1;
         }
-      else if (is_bang_star (mts, n))
+      else if (ss_equals (token->string, ss_cstr ("!*")))
         {
           for (size_t j = 0; j < me->macro->n_params; j++)
             macro_expand_arg (me, j, exp);
-          return 2;
+          return 1;
         }
     }
 
index 5c298a781dcb0dce16c80394d5cc1f35a3ee6ee8..1cf7ac6f6dfe906c901c8f18107dd0d62d216b5d 100644 (file)
@@ -1018,7 +1018,20 @@ segmenter_parse_mid_command__ (struct segmenter *s,
                                        s, input, n, eof, type);
 
     case '!':
-      return segmenter_parse_id__ (s, input, n, eof, type);
+      if (n < 2)
+        {
+          if (!eof)
+            return -1;
+          *type = SEG_PUNCT;
+          return 1;
+        }
+      else if (input[1] == '*')
+        {
+          *type = SEG_MACRO_ID;
+          return 2;
+        }
+      else
+        return segmenter_parse_id__ (s, input, n, eof, type);
 
     default:
       if (lex_uc_is_space (uc))
index 53e96921f321b9b72c62d6b9d3038315fd7b46f8..187c22efeeb88d109b00a2c3dcb6762fdab766a3 100644 (file)
@@ -25,7 +25,7 @@ m4_define([PSPP_CHECK_SCAN],
 AT_SETUP([identifiers])
 AT_KEYWORDS([scan])
 AT_DATA([input], [dnl
-a aB i5 $x @efg @@. !abcd #.# .x _z.
+a aB i5 $x @efg @@. !abcd !* !*a #.# .x _z.
 abcd. abcd.
 QRSTUV./* end of line comment */
 QrStUv./* end of line comment */ @&t@
@@ -40,6 +40,9 @@ ID "$x"
 ID "@efg"
 ID "@@."
 MACRO_ID "!abcd"
+MACRO_ID "!*"
+MACRO_ID "!*"
+ID "a"
 ID "#.#"
 MACRO_PUNCT "."
 ID "x"
index 5d9440fe216aa536d912e9f3514d611a53d7c5ff..8936ae98df86ad01da05a192400ed2d67ad18ca3 100644 (file)
@@ -291,8 +291,8 @@ AT_SETUP([punctuation])
 AT_KEYWORDS([segment])
 AT_DATA([input], [dnl
 ~ & | = >= > <= < ~= <> ( ) , - + * / [[ ]] **
-~&|=>=><=<~=<>(),-+*/[[]]**
-% : ; ? _ ` { } ~
+~&|=>=><=<~=<>(),-+*/[[]]**!*
+% : ; ? _ ` { } ~ !*
 ])
 AT_DATA([expout-base], [dnl
 punct           ~    space
@@ -337,6 +337,7 @@ punct           /
 punct           [[
 punct           ]]
 punct           **
+macro_id        !*
 newline         \n (later)
 
 punct           %    space
@@ -347,7 +348,8 @@ punct           \_    space
 punct           `    space
 punct           {    space
 punct           }    space
-punct           ~
+punct           ~    space
+macro_id        !*
 -newline         \n (later)
 -
 end