To compile the "short name" and "capitalised short name" properties.
§1. All versions of Inform, even Basic Inform, support the "short name" property. The "capitalised short name" variant property, though, may not always exist. It can be conjured into being by calling this function:
property *P_cap_short_name = NULL; property *ShortNames::cap_short_name_property(void) { if (P_cap_short_name == NULL) { inter_name *property_iname = Hierarchy::find(CAPSHORTNAME_HL); P_cap_short_name = ValueProperties::new_nameless_using( K_text, RTKindConstructors::kind_package(K_object), property_iname); Hierarchy::make_available(property_iname); } return P_cap_short_name; }
§2. But in Basic Inform projects, that function may never be called, leaving
P_cap_short_name null. This is a problem for code in BasicInformKit,
which assumes that this name means something. So in that contingency we
define it to be equivalent to regular short name, thus:
void ShortNames::compile_cap_short_name(void) { if (P_cap_short_name == NULL) { inter_name *iname = Hierarchy::find(CAPSHORTNAME_HL); Emit::iname_constant(iname, K_value, Hierarchy::find(SHORT_NAME_HL)); Hierarchy::make_available(iname); } }
§3. Most of the time the short name property holds text, in a straightforward
way: "blue hat", say. But if the property belongs to an object created as
part of an assembly, then its name needs to contain that of the object it
was assembled from: say "Marianne's blue hat", where "Marianne" is the
name of the owner.
If, however, the short name for "Marianne" varies -- through the use of
an activity -- then we want to respect that. So we don't give the name using
static text, but as a dynamic function, which first prints Marianne's name
through the usual apparatus, and then adds "'s blue hat" afterwards. That
way, if Marianne changes her name to Emilia, the result will be
"Emilia's blue hat".
This function returns the name of the function to do this, and queues a compilation
request for it. capped is TRUE if the function is to be used in a capitalised
short name, and FALSE for regular.
typedef struct short_name_notice { struct inter_name *routine_iname; struct inter_name *snn_iname; struct instance *namee; struct inference_subject *after_subject; int capped; CLASS_DEFINITION } short_name_notice; inter_name *ShortNames::iname_for_short_name_fn(instance *I, inference_subject *subj, int capped) { short_name_notice *notice = CREATE(short_name_notice); notice->routine_iname = Hierarchy::make_iname_in(SHORT_NAME_FN_HL, RTInstances::package(I)); notice->namee = I; notice->after_subject = subj; notice->capped = capped; notice->snn_iname = Hierarchy::make_iname_in(SHORT_NAME_PROPERTY_FN_HL, RTInstances::package(I)); text_stream *desc = Str::new(); WRITE_TO(desc, "short name for "); Instances::write(desc, I); Sequence::queue(&ShortNames::compilation_agent, STORE_POINTER_short_name_notice(notice), desc); return notice->snn_iname; }
- The structure short_name_notice is private to this section.
void ShortNames::compilation_agent(compilation_subtask *t) { short_name_notice *notice = RETRIEVE_POINTER_short_name_notice(t->data); instance *owner = Naming::object_this_is_named_after(notice->namee); packaging_state save = Functions::begin(notice->routine_iname); wording NA = Assertions::Assemblies::get_named_after_text(notice->after_subject); Print the owner's short name4.1; EmitCode::inv(PRINT_BIP); EmitCode::down(); EmitCode::val_text(I"'s "); EmitCode::up(); Print the assembled object's name4.2; EmitCode::rtrue(); Functions::end(save); save = EmitArrays::begin_unchecked(notice->snn_iname); EmitArrays::iname_entry(Hierarchy::find(CONSTANT_PACKED_TEXT_STORAGE_HL)); EmitArrays::iname_entry(notice->routine_iname); EmitArrays::end(save); }
§4.1. Print the owner's short name4.1 =
if (notice->capped) { inter_name *porname = Hierarchy::find(PRINTORRUN_HL); EmitCode::inv(IFELSE_BIP); EmitCode::down(); EmitCode::inv(PROPERTYARRAY_BIP); EmitCode::down(); EmitCode::val_iname(K_value, RTKindIDs::weak_iname(K_object)); EmitCode::val_iname(K_value, RTInstances::value_iname(owner)); EmitCode::val_iname(K_value, Hierarchy::find(CAPSHORTNAME_HL)); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::call(porname); EmitCode::down(); EmitCode::val_iname(K_value, RTInstances::value_iname(owner)); EmitCode::val_iname(K_value, Hierarchy::find(CAPSHORTNAME_HL)); EmitCode::val_number(1); EmitCode::up(); EmitCode::up(); EmitCode::code(); EmitCode::down(); EmitCode::call(porname); EmitCode::down(); EmitCode::val_iname(K_value, RTInstances::value_iname(owner)); EmitCode::val_iname(K_value, Hierarchy::find(SHORT_NAME_HL)); EmitCode::val_number(1); EmitCode::up(); EmitCode::up(); EmitCode::up(); } else { inter_name *psnname = Hierarchy::find(PRINTSHORTNAME_HL); EmitCode::call(psnname); EmitCode::down(); EmitCode::val_iname(K_value, RTInstances::value_iname(owner)); EmitCode::up(); }
- This code is used in §4.
§4.2. Print the assembled object's name4.2 =
TEMPORARY_TEXT(SNAMES) LOOP_THROUGH_WORDING(j, NA) { TranscodeText::from_wide_string(SNAMES, Lexer::word_raw_text(j), 0); if (j<Wordings::last_wn(NA)) WRITE_TO(SNAMES, " "); } EmitCode::inv(PRINT_BIP); EmitCode::down(); EmitCode::val_text(SNAMES); EmitCode::up(); DISCARD_TEXT(SNAMES)
- This code is used in §4.