Example #1
0
File: ex4_11.c Project: yufw/kr
int main()
{
    int type;
    double op2;
    char s[MAXOP];

    while ((type = getop(s)) != EOF) {
        switch (type) {
        case NUMBER:
            push(atof(s));
            break;
        case MATHFUNC:
            push(mathfunc(s));
            break;
        case '+':
            push(pop() + pop());
            break;
        case '*':
            push(pop() * pop());
            break;
        case '-':
            op2 = pop();
            push(pop() - op2);
            break;
        case '/':
            op2 = pop();
            if (op2 != 0.0)
                push(pop() / op2);
            else
                printf("error: zero divisor\n");
            break;
        case '%':
            op2 = pop();
            if (op2 != 0.0)
                push(fmod(pop(), op2));
            else
                printf("error: zero divisor\n");
            break;
        case '\n':
            printf("\t%.8g\n", pop());
            break;
        default:
            printf("error: unknow command %s\n", s);
            break;
        }
    }
    return 0;
}
Example #2
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;
    }
}
Example #3
0
type function(double t, double *X)
{
	char f[20], *p;
	type v;
	
	p = f;
	while(p-f < 19 && c >= 'a' && c <= 'z') { *p++ = c; next(); }
	
	*p = 0;
	
	if(!strcmp(f,"pi")) return M_PI;
	if(!strcmp(f,"e" )) return M_E;
  
	v = term(t,X);
	
#define mathfunc(a,b) if(!strcmp(f,a)) return b;
  
	mathfunc("abs"   , fabs(v));
	mathfunc("fabs"  , fabs(v));
	mathfunc("floor" , floor(v));
	mathfunc("ceil"  , ceil(v));
	mathfunc("sqrt"  , sqrt(v));
	mathfunc("exp"   , exp(v));
  
	mathfunc("sin"   , sin(v));
	mathfunc("cos"   , cos(v));
	mathfunc("tan"   , tan(v));
	mathfunc("asin"  , asin(v));
	mathfunc("acos"  , acos(v));
	mathfunc("atan"  , atan(v));
  
	mathfunc("sinh"  , sinh(v));
	mathfunc("cosh"  , cosh(v));
	mathfunc("tanh"  , tanh(v));
	mathfunc("asinh" , asinh(v));
	mathfunc("acosh" , acosh(v));
	mathfunc("atanh" , atanh(v));
  
  unknown(f);
  return 0;
}
Example #4
0
/*注意输入的时候,需要用空格作为间断*/
main()
{
	int type;
	double temp,temp2;
 	double v; 
	char s[MAXOP];
	int i,var=0;
	double variable[26];/*26个字母,需要一个长为27的数组*/
	for(i=0;i<26;i++)
		variable[i]=0.0;/*初始化数组*/
	
	printf("\n----------RPN calculator-------------\n");
	printf("*      察看栈顶元素-?               *\n");
	printf("*      复制栈顶元素-c(copy)         *\n");
	printf("*      清空栈中元素-e(erase)        *\n");
	printf("*      交换栈顶元素-s(swap)         *\n");
	printf("*      可用函数:sin,cos,exp,pow     *\n");
	printf("*      请用空格间隔输入             *\n");
	printf("---------------------------------------\n");
	printf("please input:");
	
	while((type=getop(s))!=EOF)
	{
		switch (type)
		{
			case NUMBER:
				push(atof(s));
				break;
			case NAME:/*数学函数*/
				mathfunc(s);
				break;
			case '+':
				push(pop()+pop());
				break;
			case '*':
				push(pop()*pop());
				break;
			case '-':
				temp=pop();
				push(pop()-temp);
				break;
			case '/':
				temp=pop();
				if(temp!=0.0)
					push(pop()/temp);
				else
					printf("error:zero divisor\n");
				break;
			case '%':/*求模运算*/
				temp=pop();
				if(temp!=0.0)
					push(fmod(pop(),temp));
				else
					printf("error:zero divisor\n");
				break;
			case '\n':
				v=pop();/*最近打印的结果存在v中*/
				printf("result:\t%.8g\n",v);/*注意:此处是v,不是pop(),否则会弹出下一个值*/
				break;
			case '?':
				temp=pop();
				printf("top element :\t%.8g\n",temp);
				push(temp);
				break;
			case 'c':
				temp=pop();
				push(temp);
				push(temp);
				break;
			case 'e':
				clear();
				break;
			case 's':
				temp=pop();
				temp2=pop();
				push(temp);
				push(temp2);
				break;
			case '=':/*赋值操作*/
				pop();/*把varibale相应位置弹出*/
				if(var>='A'&&var<='Z')/*此时var是刚才的type(A)*/
					variable[var-'A']=pop();/*把压入的字母弹出赋值给数组对应位置*/
				else
					printf("error:no variable name\n");
				break;
			default:
				if(type>='A'||type<='Z')/*A-Z为数组变量的索引*/
					push(variable[type-'A']);/*把数组相应位置元素压入,第一次赋值的时候是0,但是=赋值进行后,就变成了 字母前面的数字,并在调用的时候,该数字被压入*/
				else if(type=='v')/*如果输入v,则把结果v压入栈中*/
					push(v);
				else
					printf("error:unknow command %s\n",s);
				break;
		}
		var=type;/*每次switch结束后,都把刚才的type赋值给var*/
	}
	return 0;
}