git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@5258 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
174
src/variable.cpp
174
src/variable.cpp
@ -608,7 +608,7 @@ void Variable::copy(int narg, char **from, char **to)
|
||||
constant = PI
|
||||
thermo keyword = ke, vol, atoms, ...
|
||||
math operation = (),-x,x+y,x-y,x*y,x/y,x^y,
|
||||
x==y,x!=y,x<y,x<=y,x>y,x>=y,
|
||||
x==y,x!=y,x<y,x<=y,x>y,x>=y,x&&y,x||y,
|
||||
sqrt(x),exp(x),ln(x),log(x),
|
||||
sin(x),cos(x),tan(x),asin(x),atan2(y,x),...
|
||||
group function = count(group), mass(group), xcm(group,x), ...
|
||||
@ -3069,3 +3069,175 @@ void Variable::print_tree(Tree *tree, int level)
|
||||
if (tree->right) print_tree(tree->right,level+1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
recursive evaluation of string str
|
||||
called from "if" command in input script
|
||||
str is a boolean expression containing one or more items:
|
||||
number = 0.0, -5.45, 2.8e-4, ...
|
||||
math operation = (),x==y,x!=y,x<y,x<=y,x>y,x>=y,x&&y,x||y
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double Variable::evaluate_boolean(char *str)
|
||||
{
|
||||
int op,opprevious;
|
||||
double value1,value2;
|
||||
char onechar;
|
||||
char *ptr;
|
||||
|
||||
double argstack[MAXLEVEL];
|
||||
int opstack[MAXLEVEL];
|
||||
int nargstack = 0;
|
||||
int nopstack = 0;
|
||||
|
||||
int i = 0;
|
||||
int expect = ARG;
|
||||
|
||||
while (1) {
|
||||
onechar = str[i];
|
||||
|
||||
// whitespace: just skip
|
||||
|
||||
if (isspace(onechar)) i++;
|
||||
|
||||
// ----------------
|
||||
// parentheses: recursively evaluate contents of parens
|
||||
// ----------------
|
||||
|
||||
else if (onechar == '(') {
|
||||
if (expect == OP) error->all("Invalid Boolean syntax in if command");
|
||||
expect = OP;
|
||||
|
||||
char *contents;
|
||||
i = find_matching_paren(str,i,contents);
|
||||
i++;
|
||||
|
||||
// evaluate contents and push on stack
|
||||
|
||||
argstack[nargstack++] = evaluate_boolean(contents);
|
||||
|
||||
delete [] contents;
|
||||
|
||||
// ----------------
|
||||
// number: push value onto stack
|
||||
// ----------------
|
||||
|
||||
} else if (isdigit(onechar) || onechar == '.') {
|
||||
if (expect == OP) error->all("Invalid Boolean syntax in if command");
|
||||
expect = OP;
|
||||
|
||||
// istop = end of number, including scientific notation
|
||||
|
||||
int istart = i;
|
||||
while (isdigit(str[i]) || str[i] == '.') i++;
|
||||
if (str[i] == 'e' || str[i] == 'E') {
|
||||
i++;
|
||||
if (str[i] == '+' || str[i] == '-') i++;
|
||||
while (isdigit(str[i])) i++;
|
||||
}
|
||||
int istop = i - 1;
|
||||
|
||||
int n = istop - istart + 1;
|
||||
char *number = new char[n+1];
|
||||
strncpy(number,&str[istart],n);
|
||||
number[n] = '\0';
|
||||
|
||||
argstack[nargstack++] = atof(number);
|
||||
|
||||
delete [] number;
|
||||
|
||||
// ----------------
|
||||
// Boolean operator, including end-of-string
|
||||
// ----------------
|
||||
|
||||
} else if (strchr("<>=!&|\0",onechar)) {
|
||||
if (onechar == '=') {
|
||||
if (str[i+1] != '=')
|
||||
error->all("Invalid Boolean syntax in if command");
|
||||
op = EQ;
|
||||
i++;
|
||||
} else if (onechar == '!') {
|
||||
if (str[i+1] != '=')
|
||||
error->all("Invalid Boolean syntax in if command");
|
||||
op = NE;
|
||||
i++;
|
||||
} else if (onechar == '<') {
|
||||
if (str[i+1] != '=') op = LT;
|
||||
else {
|
||||
op = LE;
|
||||
i++;
|
||||
}
|
||||
} else if (onechar == '>') {
|
||||
if (str[i+1] != '=') op = GT;
|
||||
else {
|
||||
op = GE;
|
||||
i++;
|
||||
}
|
||||
} else if (onechar == '&') {
|
||||
if (str[i+1] != '&')
|
||||
error->all("Invalid Boolean syntax in if command");
|
||||
op = AND;
|
||||
i++;
|
||||
} else if (onechar == '|') {
|
||||
if (str[i+1] != '|')
|
||||
error->all("Invalid Boolean syntax in if command");
|
||||
op = OR;
|
||||
i++;
|
||||
} else op = DONE;
|
||||
|
||||
i++;
|
||||
|
||||
if (expect == ARG) error->all("Invalid Boolean syntax in if command");
|
||||
expect = ARG;
|
||||
|
||||
// evaluate stack as deep as possible while respecting precedence
|
||||
// before pushing current op onto stack
|
||||
|
||||
while (nopstack && precedence[opstack[nopstack-1]] >= precedence[op]) {
|
||||
opprevious = opstack[--nopstack];
|
||||
|
||||
value2 = argstack[--nargstack];
|
||||
value1 = argstack[--nargstack];
|
||||
|
||||
if (opprevious == EQ) {
|
||||
if (value1 == value2) argstack[nargstack++] = 1.0;
|
||||
else argstack[nargstack++] = 0.0;
|
||||
} else if (opprevious == NE) {
|
||||
if (value1 != value2) argstack[nargstack++] = 1.0;
|
||||
else argstack[nargstack++] = 0.0;
|
||||
} else if (opprevious == LT) {
|
||||
if (value1 < value2) argstack[nargstack++] = 1.0;
|
||||
else argstack[nargstack++] = 0.0;
|
||||
} else if (opprevious == LE) {
|
||||
if (value1 <= value2) argstack[nargstack++] = 1.0;
|
||||
else argstack[nargstack++] = 0.0;
|
||||
} else if (opprevious == GT) {
|
||||
if (value1 > value2) argstack[nargstack++] = 1.0;
|
||||
else argstack[nargstack++] = 0.0;
|
||||
} else if (opprevious == GE) {
|
||||
if (value1 >= value2) argstack[nargstack++] = 1.0;
|
||||
else argstack[nargstack++] = 0.0;
|
||||
} else if (opprevious == AND) {
|
||||
if (value1 != 0.0 && value2 != 0.0) argstack[nargstack++] = 1.0;
|
||||
else argstack[nargstack++] = 0.0;
|
||||
} else if (opprevious == OR) {
|
||||
if (value1 != 0.0 || value2 != 0.0) argstack[nargstack++] = 1.0;
|
||||
else argstack[nargstack++] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
// if end-of-string, break out of entire formula evaluation loop
|
||||
|
||||
if (op == DONE) break;
|
||||
|
||||
// push current operation onto stack
|
||||
|
||||
opstack[nopstack++] = op;
|
||||
|
||||
} else error->all("Invalid Boolean syntax in if command");
|
||||
}
|
||||
|
||||
if (nopstack) error->all("Invalid Boolean syntax in if command");
|
||||
if (nargstack != 1) error->all("Invalid Boolean syntax in if command");
|
||||
return argstack[0];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user