static an CnvRnd( an name, type_def *tipe, cg_op op ) { /***********************************************************/ if( NeedConvert( name->tipe, tipe ) ) { name = Unary( op, name, tipe ); } else if( name->tipe != tipe ) { AddrDemote( name ); /* it's not quite the right type */ } name->tipe = tipe; return( name ); }
void BinOp( TYPE typ1, TYPE typ2, OPTR opr ) { //=============================================== // Generate code to perform a binary operation. if( typ1 != FT_NO_TYPE ) { // binary operator Binary( typ1, typ2, opr ); } else { // unary operator. Unary( typ2, opr ); } }
an Arithmetic( an name, type_def *tipe ) /*******************************************/ { if( name->format == NF_BOOL ) { if( (tipe->attr & TYPE_FLOAT) != 0 || ( tipe->length > TypeInteger->length ) ) { name = FlowOut( name, TypeInteger ); name = Unary( O_CONVERT, name, tipe ); } else { name = FlowOut( name, tipe ); } } return( name ); }
/* Apply - apply an operator to operands */ static void Apply(EvalState *c, int op) { if (Unary(op)) { PVAL *pval; if (rStackCount(c) < 1) Error(c, "syntax error"); pval = &c->rStackPtr[0]; ApplyUnary(c, op, pval); } else { PVAL *left, *right; if (rStackCount(c) < 2) Error(c, "syntax error"); left = &c->rStackPtr[-1]; right = &c->rStackPtr[0]; ApplyBinary(c, op, left, right); rStackDrop(c); } }
/* EvalExpr - Eval and evaluate an expression using the shunting yard algorithm */ int EvalExpr(EvalState *c, const char *str, VALUE *pValue) { int unaryPossible = TRUE; int tkn, count, prec, op; PVAL pval; /* setup an error target */ if (setjmp(c->errorTarget)) return FALSE; /* initialize the parser */ c->linePtr = (char *)str; c->savedToken = TKN_NONE; /* initialize the operator and operand stacks */ c->oStackPtr = c->oStack - 1; c->rStackPtr = c->rStack - 1; /* handle each input token */ while ((tkn = GetToken(c, &pval)) != TKN_EOF) { switch (tkn) { case TKN_IDENTIFIER: case TKN_NUMBER: if (!unaryPossible) Error(c, "syntax error"); rStackPush(c, pval); unaryPossible = FALSE; break; case TKN_FCALL: oStackPush(c, c->argc); oStackPushData(c, c->fcn); oStackPush(c, tkn); c->fcn = pval.v.fcn; c->argc = 0; unaryPossible = FALSE; break; case '(': if (oStackTop(c) == TKN_FCALL) c->oStackPtr->op = TKN_FCALL_ARGS; else oStackPush(c, tkn); unaryPossible = TRUE; break; case ',': if (PopAndEvaluate(c) != TKN_FCALL_ARGS) Error(c, "argument list outside of a function call"); unaryPossible = FALSE; break; case ')': tkn = PopAndEvaluate(c); oStackDrop(c); if (tkn == TKN_FCALL || tkn == TKN_FCALL_ARGS) CallFunction(c); unaryPossible = FALSE; break; default: if (unaryPossible && tkn == '-') tkn = TKN_UNARY_MINUS; if (unaryPossible && !Unary(tkn)) Error(c, "syntax error"); prec = Prec(c, tkn); while (!oStackIsEmpty(c)) { int stackPrec = Prec(c, oStackTop(c)); if ((Assoc(tkn) == ASSOC_LEFT && prec > stackPrec) || prec >= stackPrec) break; op = oStackTop(c); oStackDrop(c); if (op == TKN_FCALL) CallFunction(c); else Apply(c, op); } oStackPush(c, tkn); unaryPossible = TRUE; break; } } /* apply all of the remaining operands on the operator stack */ while (!oStackIsEmpty(c)) { int op = oStackTop(c); oStackDrop(c); if (op == '(') Error(c, "mismatched parens"); if (op == TKN_FCALL) CallFunction(c); else Apply(c, op); } /* if the operand stack is empty then there was no expression to parse */ if ((count = rStackCount(c)) == 0) return FALSE; /* otherwise, make sure there is only one entry left on the operand stack */ else if (count != 1) Error(c, "syntax error"); /* return the expression value */ RValue(c, &c->rStackPtr[0]); *pValue = c->rStackPtr[0].v.value; /* return successfully */ return TRUE; }