changeset 28157:884a9f759eaa

maint: merge stable to default.
author John W. Eaton <jwe@octave.org>
date Fri, 13 Mar 2020 00:14:41 -0400
parents 043deadaecf9 (current diff) 22cddebcb0d0 (diff)
children 687d452070c9
files
diffstat 4 files changed, 75 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/lex.h	Thu Mar 12 16:56:46 2020 -0700
+++ b/libinterp/parse-tree/lex.h	Fri Mar 13 00:14:41 2020 -0400
@@ -655,8 +655,6 @@
 
     bool is_variable (const std::string& name, const symbol_scope& scope);
 
-    bool is_keyword_token (const std::string& s);
-
     int make_keyword_token (const std::string& s);
 
     bool fq_identifier_contains_keyword (const std::string& s);
--- a/libinterp/parse-tree/lex.ll	Thu Mar 12 16:56:46 2020 -0700
+++ b/libinterp/parse-tree/lex.ll	Fri Mar 13 00:14:41 2020 -0400
@@ -301,6 +301,25 @@
   return c == ' ' || c == '\t' || c == '\n' || c == '\r';
 }
 
+namespace octave
+{
+  bool iskeyword (const std::string& s)
+  {
+    // Parsing function names like "set.property_name" inside
+    // classdef-style class definitions is simplified by handling the
+    // "set" and "get" portions of the names using the same mechanism
+    // as is used for keywords.  However, they are not really keywords
+    // in the language, so omit them from the list of possible
+    // keywords.  Likewise for "enumeration", "events", "methods", and
+    // "properties".
+
+    return (octave_kw_hash::in_word_set (s.c_str (), s.length ()) != nullptr
+            && ! (s == "set" || s == "get"
+                  || s == "enumeration" || s == "events"
+                  || s == "methods" || s == "properties"));
+  }
+}
+
 %}
 
 D       [0-9]
@@ -1377,11 +1396,9 @@
                 ident.erase (std::remove_if (ident.begin (), ident.end (),
                                              is_space_or_tab), ident.end ());
 
-                bool kw_token = curr_lexer->is_keyword_token (ident);
-
                 octave::token *tok;
 
-                if (kw_token)
+                if (octave::iskeyword (ident))
                   tok = new octave::token (LEXICAL_ERROR,
                                            "function handles may not refer to keywords",
                                            curr_lexer->m_tok_beg,
@@ -2030,26 +2047,6 @@
       }
 }
 
-namespace octave
-{
-  bool
-  iskeyword (const std::string& s)
-  {
-    // Parsing function names like "set.property_name" inside
-    // classdef-style class definitions is simplified by handling the
-    // "set" and "get" portions of the names using the same mechanism
-    // as is used for keywords.  However, they are not really keywords
-    // in the language, so omit them from the list of possible
-    // keywords.  Likewise for "enumeration", "events", "methods", and
-    // "properties".
-
-    return (octave_kw_hash::in_word_set (s.c_str (), s.length ()) != nullptr
-            && ! (s == "set" || s == "get"
-                  || s == "enumeration" || s == "events"
-                  || s == "methods" || s == "properties"));
-  }
-}
-
 DEFUN (iskeyword, args, ,
        doc: /* -*- texinfo -*-
 @deftypefn  {} {} iskeyword ()
@@ -2080,7 +2077,9 @@
         {
           std::string kword = wordlist[i].name;
 
-          if (kword != "set" && kword != "get")
+          if (! (kword == "set" || kword == "get"
+                 || kword == "enumeration" || kword == "events"
+                 || kword == "methods" || kword == "properties"))
             lst[j++] = kword;
         }
 
@@ -2580,16 +2579,6 @@
                 != m_pending_local_variables.end ()));
   }
 
-  // Handle keywords.  Return -1 if the keyword should be ignored.
-
-  bool
-  base_lexer::is_keyword_token (const std::string& s)
-  {
-    int len = s.length ();
-
-    return octave_kw_hash::in_word_set (s.c_str (), len);
-  }
-
   int
   base_lexer::make_keyword_token (const std::string& s)
   {
@@ -2854,7 +2843,7 @@
         else
           s_part = s.substr (p1);
 
-        if (is_keyword_token (s_part))
+        if (iskeyword (s_part))
           return true;
       }
     while (p2 != std::string::npos);
@@ -3086,10 +3075,7 @@
     std::string meth = txt.substr (0, pos);
     std::string cls = txt.substr (pos + 1);
 
-    bool kw_token = (is_keyword_token (meth)
-                     || fq_identifier_contains_keyword (cls));
-
-    if (kw_token)
+    if (iskeyword (meth) || fq_identifier_contains_keyword (cls))
       {
         token *tok
           = new token (LEXICAL_ERROR,
@@ -3193,7 +3179,7 @@
         return STRUCT_ELT;
       }
 
-    // If ident is a keyword token, then is_keyword_token will set
+    // If ident is a keyword token, then make_keyword_token will set
     // m_at_beginning_of_statement.  For example, if tok is an IF
     // token, then m_at_beginning_of_statement will be false.
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/fcn-handle/keyword.tst	Fri Mar 13 00:14:41 2020 -0400
@@ -0,0 +1,48 @@
+########################################################################
+##
+## Copyright (C) 2020 The Octave Project Developers
+##
+## See the file COPYRIGHT.md in the top-level directory of this
+## distribution or <https://octave.org/copyright/>.
+##
+## This file is part of Octave.
+##
+## Octave is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <https://www.gnu.org/licenses/>.
+##
+########################################################################
+
+%!test <*57988>
+%! fh = @get;
+%! fh = @set;
+%! fh = @enumeration;
+%! fh = @events;
+%! fh = @methods;
+%! fh = @properties;
+
+%!test <*57988>
+%!  kwords = iskeyword ();
+%!  for i = 1:numel (kwords)
+%!    unexpected_success = true;
+%!    kword = kwords{i};
+%!    try
+%!      eval (sprintf ("@%s;", kword));
+%!    catch
+%!      unexpected_success = false;
+%!    end_try_catch
+%!    if (unexpected_success)
+%!      error ("constructing function handle from keyword '%s' succeeded!",
+%!             kword);
+%!    endif
+%!  endfor
--- a/test/fcn-handle/module.mk	Thu Mar 12 16:56:46 2020 -0700
+++ b/test/fcn-handle/module.mk	Fri Mar 13 00:14:41 2020 -0400
@@ -14,6 +14,7 @@
   %reldir%/bug51709_c.m \
   %reldir%/derived-resolution.tst \
   %reldir%/f1.m \
+  %reldir%/keyword.tst \
   %reldir%/object-method.tst \
   %reldir%/package-function.tst \
   %reldir%/static-method.tst