more consistency checks

This commit is contained in:
Steve Plimpton
2022-06-28 16:37:04 -06:00
parent ae235b1ef5
commit e4e9b2e49a
2 changed files with 40 additions and 23 deletions

View File

@ -156,27 +156,28 @@ and Boolean operators:
Each A and B is a number or string or a variable reference like $a or
${abc}, or A or B can be another Boolean expression.
If a variable is used it can produce a number when evaluated, like an
:doc:`equal-style variable <variable>`. Or it can produce a string,
like an :doc:`index-style variable <variable>`. For an individual
Boolean operator, A and B must both be numbers or must both be
strings. You cannot compare a number to a string.
Note that all variables used will be substituted for before the
Boolean expression in evaluated. A variable can produce a number,
like an :doc:`equal-style variable <variable>`. Or it can produce a
string, like an :doc:`index-style variable <variable>`.
The Boolean operators "==" and "!=" can operate on a pair or strings
or numbers. They cannot compare a number to a string. All the other
Boolean operations can only operate on numbers.
Expressions are evaluated left to right and have the usual C-style
precedence: the unary logical NOT operator "!" has the highest
precedence, the 4 relational operators "<", "<=", ">", and ">=" are
next; the two remaining relational operators "==" and "!=" are next;
then the logical AND operator "&&"; and finally the logical OR
operator "\|\|" and logical XOR (exclusive or) operator "\|\^" have the
lowest precedence. Parenthesis can be used to group one or more
operator "\|\|" and logical XOR (exclusive or) operator "\|\^" have
the lowest precedence. Parenthesis can be used to group one or more
portions of an expression and/or enforce a different order of
evaluation than what would occur with the default precedence.
When the 6 relational operators (first 6 in list above) compare 2
numbers, they return either a 1.0 or 0.0 depending on whether the
relationship between A and B is TRUE or FALSE. When the 6 relational
operators compare 2 strings, they also return a 1.0 or 0.0 for TRUE or
FALSE, but the comparison is done by the C function strcmp().
relationship between A and B is TRUE or FALSE.
When the 3 logical operators (last 3 in list above) compare 2 numbers,
they also return either a 1.0 or 0.0 depending on whether the
@ -190,8 +191,15 @@ returns 1.0 if its argument is 0.0, else it returns 0.0. The 3
logical operators can only be used to operate on numbers, not on
strings.
The overall Boolean expression produces a TRUE result if the result is
non-zero. If the result is zero, the expression result is FALSE.
The overall Boolean expression produces a TRUE result if the numeric
result is non-zero. If the result is zero, the expression result is
FALSE.
.. note::
If the Boolean expression is a single numeric value with no Boolean
operators, it will be FALSE if the value = 0.0, otherwise TRUE. If the
Boolean expression is a single string, it will always be FALSE.
----------

View File

@ -4770,12 +4770,14 @@ double Variable::evaluate_boolean(char *str)
}
if (opprevious == NOT) {
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
if (flag2)
error->all(FLERR,"If command boolean not cannot operate on string");
if (value2 == 0.0) argstack[nargstack].value = 1.0;
else argstack[nargstack].value = 0.0;
} else if (opprevious == EQ) {
if (flag1 != flag2)
error->all(FLERR,"If command boolean comparing string to number");
error->all(FLERR,"If command boolean is comparing string to number");
if (flag2 == 0) {
if (value1 == value2) argstack[nargstack].value = 1.0;
else argstack[nargstack].value = 0.0;
@ -4787,7 +4789,7 @@ double Variable::evaluate_boolean(char *str)
}
} else if (opprevious == NE) {
if (flag1 != flag2)
error->all(FLERR,"Invalid Boolean syntax in if command");
error->all(FLERR,"If command boolean is comparing string to number");
if (flag2 == 0) {
if (value1 != value2) argstack[nargstack].value = 1.0;
else argstack[nargstack].value = 0.0;
@ -4797,32 +4799,39 @@ double Variable::evaluate_boolean(char *str)
delete[] str1;
delete[] str2;
}
} else if (opprevious == LT) {
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
if (value1 < value2) argstack[nargstack].value = 1.0;
if (flag1 || flag2)
error->all(FLERR,"If command boolean can only operate on numbers");
else argstack[nargstack].value = 0.0;
} else if (opprevious == LE) {
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
if (flag1 || flag2)
error->all(FLERR,"If command boolean can only operate on numbers");
if (value1 <= value2) argstack[nargstack].value = 1.0;
else argstack[nargstack].value = 0.0;
} else if (opprevious == GT) {
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
if (flag1 || flag2)
error->all(FLERR,"If command boolean can only operate on numbers");
if (value1 > value2) argstack[nargstack].value = 1.0;
else argstack[nargstack].value = 0.0;
} else if (opprevious == GE) {
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
if (flag1 || flag2)
error->all(FLERR,"If command boolean can only operate on numbers");
if (value1 >= value2) argstack[nargstack].value = 1.0;
else argstack[nargstack].value = 0.0;
} else if (opprevious == AND) {
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
if (flag1 || flag2)
error->all(FLERR,"If command boolean can only operate on numbers");
if (value1 != 0.0 && value2 != 0.0) argstack[nargstack].value = 1.0;
else argstack[nargstack].value = 0.0;
} else if (opprevious == OR) {
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
if (flag1 || flag2)
error->all(FLERR,"If command boolean can only operate on numbers");
if (value1 != 0.0 || value2 != 0.0) argstack[nargstack].value = 1.0;
else argstack[nargstack].value = 0.0;
} else if (opprevious == XOR) {
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
if (flag1 || flag2)
error->all(FLERR,"If command boolean can only operate on numbers");
if ((value1 == 0.0 && value2 != 0.0) ||
(value1 != 0.0 && value2 == 0.0))
argstack[nargstack].value = 1.0;