Ejemplo n.º 1
1
/*******************************************************************************
This function is called when a "sort(FIELD, expr)" statement is encountered.
It evaluates expr for each instance of FIELD, determines the type of these
values, (int, float, or string), selects the appropriate comparison function,
and then calls qsort to do the sorting.
*******************************************************************************/
static void
sortaxisarray(Exprnode *exprptr, int newdepth, Flag reverseflag)
{
    Exprnode result;
    int (*cmpfuncptr)() = NULL;
    int i;

    axistbl[newdepth].first = 0;
    axistbl[newdepth].last = axistbl[newdepth].number - 1;

    for (i=axistbl[newdepth].first; i<=axistbl[newdepth].last; i++) {
	curfldvalptrtbl[newdepth] = axistbl[newdepth].array[i];
	result = *exprptr;
	evalexpr(&result);
	switch(result.typ) {
	    case INTEGER:
		(axistbl[newdepth].array[i])->sortarg.ival = result.arg.ival;
		break;
	    case FLOAT:
		(axistbl[newdepth].array[i])->sortarg.fval = result.arg.fval;
		break;
	    case STRING:
		(axistbl[newdepth].array[i])->sortarg.sval = result.arg.sval;
		break;
	    default:  fatalerrlin("sortaxisarray: illegal expr type (msg 1)");
		break;
	}
    }
    if (reverseflag) {
	sortdirection = REVERSESORTVALUE;
    } else {
	sortdirection = FORWARDSORTVALUE;
    }
    curfldvalptrtbl[newdepth] = NULL;
    switch(result.typ) {
	case INTEGER: cmpfuncptr = axisintcmp; break;
	case FLOAT:   cmpfuncptr = axisfltcmp; break;
	case STRING:  cmpfuncptr = axisstrcmp; break;
	default:  fatalerrlin("sortaxisarray: illegal expr type (msg 2)");
	    break;
    }

    qsort((void*)axistbl[newdepth].array, axistbl[newdepth].number,
					sizeof(Axisnode*), cmpfuncptr);
}
Ejemplo n.º 2
0
/*******************************************************************************
This function is only called when in report mode, NEVER from select mode.
*******************************************************************************/
void
assignop(Exprnode *lhsexprptr, int optyp, Exprnode *rhsexprptr)
{
    Exprnode lresult, expr, rresult;

    rresult = *rhsexprptr;
    evalexpr(&rresult);
    if (rresult.typ == NORETVALEXPR)
	fatalerrlin("function returns no value (one is required)");

    if (optyp == ASSIGN) {			/* simple assign (=) */
	*lhsexprptr = rresult;
    } else {				/* arithmetic assign (+=, etc) */
	lresult = *lhsexprptr;
	evalexpr(&lresult);
	if (lresult.typ == NORETVALEXPR)
	    fatalerrlin("function returns no value (one is required)");
	expr.typ = BINARYOPEXPR;
	switch (optyp) {
	    case ASSIGNADD:	 expr.arg.optyp = ADD; break;
	    case ASSIGNSUBTRACT: expr.arg.optyp = SUBTRACT; break;
	    case ASSIGNMULTIPLY: expr.arg.optyp = MULTIPLY; break;
	    case ASSIGNDIVIDE:	 expr.arg.optyp = DIVIDE; break;
	    case ASSIGNMOD:	 expr.arg.optyp = MOD; break;
	    case ASSIGNPOWER:	 expr.arg.optyp = POWER; break;
	    default: fatalerrlin("assignop: hit default"); break;
	}
	expr.leftptr = &lresult;
	expr.rightptr = &rresult;
	evalexpr(&expr);
	*lhsexprptr = expr;
    }
}
Ejemplo n.º 3
0
int evalexpr(struct expr *e)
{
    if (e->subexpr)
	return(applyop(e->subexpr->op, evalexpr(e->subexpr->a),
			evalexpr(e->subexpr->b)));
    else
	return(e->val);
}
Ejemplo n.º 4
0
/* evaluate *s and update s to point to the last character read */
int eval_up(char **s, int unit)
{
	defunit = unit;
	if (unit == 'v')
		abspos = -n_d;
	if (unit == 'm')
		abspos = n_lb - f_hpos();
	return evalexpr(s);
}
Ejemplo n.º 5
0
int main()
{
    char buf[500];
    while (fgets(buf, sizeof buf, stdin)) {
	struct expr *e = parse(buf);
	if (e) {
	    printf("value is %d\n", evalexpr(e));
	    freeexpr(e);
	} else {
	    printf("%s\n", errorstatus);
	}
    }
    return(0);
}
Ejemplo n.º 6
0
static int evalatom(char **s)
{
	int ret;
	if (evalisnum(s))
		return evalnum(s);
	if (!evaljmp(s, '-'))
		return -evalatom(s);
	if (!evaljmp(s, '+'))
		return evalatom(s);
	if (!evaljmp(s, '|'))
		return abspos + evalatom(s);
	if (!evaljmp(s, '(')) {
		ret = evalexpr(s);
		evaljmp(s, ')');
		return ret;
	}
	return 0;
}
Ejemplo n.º 7
0
/************************************************************************
 * int checksol(eqn,sols,reltverr)                                      *
 *      plugs the solution values in sols into the equation eqn.        *
 *      compares descrepancy with expection using relative err reltverr *
 * returns                                                              *
 *    0 if seems within error bars                                      *
 *    1 if within 100 * error bars                                      *
 *    2 if not within 100 * error bars                                  *
 *    3 floating point error (really, really not ok)                    *
 * NOTE: currently the error bar calculation has faults                 *
 ************************************************************************/
int checksol(const binopexp* const eqn, const vector<double>* const sols,
             const double reltverr) {
    DBG(cout << "entered checksol" << endl);
#ifdef WITHDBG // for debugging
    recall=0;
#endif
    answitherr* value;
    expr* eqexpr = copyexpr(eqn); // g++ refused this without copyexpr
    try {
        value = evalexpr(eqexpr, sols, reltverr);
    }
    catch (string &err) {
        // don't delete value, it has never been assigned.
        eqexpr->destroy();
        DBG(cout << " ERROR " << err << endl);
        if(FPE_handler==err.substr(0,FPE_handler.length()))  //if beginning matches
            return(3);
        else {
            throw(err);
        }
    }
    eqexpr->destroy();
    DBGM(cout << "Eqn " << eqn->getInfix() <<
         " balenced with discrepancy " << value->value
         << " and absolute error " << value->abserr << endl);
    if ((fabs(value->value) <= value->abserr)) {
        DBG(cout << " seems OK" << endl);
        delete value;
        return(0);
    } else if ((fabs(value->value) <= 100 * value->abserr)) {
        DBG(cout << " NOT REALLY OK" << endl);
        delete value;
        return(1);
    } else {
        DBG(cout << " seems VERY NOT OK on" << endl; cout << eqn->getInfix()
            << endl);
        delete value;
        return(2);
    }
}
Ejemplo n.º 8
0
Archivo: tagfs.c Proyecto: ericvh/tagfs
static void
fsread(Req* r)
{
	Query*	q;
	char**	toks;
	int	ntoks;
	int	atoks;
	char*	s;
	int	pos;
	File*	f;

	if(r->fid->qid.type&QTDIR){
		respond(r, "bug: write on dir");
		return;
	}
	f = r->fid->file;
	if(f == ctlf){
		ctlread(r);
		return;
	}
	q = f->aux;

	/* The first read process the query.
	 * Further reads just retrieve more data,
	 * if any.
	 */
	if(q->expr == nil){
		atoks = 512;
		toks = emalloc9p(atoks*sizeof(char*));
		do {
			s = estrdup9p(q->text);
			ntoks = tokenize(s, toks, atoks);
			if(ntoks == atoks){
				atoks += 512;
				toks = erealloc9p(toks, atoks*sizeof(char*));
				free(s);
			}
		}while(ntoks == atoks);
		pos = 0;
		if(chatty9p)
			fprint(2, "compiling %s (%d toks)\n", q->text, ntoks);
		q->expr = parseexpr(ntoks, toks, &pos);
		if(q->expr == nil){
			free(s);
			free(toks);
			respond(r, "syntax error");
			return;
		}
		if(chatty9p)
			fprint(2, "evaluating %s (%d toks)\n", q->text, ntoks);
		evalexpr(trie, q->expr);
		free(s);
		free(toks);
		free(q->text);
		/* smprintexprval limits the total output to
		 * at most 64K of text
		 */
		q->text = smprintexprval(q->expr);
		if(chatty9p)
			fprint(2, "result is [%s]\n", q->text);
	}
	/* After the query is process,
	 * q->text holds the reply.
	 */
	readstr(r,  q->text);
	respond(r, nil);
}
Ejemplo n.º 9
0
Archivo: syntax.c Proyecto: k0gaMSX/mcm
int syntaxan (int token,symbol * sym)
{
  static unsigned char num_channel;
  static unsigned char channels[12]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  static symbol ptr;

  switch (status)
    {
    case STATUS_INIT:     /* Initial status */
      recst = STATUS_INIT;    /*Save actual state for error handling  */
      switch (token)
        {
        case VAR:            /* Begin variable declaration */
          status = STATUS_BEGIN_VAR_DECL;
          return 0;

        case CHANNEL:        /* Begin channel declaration */
          status = STATUS_BEGIN_CHN_DECL;
          return 0;

        case IDEN:            /* Begin assign statement */
          status = STATUS_BEGIN_GLOBAL_ASGN; /* TODO: Join to local assign */
          if ((*sym = searchsym(lexcad)) == NULL)
            rerror(ESYNTAX, EIDEN_NAME, 0);
          return 0;

        case LN:              /* Empty sentence  */
          return 1;

        default:
          rerror(ESYNTAX, E_INI, 0);
        }

      /* Variable declaration states  */

    case STATUS_BEGIN_VAR_DECL: /* VAR ; variable declaration */
      switch (token)
        {
        case IDEN:            /* Name of the variable */
          status = STATUS_NAME_VAR_DECL;
          *sym = newsymbol(lexcad);
          return 0;

        default:
          rerror(ESYNTAX, E_VAR_DECL, 0);
        }

    case STATUS_NAME_VAR_DECL: /* VAR IDEN ; variable declaration */
      switch (token)
        {
        case LN:             /* end of declaration */
          status = STATUS_INIT;
          insvar(*sym);
          return 1;

        case COMA:            /* multiple declaration */
          status = STATUS_BEGIN_VAR_DECL;
          insvar(*sym);
          return 0;

        default:
          rerror(ESYNTAX, E_VAR_DECL, 0);
        }

      /* Channel declaration states */

    case STATUS_BEGIN_CHN_DECL: /* CHANNEL ; channel declaration */
      switch (token)
        {
        case NUMBER:         /* Number of the channel */
          status = STATUS_END_OF_CHANNEL;
          num_channel = atoi(lexcad) - 1;

          if(num_channel >= 12)
            rerror(ESYNTAX, E_BAD_CH, 0);
          else
            {
              ssymval(syms1, num_channel);
              *sym = syms1;
            }

          if(channels[num_channel])
            rerror(ESYNTAX, E_DECL_CH, 0);

          channels[num_channel]=1;
          return 0;

        case IDEN:           /* Variable with the name of the channel */
          status = STATUS_END_OF_CHANNEL;
          if ((*sym = searchsym(lexcad)) == NULL)
            rerror(ESYNTAX, EIDEN_NAME, 0);
          else if ((num_channel = gsymval(*sym)) >= 12)
            rerror(ESYNTAX, E_BAD_CH, 0);

          if (channels[num_channel])
            rerror(ESYNTAX, E_DECL_CH, 0);

          channels[num_channel] = 1;
          return 0;

        default: rerror(ESYNTAX, E_CHANNEL, 0);
        }

      /* end of channel declaration */
    case STATUS_END_OF_CHANNEL: /* CHANNEL IDEN | NUMBER ; end of channl dcl*/
      switch (token)
        {
        case LN:             /* finish channel dcl */
          status = STATUS_BEGIN_CHN_BODY;
          inscode2(CHANNEL, gsymval(*sym));
          return 1;

        default:
          rerror(ESYNTAX, E_CHANNEL, 0);
        }

      /* Begin channel body */
    case STATUS_BEGIN_CHN_BODY:      /* CHANNEL IDEN | NUMBER LN ; chl body*/
      recst = STATUS_BEGIN_CHN_BODY;   /*Save state for error handling*/
      switch (token)
        {
        case LN:
          return 1;

        case ENDC:           /* end of channel statement */
          status = STATUS_BEGIN_ENDC;
          initsym(syms1, token, token);
          *sym = syms1;
          return 0;

        case PLAY:
          status = 11;          /* play statement */
          initexpr();
          initsym(syms1, token, token);
          *sym = syms1;
          return 0;

        case SIL:               /* silence statement  */
        case DECOC:             /* dec octave statement */
        case INCOC:             /* inc octave statement */
        case ENDL:              /* end of loop statement */
        case DECV:              /* dec volume */
        case INCV:              /* inc volume */
          status = STATUS_END_OF_1CMD;
          initsym(syms1, token, token);
          *sym = syms1;
          return 0;

        case OCT:               /* octave statement */
        case VOL:               /* volume statement */
        case BAT:               /* battery statement */
        case INST:              /* instrument statement */
        case LOOP:              /* loop statement */
        case AMPL:
        case VIB:               /* vibrato statement */
        case TIMES:             /* time short format statement */
        case TIMEL:             /* time long format statement */
        case DIVSUS:
        case BATL:              /* battery long format statement */
        case INSTL:             /* instrument long format statement */
        case FREC:              /* set frequency statement */
          status = STATUS_BEGIN_EXP_2CMD;
          initexpr();
          initsym(syms1, token, token);
          *sym = syms1;
          return 0;

        case TIMEP:
          status = 39;
          initexpr();
          initsym(syms1, token, token);
          initsym(syms2, NUMBER, 0);
          ssymsig(syms2, syms1);
          *sym = syms2;
          return 0;

        case REGFM:             /* write to fm register statement */
          status = 8;
          initexpr();
          initsym(syms1, token, token);
          *sym = syms1;
          return 0;

        case PAR:               /* parameter statement */
          status = 9;
          initsym(syms1, token, token);
          *sym = syms1;
          return 0;

        case IDEN:              /* Begin a assign statement */
          status = 10;
          if ((*sym = searchsym(lexcad)) == NULL)
            rerror(ESYNTAX, EIDEN_NAME, 0);

          return 0;

        default:
          rerror(ESYNTAX, E_UNK_COMM, 0);
        }

      /* End of 1 word statement */
    case STATUS_END_OF_1CMD:
      switch (token)
        {
        case LN:
          status = STATUS_BEGIN_CHN_BODY;
          inscodeI(*sym, NULL, num_channel);
          return 1;

        default:
          rerror(ESYNTAX, E_BAD_COMM, 0);
        }

    case 8:
      switch (token)
        {
        case NUMBER:
          status = 21;
          initsym(syms3, NUMBER, 0);
          ssymsig(syms3,*sym);
          *sym = syms3;
          pushexp(NUMBER, atoi(lexcad));
          return 0;

        case IDEN:
          status = 21;
          if((ptr = searchsym(lexcad)) == NULL)
            rerror(ESYNTAX, EIDEN_NAME, 0);

          initsym(syms3, NUMBER, 0);
          ssymsig(syms3,*sym);
          *sym = syms3;
          pushexp(NUMBER, gsymval(ptr));
          return 0;

        case PARI:
          status = 22;
          ssymsig(syms3,*sym);
          *sym = syms3;
          pushexp(token, 0);
          return 0;

        default:
          rerror(ESYNTAX, E_EXP, 0);
        }

    case 9:
      switch (token)
        {
        case ENVLOFF:
        case ENVLON:
        case SUSON:
        case HFNUM:
        case LFNUM:
        case NOISE:
        case TONE:
          status = STATUS_END_OF_1CMD;
          initsym(syms2, token, token);
          ssymsig(syms2,*sym);
          *sym = syms2;
          return 0;

        case DECO:
          status = STATUS_BEGIN_EXP_2CMD;
          initexpr();
          initsym(syms3, token, token);
          ssymsig(syms3,*sym);
          *sym = syms3;
          return 0;

        case TAMP:
          status = STATUS_BEGIN_EXP_2CMD;
          initexpr();
          initsym(syms3, token, token);
          ssymsig(syms3,*sym);
          *sym = syms3;
          return 0;

        case RITMON:
          status = STATUS_END_OF_1CMD;
          initsym(syms2, token, token);
          ssymsig(syms2,*sym);
          *sym = syms2;
          return 0;

        case MELON:
          status = STATUS_END_OF_1CMD;
          initsym(syms2, token, token);
          ssymsig(syms2,*sym);
          *sym = syms2;
          return 0;

        default:
          rerror(ESYNTAX, E_PAR, 0);
        }
    case 10:
      switch (token)
        {
        case EQ:
          status = STATUS_BEGIN_EXP_2CMD;
          initexpr();
          initsym(syms3, EQ, EQ);
          ssymsig(syms3, *sym);
          *sym = syms3;
          return 0;

        default:
          rerror(ESYNTAX, E_ASIG, 0);
        }

    case 11:
      switch(token)
        {
        case NUMBER:
          status = STATUS_PLAY_EXPRESION;
          initsym(syms2, NUMBER, 0);
          ssymsig(syms2,*sym);
          *sym = syms2;
          pushexp(NUMBER, atoi(lexcad));
          return 0;

        case IDEN:
          status = STATUS_PLAY_EXPRESION;
          if((ptr = searchsym(lexcad)) == NULL)
            rerror(ESYNTAX, EIDEN_NAME, 0);

          initsym(syms2, NUMBER, 0);
          ssymsig(syms2,*sym);
          *sym = syms2;
          pushexp(NUMBER, gsymval(ptr));
          return 0;

        case PARI:
          status = STATUS_PLAY_EXPRESION;
          ssymsig(syms2,*sym);
          *sym = syms2;
          pushexp(token, 0);
          return 0;

        default:
          rerror(ESYNTAX, E_EXP, 0);
        }

      /* Begin end of channel statement */
    case STATUS_BEGIN_ENDC:   /* ENDC ; endc command */
      switch(token)
        {
        case LN:
          status = 13;
          inscode(gsymval(*sym));
          execute();
          return 1;

        default:
          rerror(ESYNTAX, E_BAD_COMM, 0);
        }


    case 13:
      recst = 13;

      switch(token)
        {
        case WRITE:
          status = 38;
          return 0;

        case CHANNEL:
          status = STATUS_BEGIN_CHN_DECL;
          return 0;

        case LN:
          return 1;

        default:
          rerror(ESYNTAX, E_INI, 0);
        }



    case STATUS_BEGIN_GLOBAL_ASGN:
      switch(token)
        {
        case EQ:
          status = 15;
          initexpr();
          return 0;

        default: rerror(ESYNTAX, E_ASIG, 0);
        }

    case 15:
      switch(token)
        {
        case NUMBER:
          status = 26;
          {pushexp(NUMBER, atoi(lexcad));};
          return 0;
        case IDEN:
          status = 26;
          (ptr = searchsym(lexcad))?pushexp(NUMBER, gsymval(ptr)):rerror(ESYNTAX, EIDEN_NAME, 0);
          return 0;
        case PARI:
          status = 27;
          pushexp(token, 0);
          return 0;
        default: rerror(ESYNTAX, E_EXP, 0);
        }


      /*******************************************************************/
    case STATUS_BEGIN_EXP_2CMD:
      switch (token)
        {
        case PARI:
          status = STATUS_EXP2_OPERAND;
          ssymsig(syms2,*sym);
          *sym = syms2;
          pushexp(token, 0);
          return 0;

        case NUMBER:
          status = STATUS_EXP2_OPERAND;
          initsym(syms2, NUMBER, 0);
          ssymsig(syms2,*sym);
          *sym = syms2;
          pushexp(NUMBER, atoi(lexcad));
          return 0;

        case IDEN:
          status = STATUS_EXP2_OPERAND;
          if(!(ptr = searchsym(lexcad)))
            rerror(ESYNTAX, EIDEN_NAME, 0);

          initsym(syms2, NUMBER, 0);
          ssymsig(syms2,*sym);
          *sym = syms2;
          pushexp(NUMBER, gsymval(ptr));
          return 0;

        default:
          rerror(ESYNTAX, E_EXP, 0);

        }


    case STATUS_EXP2_OPERAND:
      switch(token)
        {
        case NUMBER:
          status = STATUS_EXP2_OPERAND;
          pushexp(NUMBER, atoi(lexcad));
          return 0;

        case IDEN:
          status = STATUS_EXP2_OPERAND;
          if ((ptr = searchsym(lexcad)) == NULL)
            rerror(ESYNTAX, EIDEN_NAME, 0);

          pushexp(NUMBER, gsymval(ptr));
          return 0;

        case ADD:
        case SUB:
        case MUL:
        case DIV:
        case PARD:
        case PARI:              /* left parenthesis  */
          status = STATUS_EXP2_OPERAND;
          pushexp(token, 0);
          return 0;

        case LN:
          status = recst;
          pushexp(token, 0);
          ssymval(*sym, evalexpr());
          inscodeI(*sym, NULL, num_channel);
          return 1;

        default:
          rerror(ESYNTAX, E_EXP, 0);
        }


      /***********************************************/

      /* initial assign expression*/
    case 26:
      switch(token)
        {
        case ADD:
          status = 15;
          pushexp(token, 0);
          return 0;
        case SUB:
          status = 15;
          pushexp(token, 0);
          return 0;
        case MUL:
          status = 15;
          pushexp(token, 0);
          return 0;
        case DIV:
          status = 15;
          pushexp(token, 0);
          return 0;
        case LN:
          status = STATUS_INIT;{pushexp(token, 0);ssymval(*sym, evalexpr());}  return 1;
        default: rerror(ESYNTAX, E_EXP, 0);
        }
    case 27:
      switch(token)
        {
        case NUMBER:
          status = 28;{pushexp(NUMBER, atoi(lexcad));}return 0;
        case IDEN:
          status = 28;{symbol ptr;(ptr = searchsym(lexcad))?pushexp(NUMBER, gsymval(ptr)):rerror(ESYNTAX, EIDEN_NAME, 0);}return 0;
        case PARI:
          status = 27;
          pushexp(token, 0);
          return 0;
        default: rerror(ESYNTAX, E_EXP, 0);
        }

    case 28:
      switch(token)
        {
        case PARD:
          status = 28;
          pushexp(token, 0);
          return 0;
        case ADD:
          status = 27;
          pushexp(token, 0);
          return 0;
        case SUB:
          status = 27;
          pushexp(token, 0);
          return 0;
        case MUL:
          status = 27;
          pushexp(token, 0);
          return 0;
        case DIV:
          status = 27;
          pushexp(token, 0);
          return 0;
        case LN:
          status = STATUS_INIT;{pushexp(token, 0);ssymval(*sym, evalexpr());}return 1;
        default: rerror(ESYNTAX, E_EXP, 0);
        }


    case 30:


      /*Expresion de play*/

    case STATUS_PLAY_EXPRESION:
            switch(token) {
            case ADD:
            case SUB:
            case MUL:
            case DIV:
                    status = 32;
                    pushexp(token, 0);
                    return 0;

            case SOS:
                    status = STATUS_PLAY_SOST;
                    return 0;

            case BEMOL:
                    status = STATUS_PLAY_BEMOL;
                    return 0;

            case COMA:
            case LN:
                    pushexp(LN, 0);
                    ssymval(*sym, evalexpr());
                    inscodeI(*sym, NULL, num_channel);
                    if (token == COMA) {
                            status = 32;
                            initexpr();
                            return 0;
                    } else {
                            status = STATUS_BEGIN_CHN_BODY;
                            return 1;
                    }


            default:
                    rerror(ESYNTAX, E_EXP, 0);
            }


    case 32:
      switch(token)
        {
        case NUMBER:
          status = 33;{pushexp(NUMBER, atoi(lexcad));}return 0;
        case IDEN:
          status = 33;{symbol ptr;(ptr = searchsym(lexcad))?pushexp(NUMBER, gsymval(ptr)):rerror(ESYNTAX, EIDEN_NAME, 0);}return 0;
        case PARI:
          status = 32;
          pushexp(token, 0);
          return 0;
        default: rerror(ESYNTAX, E_EXP, 0);
        }

    case 33:
      switch(token)
        {
        case PARD:
          status = 33;
          pushexp(token, 0);
          return 0;
        case ADD:
          status = 34;
          pushexp(token, 0);
          return 0;
        case SUB:
          status = 34;
          pushexp(token, 0);
          return 0;
        case MUL:
          status = 34;
          pushexp(token, 0);
          return 0;
        case DIV:
          status = 34;
          pushexp(token, 0);
          return 0;
        case SOS:
          status = STATUS_PLAY_SOST;{pushexp(token, 0);ssymval(*sym, evalexpr());}return 0;
        case BEMOL:
          status = STATUS_PLAY_BEMOL;{pushexp(token, 0);ssymval(*sym, evalexpr());}return 0;
        case COMA:
          status = 32;{pushexp(LN, 0);ssymval(*sym, evalexpr());inscodeI(*sym, NULL, num_channel);initexpr();} return 0;
        case LN:
          status = STATUS_BEGIN_CHN_BODY;{pushexp(token, 0);ssymval(*sym, evalexpr());inscodeI(*sym, NULL, num_channel);}return 1;
        default: rerror(ESYNTAX, E_EXP, 0);
        }
    case 34:
      switch(token)
        {
        case NUMBER:
          status = STATUS_PLAY_EXPRESION;{pushexp(NUMBER, atoi(lexcad));}return 0;
        case IDEN:
          status = STATUS_PLAY_EXPRESION;{symbol ptr;(ptr = searchsym(lexcad))?pushexp(NUMBER, gsymval(ptr)):rerror(ESYNTAX, EIDEN_NAME, 0);}return 0;
        case PARI:
          status = 32;
          pushexp(token, 0);
          return 0;
        default: rerror(ESYNTAX, E_EXP, 0);
        }

    case STATUS_PLAY_BEMOL:
      switch(token) {
      case BEMOL:
              pushexp(SUB, 0);
              pushexp(NUMBER, 3);
              return 0;

      case COMA:
      case LN:
              pushexp(LN, 0);
              ssymval(*sym, evalexpr() - 3);
              inscodeI(*sym, NULL, num_channel);
              if (token == LN) {
                      status = STATUS_BEGIN_CHN_BODY;
                      return 1;
              } else {
                      status = 32;
                      initexpr();
                      return 0;
              }

      default: rerror(ESYNTAX, E_BEMOL, 0);
      }

    case STATUS_PLAY_SOST:
      switch(token) {
      case SOS:
              pushexp(ADD, 0);
              pushexp(NUMBER, 3);
              return 0;

      case COMA:
      case LN:
              pushexp(LN, 0);
              ssymval(*sym, evalexpr() + 3);
              inscodeI(*sym, NULL, num_channel);
              if (token == LN) {
                      status = STATUS_BEGIN_CHN_BODY;
                      return 1;
              } else {
                      status = 32;
                      initexpr();
                      return 0;
              }


      default: rerror(ESYNTAX, E_SOS, 0);
      }


    case 38:
      switch(token)
        {
        case LN:
          status = 37;{errorg?rerror(EERROR, 0, 0):writesong();}return 2;            /*Fin de entrada*/
        default: rerror(ESYNTAX, E_BAD_COMM, 0);
        }


    case 39:
      switch (token)
        {
        case NUMBER:
          status = 40;{pushexp(NUMBER, atoi(lexcad));}return 0;
        case IDEN:
          status = 40;{symbol ptr;(ptr = searchsym(lexcad))?pushexp(NUMBER, gsymval(ptr)):rerror(ESYNTAX, EIDEN_NAME, 0);}return 0;
        case PARI:
          status = 41;
          pushexp(token, 0);
          return 0;
        default: rerror(ESYNTAX, E_EXP, 0);
        }


    case 40:
      switch(token)
        {
        case ADD:
          status = 39;
          pushexp(token, 0);
          return 0;
        case SUB:
          status = 39;
          pushexp(token, 0);
          return 0;
        case MUL:
          status = 39;
          pushexp(token, 0);
          return 0;
        case DIV:
          status = 39;
          pushexp(token, 0);
          return 0;
        case POINT:
          status = 43;{pointp = point=32;};
          return 0;
        case LN:
          status = STATUS_BEGIN_CHN_BODY;
          {
            float time;

            pushexp(token, 0);
            time = evalexpr();
            time/=64.0;
            time*=(240.0*((float)(gsymval(hz))))/((float)(gsymval(tempo)));
            if((time-((float)((unsigned char)time))) > 0.5)
              time=((float)((unsigned char)time))+1.0;
            else
              time=(float)((unsigned char)time);

            ssymval(*sym,(unsigned char)time);
            inscodeI(*sym, NULL, num_channel);
          }return 1;


        default: rerror(ESYNTAX, E_EXP, 0);
        }

    case 41:
      switch(token)
        {
        case NUMBER:
          status = 42;{pushexp(NUMBER, atoi(lexcad));}return 0;
        case IDEN:
          status = 42;{symbol ptr;(ptr = searchsym(lexcad))?pushexp(NUMBER, gsymval(ptr)):rerror(ESYNTAX, EIDEN_NAME, 0);}return 0;
        case PARI:
          status = 41;
          pushexp(token, 0);
          return 0;
        default: rerror(ESYNTAX, E_EXP, 0);
        }

    case 42:
      switch(token)
        {
        case PARD:
          status = 42;
          pushexp(token, 0);
          return 0;
        case ADD:
        case SUB:
        case MUL:
        case DIV:
          status = 41;
          pushexp(token, 0);
          return 0;

        case POINT:
          status = 43;{pointp = point=32;} return 0;
        case LN:
          status = STATUS_BEGIN_CHN_BODY;
          {
            float time, timei;

            pushexp(token, 0);
            time = evalexpr();
            time/=64.0;
            time*=(240.0*((float)(gsymval(hz))))/((float)(gsymval(tempo)));
            time = fabs(time);

            timei = floor(time);
            if(time-timei)
              time = timei+1.0;
            else
              time = timei;

            ssymval(*sym,(unsigned char)time);
            inscodeI(*sym, NULL, num_channel);
          }return 1;
        default: rerror(ESYNTAX, E_EXP, 0);
        }
    case 43:
      switch(token)
        {
        case POINT:
          pointp >>= 1;
          point += pointp;
          return 0;

        case LN:
          status = STATUS_BEGIN_CHN_BODY;
          {
            float time, timei;

            pushexp(token, 0);
            time = evalexpr();
            time/=64;
            time*=(240.0*((float)(gsymval(hz))))/((float)(gsymval(tempo)));
            time = fabs(time);
            time+=time*(((float)point)/64.0);


            timei = floor(time);
            if(time-timei)
              time = timei+1.0;
            else
              time = timei;

            ssymval(*sym,(unsigned char)time);
            inscodeI(*sym, NULL, num_channel);
          }return 1;
        }
    default:
      rerror(ESYNTAX, E_POINT, 0);

    }
}
Ejemplo n.º 10
0
/*******************************************************************************
This function is called to sequence through "blocks" of statements.  The entire
program is the outer-most block, and each foreach statement begins another one.
That is, this function is RECURSIVE!!!
*******************************************************************************/
Exprnode
doblock(int begstmtidx, int endstmtidx)
{
    Exprnode  *lhsexprptr, result;
    int       newdepth, i;

    int stmtidx;
    stmtidx = begstmtidx;
    while (stmtidx <= endstmtidx) {
	curstmtidx = stmtidx;			/* global, for error messages */
	switch (stmts[stmtidx].typ) {
	    case PRINTF: case SPRINTF:
		printfmt(stmtidx);
		stmtidx++;
		break;
	    case FOREACH:
		newdepth = stmts[stmtidx].s.foreach.fldidx;
		for (i=axistbl[newdepth].first; i<=axistbl[newdepth].last; i++){
		    curfldvalptrtbl[newdepth] = axistbl[newdepth].array[i];

		    /* this skips "outer joins" where there is no data */
		    if (stmts[stmtidx].s.foreach.restrictflag) {
			chk4badflds(stmts[stmtidx].s.foreach.fldbits,
					    stmts[stmtidx].s.foreach.maxdepth);
			if (getcount(datarootptr,
					stmts[stmtidx].s.foreach.fldbits, 0,
					stmts[stmtidx].s.foreach.maxdepth) == 0)
			    continue; /* skip doblock */
		    }

		    doblock(stmtidx+1, stmts[stmtidx].s.foreach.next-1);
		}
		curfldvalptrtbl[newdepth] = NULL;
		stmtidx = stmts[stmtidx].s.foreach.next;
		break;
	    case WHILE:
		result = *(stmts[stmtidx].s.while_.exprptr);
		evalexpr(&result);
		while (result.arg.ival) {
		    doblock(stmtidx+1, stmts[stmtidx].s.while_.next-1);
		    result = *(stmts[stmtidx].s.while_.exprptr);
		    evalexpr(&result);
		}
		stmtidx = stmts[stmtidx].s.while_.next;
		break;
	    case DO:
		result = *(stmts[stmtidx].s.dowhile.exprptr);
		evalexpr(&result);
		if (result.arg.ival)
		    stmtidx = stmts[stmtidx].s.dowhile.next;
		else
		    stmtidx++;
		break;
	    case IF:
		result = *(stmts[stmtidx].s.if_.exprptr);
		evalexpr(&result);
		if (result.arg.ival)
		    stmtidx++;
		else
		    stmtidx = stmts[stmtidx].s.if_.next;
		break;
	    case ELSE:
		stmtidx = stmts[stmtidx].s.else_.next;
		break;
	    case ASSIGNOP:			/* assign ops are STATMENTS */
		switch (stmts[stmtidx].s.assign.lhsexprptr->typ) {
		    case UFNCPARAMEXPR:
			lhsexprptr = &argstk[botargstkidx]+stmts[stmtidx].s.
						    assign.lhsexprptr->arg.ival;
			break;
		    case ARRAYVAREXPR:
			lhsexprptr = rtgetarrvaraddr(
					    stmts[stmtidx].s.assign.lhsexprptr);
			break;
		    default:			/* an "ordinary" variable */
			lhsexprptr = stmts[stmtidx].s.assign.lhsexprptr;
			break;
		}
		assignop(lhsexprptr, stmts[stmtidx].s.assign.optyp,
					    stmts[stmtidx].s.assign.rhsexprptr);
		stmtidx++;
		break;
	    case SORT:
		newdepth = stmts[stmtidx].s.sort.fldidx;
		sortaxisarray(stmts[stmtidx].s.sort.exprptr, newdepth, 
					    stmts[stmtidx].s.sort.reverseflag);
		stmtidx++;
		break;
	    case FIRST:
		newdepth = stmts[stmtidx].s.fstlst.fldidx;
		result = *(stmts[stmtidx].s.fstlst.exprptr);
		evalexpr(&result);
		axistbl[newdepth].last =
		    MIN(axistbl[newdepth].first+result.arg.ival-1,
			axistbl[newdepth].last);
		stmtidx++;
		break;
	    case LAST:
		newdepth = stmts[stmtidx].s.fstlst.fldidx;
		result = *(stmts[stmtidx].s.fstlst.exprptr);
		evalexpr(&result);
		axistbl[newdepth].first =
		    MAX(axistbl[newdepth].last-result.arg.ival+1,
			axistbl[newdepth].first);
		stmtidx++;
		break;
	    case SYSTEM:
		result = *(stmts[stmtidx].s.system_.exprptr);
		evalexpr(&result);
		if (result.typ == STRING) {
		    (void) system(result.arg.sval);
		} else {
		    fprintf(stderr,
			    "`system' must be called with a string argument");
		}
		stmtidx++;
		break;
	    case RETURN:
		if (stmts[stmtidx].s.return_.exprptr != NULL) {
		    result = *(stmts[stmtidx].s.return_.exprptr);
		    evalexpr(&result);
		} else {
		    result.typ = NORETVALEXPR;
		}
		return result;
	    case EXPRSTMT:
		result = *(stmts[stmtidx].s.expr.exprptr);
		evalexpr(&result);
		stmtidx++;
		break;
	    case TRAP:
		updatetraptbl(stmts[stmtidx].s.trap.linnumexprptr,
				    stmts[stmtidx].s.trap.ufncexprptr);
		stmtidx++;
		break;
	    default:
		fatalerrlin("doblock: illegal statement type");
		stmtidx++;
		break;
	}
    }
    result.typ = NORETVALEXPR;
    return result;
}
Ejemplo n.º 11
0
/*******************************************************************************
This function does the formatted printing (both PRINTF and SPRINTF).  It first
evaluates the user's format expression (argexprptrtbl[0]) - this STRING is
referenced by usrfmtptr.  It then sequences through the user's format string
copying everything except s/printf format (%) codes to rsltstr.  As % codes are
encountered, they are copied into tmpfmtstr.  This string is used by really
calling sprintf with tmpfmtstr as the format string and argexprptrtbl[n]
(evaluated) as its agument.  The result from sprintf is added to the end of
rsltstr (which has been accumulating).
*******************************************************************************/
void
printfmt(int stmtidx)
{
    Exprnode result, *lhsexprptr;
    Exprptrlistnode *exprptrlistptr;
    char *usrfmtptr, *rsltptr, *tmpfmtptr, *codeptr;
    char tmpfmtstr[MAXPRINTFFMTLEN+1], rsltstr[MAXPRINTFSTRLEN+1];
    int argidx;

    exprptrlistptr = stmts[stmtidx].s.printf_.exprptrlistptr;
    result = *exprptrlistptr->exprptr;	/* evaluate the FORMAT expr */
    evalexpr(&result);
    if (result.typ != STRING) 		/* it MUST be a string */
	fatalerrlin( "s/printf statment: format argument must be string expr");
    usrfmtptr = result.arg.sval;
    if (usrfmtptr == NULL)
	fatalerrlin("internal error: tried to print a null string");

    argidx = 1;
    rsltptr = rsltstr;
    while (*usrfmtptr) {		/* sequence thru user format string */
	if (*usrfmtptr == '%' && *(usrfmtptr+1)) {
	    tmpfmtptr = tmpfmtstr;
	    *tmpfmtptr++ = *usrfmtptr++;	/* copy the % to tmpfmtstr */
	    if (*usrfmtptr == '%') {		/* if user fmt str has "%%" */
		*rsltptr++ = *usrfmtptr++;	/* copy a % to rsltstr & cont */
		continue;
	    }
	    while (*usrfmtptr) {	/* copy all chars upto & including a */
		codeptr = printfcodes;	/* valid printf code to tmpfmtstr */
		while (*codeptr) {		/* break on a printf code ch */
		    if (*usrfmtptr == *codeptr) /* eg, 'd', 's', 'f', etc */
			break;
		    codeptr++;
		}		/* exit anyway, if we've checked them all */
		*tmpfmtptr++ = *usrfmtptr++;	/* copy this ch to tmpfmtstr */
		if (*codeptr)	/* break if we've found a printf code char */
		    break;
	    }
	    *tmpfmtptr = '\0';		/* terminate tmpfmtstr */

	    if (argidx < stmts[stmtidx].s.printf_.nargs) {
		exprptrlistptr = exprptrlistptr->next;
		result = *exprptrlistptr->exprptr;  /* evaluate the arg expr */
		evalexpr(&result);
		argidx++;
	    } else {	/* if there are more %d, %f, etc than argument(s) */
		fatalerrlin("s/printf format string: too many % codes");
	    }
	    switch (result.typ) {	/* sprintf it to the end of rsltstr */
		case INTEGER:
		    if (*codeptr == 's' || *codeptr == 'f')
			fatalerrlin("bad s/printf format code for an integer");
		    sprintf(rsltptr, tmpfmtstr, result.arg.ival);
		    break;
		case FLOAT:
		    if (*codeptr == 's' || *codeptr == 'd')
			fatalerrlin("bad s/printf format code for a float");
		    sprintf(rsltptr, tmpfmtstr, result.arg.fval);
		    break;
		case STRING:
		    if (*codeptr != 's')
			fatalerrlin("s/printf: use `%s' to print strings");
		    sprintf(rsltptr, tmpfmtstr, result.arg.sval);
		    break;
		case NORETVALEXPR:
		    fatalerrlin("printfmt: user function must return a value");
		default:
		    fatalerrlin("printfmt: s/printf hit default");
	    }
	    while (*rsltptr)	/* move rsltptr up to the end of rsltstr */
		rsltptr++;
	} else {			/* ordinary character, copy it as is */
	    *rsltptr++ = *usrfmtptr++;
	}
    }
    *rsltptr = '\0';		/* terminate rsltstr */

    if (stmts[stmtidx].typ == PRINTF) {		/* PRINTF: print it */
	printftrap(rsltstr);
    } else {						/* SPRINTF */
	switch (stmts[stmtidx].s.printf_.lhsexprptr->typ) {
	    case UFNCPARAMEXPR:
		lhsexprptr = &argstk[botargstkidx] +
				stmts[stmtidx].s.printf_.lhsexprptr->arg.ival;
		break;
	    case ARRAYVAREXPR:
		lhsexprptr=rtgetarrvaraddr(stmts[stmtidx].s.printf_.lhsexprptr);
		break;
	    default:			/* an "ordinary" variable */
		lhsexprptr = stmts[stmtidx].s.printf_.lhsexprptr;
		break;
	}
	lhsexprptr->arg.sval = (char*)malloc(strlen(rsltstr)+1);
	strcpy(lhsexprptr->arg.sval, rsltstr);
	lhsexprptr->typ = STRING;
    }
}
Ejemplo n.º 12
0
/*******************************************************************************
This function evaluates an expression.  It is passed a pointer to an expression
node to evaluate (results are also put here), and it evaluates the expression
tree.
Note: the argument stack is used for user function calls.  Even though it looks
cumbersome, indices have been used instead of stack pointers.  This is because
this is a recursive function, and it is neccessary to save previous stack
information AND the stack is dynamically resizable - that is - it can move at
any time.  Hence, any pointers saved on previous invocations of this function
would be pointing to where the stack USED to be, not where it NOW is.
*******************************************************************************/
void
evalexpr(Exprnode *exprptr)
{
    extern Field *aggrfldtbl, *fldtbl;
    extern Opmode opmode;		/* report or selrej mode */
    extern Statsinfofld *statsinfofldtbl;
    Exprnode lresult, rresult;
    Exprptrlistnode *exprptrlistptr;
    int tmpidx, argctr, intval, savebotargstkidx;
    float floatval;

    switch (exprptr->typ) {
	case INTEGER: case FLOAT: case STRING:
	    break;
	case FIELD:
	    if (opmode == REPORTMODE) {
		if (curfldvalptrtbl[exprptr->arg.ival] == NULL) {
		    fprintf(stderr, "field `%s'", 
					    aggrfldtbl[exprptr->arg.ival].name);
		    fatalerrlin(" is referenced outside a foreach loop");
		}
		exprptr->typ = aggrfldtbl[exprptr->arg.ival].typ;
		switch (exprptr->typ) {
		    case STRING:
			exprptr->arg.sval =
				curfldvalptrtbl[exprptr->arg.ival]->arg.sval;
			break;
		    case INTEGER:
			exprptr->arg.ival =
				curfldvalptrtbl[exprptr->arg.ival]->arg.ival;
			break;
		    case FLOAT:
			exprptr->arg.fval =
				curfldvalptrtbl[exprptr->arg.ival]->arg.fval;
			break;
		    default: fatalerror("evalexpr: SNARK!");
			break;
		}
	    } else {	/* selrej mode */
		evalselrejfld(exprptr);
	    }
	    break;
	case UFNCCALLEXPR:
	    argctr = exprptr->arg.ufnc.argctr;
	    if (argstkctr + argctr > maxargstkctr) {   /* enlarge stk if nec */
		maxargstkctr = MAX(maxargstkctr*ARGSTKMULTFACTOR,
							    argstkctr+argctr);
		argstk = (Exprnode*)realloc((void*)argstk,
				    (size_t)maxargstkctr*sizeof(Exprnode));
	    }
				    /* eval all args & push them on the stk */
	    exprptrlistptr = exprptr->arg.ufnc.exprptrlistptr;
	    while (exprptrlistptr != NULL) {		/* eval all args */
		lresult = *exprptrlistptr->exprptr;
		evalexpr(&lresult);
		*(argstk+argstkctr++) = lresult;	/* & push on stk */
		exprptrlistptr = exprptrlistptr->next;
	    }

	    savebotargstkidx = botargstkidx;
	    botargstkidx = argstkctr-argctr;
	    tmpidx = exprptr->arg.ufnc.begstmtidx;	/* call user func */
	    *exprptr = doblock(tmpidx+1, stmts[tmpidx].s.ufncdef.endstmtidx);
	    argstkctr -= argctr;
	    botargstkidx = savebotargstkidx;
	    break;
	case UFNCPARAMEXPR:
	    if (botargstkidx+exprptr->arg.ival >= argstkctr)
		fatalerror(STKERRMSG);
	    *exprptr = *(&argstk[botargstkidx]+exprptr->arg.ival);
	    break;
	case UNARYOPEXPR:
	    lresult = *(exprptr->leftptr);  evalexpr(&lresult);
	    switch (lresult.typ) {
		case INTEGER:
		    exprptr->arg.ival =
				iunaryop(exprptr->arg.optyp, lresult.arg.ival);
		    break;
		case FLOAT:
		    exprptr->arg.fval =
				funaryop(exprptr->arg.optyp, lresult.arg.fval);
		    break;
		default:
		    fatalerrlin("evalexpr: unary operation on illegal type");
		    break;
	    }
	    exprptr->typ = lresult.typ;
	    break;
	case BINARYOPEXPR:
	    lresult = *(exprptr->leftptr);  evalexpr(&lresult);
	    rresult = *(exprptr->rightptr); evalexpr(&rresult);
	    if ((lresult.typ == INTEGER)&&(rresult.typ == INTEGER)) {
		exprptr->arg.ival = ibinop(lresult.arg.ival,
				    exprptr->arg.optyp, rresult.arg.ival);
		exprptr->typ = INTEGER;
	    } else if (lresult.typ == INTEGER && rresult.typ == FLOAT) {
		    if ((exprptr->typ=fbinop((float)lresult.arg.ival,
				exprptr->arg.optyp, rresult.arg.fval,
				&floatval, &intval)) == FLOAT)
		    exprptr->arg.fval = floatval;
		else
		    exprptr->arg.ival = intval;
	    } else if (lresult.typ == FLOAT && rresult.typ == INTEGER) {
		    if ((exprptr->typ=fbinop(lresult.arg.fval,
				exprptr->arg.optyp, (float)rresult.arg.ival,
				&floatval, &intval)) == FLOAT)
		    exprptr->arg.fval = floatval;
		else
		    exprptr->arg.ival = intval;
	    } else if (lresult.typ == FLOAT && rresult.typ == FLOAT) {
		    if ((exprptr->typ=fbinop(lresult.arg.fval,
				exprptr->arg.optyp, rresult.arg.fval,
				&floatval, &intval)) == FLOAT)
		    exprptr->arg.fval = floatval;
		else
		    exprptr->arg.ival = intval;
	    } else if (lresult.typ == STRING && rresult.typ == STRING) {
		sbinop(lresult.arg.sval, rresult.arg.sval, exprptr);
	    } else {
		fatalerrlin( "evalexpr: illegal binary op argument type(s)");
	    }
	    break;
	case COUNT:
	    if (exprptr->arg.tdbfnc.maxdepth != INVALIDFLDIDX) {
		chk4badflds(exprptr->arg.tdbfnc.fldbits,
						exprptr->arg.tdbfnc.maxdepth);
		exprptr->arg.ival = getcount(datarootptr,
					    exprptr->arg.tdbfnc.fldbits, 0,
					    exprptr->arg.tdbfnc.maxdepth);
	    } else {
		exprptr->arg.ival = getcount(datarootptr,
					    exprptr->arg.tdbfnc.fldbits, 0, 0);
	    }
	    exprptr->typ = INTEGER;
	    break;
	case NUMBER:
	    chk4badflds(exprptr->arg.tdbfnc.fldbits,
						exprptr->arg.tdbfnc.maxdepth);
	    exprptr->arg.ival = getnumber(datarootptr,
		    exprptr->arg.tdbfnc.fldbits,
		    exprptr->arg.tdbfnc.depth, exprptr->arg.tdbfnc.maxdepth);
	    exprptr->typ = INTEGER;
	    break;
	case SUM:
	    intval = statsinfofldtbl[exprptr->arg.tdbfnc.depth].typ;
	    switch (intval) {
		case INTEGER:
		    if (exprptr->arg.tdbfnc.maxdepth != INVALIDFLDIDX) {
			chk4badflds(exprptr->arg.tdbfnc.fldbits,
						exprptr->arg.tdbfnc.maxdepth);
			exprptr->arg.ival = getintsum(datarootptr,
						exprptr->arg.tdbfnc.fldbits, 0,
						exprptr->arg.tdbfnc.maxdepth,
						exprptr->arg.tdbfnc.depth);
		    } else {
			exprptr->arg.ival = getintsum(datarootptr,
						exprptr->arg.tdbfnc.fldbits, 0,
						0, exprptr->arg.tdbfnc.depth);
		    }
		    break;
		case FLOAT:
		    if (exprptr->arg.tdbfnc.maxdepth != INVALIDFLDIDX) {
			chk4badflds(exprptr->arg.tdbfnc.fldbits,
						exprptr->arg.tdbfnc.maxdepth);
			exprptr->arg.fval = getfltsum(datarootptr,
						exprptr->arg.tdbfnc.fldbits, 0,
						exprptr->arg.tdbfnc.maxdepth,
						exprptr->arg.tdbfnc.depth);
		    } else {
			exprptr->arg.fval = getfltsum(datarootptr,
						exprptr->arg.tdbfnc.fldbits, 0,
						0, exprptr->arg.tdbfnc.depth);
		    }
		    break;
		default:
		    fatalerrlin("evalexpr: illegal SUM field type");
		    break;
	    }
	    exprptr->typ = intval;


	    break;
	case SUMSQRD:
	    intval = statsinfofldtbl[exprptr->arg.tdbfnc.depth].typ;
	    switch (intval) {
		case INTEGER:
		    if (exprptr->arg.tdbfnc.maxdepth != INVALIDFLDIDX) {
			chk4badflds(exprptr->arg.tdbfnc.fldbits,
						exprptr->arg.tdbfnc.maxdepth);
			exprptr->arg.ival = getintsumsqrd(datarootptr,
						exprptr->arg.tdbfnc.fldbits, 0,
						exprptr->arg.tdbfnc.maxdepth,
						exprptr->arg.tdbfnc.depth);
		    } else {
			exprptr->arg.ival = getintsumsqrd(datarootptr,
						exprptr->arg.tdbfnc.fldbits, 0,
						0, exprptr->arg.tdbfnc.depth);
		    }
		    break;
		case FLOAT:
		    if (exprptr->arg.tdbfnc.maxdepth != INVALIDFLDIDX) {
			chk4badflds(exprptr->arg.tdbfnc.fldbits,
						exprptr->arg.tdbfnc.maxdepth);
			exprptr->arg.fval = getfltsumsqrd(datarootptr,
						exprptr->arg.tdbfnc.fldbits, 0,
						exprptr->arg.tdbfnc.maxdepth,
						exprptr->arg.tdbfnc.depth);
		    } else {
			exprptr->arg.fval = getfltsumsqrd(datarootptr,
						exprptr->arg.tdbfnc.fldbits, 0,
						0, exprptr->arg.tdbfnc.depth);
		    }
		    break;
		default:
		    fatalerrlin("evalexpr: illegal SUM field type");
		    break;
	    }
	    exprptr->typ = intval;


	    break;
	case TYPE:
	    lresult = *(exprptr->leftptr);  evalexpr(&lresult);
	    switch (lresult.typ) {
		case INTEGER:		/* we've got an integer, make a ... */
		    if (exprptr->arg.casttyp == FLOAT) {
			exprptr->arg.fval = (float)lresult.arg.ival;
			exprptr->typ = FLOAT;
		    } else {		/* an integer */
			exprptr->arg.ival = lresult.arg.ival;
			exprptr->typ = INTEGER;
		    }
		    break;
		case FLOAT:		/* we've got a float, make an ... */
		    if (exprptr->arg.casttyp == FLOAT) {
			exprptr->arg.fval = lresult.arg.fval;
			exprptr->typ = FLOAT;
		    } else {		/* an integer */
			exprptr->arg.ival = (int)lresult.arg.fval;
			exprptr->typ = INTEGER;
		    }
		    break;
		default:
		    fatalerrlin("evalexpr: illegal type cast");
		    break;
	    }
	    break;
	case REPORTDT:			/* get the report date or time */
            exprptr->arg.ival = getreportdt(exprptr->arg.ival);
            exprptr->typ = INTEGER;
	    break;
	case FORMATDT:			/* format a date or time */
            lresult = *(exprptr->leftptr);  evalexpr(&lresult);
            rresult = *(exprptr->rightptr); evalexpr(&rresult);
            exprptr->arg.sval = formatdt(exprptr->arg.ival, &lresult, &rresult);
            exprptr->typ = STRING;
	    break;
        case STRFUNCEXPR:
            strfunc(exprptr);
	    break;
	case ATOI:
            lresult = *(exprptr->leftptr);  evalexpr(&lresult);
	    if (lresult.typ != STRING)
		fatalerrlin("evalexpr: atoi of non-string expression");
            exprptr->arg.ival = atoi(lresult.arg.sval);
            exprptr->typ = INTEGER;
	    break;
	case ATOF:
            lresult = *(exprptr->leftptr);  evalexpr(&lresult);
	    if (lresult.typ != STRING)
		fatalerrlin("evalexpr: atof of non-string expression");
            exprptr->arg.fval = (float) atof(lresult.arg.sval);
            exprptr->typ = FLOAT;
	    break;
	case MATHFUNC:
	    lresult = *(exprptr->leftptr);  evalexpr(&lresult);
	    switch (lresult.typ) {
		case INTEGER:
		    exprptr->arg.fval =
			mathfunc(exprptr->arg.optyp, (double)lresult.arg.ival);
		    break;
		case FLOAT:
		    exprptr->arg.fval =
			mathfunc(exprptr->arg.optyp, (double)lresult.arg.fval);
		    break;
		default:
		    fatalerrlin("evalexpr: math function on illegal type");
		    break;
	    }
	    exprptr->typ = FLOAT;
	    break;
	case ARRAYVAREXPR:
	    evalarrvar(exprptr);
	    break;
	case NEED:
	    lresult = *(exprptr->leftptr);  evalexpr(&lresult);
	    exprptr->typ = INTEGER;
	    exprptr->arg.ival = need(&lresult);
	    break;
	case UNDEFVAREXPR:
	    fprintf(stderr, "evalexpr: variable `%s'",exprptr->varptr->name);
	    fatalerrlin(" is undefined");
	    break;
	case NORETVALEXPR:
	    fatalerrlin("function returns no value (one is required)");
	    break;
	default:
	    fatalerrlin("evalexpr: illegal expr type");
	    break;
    }
}
Ejemplo n.º 13
0
/************************************************************************
 * evalexpr  evaluates the expression ex at the solution point, given   *
 *      by the vector of SI values sols. It also estimates the maximum  *
 *      error it should have in calculating the value.                  *
 *  It treats an equation lhs = rhs as if it were                       *
 *      the expression lhs-rhs                                          *
 *  Errors contributions from several sources are added in magnitudes,  *
 *      not in quadrature, as we are interested in a maximum rather     *
 *      than an expected error.                                         *
 * Note: The calculation simply guesses the errors in all numvals and   *
 *      solution points, so this is not a real calculation. To do that, *
 *      we would need to propagate errors in eqnumsimp and other places *
 *      numvals are calculated, and give errors on input given values   *
 *      for which we currently have no facility.                        *
 ************************************************************************/
answitherr* evalexpr(const expr* const ex, const vector<double>* const sols,
                     const double reltverr) {
    answitherr* retval = new answitherr;
    int k;

#ifdef WITHDBG // for debugging
    int thiscall=recall++;
#endif
    DBG(cout << "evalexpr call " << thiscall << " for "
        << ex->getInfix() << " with reltverr = " << reltverr << endl);
    switch (ex->etype) {
    case numval:
        retval->value = ((numvalexp*)ex)->value;
        if( ((numvalexp*)ex)->abserr<0)
            retval->abserr = reltverr * fabs(retval->value);
        else
            retval->abserr = ((numvalexp*)ex)->abserr;
        DBG(cout << "evalexpr call " << thiscall << " numval returning "
            << retval->value << "+-" << retval->abserr << endl);
        return(retval);
        break;

    case physvart:
        retval->value = (*sols)[((physvarptr *) ex)->varindex];
        retval->abserr = reltverr * fabs(retval->value);
        DBG(cout << "evalexpr call " << thiscall << " physvar returning "
            << retval->value << "+-" << retval->abserr << endl);
        return(retval);

    case function: {
        answitherr* argval = evalexpr(((functexp *)ex)->arg,sols, reltverr);
        switch(((functexp *)ex)->f->opty) {    // remember, if FAKEDEG, trig
        case sine:                // functions in degrees! if not, trig functions
            retval->value = sin(DEG2RAD * argval->value);      //  of radians
            retval->abserr = max(fabs(cos(DEG2RAD * argval->value)
                                      * DEG2RAD * (argval->abserr)), reltverr);
            break;
        case cose:
            retval->value = cos(DEG2RAD * argval->value);
            retval->abserr = max(fabs(sin(DEG2RAD * argval->value)
                                      * DEG2RAD * (argval->abserr)), reltverr);
            break;
        case tane:
            retval->value = tan(DEG2RAD * argval->value);
            retval->abserr = fabs((1.0 + pow(retval->value,2))
                                  * DEG2RAD * (argval->abserr));
            break;
        case expe:
            retval->value = exp(argval->value);
            retval->abserr = fabs(retval->value * argval->abserr);
            break;
        case lne:
            retval->value = log(argval->value);
            retval->abserr = fabs(argval->abserr / retval->value);
            break;
        case log10e:
            if(argval->value<=0) {
                \
                delete retval;
                throw(FPE_handler + string("log of negative"));
            }
            retval->value = log10(argval->value);
            retval->abserr = fabs(argval->abserr / (retval->value * log(10.0)));
            break;
        case sqrte:
            if(argval->value<0.0) {
                // if a negative value is less than the error, just set to zero.
                if(argval->abserr + argval->value>0.0)
                    retval->value=0.0;
                else {
                    delete retval;
                    throw(FPE_handler + string("sqrt of negative"));
                }
            } else
                retval->value = sqrt(argval->value);
            if (retval->value > reltverr) {
                retval->abserr = (argval->abserr / (2.0 * retval->value));
            } else {
                retval->abserr = sqrt(argval->abserr);
            }
            break;
        case abse:
            retval->value = fabs(argval->value);
            retval->abserr = argval->abserr;
            break;
        default:
            throw(string("impossible function in evalexpr"));
        }
        DBG(cout << "evalexpr call " << thiscall << " function returning "
            << retval->value << "+-" << retval->abserr << endl);
        delete argval;
        return(retval);
    }
    case binop: {
        answitherr* lhsval = evalexpr(((binopexp*)ex)->lhs,sols,reltverr);
        answitherr* rhsval = evalexpr(((binopexp*)ex)->rhs,sols,reltverr);
        switch(((binopexp*)ex)->op->opty) {
        case divbye:
            if(rhsval->value==0.0) {
                delete retval;
                throw(FPE_handler + string("divide by zero"));
            }
            retval->value = lhsval->value/rhsval->value;
            retval->abserr = lhsval->abserr/fabs(rhsval->value)
                             + rhsval->abserr * fabs(lhsval->value/pow(rhsval->value,2));
            break;
        case topowe:
            retval->value = pow(lhsval->value,rhsval->value);
            if (fabs(lhsval->value)>lhsval->abserr) {
                // AW: joel's suggested corrections for kt5a bug (email 9/8/03)
                retval->abserr = lhsval->abserr
                                 * fabs(rhsval->value * (retval->value /lhsval->value))
                                 + rhsval->abserr * fabs(log(fabs(lhsval->value)) * retval->value);
            } else {
                retval->abserr = pow(lhsval->abserr, rhsval->value - rhsval->abserr);
            }
            break;
        case equalse:
            retval->value = lhsval->value - rhsval->value;
            retval->abserr = lhsval->abserr + rhsval->abserr;
            break;
        case grte:
        case gree:
        default:
            throw(string("I can't return eval of >=, >, or unknown expr"));
        }
        delete lhsval;
        delete rhsval;
        DBG(cout << "evalexpr call " << thiscall << " binop returning "
            << retval->value << "+-" << retval->abserr << endl);
        return(retval);
    }
    case n_op: {
        switch(((n_opexp*)ex)->op->opty) {
        case pluse: {
            retval->value = 0;
            retval->abserr = 0;
            for (k=0; k<((n_opexp*)ex)->args->size(); k++) {
                answitherr* argval
                    = evalexpr((*((n_opexp *)ex)->args)[k], sols,reltverr);
                retval->value += argval->value;
                retval->abserr += argval->abserr;
                delete argval;
            }
            break;
        }
        case multe: {
            retval->value = 1;
            retval->abserr = 0;
            for (k=0; k<((n_opexp*)ex)->args->size(); k++)  {
                answitherr* argval
                    = evalexpr((*((n_opexp*)ex)->args)[k],sols,reltverr);
                retval->abserr = fabs(argval->value*retval->abserr)
                                 + fabs(argval->abserr * retval->value);
                retval->value *= argval->value;
                delete argval;
            }
            break;
        }
        default:
            throw(string("unknown n_op in evalexpr"));
        }
    }
    DBG(cout << "evalexpr call " << thiscall << " n_op returning "
        << retval->value << "+-" << retval->abserr << endl);
    return(retval);
    case unknown:
    case fake:
    default:
        throw(string("I can't return eval of fake or unknown expr"));
    }
}
Ejemplo n.º 14
0
/*******************************************************************************
Handle all the built-in string functions (PATMATCH INDEXSTR STRLEN SUBSTR
LOOKUP)
*******************************************************************************/
int
strfunc(Exprnode *exprptr)
{
    Exprnode result1, result2, result3;
    char *chptr;
    int len, newlen;
				    /* all functions have a first argument */
    result1 = *(exprptr->leftptr);  evalexpr(&result1);
    switch (exprptr->arg.strfnc.functyp) {
        case PATMATCH:
            result2 = *(exprptr->rightptr); evalexpr(&result2);
	    if ((result1.typ != STRING) || (result2.typ != STRING))
		fatalerrlin("patmatch: both arguments must be strings");
            exprptr->arg.ival = patmatch(&result1, &result2);
            exprptr->typ = INTEGER;
	    break;
	case STRLEN:
	    if (result1.typ != STRING)
		fatalerrlin("strlen: argument must be a string");
	    exprptr->arg.ival = strlen(result1.arg.sval);
	    exprptr->typ = INTEGER;
	    break;
	case INDEXSTR:
            result2 = *(exprptr->rightptr); evalexpr(&result2);
	    if ((result1.typ != STRING) || (result2.typ != STRING))
		fatalerrlin("indexstr: both arguments must be strings");
	    if ((chptr=strstr(result2.arg.sval, result1.arg.sval)) == NULL) {
		exprptr->arg.ival = 0;
	    } else {
		exprptr->arg.ival = chptr - result2.arg.sval + 1;
	    }
            exprptr->typ = INTEGER;
	    break;
	case SUBSTR:
	    if (result1.typ != STRING)
		fatalerrlin("substr: first argument must be a string");
            result2 = *(exprptr->rightptr); evalexpr(&result2);
	    result3 = *(exprptr->arg.strfnc.expr3ptr); evalexpr(&result3);
	    if (result2.typ != INTEGER || result3.typ != INTEGER)
		fatalerrlin("substr: 2nd and 3rd arguments must be integers");
	    len = strlen(result1.arg.sval);
	    if (result2.arg.ival < 1 || result2.arg.ival > len) {
		fprintf(stderr, "substr: bad index %d", result2.arg.ival);
		fatalerrlin("");
	    }
	    if (result3.arg.ival < 1) {
		fprintf(stderr, "substr: bad length %d", result3.arg.ival);
		fatalerrlin("");
	    }
	    newlen = MIN(len-result2.arg.ival+1, result3.arg.ival);
	    chptr = (char*)malloc((size_t)(newlen+1));
	    strncpy(chptr, result1.arg.sval+result2.arg.ival-1, newlen);
	    *(chptr+newlen) = '\0';
	    exprptr->arg.sval = chptr;
            exprptr->typ = STRING;
	    break;
	case LOOKUP:
	    if (result1.typ != STRING)
		fatalerrlin("lookup: first argument must be a string");
						/* second argument */
            result2 = *(exprptr->rightptr);  evalexpr(&result2);
	    if (result2.typ != STRING)
		fatalerrlin("lookup: second argument must be a string");
						/* optional 3rd arg */
	    if (exprptr->arg.strfnc.expr3ptr == NULL) {
		result3.arg.ival = 2;
	    } else {
		result3 = *(exprptr->arg.strfnc.expr3ptr);
		evalexpr(&result3);
		if (result3.typ != INTEGER)
		    fatalerrlin("lookup: third argument must be an integer");
	    }
	    exprptr->arg.sval = dolookup(result1.arg.sval, result2.arg.sval,
							    result3.arg.ival);
	    exprptr->typ = STRING;
	    break;
	default: fatalerror("strfunc: hit default");
	    break;
    }
}