Mercurial > octave
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