//#define msgx

#include "parser.ih"

SemVal pmv_ternary(SemVal *cond, SemVal *ifTrue, SemVal *ifFalse)
{
    int ifTrueType = svType(ifTrue) & e_typeMask;

    if ( (ifTrueType & svType(ifFalse) & e_typeMask) == 0)
    {                                   // error at different expr. types
        util_semantic(sem_typeConflict, "?:");
        return pmv_semVal(3, cond, ifTrue, ifFalse);
    }

    if (svTestType(cond, e_const))      // constant: true or false  
    {
        int value = svValue(cond);      // use the condition's value
        svDestroy(cond);

        if (value == 0)                 // condition is false?
        {
            svDestroy(ifTrue);
            svPushStack(ifFalse);
            return SVmove(ifFalse);
        }

        svDestroy(ifFalse);             // or condition is true...
        svPushStack(ifTrue);
        return SVmove(ifTrue);
    }

    p_expr2bool(cond);                  // convert the condition to bool 

    svPushStack(ifTrue);                // convert the expressions to code 
    svPushStack(ifFalse);

    svPatchupTrue(cond, 1);             // destination for the ifTrue code 

    svCatenate(cond, ifTrue);           // cond = cond + ifTrue 
    svAddCode(cond, op_jmp, j_truelist);   // jmp around ifFalse 

    svPatchupFalse(cond, 1);        // destination of the false alternative 
    svCatenate(cond, ifFalse);     // cond = cond + ifTrue + jmp + ifFalse 

    svPatchupTrue(cond, 1);         // jump from ifTrue to the end of expr. 

    svSetType(cond, ifTrueType);    // return type must be the ifTrue/ifFalse
                                    // type 

    return SVmove(cond);            // ?: return 
}




