MATRIX
[pspp] / src / language / lexer / macro.c
index 977436a6041b32a7dc39f31d57daebc7262ceb9b..4419306d1d206f8dc39f40ee3a8ec6e8b31cba4e 100644 (file)
@@ -334,6 +334,8 @@ classify_token (enum token_type type)
     case T_RPAREN:
     case T_LBRACK:
     case T_RBRACK:
+    case T_LCURLY:
+    case T_RCURLY:
       return TC_PUNCT;
 
     case T_PLUS:
@@ -341,6 +343,7 @@ classify_token (enum token_type type)
     case T_ASTERISK:
     case T_SLASH:
     case T_EQUALS:
+    case T_COLON:
     case T_AND:
     case T_OR:
     case T_NOT:
@@ -359,6 +362,7 @@ classify_token (enum token_type type)
       return TC_BINOP;
 
     case T_COMMA:
+    case T_SEMICOLON:
       return TC_COMMA;
     }
 
@@ -986,12 +990,7 @@ parse_function_args (const struct macro_expander *me,
                      const char *function,
                      struct string_array *args)
 {
-  if (n < 2 || mts[1].token.type != T_LPAREN)
-    {
-      macro_error (me->stack, n > 1 ? &mts[1] : NULL,
-                   _("`(' expected following %s."), function);
-      return 0;
-    }
+  assert (n >= 2 && mts[1].token.type == T_LPAREN);
 
   for (size_t i = 2; i < n; )
     {
@@ -1043,7 +1042,8 @@ unquote_string (const char *s, enum segmenter_mode segmenter_mode,
       return false;
     }
 
-  ds_put_substring (content, token1.string);
+  if (content)
+    ds_put_substring (content, token1.string);
   token_uninit (&token1);
   return true;
 }
@@ -1090,7 +1090,6 @@ expand_macro_function (const struct macro_expander *me,
       MF_HEAD,
       MF_INDEX,
       MF_LENGTH,
-      MF_NULL,
       MF_QUOTE,
       MF_SUBSTR,
       MF_TAIL,
@@ -1104,7 +1103,6 @@ expand_macro_function (const struct macro_expander *me,
     [MF_HEAD]    = { "!HEAD",    1, 1 },
     [MF_INDEX]   = { "!INDEX",   2, 2 },
     [MF_LENGTH]  = { "!LENGTH",  1, 1 },
-    [MF_NULL]    = { "!NULL",    0, 0 },
     [MF_QUOTE]   = { "!QUOTE",   1, 1 },
     [MF_SUBSTR]  = { "!SUBSTR",  2, 3 },
     [MF_TAIL]    = { "!TAIL",    1, 1 },
@@ -1112,7 +1110,16 @@ expand_macro_function (const struct macro_expander *me,
     [MF_UPCASE]  = { "!UPCASE",  1, 1 },
   };
 
-  /* Is this a macro function? */
+  if (lex_id_match_n (ss_cstr ("!NULL"), input[0].token.string, 4))
+    return 1;
+
+  if (n_input < 2 || input[1].token.type != T_LPAREN)
+    {
+      /* Only consider macro functions when the name is followed by '('. */
+      return 0;
+    }
+
+  /* Is this a macro function name? */
   const struct macro_function *mf;
   for (mf = mfs; ; mf++)
     {
@@ -1127,8 +1134,6 @@ expand_macro_function (const struct macro_expander *me,
     }
 
   enum macro_function_id id = mf - mfs;
-  if (id == MF_NULL)
-    return 1;
 
   struct string_array args = STRING_ARRAY_INITIALIZER;
   size_t n_consumed = parse_function_args (me, input, n_input, mf->name, &args);