⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 numexpr.c

📁 类PASCAL语言的编译器,LINUX环境的,我没试过是否正确.
💻 C
📖 第 1 页 / 共 5 页
字号:
             */            CALL(ScanForNext(scr, OP_LOGOR));            expr->flags = FPL_OPERAND;          }          continue;        } else {          expr->operator=OP_BINOR;          scr->text++;        }        break;      case CHAR_PLUS:        expr->operator=OP_PLUS;        ++scr->text;        break;      case CHAR_MINUS:        expr->operator=OP_MINUS;        ++scr->text;        break;      case CHAR_QUESTION:        ++scr->text;        /*         * This is the first operator in a conditional operator sequence (?)         */        /*         * Get result from everything to the left of this!         */        CALL(Calc(scr, val, basexpr));        /*         * Clean the expression so far.         */        Clean(scr, basexpr);    /* erase the list */        /*         * Start a new list with this result         */        GETMEM(expr, sizeof(struct Expr));        memset(expr, 0, sizeof(struct Expr));        expr->flags = FPL_OPERAND;        basexpr=expr;        if(val->val.val) {          /*           * In this case, its like in the 'a ? b : c' expression and 'a'           * equals 1. Then we should skip the 'c' expression.           */          CALL(Expression(val, scr, CON_NORMAL, NULL));          if(*scr->text++!=CHAR_COLON)            return FPLERR_ILLEGAL_CONDOP;          CALL(ScanForNext(scr, OP_COND2));                  }        else {          /*           * In this case, its like in the 'a ? b : c' expression and 'a'           * equals 0. Then we should skip the 'b' expression.           */          CALL(ScanForNext(scr, OP_COND1));          if(*scr->text++!=CHAR_COLON)            return FPLERR_ILLEGAL_CONDOP;          CALL(Expression(val, scr, CON_NORMAL, NULL));        }        expr->val.val = val->val.val;        continue; /* check for next operator */        break;#if 0      case CHAR_COLON:        if(conditional) {          /* only if preceeded with the regular '?' operator! */	  conditional--;          expr->operator=OP_COND2;          ++scr->text;        }        break;#endif      case CHAR_MULTIPLY:        expr->operator=OP_MULTIPLY;        ++scr->text;        break;      case CHAR_DIVIDE:        expr->operator=OP_DIVISION;        ++scr->text;        break;      case CHAR_REMAIN:        expr->operator=OP_REMAIN;        ++scr->text;        break;      case CHAR_XOR:        expr->operator=OP_BINXOR;        ++scr->text;        break;      case CHAR_LESS_THAN:        if(scr->text[1]==CHAR_ASSIGN) {          scr->text+=2;          expr->operator=OP_LESSEQ;        } else if(scr->text[1]==CHAR_LESS_THAN) {          scr->text+=2;          expr->operator=OP_SHIFTL;        } else {          scr->text++;          expr->operator=OP_LESS;        }        break;      case CHAR_GREATER_THAN:	if(scr->text[1]==CHAR_ASSIGN) {          expr->operator= OP_GRETEQ;          scr->text+=2;        } else if(scr->text[1]==CHAR_GREATER_THAN) {          scr->text+=2;          expr->operator=OP_SHIFTR;        } else {          scr->text++;          expr->operator=OP_GRET;        }        break;      case CHAR_NOT_OPERATOR:        if(scr->text[1]==CHAR_ASSIGN) {          expr->operator=OP_NOTEQ;          scr->text+=2;        }        break;      case CHAR_COMMA:        if(control&CON_GROUNDLVL) {          /*           * Get result from everything to the left of this!           * For unary operators.           */          CALL(Calc(scr, val, basexpr));          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;          scr->text++;        }        break;      }      if(point==scr->text)        break;      expr->flags&=~FPL_OPERAND; /* clear the operand bit */    }  } while(1);  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));    /*     * If this was a stand alone statement, including no action returns an     * error!     */    if(control&CON_ACTION && !(val->flags&FPL_ACTION)) {      CALL(Warn(scr, FPLERR_NO_ACTION));      /* but we can just as good keep on anyway! */    }  }  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. * *******/ReturnCode REGARGSCalc(struct Data *scr,     struct Expr *val,     struct Expr *basexpr){  /* lower value=higher priority. Order as the operator list in script.h:   *|    +  -  /  * << >>  %  &  |  ^ && ||  ~    ?   :  == <= >=  <  > != ! */  const static uchar priority[]={    (uchar)255, 1, 1, 0, 0, 2, 2, 0, 5, 7, 6, 8, 9, (uchar)255, 10, 10, 4, 3, 3, 3, 3, 4, (uchar)255    };  ReturnCode ret;  uchar pri, minpri=(uchar)255, maxpri=0;  struct Expr *expr=basexpr, *last;  struct Unary *un, *next;  /* first all Unary expressions */  if(!(expr->flags&FPL_STRING)) {    while(expr) {      if(priority[expr->operator]<minpri)        minpri=priority[expr->operator]; /* get the lowest priority */      if(priority[expr->operator]>maxpri && expr->operator!=OP_NOTHING)        maxpri=priority[expr->operator]; /* get the highest priority */      if(expr->flags&FPL_STRING) {        CALL(Warn(scr, FPLERR_ILLEGAL_VARIABLE));        /*         * A string among the integers!         * We remove this and try next!         */        last=expr->next;        FREE(expr); /* delete this bastard from the expression!!! */        expr=last;      } else {        un=expr->unary;        while(un) {          switch(un->unary) {          case OP_NOT:            expr->val.val=!expr->val.val;            break;          case OP_COMPL:            expr->val.val=~expr->val.val;            break;          case OP_MINUS:            expr->val.val=-expr->val.val;            break;            /*simply ignored!              case OP_PLUS:              break;              */          case OP_PREDEC:          case OP_PREINC:            CALL(Warn(scr, FPLERR_ILLEGAL_PREOPERATION));            /* just ignore it! */          }          next=un->next;          FREE(un);          un=next;        }      }      expr=expr->next;    }  }  /*   * Calculate all members of the linked list in the proper way and put   * the result in "val->val.val" before returning "ret". Check for operators   * with priority within `minpri' and `maxpri' which we got in the loop   * above.   *   * Check priority level by priority level and perform the right actions.   * When reaching the maxpri, there is only one number left: the result!   */  for(pri=minpri; pri<=maxpri; pri++) {    last=expr=basexpr;    while(expr=expr->next) {      if(priority[expr->operator]==pri) {        last->flags|=expr->flags;        switch(expr->operator) {        case OP_MULTIPLY:          last->val.val*=expr->val.val;          break;        case OP_DIVISION:          if(!expr->val.val) {            CALL(Warn(scr, FPLERR_DIVISION_BY_ZERO));            /* we give a zero as result! */            last->val.val=0;          } else            last->val.val/=expr->val.val;          break;        case OP_REMAIN:          if(!expr->val.val) {            CALL(Warn(scr, FPLERR_DIVISION_BY_ZERO));            last->val.val=0;          } else            last->val.val%=expr->val.val;          break;        case OP_SHIFTL:          last->val.val<<=expr->val.val;          break;        case OP_SHIFTR:          last->val.val>>=expr->val.val;          break;        case OP_BINAND:          last->val.val&=expr->val.val;          break;        case OP_BINOR:          last->val.val|=expr->val.val;          break;        case OP_BINXOR:          last->val.val^=expr->val.val;          break;        case OP_PLUS:          last->val.val+=expr->val.val;          break;        case OP_MINUS:          last->val.val-=expr->val.val;          break;        case OP_EQUAL:          last->val.val=last->val.val==expr->val.val;          break;        case OP_NOTEQ:          last->val.val=last->val.val!=expr->val.val;          break;        case OP_LESSEQ:          last->val.val=last->val.val<=expr->val.val;          break;        case OP_LESS:          last->val.val=last->val.val<expr->val.val;          break;        case OP_GRETEQ:          last->val.val=last->val.val>=expr->val.val;          break;        case OP_GRET:          last->val.val=last->val.val>expr->val.val;          break;        case OP_LOGOR:          last->val.val=last->val.val||expr->val.val;          break;        case OP_LOGAND:          last->val.val=last->val.val&&expr->val.val;          break;        case OP_COND1:          if(expr->next && expr->next->operator==OP_COND2) {            last->val.val=last->val.val?expr->val.val:expr->next->val.val;          } else {            CALL(Warn(scr, FPLERR_ILLEGAL_CONDOP)); /* WARNING! */            last->val.val=expr->val.val; /* get the number we have! */          }          break;        }        last->next=expr->next;        FREE(expr);        expr=last;      } else        last=expr;    }  }  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! * ******/ReturnCode REGARGSAddUnary(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 e

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -