To write support code for the Standard Library's "group together" phrases.


§1. This section exists to support phrases such as:

To group (OS - description of objects) together giving articles: ...

For obscure reasons to do with the Inform 6 property list_together (see DM4 for details), each such usage needs to define a small I6 routine. The code here manages that.

The only data stored is a single bit, saying whether to give articles or not:

typedef struct list_together_routine {
    struct inter_name *ltr_array_iname;
    struct inter_name *ltr_routine_iname;
    int articles_bit;  if false, add NOARTICLE_BIT to the I6 listing style
    CLASS_DEFINITION
} list_together_routine;

§2. Creation. When the inline compiler wants a new LTR, it calls the following, which prints the name of a routine to be compiled later.

inter_name *ListTogether::new(int include_articles) {
    list_together_routine *ltr = CREATE(list_together_routine);
    package_request *PR = Hierarchy::local_package(LISTS_TOGETHER_HAP);
    ltr->ltr_routine_iname = Hierarchy::make_iname_in(LIST_TOGETHER_FN_HL, PR);
    ltr->ltr_array_iname = Hierarchy::make_iname_in(LIST_TOGETHER_ARRAY_HL, PR);

    ltr->articles_bit = include_articles;
    return ltr->ltr_array_iname;
}

§3. Compilation. And here's later. Note that there are only two possible routines made here, and we keep compiling them over and over, with different names. That looks wasteful, but we do it so that the routine addresses can be used as distinct values of the list_together property at run-time, because this is significant to the run-time list-printing code.

list_together_routine *latest_ltr_compiled = NULL;

int ListTogether::compilation_coroutine(void) {
    int N = 0;
    while (TRUE) {
        list_together_routine *ltr = FIRST_OBJECT(list_together_routine);
        if (latest_ltr_compiled)
            ltr = NEXT_OBJECT(latest_ltr_compiled, list_together_routine);
        if (ltr == NULL) break;
        Compile the actual LTR3.1;
        latest_ltr_compiled = ltr;
        N++;
    }
    return N;
}

§3.1. Again, see the DM4.

Compile the actual LTR3.1 =

    packaging_state save = Routines::begin(ltr->ltr_routine_iname);
    Produce::inv_primitive(Emit::tree(), IF_BIP);
    Produce::down(Emit::tree());
        Produce::inv_primitive(Emit::tree(), EQ_BIP);
        Produce::down(Emit::tree());
            Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(INVENTORY_STAGE_HL));
            Produce::val(Emit::tree(), K_number, LITERAL_IVAL, 1);
        Produce::up(Emit::tree());
        Produce::code(Emit::tree());
        Produce::down(Emit::tree());
            Produce::inv_primitive(Emit::tree(), SETBIT_BIP);
            Produce::down(Emit::tree());
                Produce::ref_iname(Emit::tree(), K_value, Hierarchy::find(C_STYLE_HL));
                Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(ENGLISH_BIT_HL));
            Produce::up(Emit::tree());
            if (!(ltr->articles_bit)) {
            Produce::inv_primitive(Emit::tree(), SETBIT_BIP);
            Produce::down(Emit::tree());
                Produce::ref_iname(Emit::tree(), K_value, Hierarchy::find(C_STYLE_HL));
                Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(NOARTICLE_BIT_HL));
            Produce::up(Emit::tree());
            }
            Produce::inv_primitive(Emit::tree(), CLEARBIT_BIP);
            Produce::down(Emit::tree());
                Produce::ref_iname(Emit::tree(), K_value, Hierarchy::find(C_STYLE_HL));
                Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(NEWLINE_BIT_HL));
            Produce::up(Emit::tree());
            Produce::inv_primitive(Emit::tree(), CLEARBIT_BIP);
            Produce::down(Emit::tree());
                Produce::ref_iname(Emit::tree(), K_value, Hierarchy::find(C_STYLE_HL));
                Produce::val_iname(Emit::tree(), K_value, Hierarchy::find(INDENT_BIT_HL));
            Produce::up(Emit::tree());

        Produce::up(Emit::tree());
    Produce::up(Emit::tree());

    Produce::rfalse(Emit::tree());
    Routines::end(save);

    save = Emit::named_array_begin(ltr->ltr_array_iname, K_value);
    Emit::array_iname_entry(Hierarchy::find(CONSTANT_PACKED_TEXT_STORAGE_HL));
    Emit::array_iname_entry(ltr->ltr_routine_iname);
    Emit::array_end(save);