Mercurial > jwe > octave
changeset 31078:396f60e0b984
maint: merge stable to default
author | Arun Giridhar <arungiridhar@gmail.com> |
---|---|
date | Sun, 05 Jun 2022 18:11:28 -0400 |
parents | 398a67a91798 (current diff) 277e31f0bb60 (diff) |
children | bcadacfac44f |
files | etc/NEWS.7.md libinterp/parse-tree/pt-idx.cc |
diffstat | 2 files changed, 56 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/etc/NEWS.7.md Sat Jun 04 17:14:05 2022 -0400 +++ b/etc/NEWS.7.md Sun Jun 05 18:11:28 2022 -0400 @@ -148,19 +148,42 @@ between these operators and the variable they affect were allowed. That is no longer the case. -- When an expression involving operators could be interpreted ambiguously -either as command style syntax or function style syntax, it is -interpreted as command style syntax in more cases than in previous -versions. To still be interpreted as function style syntax, inplace -operators (`+=`, `-=`, `*=`, `.*=`, `/=`, `./=`, `\=`, `.\=`, `^=`, -`.^=`, `|=`, `&=`) must now either be followed by a whitespace character -or must not be preceded by a whitespace character. For ambiguous -expressions involving binary operators (`+`, `-`, `*`, `.*`, `/`, `./`, -`\`, `.\`, `^`, `.^`, `|`, `&`, `||`, `&&`), the same rules apply. -E.g., `a + b`, `a+ b`, or `a+b` are valid expressions if `a` is a -variable. In contrast, `a +b` will throw an error if `a` is a variable. -The latter example is now interpreted as a command syntax expression -(equivalent to the function syntax expression `a ("+b")`). +- Parsing of command-style function calls has changed to improve +consistency of behavior and compatibility with Matlab. This change +affects statements that begin with binary operator expressions when the +first operand is a plain symbol followed by a whitespace character and +the binary operator is not followed by a whitespace character. For +example, the statement `cmd -option` is parsed as a command-style +function call, not a binary subtraction operation. + + This change affects all binary operators: `+`, `-`, `*`, `/`, `\`, +`^`, `.*`, `./`, `.\`, `.^`, `|`, `&`, `||`, `&&`, `+=`, `-=`, `*=`, +`/=`, `\=`, `^=`, `.*=`, `./=`, `.\=`, `.^=`, `|=`, and `&=`. + + Previous versions of Octave would attempt to determine whether the +first operand in an expression was a variable, and if so, parse +expressions like `var -val` as an expression. However, this attempt to +"do the right thing" could cause trouble (for example, if a variable is +only defined conditionally). + + Now, parsing command-style function calls is purely based on syntax. + + Command-style function call syntax is only allowed at the beginning +of a statement. Expressions in other contexts are not affected, so an +expression like `a + b +c` will not be parsed as a command-style function +call. + + For compatibility with Matlab, a binary expression at the beginning +of a statement that starts with one of the symbols `I`, `i`, `J`, `j`, +`Inf`, `inf`, `NaN`, `nan`, or `pi` is never parsed as a command-style +function call. Octave also extends this behavior to `e`, which is not +present as a special numeric constant in Matlab. + + Note that full compatibility with Matlab, which does not have the +OP= operators, would require that even `a -= b` is parsed as a +command-style function call. As that would significantly hinder the use +of these operators, Octave treats them as the other binary operators +instead of providing fully compatible behavior. - The `mldivide` function (i.e., the `\` operator) now uses an LU decomposition to solve nearly singular full square matrices. This is
--- a/libinterp/parse-tree/pt-idx.cc Sat Jun 04 17:14:05 2022 -0400 +++ b/libinterp/parse-tree/pt-idx.cc Sun Jun 05 18:11:28 2022 -0400 @@ -366,7 +366,26 @@ std::string nm = id->name (); if (is_var && is_word_list_cmd ()) - error ("%s used as variable and later as function", nm.c_str ()); + { + bool maybe_binary_op = false; + if ((*p_args) && (*p_args)->length () > 0) + { + // check if first character of first argument might be (the + // start of) a binary operator + std::string ops = "+-*/\\.^|&"; + string_vector arg_list = (*p_args)->get_arg_names (); + if (! arg_list.isempty () + && (ops.find (arg_list(0)[1]) != std::string::npos)) + maybe_binary_op = true; + } + + std::string advice; + if (maybe_binary_op) + advice = "\nCheck whitespace around potential binary operator."; + + error ("variable \"%s\" used as function in command style expression%s", + nm.c_str (), advice.c_str ()); + } if (! is_var) {