To apply a given command to a given kind constructor.
void KindCommands::apply(single_kind_command stc, kind_constructor *con) { if (stc.completed) return; LOGIF(KIND_CREATIONS, "apply: %s (%d/%d/%S/%S) to %d/%S\n", stc.which_kind_command->text_of_command, stc.boolean_argument, stc.numeric_argument, stc.textual_argument, stc.constructor_argument, con->allocation_id, con->explicit_identifier); int tcc = stc.which_kind_command->opcode_number; Apply kind macros or transcribe kind templates on request1.1; Most kind commands simply set a field in the constructor structure1.2; A few kind commands contribute to linked lists in the constructor structure1.3; And the rest fill in fields in the constructor structure in miscellaneous other ways1.4; TEMPORARY_TEXT(cmd) WRITE_TO(cmd, "%s", stc.which_kind_command->text_of_command); NeptuneFiles::error(cmd, I"unimplemented kind command", stc.origin); DISCARD_TEXT(cmd) }
§1.1. Apply kind macros or transcribe kind templates on request1.1 =
switch (tcc) { case invent_source_text_KCC: StarTemplates::note(stc.template_argument, con, stc.origin); return; case apply_macro_KCC: NeptuneMacros::play_back(stc.macro_argument, con, stc.origin); return; }
- This code is used in §1.
define SET_BOOLEAN_FIELD(field) case field##_KCC: con->field = stc.boolean_argument; return; define SET_INTEGER_FIELD(field) case field##_KCC: con->field = stc.numeric_argument; return; define SET_TEXTUAL_FIELD(field) case field##_KCC: con->field = Str::duplicate(stc.textual_argument); return; define SET_CCM_FIELD(field) case field##_KCC: con->field = stc.ccm_argument; return;
Most kind commands simply set a field in the constructor structure1.2 =
switch (tcc) { SET_BOOLEAN_FIELD(can_coincide_with_property) SET_BOOLEAN_FIELD(can_exchange) SET_BOOLEAN_FIELD(indexed_grey_if_empty) SET_BOOLEAN_FIELD(is_incompletely_defined) SET_BOOLEAN_FIELD(multiple_block) SET_INTEGER_FIELD(heap_size_estimate) SET_INTEGER_FIELD(index_priority) SET_INTEGER_FIELD(small_block_size) SET_CCM_FIELD(constant_compilation_method) SET_TEXTUAL_FIELD(default_value) SET_TEXTUAL_FIELD(distinguishing_routine) SET_TEXTUAL_FIELD(documentation_reference) SET_TEXTUAL_FIELD(explicit_GPR_identifier) SET_TEXTUAL_FIELD(index_default_value) SET_TEXTUAL_FIELD(index_maximum_value) SET_TEXTUAL_FIELD(index_minimum_value) SET_TEXTUAL_FIELD(loop_domain_schema) SET_TEXTUAL_FIELD(recognition_routine) SET_TEXTUAL_FIELD(specification_text) }
- This code is used in §1.
§1.3. A few kind commands contribute to linked lists in the constructor structure1.3 =
if (tcc == compatible_with_KCC) { #ifdef CORE_MODULE if ((Str::eq(stc.constructor_argument, I"SNIPPET_TY")) && (PluginManager::active(parsing_plugin) == FALSE)) return; #endif kind_constructor_casting_rule *dtcr = CREATE(kind_constructor_casting_rule); dtcr->next_casting_rule = con->first_casting_rule; con->first_casting_rule = dtcr; dtcr->cast_from_kind_unparsed = Str::duplicate(stc.constructor_argument); dtcr->cast_from_kind = NULL; return; } if (tcc == conforms_to_KCC) { kind_constructor_instance *dti = CREATE(kind_constructor_instance); dti->next_instance_rule = con->first_instance_rule; con->first_instance_rule = dti; dti->instance_of_this_unparsed = Str::duplicate(stc.constructor_argument); dti->instance_of_this = NULL; return; } if (tcc == comparison_schema_KCC) { kind_constructor_comparison_schema *dtcs = CREATE(kind_constructor_comparison_schema); dtcs->next_comparison_schema = con->first_comparison_schema; con->first_comparison_schema = dtcs; dtcs->comparator_unparsed = Str::duplicate(stc.constructor_argument); dtcs->comparator = NULL; dtcs->comparison_schema = Str::duplicate(stc.textual_argument); return; }
- This code is used in §1.
§1.4. And the rest fill in fields in the constructor structure in miscellaneous other ways1.4 =
switch (tcc) { case terms_KCC: Parse the constructor arity text1.4.1; return; case comparison_routine_KCC: if (Str::len(stc.textual_argument) > 31) NeptuneFiles::error(stc.textual_argument, I"overlong identifier", stc.origin); else con->comparison_routine = Str::duplicate(stc.textual_argument); return; case printing_routine_KCC: if (Str::len(stc.textual_argument) > 31) NeptuneFiles::error(stc.textual_argument, I"overlong identifier", stc.origin); else con->print_identifier = Str::duplicate(stc.textual_argument); return; case printing_routine_for_debugging_KCC: if (Str::len(stc.textual_argument) > 31) NeptuneFiles::error(stc.textual_argument, I"overlong identifier", stc.origin); else con->ACTIONS_identifier = Str::duplicate(stc.textual_argument); return; case singular_KCC: case plural_KCC: { vocabulary_entry **array; int length; WordAssemblages::as_array(&(stc.vocabulary_argument), &array, &length); if (length == 1) { Kinds::mark_vocabulary_as_kind(array[0], Kinds::base_construction(con)); } else { for (int i=0; i<length; i++) { Vocabulary::set_flags(array[i], KIND_SLOW_MC); NTI::mark_vocabulary(array[i], <k-kind>); } if (con->group != PROPER_CONSTRUCTOR_GRP) { vocabulary_entry *ve = WordAssemblages::hyphenated(&(stc.vocabulary_argument)); if (ve) Kinds::mark_vocabulary_as_kind(ve, Kinds::base_construction(con)); } } feed_t id = Feeds::begin(); for (int i=0; i<length; i++) Feeds::feed_C_string(Vocabulary::get_exemplar(array[i], FALSE)); wording LW = Feeds::end(id); if (tcc == singular_KCC) { int ro = 0; if (con->group != PROPER_CONSTRUCTOR_GRP) ro = ADD_TO_LEXICON_NTOPT + WITH_PLURAL_FORMS_NTOPT; NATURAL_LANGUAGE_WORDS_TYPE *L = NULL; #ifdef CORE_MODULE L = Task::language_of_syntax(); #endif noun *nt = Nouns::new_common_noun(LW, NEUTER_GENDER, ro, KIND_SLOW_MC, STORE_POINTER_kind_constructor(con), L); con->dt_tag = nt; } else { NATURAL_LANGUAGE_WORDS_TYPE *L = NULL; #ifdef CORE_MODULE L = Task::language_of_syntax(); #endif Nouns::set_nominative_plural_in_language(con->dt_tag, LW, L); } return; } }
- This code is used in §1.
§1.4.1. Parse the constructor arity text1.4.1 =
int c = 0; string_position pos = Str::start(stc.textual_argument); while (TRUE) { while (Characters::is_space_or_tab(Str::get(pos))) pos = Str::forward(pos); if (Str::get(pos) == 0) break; if (Str::get(pos) == ',') { c++; pos = Str::forward(pos); continue; } if (c >= 2) { c=1; break; } TEMPORARY_TEXT(wd) while ((!Characters::is_space_or_tab(Str::get(pos))) && (Str::get(pos) != ',') && (Str::get(pos) != 0)) { PUT_TO(wd, Str::get(pos)); pos = Str::forward(pos); } if (Str::len(wd) > 0) { if (Str::eq_wide_string(wd, L"covariant")) con->variance[c] = COVARIANT; else if (Str::eq_wide_string(wd, L"contravariant")) con->variance[c] = CONTRAVARIANT; else if (Str::eq_wide_string(wd, L"optional")) con->tupling[c] = ALLOW_NOTHING_TUPLING; else if (Str::eq_wide_string(wd, L"list")) con->tupling[c] = ARBITRARY_TUPLING; else NeptuneFiles::error(wd, I"illegal constructor-arity keyword", stc.origin); } DISCARD_TEXT(wd) } con->constructor_arity = c+1;
- This code is used in §1.4.