§1. Requirements. Inform's code for compiling resources to different positions in the Inter hierarchy is quite defensively written, in order to keep everything to a fairly tightly specified schema.
The following is really a union: a requirement should have exactly one of the following fields set.
typedef struct location_requirement { struct submodule_identity *any_submodule_package_of_this_identity; struct package_request *this_exact_package; int this_exact_package_not_yet_created; struct text_stream *any_package_of_this_type; int any_enclosure; int must_be_plug; int must_be_main_source_text; } location_requirement; location_requirement HierarchyLocations::blank(void) { location_requirement req; req.any_submodule_package_of_this_identity = NULL; req.this_exact_package = NULL; req.this_exact_package_not_yet_created = -1; req.any_package_of_this_type = NULL; req.any_enclosure = FALSE; req.must_be_plug = FALSE; req.must_be_main_source_text = FALSE; return req; }
- The structure location_requirement is private to this section.
§2. Here are the functions to create requirements:
location_requirement HierarchyLocations::local_submodule(submodule_identity *sid) { location_requirement req = HierarchyLocations::blank(); req.any_submodule_package_of_this_identity = sid; return req; } location_requirement HierarchyLocations::completion_submodule(inter_tree *I, submodule_identity *sid) { location_requirement req = HierarchyLocations::blank(); req.this_exact_package = Packaging::completion_submodule(I, sid); req.must_be_main_source_text = TRUE; return req; } location_requirement HierarchyLocations::generic_submodule(inter_tree *I, submodule_identity *sid) { location_requirement req = HierarchyLocations::blank(); req.this_exact_package = Packaging::generic_submodule(I, sid); return req; } location_requirement HierarchyLocations::synoptic_submodule(inter_tree *I, submodule_identity *sid) { location_requirement req = HierarchyLocations::blank(); req.this_exact_package = Packaging::synoptic_submodule(I, sid); return req; } location_requirement HierarchyLocations::any_package_of_type(text_stream *ptype_name) { location_requirement req = HierarchyLocations::blank(); req.any_package_of_this_type = Str::duplicate(ptype_name); return req; } location_requirement HierarchyLocations::any_enclosure(void) { location_requirement req = HierarchyLocations::blank(); req.any_enclosure = TRUE; return req; } location_requirement HierarchyLocations::the_veneer(inter_tree *I) { return HierarchyLocations::this_package(Site::veneer_request(I)); } location_requirement HierarchyLocations::this_package(package_request *P) { location_requirement req = HierarchyLocations::blank(); req.this_exact_package = P; return req; } location_requirement HierarchyLocations::this_exotic_package(int N) { location_requirement req = HierarchyLocations::blank(); req.this_exact_package_not_yet_created = N; return req; } location_requirement HierarchyLocations::plug(void) { location_requirement req = HierarchyLocations::blank(); req.must_be_plug = TRUE; return req; }
typedef struct hierarchy_location { int access_number; struct text_stream *access_name; struct text_stream *function_package_name; struct text_stream *datum_package_name; struct location_requirement requirements; struct inter_name *equates_to_iname; struct text_stream *package_type; struct name_translation trans; CLASS_DEFINITION } hierarchy_location; hierarchy_location *HierarchyLocations::new(void) { hierarchy_location *hl = CREATE(hierarchy_location); hl->access_number = -1; hl->access_name = NULL; hl->function_package_name = NULL; hl->datum_package_name = NULL; hl->equates_to_iname = NULL; hl->package_type = NULL; hl->trans = Translation::same(); hl->requirements = HierarchyLocations::blank(); return hl; } hierarchy_location *HierarchyLocations::ctr(inter_tree *I, int id, text_stream *name, name_translation nt, location_requirement req) { hierarchy_location *hl = HierarchyLocations::new(); hl->access_number = id; hl->access_name = Str::duplicate(name); hl->requirements = req; hl->trans = nt; HierarchyLocations::index(I, hl); return hl; } hierarchy_location *HierarchyLocations::con(inter_tree *I, int id, text_stream *name, location_requirement req) { hierarchy_location *hl = HierarchyLocations::new(); hl->access_number = id; hl->access_name = Str::duplicate(name); hl->requirements = req; hl->trans = Translation::same(); HierarchyLocations::index(I, hl); return hl; } hierarchy_location *HierarchyLocations::pkg(inter_tree *I, int id, text_stream *name, text_stream *ptype_name, location_requirement req) { hierarchy_location *hl = HierarchyLocations::new(); hl->access_number = id; hl->access_name = Str::duplicate(name); hl->requirements = req; hl->package_type = Str::duplicate(ptype_name); HierarchyLocations::index(I, hl); return hl; } hierarchy_location *HierarchyLocations::make_as(inter_tree *I, int id, text_stream *name, inter_name *iname) { hierarchy_location *hl = HierarchyLocations::new(); hl->access_number = id; hl->access_name = Str::duplicate(name); hl->requirements = HierarchyLocations::this_package(InterNames::location(iname)); hl->equates_to_iname = iname; HierarchyLocations::index(I, hl); return hl; } hierarchy_location *HierarchyLocations::fun(inter_tree *I, int id, text_stream *name, name_translation nt, location_requirement req) { hierarchy_location *hl = CREATE(hierarchy_location); hl->access_number = id; hl->access_name = Str::duplicate(nt.translate_to); hl->function_package_name = Str::duplicate(name); hl->requirements = req; hl->trans = nt; HierarchyLocations::index(I, hl); return hl; } hierarchy_location *HierarchyLocations::dat(inter_tree *I, int id, text_stream *name, name_translation nt, location_requirement req) { hierarchy_location *hl = CREATE(hierarchy_location); hl->access_number = id; hl->access_name = Str::duplicate(nt.translate_to); hl->datum_package_name = Str::duplicate(name); hl->requirements = req; hl->trans = nt; HierarchyLocations::index(I, hl); return hl; } void HierarchyLocations::index(inter_tree *I, hierarchy_location *hl) { if (hl->access_number >= 0) I->site.hls_indexed_by_id[hl->access_number] = hl; if (hl->requirements.any_package_of_this_type == NULL) { Dictionaries::create(I->site.hls_indexed_by_name, hl->access_name); Dictionaries::write_value(I->site.hls_indexed_by_name, hl->access_name, (void *) hl); } } inter_name *HierarchyLocations::find(inter_tree *I, int id) { if ((id < 0) || (id >= NO_DEFINED_HL_VALUES) || (I->site.hls_indexed_by_id[id] == NULL)) internal_error("bad hl ID"); return HierarchyLocations::hl_to_iname(I, I->site.hls_indexed_by_id[id]); } inter_name *HierarchyLocations::find_by_name(inter_tree *I, text_stream *name) { if (Str::len(name) == 0) internal_error("bad hl name"); if (Dictionaries::find(I->site.hls_indexed_by_name, name)) return HierarchyLocations::hl_to_iname(I, (hierarchy_location *) Dictionaries::read_value(I->site.hls_indexed_by_name, name)); return NULL; } inter_name *HierarchyLocations::function(inter_tree *I, package_request *R, text_stream *name, text_stream *trans) { inter_name *iname = Packaging::function(I, InterNames::explicitly_named(name, R), NULL); if (trans) Produce::change_translation(iname, trans); return iname; } inter_name *HierarchyLocations::hl_to_iname(inter_tree *I, hierarchy_location *hl) { if (hl->requirements.any_package_of_this_type) internal_error("NRL accessed inappropriately"); if (hl->equates_to_iname == NULL) { if (hl->requirements.must_be_plug) { hl->equates_to_iname = InterNames::explicitly_named_in_template(I, hl->access_name); } else { if (hl->requirements.this_exact_package == NULL) { if (hl->requirements.this_exact_package_not_yet_created >= 0) { #ifdef CORE_MODULE hl->requirements.this_exact_package = Hierarchy::exotic_package(hl->requirements.this_exact_package_not_yet_created); #endif #ifndef CORE_MODULE internal_error("feature not available in inter"); #endif } else internal_error("package can't be found"); } if (Str::len(hl->function_package_name) > 0) { hl->equates_to_iname = Packaging::function_text(I, InterNames::explicitly_named(hl->function_package_name, hl->requirements.this_exact_package), hl->access_name); } else if (Str::len(hl->datum_package_name) > 0) { hl->equates_to_iname = Packaging::datum_text(I, InterNames::explicitly_named(hl->datum_package_name, hl->requirements.this_exact_package), hl->access_name); } else if ((hl->requirements.this_exact_package) && (hl->equates_to_iname == NULL)) { hl->equates_to_iname = InterNames::explicitly_named(hl->access_name, hl->requirements.this_exact_package); } } hl->requirements.this_exact_package = InterNames::location(hl->equates_to_iname); if (hl->trans.translate_to) Produce::change_translation(hl->equates_to_iname, hl->trans.translate_to); } return hl->equates_to_iname; } inter_name *HierarchyLocations::find_in_package(inter_tree *I, int id, package_request *P, wording W, inter_name *derive_from, int fix, text_stream *imposed_name) { if ((id < 0) || (id >= NO_DEFINED_HL_VALUES) || (I->site.hls_indexed_by_id[id] == NULL)) internal_error("bad hl ID"); hierarchy_location *hl = I->site.hls_indexed_by_id[id]; if ((hl->requirements.any_package_of_this_type == NULL) && (hl->requirements.any_enclosure == FALSE)) internal_error("NRL accessed inappropriately"); if (hl->requirements.any_enclosure) { if (Inter::Symbols::read_annotation(P->eventual_type, ENCLOSING_IANN) != 1) internal_error("subpackage not in enclosing superpackage"); } else if (P == NULL) { internal_error("constant in null package"); } else if (P->eventual_type != PackageTypes::get(I, hl->requirements.any_package_of_this_type)) { LOG("AN: %S, FPN: %S\n", hl->access_name, hl->function_package_name); LOG("Have type: $3, required: %S\n", P->eventual_type, hl->requirements.any_package_of_this_type); internal_error("constant in wrong superpackage"); } inter_name *iname = NULL; if (hl->trans.translate_to) { text_stream *T = hl->trans.translate_to; Make the actual iname3.1; } else if (hl->trans.by_imposition) { text_stream *T = NULL; Make the actual iname3.1; } else if (hl->trans.name_generator) { TEMPORARY_TEXT(T) inter_name *temp_iname = NULL; if (derive_from) { temp_iname = InterNames::derived(hl->trans.name_generator, derive_from, W); } else { temp_iname = InterNames::generated(hl->trans.name_generator, fix, W); } W = EMPTY_WORDING; WRITE_TO(T, "%n", temp_iname); Make the actual iname3.1; DISCARD_TEXT(T) } else { text_stream *T = NULL; Make the actual iname3.1; } if (hl->trans.then_make_unique) Produce::set_flag(iname, MAKE_NAME_UNIQUE); return iname; }
- The structure hierarchy_location is private to this section.
§3.1. Make the actual iname3.1 =
if (Str::len(hl->function_package_name) > 0) { iname = Packaging::function(I, InterNames::explicitly_named(hl->function_package_name, P), NULL); } else { if (hl->trans.by_imposition) iname = InterNames::explicitly_named_with_memo(imposed_name, P, W); else if (Str::len(hl->access_name) == 0) iname = InterNames::explicitly_named_with_memo(T, P, W); else iname = InterNames::explicitly_named_with_memo(hl->access_name, P, W); } if ((Str::len(T) > 0) && (hl->access_name)) Produce::change_translation(iname, T);
- This code is used in §3 (four times).
package_request *HierarchyLocations::package_in_package(inter_tree *I, int id, package_request *P) { if ((id < 0) || (id >= NO_DEFINED_HL_VALUES) || (I->site.hls_indexed_by_id[id] == NULL)) internal_error("bad hl ID"); hierarchy_location *hl = I->site.hls_indexed_by_id[id]; if (P == NULL) internal_error("no superpackage"); if (hl->package_type == NULL) internal_error("package_in_package used wrongly"); if (hl->requirements.any_package_of_this_type) { if (P->eventual_type != PackageTypes::get(I, hl->requirements.any_package_of_this_type)) internal_error("subpackage in wrong superpackage"); } else if (hl->requirements.any_enclosure) { if (Inter::Symbols::read_annotation(P->eventual_type, ENCLOSING_IANN) != 1) internal_error("subpackage not in enclosing superpackage"); } else internal_error("NRL accessed inappropriately"); return Packaging::request(I, InterNames::explicitly_named(hl->access_name, P), PackageTypes::get(I, hl->package_type)); }
typedef struct hierarchy_attachment_point { int hap_id; struct text_stream *name_stem; struct text_stream *type; struct location_requirement requirements; CLASS_DEFINITION } hierarchy_attachment_point; void HierarchyLocations::index_ap(inter_tree *I, hierarchy_attachment_point *hap) { if (hap->hap_id >= 0) I->site.haps_indexed_by_id[hap->hap_id] = hap; } hierarchy_attachment_point *HierarchyLocations::att(inter_tree *I, int hap_id, text_stream *iterated_text, text_stream *ptype_name, location_requirement req) { hierarchy_attachment_point *hap = CREATE(hierarchy_attachment_point); hap->hap_id = hap_id; hap->requirements = req; hap->name_stem = Str::duplicate(iterated_text); hap->type = Str::duplicate(ptype_name); HierarchyLocations::index_ap(I, hap); return hap; } #ifdef CORE_MODULE package_request *HierarchyLocations::attach_new_package(inter_tree *I, compilation_unit *C, package_request *R, int hap_id) { if ((hap_id < 0) || (hap_id >= NO_DEFINED_HAP_VALUES) || (I->site.haps_indexed_by_id[hap_id] == NULL)) internal_error("invalid HAP request"); hierarchy_attachment_point *hap = I->site.haps_indexed_by_id[hap_id]; if (hap->requirements.must_be_main_source_text) { R = hap->requirements.this_exact_package; } else if (hap->requirements.any_submodule_package_of_this_identity) { R = Packaging::request_submodule(I, C, hap->requirements.any_submodule_package_of_this_identity); } else if (hap->requirements.this_exact_package) { R = hap->requirements.this_exact_package; } else if (hap->requirements.this_exact_package_not_yet_created >= 0) { R = Hierarchy::exotic_package(hap->requirements.this_exact_package_not_yet_created); } else if (hap->requirements.any_package_of_this_type) { if ((R == NULL) || (R->eventual_type != PackageTypes::get(I, hap->requirements.any_package_of_this_type))) internal_error("subpackage in wrong superpackage"); } return Packaging::request(I, Packaging::make_iname_within(R, hap->name_stem), PackageTypes::get(I, hap->type)); } #endif
- The structure hierarchy_attachment_point is accessed in 1/pck, 1/in and here.