std::string Operators::what_is_binary_name(const std::string& op)const { size_t prec = op_prec(op); if (prec > 0) { return Str::split(binary(prec),' ')[0]; } return ""; }
/* * Perform the hard work of evaluation. * * This function works because: * -- all unary operators are right to left associative, and with * identical precedence * -- all binary operators are left to right associative * -- there is only one non-unary and non-binary operator: the quest-colon * * If do_eval is 0, the evaluation of operators is not done. This is * for sequence point operators (&&, || and ?:). */ static ppval eval_shrd(struct token_fifo *tf, int minprec, int do_eval) { ppval top; struct ucpp_token *ct; top.sign = 1; if (tf->art == tf->nt) goto trunc_err; ct = tf->t + (tf->art ++); if (ct->type == LPAR) { top = eval_shrd(tf, 0, do_eval); if (tf->art == tf->nt) goto trunc_err; ct = tf->t + (tf->art ++); if (ct->type != RPAR) { error(eval_line, "a right parenthesis was expected"); throw(eval_exception); } } else if (ct->type == NUMBER || ct->type == CHAR) { top = pp_strtoconst(ct->name); } else if (OP_UN(ct->type)) { top = eval_opun(ct->type, eval_shrd(tf, op_prec(ct->type), do_eval)); goto eval_loop; } else if (ttOP(ct->type)) goto rogue_op_err; else { goto invalid_token_err; } eval_loop: if (tf->art == tf->nt) { return top; } ct = tf->t + (tf->art ++); if (OP_BIN(ct->type)) { int bp = op_prec(ct->type); if (bp > minprec) { ppval tr; if ((ct->type == LOR && boolval(top)) || (ct->type == LAND && !boolval(top))) { tr = eval_shrd(tf, bp, 0); if (do_eval) { top.sign = 1; if (ct->type == LOR) top.u.sv = big_s_fromint(1); if (ct->type == LAND) top.u.sv = big_s_fromint(0); } } else { tr = eval_shrd(tf, bp, do_eval); if (do_eval) top = eval_opbin(ct->type, top, tr); } goto eval_loop; } } else if (ct->type == QUEST) { int bp = op_prec(QUEST); ppval r1, r2; if (bp >= minprec) { int qv = boolval(top); r1 = eval_shrd(tf, bp, qv ? do_eval : 0); if (tf->art == tf->nt) goto trunc_err; ct = tf->t + (tf->art ++); if (ct->type != COLON) { error(eval_line, "a colon was expected"); throw(eval_exception); } r2 = eval_shrd(tf, bp, qv ? 0 : do_eval); if (do_eval) { if (qv) top = r1; else top = r2; } goto eval_loop; } } tf->art --; return top; trunc_err: error(eval_line, "truncated constant integral expression"); throw(eval_exception); rogue_op_err: error(eval_line, "rogue operator '%s' in constant integral " "expression", operators_name[ct->type]); throw(eval_exception); invalid_token_err: error(eval_line, "invalid token in constant integral expression"); throw(eval_exception); }