📄 numexpr.c
字号:
} /* * We add the symbol to the local data in all cases except when * the symbol is global or static. */ CALL(AddVar(scr, pident, control&(CON_DECLGLOB|CON_DECLSTATIC)? &scr->globals:&scr->locals)); } /* * Now when all declarations is done, all assigns are left: */ expr->flags|=FPL_OPERAND; if (pident->flags&FPL_STRING_VARIABLE) { /* string variable */ if(*scr->text==CHAR_OPEN_BRACKET) { /* just one character */ /* * Get the result of the expression. */ uchar *value; if(control&CON_STRING) { /* NO integers allowed! */ return FPLERR_UNEXPECTED_INT_STATEMENT; } CALL(Expression(val, (scr->text++, scr), CON_GROUNDLVL|CON_NUM, NULL)); if(val->val.val<0) { strcpy(scr->buf, pident->name); return FPLERR_STRING_INDEX; /* we don't know what was meant! */ } if(*scr->text!=CHAR_CLOSE_BRACKET) { CALL(Warn(scr, FPLERR_MISSING_BRACKET)); /* we can continue anyway! */ } else scr->text++; CALL(Eat(scr)); /* eat white space */ if(pident->data.variable.num) { /* pick out the proper array member */ pos=ArrayNum(num, pident->data.variable.num, dims, pident->data.variable.dims); if(pos<0) { strcpy(scr->buf, pident->name); return FPLERR_ILLEGAL_ARRAY; /* we don't know what was meant! */ } } else pos=0; if(!pident->data.variable.var.str[pos] || !pident->data.variable.var.str[pos]->len) /* no-length-string */ return FPLERR_STRING_INDEX; if(val->val.val >= pident->data.variable.var.str[pos]->len) { /* force to zero! */ val->val.val=0; } /* * (I) Here we should be able to operate the character read * from the string. ++ and -- should work to enable advanced * string modification handling without the * overhead of getting the string, changing it and then re- * assign it back. This *MUST* be implemented soon cause * it's a real killer! */ value=(uchar *)&pident->data.variable.var.str[pos]->string[val->val.val]; if(ASSIGN_OPERATOR) { uchar was=*scr->text; long valint=*value; if(pident->flags&FPL_READONLY) return FPLERR_READONLY_VIOLATE; expr->flags|=FPL_ACTION; if(*scr->text==CHAR_ASSIGN) scr->text++; else if(scr->text[2]==CHAR_ASSIGN) scr->text+=3; else scr->text+=2; /* single assign */ CALL(Expression(val, scr, CON_NORMAL|CON_NUM, NULL)); CALL(CmpAssign(scr, val->val.val, &valint, FPL_CHAR_VARIABLE, was)); *value=(uchar)valint; } expr->val.val=*value; /* only one byte */ CALL(NewMember(scr, &expr)); } else if(control&CON_NUM) { /* NO strings allowed! */ return FPLERR_UNEXPECTED_STRING_STATEMENT; /* be able to continue here, we must pass everything that has to to with the strings in this expression */ } else if (*scr->text==CHAR_ASSIGN || (*scr->text==CHAR_PLUS && scr->text[1]==CHAR_ASSIGN)) { uchar array=FALSE; uchar multi=FALSE; struct fplStr **string; /* current string */ uchar app=(*scr->text==CHAR_PLUS); if(pident->flags&FPL_READONLY && !(control&CON_DECLARE)) return FPLERR_READONLY_VIOLATE; scr->text+=1+app; expr->flags|=FPL_ACTION; if(pident->data.variable.num) { /* if array member assign */ Eat(scr); if(*scr->text==CHAR_OPEN_BRACE) { /* array assign */ multi=TRUE; scr->text++; CALL(Eat(scr)); } array=TRUE; } if(!multi) { /* single (array) variable assign */ if(array) { pos=ArrayNum(num, pident->data.variable.num, dims, pident->data.variable.dims); if(pos<0) { CALL(Warn(scr, FPLERR_ILLEGAL_ARRAY)); pos=0; /* we don't know what was meant! */ } } else pos=0; CALL(Expression(val, scr, CON_STRING, NULL)); CALL(StringExpr(val, scr)); /* get more strings? */ string=&pident->data.variable.var.str[pos]; if(!app && val->flags&FPL_NOFREE) { /* * Only do this this is not an append action _and_ * we can't free this string (== someone else is * taking care of this string!) */ if(*string) { FREE_KIND(*string); /* free old string */ } if(val->val.str) { /* duplicate string */ STRFPLDUP((*string), val->val.str); } else *string=NULL; } else { CALL(StrAssign(val->val.str, scr, string, app)); } if(*string && MALLOC_STATIC == TypeMem(pident) ) SwapMem(scr, *string, MALLOC_STATIC); if(app && !(val->flags&FPL_NOFREE) && val->val.str) /* Only do this if appending! */ FREE(val->val.str); } else { /* multi [compound] assign! */ /* * Count the preceding open braces to get proper level * to assign in. */ while(*scr->text==CHAR_OPEN_BRACE) { num++; /* next dimension */ scr->text++; /* pass it! */ CALL(Eat(scr)); } do { do { hit=TRUE; /* parse the controlling braces and commas */ switch(*scr->text) { case CHAR_CLOSE_BRACE: num--; /* back one dimension */ if(num>=0 && num<pident->data.variable.num) dims[num]=0; else { CALL(Warn(scr,FPLERR_ILLEGAL_ARRAY)); num=0; /* force counter to zero! */ } scr->text++; break; case CHAR_COMMA: /* * Increase the last dimension member for next loop: */ if(num>0 && num<=pident->data.variable.num) dims[num-1]++; else { CALL(Warn(scr, FPLERR_ILLEGAL_ARRAY)); /* force counter back to top position! */ num=pident->data.variable.num; } scr->text++; break; case CHAR_OPEN_BRACE: num++; /* next dimension */ scr->text++; break; default: hit=FALSE; break; } if(hit && !ret) { CALL(Eat(scr)); } else break; } while(1); if(!num) break; pos=ArrayNum(num, pident->data.variable.num, dims, pident->data.variable.dims); if(pos<0) { CALL(Warn(scr, FPLERR_ILLEGAL_ARRAY)); pos=0; /* force back to sane number */ } /* assign! */ string=&pident->data.variable.var.str[pos]; CALL(Expression(val, scr, CON_STRING, NULL)); CALL(StringExpr(val, scr)); /* get more strings? */ if(!app && val->flags&FPL_NOFREE) { /* * Only do this this is not an append action _and_ * we can't free this string (== someone else is * taking care of this string!) */ if(*string) { FREE_KIND(*string); /* free old string */ } if(val->val.str) { STRFPLDUP((*string), val->val.str); /* duplicate string */ } else *string = NULL; } else { CALL(StrAssign(val->val.str, scr, string, app)); } if(*string && MALLOC_STATIC == TypeMem(pident)) SwapMem(scr, *string, MALLOC_STATIC); if(app && !(val->flags&FPL_NOFREE) && val->val.str) { /* only if we're appending! */ FREE(val->val.str); }#ifdef STRING_STACK if(app) /* the string couldn't be freed, but we let them know that we don't use it anymore! */ val->val.str->flags=FPLSTR_UNUSED;#endif /* while */ } while(1); } expr->val.str=*string; expr->flags|=FPL_STRING|FPL_NOFREE; } else { if(control&CON_DECLARE) expr->val.val=0; else if(pident->data.variable.num) { pos=ArrayNum(num, pident->data.variable.num, dims, pident->data.variable.dims); if(pos<0) { CALL(Warn(scr, FPLERR_ILLEGAL_ARRAY)); pos=0; /* force back to sane number */ } expr->val.str=pident->data.variable.var.str[pos]; } else expr->val.str=pident->data.variable.var.str[0]; expr->flags|=FPL_STRING|FPL_NOFREE; CALL(StringExpr(expr, scr)); } } else { /* * Integer variable... */ if(control&CON_STRING) { /* NO integers allowed! */ return FPLERR_UNEXPECTED_INT_STATEMENT; }#if 0 if(pident->flags&FPL_READONLY && !(control&CON_DECLARE)) { if(!pident->data.variable.num) expr->val.val=pident->data.variable.var.val32[0]; else { pos=ArrayNum(num, pident->data.variable.num, dims, pident->data.variable.dims); if(pos<0) { CALL(Warn(scr, FPLERR_ILLEGAL_ARRAY)); pos=0; /* force back to sane number */ } expr->val.val=pident->data.variable.var.val32[pos]; } } else#endif if(!expr->operator && !expr->unary && ASSIGN_OPERATOR) { /* integer assign */ uchar array=FALSE; /* is it an array variable */ uchar multi=FALSE; /* mutiple variable */ uchar was=*scr->text; if(pident->flags&FPL_READONLY && !(control&CON_DECLARE)) return FPLERR_READONLY_VIOLATE; expr->flags|=FPL_ACTION; if(*scr->text==CHAR_ASSIGN) scr->text++; else if(scr->text[2]==CHAR_ASSIGN) scr->text+=3; else scr->text+=2; if(pident->data.variable.num) { /* if array member assign */ Eat(scr); if(*scr->text==CHAR_OPEN_BRACE) { /* array assign */ multi=TRUE; scr->text++; CALL(Eat(scr)); } array=TRUE; } if(!multi) { if(!array) pos=0; else { /* single (array) variable assign */ pos=ArrayNum(num, pident->data.variable.num, dims, pident->data.variable.dims); if(pos<0) { CALL(Warn(scr, FPLERR_ILLEGAL_ARRAY)); pos=0; /* force back to a decent number */ } } CALL(Expression(val, scr, CON_NORMAL|CON_NUM, NULL)); CALL(CmpAssign(scr, val->val.val, &pident->data.variable.var.val32[pos], pident->flags, was)); expr->val.val=pident->data.variable.var.val32[pos]; } else { /* multi [compound] assign */ /* * Count the preceding open braces to get proper level * to assign in. */ while(*scr->text==CHAR_OPEN_BRACE) { num++; /* next dimension */ scr->text++; /* pass it! */ CALL(Eat(scr)); } do { while(1) { uchar hit=TRUE; /* parse the controlling braces and commas */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -