To compile run-time support for instances.

§1.

typedef struct instance_compilation_data {
    struct package_request *instance_package;
    struct inter_name *instance_iname;
    int instance_emitted;
} instance_compilation_data;

void RTInstances::initialise_icd(instance *I) {
    I->icd.instance_package = Hierarchy::local_package(INSTANCES_HAP);
    NounIdentifiers::noun_compose_identifier(I->icd.instance_package,
        I->as_noun, I->allocation_id);
    I->icd.instance_iname = NounIdentifiers::iname(I->as_noun);
    I->icd.instance_emitted = FALSE;
}

void RTInstances::compile_metadata(void) {
    instance *I;
    LOOP_OVER(I, instance) {
        Hierarchy::apply_metadata_from_wording(I->icd.instance_package,
            INSTANCE_NAME_MD_HL,
            Nouns::nominative(I->as_noun, FALSE));
        Hierarchy::apply_metadata_from_iname(I->icd.instance_package,
            INSTANCE_VALUE_MD_HL,
            I->icd.instance_iname);
        inter_name *kn_iname = Hierarchy::make_iname_in(INSTANCE_KIND_MD_HL,
            I->icd.instance_package);
        kind *K = Instances::to_kind(I);
        RTKinds::constant_from_strong_id(kn_iname, K);
        if ((K_scene) && (Kinds::eq(K, K_scene)))
            Hierarchy::apply_metadata_from_number(I->icd.instance_package,
                INSTANCE_IS_SCENE_MD_HL, 1);
        if ((K_sound_name) && (Kinds::eq(K, K_sound_name)))
            Hierarchy::apply_metadata_from_number(I->icd.instance_package,
                INSTANCE_IS_SOUND_MD_HL, 1);
        if ((K_figure_name) && (Kinds::eq(K, K_figure_name)))
            Hierarchy::apply_metadata_from_number(I->icd.instance_package,
                INSTANCE_IS_FIGURE_MD_HL, 1);
        if ((K_external_file) && (Kinds::eq(K, K_external_file)))
            Hierarchy::apply_metadata_from_number(I->icd.instance_package,
                INSTANCE_IS_EXF_MD_HL, 1);
    }
}

inter_name *RTInstances::iname(instance *I) {
    if (I == NULL) return NULL;
    return I->icd.instance_iname;
}

§2.

int RTInstances::emit_element_of_condition(inference_subject_family *family,
    inference_subject *infs, inter_symbol *t0_s) {
    instance *I = InstanceSubjects::to_instance(infs);
    EmitCode::inv(EQ_BIP);
    EmitCode::down();
        EmitCode::val_symbol(K_value, t0_s);
        EmitCode::val_iname(K_value, RTInstances::iname(I));
    EmitCode::up();
    return TRUE;
}

§3. Compilation looks tricky only because we need to compile instances in a set order which is not the order of their creation. (This is because objects must be compiled in containment-tree traversal order in the final Inform 6 code.) So in reply to a request to compile all instances, we first delegate the object instances, then compile the non-object ones (all just constant declarations) and finally return TRUE to indicate that the task is finished.

int RTInstances::emit_all(inference_subject_family *family, int ignored) {
    instance *I;
    LOOP_THROUGH_INSTANCE_ORDERING(I)
        RTInstances::emit_one(family, Instances::as_subject(I));
    LOOP_OVER(I, instance)
        if (Kinds::Behaviour::is_object(Instances::to_kind(I)) == FALSE)
            RTInstances::emit_one(family, Instances::as_subject(I));
    RTNaming::compile_small_names();
    return TRUE;
}

§4. Either way, the actual compilation happens here:

void RTInstances::emit_one(inference_subject_family *family, inference_subject *infs) {
    instance *I = InstanceSubjects::to_instance(infs);
    RTInstances::emitted_iname(I);
    RTProperties::emit_instance_permissions(I);
    RTPropertyValues::emit_subject(infs);
}

inter_name *RTInstances::emitted_iname(instance *I) {
    if (I == NULL) return NULL;
    inter_name *iname = RTInstances::iname(I);
    if (I->icd.instance_emitted == FALSE) {
        I->icd.instance_emitted = TRUE;
        Emit::instance(iname, Instances::to_kind(I), I->enumeration_index);
    }
    return iname;
}

package_request *RTInstances::package(instance *I) {
    RTInstances::iname(I);  Thus forcing this to exist...
    return I->icd.instance_package;
}