static void applyPOWER(void) { Real r, x = evalreal(getN(1)), y = evalreal(getN(2)); Integer i = y; if(x < 0 && y != i) runtimeerror(ERROR, template_power->value); if(x == 0) { if(y < 0) runtimeerror(ERROR, template_power->value); else if(y == 0) makeINT(1); else makeINT(0); } else { errno = 0; r = pow(x, y); if(errno != 0) runtimeerror(ERROR, template_power->value); if(r >= LONG_MIN && r <= LONG_MAX && r == (i = r)) makeINT(i); else makeREAL(r); } }
static void applyDIVIDE(void) { Real x = evalreal(getN(1)), y = evalreal(getN(2)); if(y==0) makeconstant(ERROR, template_divide->value); else makeREAL(x/y); }
static void applyNEG(void) { Cell *c = getN(1); evaluate(c); if(c->tag == INT) makeINT(-integer(c)); else makeREAL(-real(c)); }
static void applyTIMES(void) { Cell *c1 = getN(1), *c2 = getN(2); evaluate(c1); evaluate(c2); if(c1->tag == INT) { if(c2->tag == INT) makeINT(integer(c1) * integer(c2)); else makeREAL(integer(c1) * real(c2)); } else { if(c2->tag == INT) makeREAL(real(c1) * integer(c2)); else makeREAL(real(c1) * real(c2)); } }
static void parseterm(void) { int count; switch(tokentype) { case NUMBER: if(strchr(tokenval, '.') == NULL) makeINT(atol(tokenval)); else makeREAL(atof(tokenval)); gettoken(); break; case IDENTIFIER: parsename(); break; case TYPEID: push(gettemplate(tokenval)); makecompound(STRUCT, 1); gettoken(); break; case CHARACTER: makeconstant(CHAR, tokenval[0]); gettoken(); break; case STRING: buildstring(tokenval); gettoken(); break; case LPAR: gettoken(); if(tokentype == OPERATOR && strcmp(tokenval, "-") != 0) { parsename(); if(tokentype != RPAR) { parseexpression(MAXPRIO); rotatestack(); push(gettemplate("_section")); make(APPLY); make(APPLY); } } else if(tokentype == RPAR) makeconstant(NULLTUPLE, 0); else { parseexpression(MAXPRIO); if(tokentype == COMMA) { count = 1; while(tokentype == COMMA) { gettoken(); parseexpression(MAXPRIO); count++; } makecompound(PAIR, count); } } if(tokentype != RPAR) parseerror(2); gettoken(); break; case LBRACK: parselist(); break; case LACC: count = 0; do { gettoken(); if(tokentype != IDENTIFIER) parseerror(25); push(gettemplate(tokenval)); gettoken(); if(strcmp(tokenval, "=") != 0) parseerror(5); gettoken(); parseexpression(MAXPRIO); makeinverse(ALIAS); count++; } while(tokentype == COMMA); makecompound(RECORD, count); if(tokentype != RACC) parseerror(33); gettoken(); break; default: parseerror(3); } }