Compiling conditions is mostly a matter of getting callings right.

§1. We need to keep track of the callings made in any condition so that the variables, which generally have a scope extending beyond that condition, can't be left with kind-unsafe (or no) values. For example, if:

if a device (called the mechanism) is switched on: ...

turns out false, then "mechanism" has to be safely defused to some kind-safe value.

define MAX_CALLINGS_IN_MATCH 128
int current_session_number = -1;
int callings_in_condition_sp = 0;
int callings_session_number[MAX_CALLINGS_IN_MATCH];
local_variable *callings_in_condition[MAX_CALLINGS_IN_MATCH];

void RTConditions::add_calling_to_condition(local_variable *lvar) {
    if (current_session_number < 0) internal_error("no PM session");
    if (callings_in_condition_sp + 1 == MAX_CALLINGS_IN_MATCH)
        StandardProblems::sentence_problem(Task::syntax_tree(), _p_(BelievedImpossible),
        "that makes too complicated a condition to test",
        "with all of those clauses involving 'called' values.");
    else {
        callings_session_number[callings_in_condition_sp] = current_session_number;
        callings_in_condition[callings_in_condition_sp++] = lvar;
    }
}

void RTConditions::begin_condition_emit(void) {
    current_session_number++;
    Produce::inv_primitive(Emit::tree(), OR_BIP);
    Produce::down(Emit::tree());
}

void RTConditions::end_condition_emit(void) {
    if (current_session_number < 0) internal_error("unstarted PM session");

    int NC = 0, x = callings_in_condition_sp, downs = 1;
    while ((x > 0) &&
        (callings_session_number[x-1] == current_session_number)) {
        NC++;
        x--;
    }

    if (NC == 0) {
        Produce::val(Emit::tree(), K_truth_state, LITERAL_IVAL, 0);
    } else {
        Produce::inv_primitive(Emit::tree(), SEQUENTIAL_BIP);
        Produce::down(Emit::tree()); downs++;
        int NM = 0, inner_downs = 0;;
        while ((callings_in_condition_sp > 0) &&
            (callings_session_number[callings_in_condition_sp-1] == current_session_number)) {
            NM++;
            local_variable *lvar = callings_in_condition[callings_in_condition_sp-1];
            if (NM < NC) { Produce::inv_primitive(Emit::tree(), SEQUENTIAL_BIP); Produce::down(Emit::tree()); inner_downs++; }
            Produce::inv_primitive(Emit::tree(), STORE_BIP);
            Produce::down(Emit::tree());
                inter_symbol *lvar_s = LocalVariables::declare(lvar);
                Produce::ref_symbol(Emit::tree(), K_value, lvar_s);
                kind *K = LocalVariables::kind(lvar);
                if ((K == NULL) ||
                    (Kinds::Behaviour::is_object(K)) ||
                    (Kinds::Behaviour::definite(K) == FALSE) ||
                    (RTKinds::emit_default_value_as_val(K, EMPTY_WORDING, "'called' value") != TRUE))
                    Produce::val(Emit::tree(), K_truth_state, LITERAL_IVAL, 0);
            Produce::up(Emit::tree());
            callings_in_condition_sp--;
        }
        while (inner_downs > 0) { inner_downs--; Produce::up(Emit::tree()); }
        Produce::val(Emit::tree(), K_truth_state, LITERAL_IVAL, 0);
    }
    current_session_number--;
    while (downs > 0) { downs--; Produce::up(Emit::tree()); }
}