Merge pull request #6180 from gemu2015/scripter-update

scripter expression brackets
This commit is contained in:
Theo Arends 2019-08-05 13:46:08 +02:00 committed by GitHub
commit 266856eb28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 214 additions and 182 deletions

View File

@ -172,7 +172,9 @@ then
remarks: remarks:
the last closing bracket must be on a single line the last closing bracket must be on a single line
the condition may not be enclosed in brackets the condition may be enclosed in brackets
and on the same line conditions may be bracketed e.g. if ((a==b) and ((c==d) or (c==e)) and (s!="x"))
>**break** exits a section or terminates a for next loop >**break** exits a section or terminates a for next loop
**dpx** sets decimal precision to x (0-9) **dpx** sets decimal precision to x (0-9)

View File

@ -1935,7 +1935,111 @@ void toSLog(const char *str) {
#endif #endif
} }
char *Evaluate_expression(char *lp,uint8_t and_or, uint8_t *result,JsonObject *jo) {
float fvar,*dfvar,fvar1;
uint8_t numeric;
struct T_INDEX ind;
uint8_t vtype=0,lastop;
uint8_t res=0;
SCRIPT_SKIP_SPACES
if (*lp=='(') {
lp++;
lp=Evaluate_expression(lp,and_or,result,jo);
lp++;
// check for next and or
SCRIPT_SKIP_SPACES
if (!strncmp(lp,"or",2)) {
lp+=2;
and_or=1;
SCRIPT_SKIP_SPACES
lp=Evaluate_expression(lp,and_or,result,jo);
} else if (!strncmp(lp,"and",3)) {
lp+=3;
and_or=2;
SCRIPT_SKIP_SPACES
lp=Evaluate_expression(lp,and_or,result,jo);
}
return lp;
}
// compare
dfvar=&fvar;
glob_script_mem.glob_error=0;
char *slp=lp;
numeric=1;
lp=GetNumericResult(lp,OPER_EQU,dfvar,0);
if (glob_script_mem.glob_error==1) {
// was string, not number
char cmpstr[SCRIPT_MAXSSIZE];
lp=slp;
numeric=0;
// get the string
lp=isvar(lp,&vtype,&ind,0,cmpstr,0);
lp=getop(lp,&lastop);
// compare string
char str[SCRIPT_MAXSSIZE];
lp=GetStringResult(lp,OPER_EQU,str,jo);
if (lastop==OPER_EQUEQU || lastop==OPER_NOTEQU) {
uint8_t res=0;
res=strcmp(cmpstr,str);
if (lastop==OPER_EQUEQU) res=!res;
if (!and_or) {
*result=res;
} else if (and_or==1) {
*result|=res;
} else {
*result&=res;
}
}
} else {
// numeric
// evaluate operand
lp=getop(lp,&lastop);
lp=GetNumericResult(lp,OPER_EQU,&fvar1,jo);
switch (lastop) {
case OPER_EQUEQU:
res=(*dfvar==fvar1);
break;
case OPER_NOTEQU:
res=(*dfvar!=fvar1);
break;
case OPER_LOW:
res=(*dfvar<fvar1);
break;
case OPER_LOWEQU:
res=(*dfvar<=fvar1);
break;
case OPER_GRT:
res=(*dfvar>fvar1);
break;
case OPER_GRTEQU:
res=(*dfvar>=fvar1);
break;
default:
// error
break;
}
if (!and_or) {
*result=res;
} else if (and_or==1) {
*result|=res;
} else {
*result&=res;
}
}
exit:
#if SCRIPT_DEBUG>0
char tbuff[128];
sprintf(tbuff,"p1=%d,p2=%d,cmpres=%d line: ",(int32_t)*dfvar,(int32_t)fvar1,*result);
toLogEOL(tbuff,lp);
#endif
return lp;
}
//#define IFTHEN_DEBUG //#define IFTHEN_DEBUG
@ -2305,19 +2409,15 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
// check for variable result // check for variable result
if (if_state[ifstck]==1) { if (if_state[ifstck]==1) {
// compare // evaluate exxpression
dfvar=&fvar; lp=Evaluate_expression(lp,and_or,&if_result[ifstck],jo);
glob_script_mem.glob_error=0; SCRIPT_SKIP_SPACES
char *slp=lp; if (*lp=='{' && if_state[ifstck]==1) {
numeric=1; lp+=1; // then
lp=GetNumericResult(lp,OPER_EQU,dfvar,0); if_state[ifstck]=2;
if (glob_script_mem.glob_error==1) { if (if_exe[ifstck-1]) if_exe[ifstck]=if_result[ifstck];
// was string, not number
lp=slp;
numeric=0;
// get the string
lp=isvar(lp,&vtype,&ind,0,cmpstr,0);
} }
goto next_line;
} else { } else {
lp=isvar(lp,&vtype,&ind,&sysvar,0,0); lp=isvar(lp,&vtype,&ind,&sysvar,0,0);
if (vtype!=VAR_NV) { if (vtype!=VAR_NV) {
@ -2335,180 +2435,110 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
sysv_type=0; sysv_type=0;
} }
numeric=1; numeric=1;
} else { lp=getop(lp,&lastop);
// string result char *slp=lp;
numeric=0; glob_script_mem.glob_error=0;
sindex=index; lp=GetNumericResult(lp,OPER_EQU,&fvar,jo);
} if (glob_script_mem.glob_error==1) {
} // mismatch was string, not number
} // get the string and convert to number
// evaluate operand lp=isvar(slp,&vtype,&ind,0,cmpstr,jo);
lp=getop(lp,&lastop); fvar=CharToFloat(cmpstr);
if (if_state[ifstck]==1) { }
if (numeric) { switch (lastop) {
uint8_t res=0; case OPER_EQU:
lp=GetNumericResult(lp,OPER_EQU,&fvar1,jo); if (glob_script_mem.var_not_found) {
switch (lastop) { if (!js) toLog("var not found\n");
case OPER_EQUEQU: goto next_line;
res=(*dfvar==fvar1); }
break; *dfvar=fvar;
case OPER_NOTEQU: break;
res=(*dfvar!=fvar1); case OPER_PLSEQU:
break; *dfvar+=fvar;
case OPER_LOW: break;
res=(*dfvar<fvar1); case OPER_MINEQU:
break; *dfvar-=fvar;
case OPER_LOWEQU: break;
res=(*dfvar<=fvar1); case OPER_MULEQU:
break; *dfvar*=fvar;
case OPER_GRT: break;
res=(*dfvar>fvar1); case OPER_DIVEQU:
break; *dfvar/=fvar;
case OPER_GRTEQU: break;
res=(*dfvar>=fvar1); case OPER_PERCEQU:
break; *dfvar=fmodf(*dfvar,fvar);
default: break;
// error case OPER_ANDEQU:
break; *dfvar=(uint32_t)*dfvar&(uint32_t)fvar;
} break;
case OPER_OREQU:
if (!and_or) { *dfvar=(uint32_t)*dfvar|(uint32_t)fvar;
if_result[ifstck]=res; break;
} else if (and_or==1) { case OPER_XOREQU:
if_result[ifstck]|=res; *dfvar=(uint32_t)*dfvar^(uint32_t)fvar;
} else { break;
if_result[ifstck]&=res; default:
} // error
#if SCRIPT_DEBUG>0 break;
char tbuff[128]; }
sprintf(tbuff,"p1=%d,p2=%d,cmpres=%d line: ",(int32_t)*dfvar,(int32_t)fvar1,if_result[ifstck]); // var was changed
toLogEOL(tbuff,lp); glob_script_mem.type[globvindex].bits.changed=1;
#endif if (glob_script_mem.type[globvindex].bits.is_filter) {
if (globaindex>=0) {
} else { Set_MFVal(glob_script_mem.type[globvindex].index,globaindex,*dfvar);
// compare string } else {
char str[SCRIPT_MAXSSIZE]; Set_MFilter(glob_script_mem.type[globvindex].index,*dfvar);
lp=GetStringResult(lp,OPER_EQU,str,0);
if (lastop==OPER_EQUEQU || lastop==OPER_NOTEQU) {
uint8_t res=0;
res=strcmp(cmpstr,str);
if (lastop==OPER_EQUEQU) res=!res;
if (!and_or) {
if_result[ifstck]=res;
} else if (and_or==1) {
if_result[ifstck]|=res;
} else {
if_result[ifstck]&=res;
}
}
}
SCRIPT_SKIP_SPACES
if (*lp=='{' && if_state[ifstck]==1) {
lp+=1; // then
if_state[ifstck]=2;
if (if_exe[ifstck-1]) if_exe[ifstck]=if_result[ifstck];
}
goto next_line;
} else {
if (numeric) {
char *slp=lp;
glob_script_mem.glob_error=0;
lp=GetNumericResult(lp,OPER_EQU,&fvar,jo);
if (glob_script_mem.glob_error==1) {
// mismatch was string, not number
// get the string and convert to number
lp=isvar(slp,&vtype,&ind,0,cmpstr,jo);
fvar=CharToFloat(cmpstr);
}
switch (lastop) {
case OPER_EQU:
if (glob_script_mem.var_not_found) {
if (!js) toLog("var not found\n");
goto next_line;
} }
*dfvar=fvar; }
break;
case OPER_PLSEQU: if (sysv_type) {
*dfvar+=fvar; switch (sysv_type) {
break; case SCRIPT_LOGLEVEL:
case OPER_MINEQU: glob_script_mem.script_loglevel=*dfvar;
*dfvar-=fvar; break;
break; case SCRIPT_TELEPERIOD:
case OPER_MULEQU: if (*dfvar<10) *dfvar=10;
*dfvar*=fvar; if (*dfvar>300) *dfvar=300;
break; Settings.tele_period=*dfvar;
case OPER_DIVEQU: break;
*dfvar/=fvar; }
break; sysv_type=0;
case OPER_PERCEQU: }
*dfvar=fmodf(*dfvar,fvar);
break;
case OPER_ANDEQU:
*dfvar=(uint32_t)*dfvar&(uint32_t)fvar;
break;
case OPER_OREQU:
*dfvar=(uint32_t)*dfvar|(uint32_t)fvar;
break;
case OPER_XOREQU:
*dfvar=(uint32_t)*dfvar^(uint32_t)fvar;
break;
default:
// error
break;
}
// var was changed
glob_script_mem.type[globvindex].bits.changed=1;
if (glob_script_mem.type[globvindex].bits.is_filter) {
if (globaindex>=0) {
Set_MFVal(glob_script_mem.type[globvindex].index,globaindex,*dfvar);
} else { } else {
Set_MFilter(glob_script_mem.type[globvindex].index,*dfvar); // string result
} numeric=0;
} sindex=index;
// string result
char str[SCRIPT_MAXSSIZE];
char *slp=lp;
lp=getop(lp,&lastop);
lp=GetStringResult(lp,OPER_EQU,str,jo);
if (!js && glob_script_mem.var_not_found) {
// mismatch
lp=GetNumericResult(slp,OPER_EQU,&fvar,0);
dtostrfd(fvar,6,str);
glob_script_mem.var_not_found=0;
}
if (sysv_type) { if (!glob_script_mem.var_not_found) {
switch (sysv_type) { // var was changed
case SCRIPT_LOGLEVEL: glob_script_mem.type[globvindex].bits.changed=1;
glob_script_mem.script_loglevel=*dfvar; if (lastop==OPER_EQU) {
break; strlcpy(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize);
case SCRIPT_TELEPERIOD: } else if (lastop==OPER_PLSEQU) {
if (*dfvar<10) *dfvar=10; strncat(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize);
if (*dfvar>300) *dfvar=300; }
Settings.tele_period=*dfvar; }
break;
} }
sysv_type=0;
}
} else { }
// string result SCRIPT_SKIP_SPACES
char str[SCRIPT_MAXSSIZE]; if (*lp=='{' && if_state[ifstck]==3) {
char *slp=lp; lp+=1; // else
lp=GetStringResult(lp,OPER_EQU,str,jo); //if_state[ifstck]=3;
if (!js && glob_script_mem.var_not_found) { }
// mismatch goto next_line;
lp=GetNumericResult(slp,OPER_EQU,&fvar,0); }
dtostrfd(fvar,6,str);
glob_script_mem.var_not_found=0;
}
if (!glob_script_mem.var_not_found) {
// var was changed
glob_script_mem.type[globvindex].bits.changed=1;
if (lastop==OPER_EQU) {
strlcpy(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize);
} else if (lastop==OPER_PLSEQU) {
strncat(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize);
}
}
}
SCRIPT_SKIP_SPACES
if (*lp=='{' && if_state[ifstck]==3) {
lp+=1; // else
//if_state[ifstck]=3;
}
goto next_line;
}
} else { } else {
// decode line // decode line
if (*lp=='>' && tlen==1) { if (*lp=='>' && tlen==1) {