📄 numexpr.c
字号:
expr->flags|=FPL_ACTION; scr->text+=2; CALL(AddUnary(scr, expr, OP_PREDEC)); CALL(Put(scr, COMP_PREDEC)); } else { CALL(AddUnary(scr, expr, OP_MINUS)); CALL(Put(scr, COMP_NEGATE)); scr->text++; } break; default: INFO(scr, CERROR_MISSING_OPERAND); return FPLERR_MISSING_OPERAND; } }#if 0 if(control&CON_STRING) /* get outta string calcs */ break;#endif } else { /* waiting for operator */ uchar *point=scr->text; switch(*scr->text) { case CHAR_ASSIGN: if(scr->text[1]==CHAR_ASSIGN) { expr->operator=OP_EQUAL; CALL(Put(scr, COMP_EQUAL)); scr->text+=2; } break; case CHAR_AND: if(scr->text[1]==CHAR_AND) { /* * This is a logical AND (&&) */ expr->operator=OP_LOGAND; scr->text+=2; CALL(Put(scr, COMP_LOGICAND)); } else { expr->operator=OP_BINAND; scr->text++; CALL(Put(scr, COMP_BINARYAND)); } break; case CHAR_OR: if(scr->text[1]==CHAR_OR) { /* * This is a logical OR operator (||) */ expr->operator=OP_LOGOR; CALL(Put(scr, COMP_LOGICOR)); scr->text+=2; } else { expr->operator=OP_BINOR; CALL(Put(scr, COMP_BINARYOR)); scr->text++; } break; case CHAR_PLUS: expr->operator=OP_PLUS; CALL(Put(scr, COMP_PLUS)); ++scr->text; break; case CHAR_MINUS: expr->operator=OP_MINUS; CALL(Put(scr, COMP_MINUS)); ++scr->text; break; case CHAR_QUESTION: CALL(Put(scr, COMP_CONDOPSTART)); ++scr->text; /* * This is the first operator in a conditional operator sequence (?) */ /* * Clean the expression so far. */ CALL(Calc(scr, val, basexpr, (char)(control&CON_NUM))); /* erase the list */ expr = basexpr; CALL(Put(scr, COMP_START_OF_EXPR)); CALL(Expression(val, scr, CON_NORMAL, NULL)); CALL(Put(scr, COMP_END_OF_EXPR)); if(*scr->text!=CHAR_COLON) { INFO(scr, CERROR_ILLEGAL_CONDOPER); return FPLERR_ILLEGAL_CONDOP; } else ++scr->text; CALL(Put(scr, COMP_CONDOPEND)); CALL(Put(scr, COMP_START_OF_EXPR)); CALL(Expression(val, scr, CON_NORMAL, NULL)); CALL(Put(scr, COMP_END_OF_EXPR)); point=scr->text; break; case CHAR_MULTIPLY: expr->operator=OP_MULTIPLY; CALL(Put(scr, COMP_MULTIPLY)); ++scr->text; break; case CHAR_DIVIDE: expr->operator=OP_DIVISION; CALL(Put(scr, COMP_DIVISION)); ++scr->text; break; case CHAR_REMAIN: expr->operator=OP_REMAIN; CALL(Put(scr, COMP_REMAIN)); ++scr->text; break; case CHAR_XOR: expr->operator=OP_BINXOR; CALL(Put(scr, COMP_XOR)); ++scr->text; break; case CHAR_LESS_THAN: if(scr->text[1]==CHAR_ASSIGN) { CALL(Put(scr, COMP_LESSEQ)); scr->text+=2; expr->operator=OP_LESSEQ; } else if(scr->text[1]==CHAR_LESS_THAN) { CALL(Put(scr, COMP_SHIFTLEFT)); scr->text+=2; expr->operator=OP_SHIFTL; } else { CALL(Put(scr, COMP_LESS)); scr->text++; expr->operator=OP_LESS; } break; case CHAR_GREATER_THAN: if(scr->text[1]==CHAR_ASSIGN) { CALL(Put(scr, COMP_GREATEQ)); expr->operator= OP_GRETEQ; scr->text+=2; } else if(scr->text[1]==CHAR_GREATER_THAN) { CALL(Put(scr, COMP_SHIFTRIGHT)); scr->text+=2; expr->operator=OP_SHIFTR; } else { CALL(Put(scr, COMP_GREATER)); scr->text++; expr->operator=OP_GRET; } break; case CHAR_NOT_OPERATOR: if(scr->text[1]==CHAR_ASSIGN) { expr->operator=OP_NOTEQ; CALL(Put(scr, COMP_NOTEQUAL)); scr->text+=2; } break; case CHAR_COMMA: if(control&CON_GROUNDLVL) { Clean(scr, basexpr); GETMEM(basexpr, sizeof(struct Expr)); expr=basexpr; expr->val.val=0; expr->unary=NULL; expr->operator=expr->flags=OP_NOTHING; expr->next=NULL; if(!(control&CON_DECLARE)) { /* only output this when not declaring */ CALL(Put(scr, COMP_COMMA)); } ++scr->text; } break; } if(point==scr->text) break; expr->flags&=~FPL_OPERAND; /* clear the operand bit */ } } if(!(control&(CON_DECLARE /* |CON_ACTION */ ))) { /* * Get result of the current expression only if this isn't called * as a declaring (no one wants the return code from 'int a'!) * or a stand-alone (they have no receiver anyway) statement. */ CALL(Calc(scr, val, basexpr, (char)(control&CON_NUM))); /* * If this was a stand alone statement, including no action returns an * error! */ if(control&CON_ACTION && !(val->flags&FPL_ACTION)) { INFO(scr, CERROR_INCOMPLETE_STATEMENT); return FPLERR_NO_ACTION; } } Clean(scr, basexpr); /* erase the rest of the list */ if(dims) FREE(dims); return(FPL_OK);}/********************************************************************** * * ReturnCode Calc(); * * Returns the result in the first Expr struct of the expression that * the second parameter holds. This function does not free the expression * list. * *******/static ReturnCodeCalc(struct Data *scr, struct Expr *val, struct Expr *basexpr, char numeric){ struct Expr *expr=basexpr, *last; struct Unary *un, *next; /* first all Unary expressions */ if(numeric) { while(expr) { if(expr->flags&FPL_STRING) { return FPLERR_ILLEGAL_VARIABLE; } else { un=expr->unary; while(un) { switch(un->unary) { case OP_PREDEC: case OP_PREINC: return FPLERR_ILLEGAL_PREOPERATION; } next=un->next; FREE(un); un=next; } } expr=expr->next; } } last=expr=basexpr; while(expr=expr->next) { last->flags|=expr->flags; last->next=expr->next; FREE(expr); expr=last; } val->val.val=basexpr->val.val; /* get the final value */ val->flags=basexpr->flags; /* copy the flags */ return(FPL_OK);}/********************************************************************** * * AddUnary(); * * Build a linked list on the unary member of the Expr struct! * ******/static ReturnCodeAddUnary(struct Data *scr, struct Expr *expr, Operator unary){ struct Unary *next=expr->unary; GETMEM(expr->unary, sizeof(struct Unary)); expr->unary->unary=unary; expr->unary->next=next; return(FPL_OK);}/********************************************************************** * * Clean() * * Erases every track of the linked TalStruct list... * ******/static void Clean(struct Data *scr, struct Expr *basexpr){ struct Expr *last; while(basexpr) { last=basexpr->next; FREE(basexpr); basexpr=last; }}/********************************************************************** * * Convert() * * Converts the following "string" in the line to a string which it returns. * *********/static ReturnCode INLINE Convert(struct Expr *expr, struct Data *scr){ ReturnCode ret=FPL_OK; long a; long pos=0; /* start position */ struct fplStr *pointer, *pek; expr->flags|=FPL_STRING; GETMEM(pointer, sizeof(struct fplStr) + ADDSTRING_DEFAULT); /* create default string space */ pointer->alloc=ADDSTRING_DEFAULT; pointer->len=0; expr->val.str=pointer; do { scr->text++; while(*scr->text!=CHAR_QUOTATION_MARK) { CALL(ReturnChar(scr, &a, TRUE)); if(a<256) { pointer->string[pos]=(uchar)a; if(++pos>=pointer->alloc) { GETMEM(pek, (pointer->alloc+=ADDSTRING_INC)+sizeof(struct fplStr)); memcpy(pek, pointer, pos+sizeof(struct fplStr)); FREE(pointer); pointer=pek; expr->val.str=pointer; } } } scr->text++; CALL(Eat(scr)); } while(*scr->text==CHAR_QUOTATION_MARK); pointer->string[pos]=0; /* zero terminate */ pointer->len=pos; /* length of string */ expr->val.str=pointer; return(ret);}#ifdef STRING_STACKstatic ReturnCode INLINE StringToStack(struct Data *scr, struct fplStr **string){ if(scr->stringstackptr >= scr->strings_in_stack_max) { FREE(scr->stringkeeper[ 0 ]); /* free the previous holder of that position! */ scr->stringstackptr = 0; } else scr->strings_in_stack_now++; scr->stringstack[ current_entry ].string = *string; scr->stringstack[ current_entry ].text = scr->text; scr->stringstack[ current_entry ].prg = scr->prg; scr->stringstack[ current_entry ].virprg = scr->virprg; scr->stringstackptr++;}static ReturnCode INLINE StringFromStack(struct Data *scr, struct fplStr **string){ const long num = scr->stringstackptr; const long max = scr->strings_in_stack_max; long count; for(count=0; count<scr->strings_in_stack_now; count++) { if(scr->stringprogram[ (num-count) >= 0 ? num-count : max-count] == scr->text) { *string = scr->stringstack[ count ].string; scr->text = scr->stringstack[ count ].text; scr->prg = scr->stringstack[ count ].prg; scr->virprg = scr->stringstack[ count ].virprg; return FPL_OK; } } *string=NULL; return FPL_OK;}#endif/********************************************************************** * * GetArrayInfo() * * Read the []'s and store the information. Make sure you're standing on * the open bracket! *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -