예제 #1
0
파일: funcs.c 프로젝트: jasison27/Caculator
double eval(struct ast *a) {
	double v;
	if(!a) { // default value
		return 0.0;
	}
	switch(a->nodetype) {
		// constant number
		case 'K': v = ((struct numval *)a)->number; break;
		// name reference
		case 'N': v = ((struct symref *)a)->s->value; break;
		// assignment
		case '=': v = ((struct symasgn *)a)->s->value = eval(((struct symasgn *)a)->v); break;
		// expressions
		case '+': v = eval(a->l) + eval(a->r); break;
		case '-': v = eval(a->l) - eval(a->r); break;
		case '*': v = eval(a->l) * eval(a->r); break;
		case '/': v = eval(a->l) / eval(a->r); break;
		case '|': v = fabs(eval(a->l)); break;
		case 'M': v = -eval(a->l); break;
		// comparisons
		case '1': v = (eval(a->l) > eval(a->r))? 1 : 0; break;
		case '2': v = (eval(a->l) < eval(a->r))? 1 : 0; break;
		case '3': v = (eval(a->l) != eval(a->r))? 1 : 0; break;
		case '4': v = (eval(a->l) == eval(a->r))? 1 : 0; break;
		case '5': v = (eval(a->l) >= eval(a->r))? 1 : 0; break;
		case '6': v = (eval(a->l) <= eval(a->r))? 1 : 0; break;
		// if flow
		case 'I':
			if( eval( ((struct flow *)a)->cond) != 0) {
				if( ((struct flow *)a)->tl) { // else branch if exists
					v = eval( ((struct flow *)a)->tl);
				} else {
					v = 0.0; // default value
				}
			} else {
				if( ((struct flow *)a)->el) { // if branch if exists
					v = eval(((struct flow *)a)->el);
				} else {
					v = 0.0; // default value
				}
			}
			break;
		case 'W': // while flow
			v = 0.0;		/* default value */
			if( ((struct flow *)a)->tl) {
				while( eval(((struct flow *)a)->cond) != 0) { // loop
					v = eval(((struct flow *)a)->tl);
				}
			}
			break; // last value is the value returned
		// define user function						
		case 'L': eval(a->l); v = eval(a->r); break;
		// call built-in function
		case 'F': v = callbuiltin((struct fncall *)a); break;
		// call user-defined function
		case 'C': v = calluser((struct ufncall *)a); break;
		// error
		default: printf("internal error: bad node %c\n", a->nodetype);
	}
	return v;
}
예제 #2
0
double
eval(struct pcdata *pp, struct ast *a)
{
  double v;

  if(!a) {
    yyerror(pp, "internal error, null eval");
    return 0.0;
  }

  switch(a->nodetype) {
    /* constant */
  case 'K': v = ((struct numval *)a)->number; break;

    /* name reference */
  case 'N': v = ((struct symref *)a)->s->value; break;

    /* assignment */
  case '=': v = ((struct symasgn *)a)->s->value =
      eval(pp, ((struct symasgn *)a)->v); break;

    /* expressions */
  case '+': v = eval(pp, a->l) + eval(pp, a->r); break;
  case '-': v = eval(pp, a->l) - eval(pp, a->r); break;
  case '*': v = eval(pp, a->l) * eval(pp, a->r); break;
  case '/': v = eval(pp, a->l) / eval(pp, a->r); break;
  case '|': v = fabs(eval(pp, a->l)); break;
  case 'M': v = -eval(pp, a->l); break;

    /* comparisons */
  case '1': v = (eval(pp, a->l) > eval(pp, a->r))? 1 : 0; break;
  case '2': v = (eval(pp, a->l) < eval(pp, a->r))? 1 : 0; break;
  case '3': v = (eval(pp, a->l) != eval(pp, a->r))? 1 : 0; break;
  case '4': v = (eval(pp, a->l) == eval(pp, a->r))? 1 : 0; break;
  case '5': v = (eval(pp, a->l) >= eval(pp, a->r))? 1 : 0; break;
  case '6': v = (eval(pp, a->l) <= eval(pp, a->r))? 1 : 0; break;

  /* control flow */
  /* null if/else/do expressions allowed in the grammar, so check for them */
  case 'I': 
    if( eval(pp,  ((struct flow *)a)->cond) != 0) {
      if( ((struct flow *)a)->tl) {
	v = eval(pp,  ((struct flow *)a)->tl);
      } else
	v = 0.0;		/* a default value */
    } else {
      if( ((struct flow *)a)->el) {
        v = eval(pp, ((struct flow *)a)->el);
      } else
	v = 0.0;		/* a default value */
    }
    break;

  case 'W':
    v = 0.0;		/* a default value */
    
    if( ((struct flow *)a)->tl) {
      while( eval(pp, ((struct flow *)a)->cond) != 0)
	v = eval(pp, ((struct flow *)a)->tl);
    }
    break;			/* last value is value */
	              
  case 'L': eval(pp, a->l); v = eval(pp, a->r); break;

  case 'F': v = callbuiltin(pp, (struct fncall *)a); break;

  case 'C': v = calluser(pp, (struct ufncall *)a); break;

  default: printf("internal error: bad node %c\n", a->nodetype);
  }
  return v;
}
예제 #3
0
double eval(struct ast *a)
{
	double v;  /* calculated value of this subtree */

	if(NULL == a)
	{
		yyerror("internal error, null eval");
		return 0.0;
	}

	switch(a->nodetype)
	{
	case 'K':
		v = ((struct numval *)a)->number;
		break;

	case 'N':
		v = ((struct symref *)a)->s->value;
		break;

	case '=':
		v = ((struct symasgn *)a)->s->value = eval( ((struct symasgn *)a)->v );
		break;

	case '+':
		v = eval(a->l) + eval(a->r);
		break;

	case '-':
		v = eval(a->l) - eval(a->r);
		break;

	case '*':
		v = eval(a->l) * eval(a->r);
		break;

	case '/':
		v = eval(a->l) / eval(a->r);
		break;

	case '|':
		v = fabs(eval(a->l));
		break;

	case 'M':
		v = -eval(a->l);
		break;

	case '1':
		v = (eval(a->l) > eval(a->r)) ? 1 : 0;
		break;

	case '2':
		v = (eval(a->l) < eval(a->r)) ? 1 : 0;
		break;

	case '3':
		v = (eval(a->l) != eval(a->r)) ? 1 : 0;
		break;

	case '4':
		v = (eval(a->l) == eval(a->r)) ? 1 : 0;
		break;

	case '5':
		v = (eval(a->l) >= eval(a->r)) ? 1 : 0;
		break;

	case '6':
		v = (eval(a->l) <= eval(a->r)) ? 1 : 0;
		break;

	/* control flow */

	case 'I':
		if( eval( ((struct flow *)a)->cond) != 0)
		{
			if( ((struct flow *)a)->tl )
			{
				v = eval( ((struct flow *)a)->tl );
			}
			else
				v = 0.0;
		}
		else
		{
			if( ((struct flow *)a)->el )
			{
				v = eval( ((struct flow *)a)->el );
			}
			else
				v = 0.0;
		}
		break;

	case 'W':
		v = 0.0;

		if( ((struct flow *)a)->tl )
		{
			while( eval(((struct flow *)a)->cond) != 0)
				v = eval(((struct flow *)a)->tl);
		}
		break;

	case 'L':
		eval(a->l);
		v = eval(a->r);
		break;

	case 'F':
		v = callbuiltin( (struct fncall *)a );
		break;

	case 'C':
		v = calluser( (struct ufncall *)a );
		break;

	default:
		printf("internal error:  bad node %c\n", a->nodetype);
	}

	return v;
}