diff test/eval-command.tst @ 26662:05fc703b419a

update handling of command-style function call syntax in eval * lex.h, lex.ll (lexical_feedback::m_allow_command_syntax): New data member. (lexical_feedback::reset): Reset it. (lexical_feedback::previous_token_may_be_command, base_lexer::looks_like_command_arg): Return false immediately if m_allow_command_syntax is false. (base_lexer::is_variable): Check if name is a variable if parsing in top level scope. * parse.h, oct-parse.yy (base_parser::disallow_command_syntax): New function. (word_list_command): Mark index expression as a word list command. * pt-eval.cc (tree_evaluator::eval_string): If nargout > 0, don't allow evaluated code to be parsed as a command-style function call. (tree_evaluator::visit_index_expression): Error if identifier is a variable and index expression is a command-style function call. * pt-idx.h, pt-idx.cc (tree_index_expression::m_word_list_cmd): New member variable. (tree_index_expression::mark_word_list_cmd, tree_index_expression::is_word_list_cmd): New functions. * clearvars.m: Avoid evaluating command-style function call when assigning result of call to eval. * test/eval-command.tst: New file. * bug-38565.tst, bug-38576.tst: Delete obsolete tests. * test/module.mk: Update.
author John W. Eaton <jwe@octave.org>
date Thu, 31 Jan 2019 18:45:37 +0000
parents test/bug-38576.tst@00f796120a6d
children b442ec6dda5c
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/eval-command.tst	Thu Jan 31 18:45:37 2019 +0000
@@ -0,0 +1,154 @@
+## Copyright (C) 2013-2019 John W. Eaton
+##
+## 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/>.
+
+%!function r = sigma (opt)
+%!  global sigma_call;
+%!  if (nargin == 0)
+%!    sigma_call = "function";
+%!    r = 1;
+%!  elseif (ischar (opt))
+%!    sigma_call = "command";
+%!    r = 1;
+%!  else
+%!    sigma_call = "unexpected";
+%!  endif
+%!endfunction
+%!
+%!function f1 ()
+%!  ## ERROR; sigma used as variable and later parsed as command
+%!  sigma = svd (1);
+%!  eval ("sigma -1;");
+%!endfunction
+%!
+%!function f1a ()
+%!  ## Assignment of eval result means eval code is not parsed as command.
+%!  sigma = svd (1);
+%!  val = eval ("sigma -1;");
+%!endfunction
+%!
+%!function f2 ()
+%!  ## ERROR; sigma used as variable and later parsed as command
+%!  [u, sigma, v] = svd (1);
+%!  eval ("sigma -1;");
+%!endfunction
+%!
+%!function f2a ()
+%!  ## Assignment of eval result means eval code is not parsed as command.
+%!  [u, sigma, v] = svd (1);
+%!  val = eval ("sigma -1;");
+%!endfunction
+%!
+%!function f3 (sigma)
+%!  ## No assignment of eval result means eval code is parsed as command.
+%!  ## If f3 is called with a value for sigma, it will be used.  Otherwise,
+%!  ## search for the function sigma and call with no arguments.
+%!  eval ("sigma -1;");
+%!endfunction
+%!
+%!function f3a (sigma)
+%!  ## Assignment of eval result means eval code is not parsed as command.
+%!  val = eval ("sigma -1;");
+%!endfunction
+%!
+%!function f4 ()
+%!  ## No assignment of eval result means eval code is parsed as command.
+%!  eval ("sigma -1;");
+%!endfunction
+%!
+%!function f4a ()
+%!  ## Assignment of eval result means eval code is not parsed as command.
+%!  val = eval ("sigma -1;");
+%!endfunction
+%!
+%!test <55610>
+%! global sigma_call;
+%! sigma_call = "none";
+%! ## Matlab complains about sigma previously being used as a variable
+%! ## before being used as a command.
+%! fail ("f1 ()", "used as variable and later as function");
+%! assert (sigma_call, "none");
+%! clear -global sigma_call
+%!
+%!test <55610>
+%! global sigma_call;
+%! sigma_call = "none";
+%! f1a ();
+%! assert (sigma_call, "none");
+%! clear -global sigma_call
+%!
+%!test <55610>
+%! global sigma_call;
+%! sigma_call = "none";
+%! ## Matlab complains about sigma previously being used as a variable
+%! ## before being used as a command.
+%! fail ("f2 ()", "used as variable and later as function");
+%! assert (sigma_call, "none");
+%! clear -global sigma_call
+%!
+%!test <55610>
+%! global sigma_call;
+%! sigma_call = "none";
+%! f2a ();
+%! assert (sigma_call, "none");
+%! clear -global sigma_call
+%!
+%!test <55610>
+%! global sigma_call;
+%! sigma_call = "none";
+%! f3 ();
+%! assert (sigma_call, "command");
+%! clear -global sigma_call
+%!
+%!test <55610>
+%! global sigma_call;
+%! sigma_call = "none";
+%! f3a ();
+%! assert (sigma_call, "function");
+%! clear -global sigma_call
+%!
+%!test <55610>
+%! global sigma_call;
+%! sigma_call = "none";
+%! ## NOTE: this result disagrees with Matlab, which evaluates sigma
+%! ## as a command-style function even though there is a variable named
+%! ## sigma defined in the workspace prior to evaluating the function
+%! ## call (compare with f1() and f2() above).
+%! fail ("f3 (1)", "used as variable and later as function");
+%! assert (sigma_call, "none");
+%! clear -global sigma_call
+%!
+%!test <55610>
+%! global sigma_call;
+%! sigma_call = "none";
+%! f3a (1);
+%! assert (sigma_call, "none");
+%! clear -global sigma_call
+%!
+%!test <55610>
+%! global sigma_call;
+%! sigma_call = "none";
+%! f4 ();
+%! assert (sigma_call, "command");
+%! clear -global sigma_call
+%!
+%!test <55610>
+%! global sigma_call;
+%! sigma_call = "none";
+%! f4a ();
+%! assert (sigma_call, "function");
+%! clear -global sigma_call