SemVal *p_catStmnts(SemVal *lval, SemVal *rval) { p_patchupFalse(lval, 1); msg("lval length: %u, rval length: %u", lval->codelen, rval->codelen); if (gp_nestLevel == 0) { util_out(gp_bin, lval->code, lval->codelen); p_discard(lval); return rval; } return p_catCode(lval, rval); }
void p_bool2int(SemVal *e) { if (!test_type(e, e_bool)) /* no batchpatching needed */ return; p_patchupTrue(e, 1); e->truelen = 0; p_generateCode(e, op_push_1_jmp_end); /* truelist target */ p_patchupFalse(e, 1); e->falselen = 0; p_generateCode(e, op_push_0); /* falselist target */ set_type(e, e_int | e_stack); /* set int code type */ }
SemVal *p_ternary(SemVal *cond, SemVal *ifTrue, SemVal *ifFalse) { if ((ifTrue->type & ifFalse->type & e_typeMask) == 0) { util_semantic(gp_typeConflict, "?:"); p_clearOperands(ifTrue, ifFalse); return cond; } if (test_type(cond, e_const)) /* constant: true or false */ { p_discard(cond); if (cond->evalue) { p_discard(ifFalse); p_expr2stack(ifTrue); return ifTrue; } p_discard(ifTrue); p_expr2stack(ifFalse); return ifFalse; } p_expr2stack(ifTrue); /* convert the expressions to code */ p_expr2stack(ifFalse); p_generateCode(cond, op_jmp_false, j_falselist); /* jmp around the ifTrue code */ p_patchupTrue(cond, 1); /* destination for the ifTrue code */ p_catCode(cond, ifTrue); /* cond = cond + ifTrue */ p_generateCode(cond, op_jmp, j_truelist); /* jmp around the ifFalse code */ p_patchupFalse(cond, 1); /* destination of the false alternative */ p_catCode(cond, ifFalse); /* cond = cond + ifTrue + jmp + ifFalse */ p_patchupTrue(cond, 1); /* jump from ifTrue to the end of expr. */ return cond; /* ?: return */ }
SemVal *p_orBool(SemVal *lexp, SemVal *rexp) { if (lexp->type & rexp->type & e_const) /* two constants: compute result */ { lexp->evalue = (test_type(lexp, e_str) || lexp->evalue) || (test_type(rexp, e_str) || rexp->evalue); set_type(lexp, e_const | e_int); } else /* at least one code-part */ { p_forceExpr2Bool(lexp); /* boolean code */ p_forceExpr2Bool(rexp); lexp->codelen -= p_rmJmpZero(lexp->codelen, lexp->falselist, lexp->falselen); p_patchupFalse(lexp, 1); lexp = p_catCode(lexp, rexp); set_type(lexp, e_bool | e_stack); } return (lexp); }