mirror of
https://github.com/ganelson/inform.git
synced 2024-06-29 05:24:57 +03:00
187 lines
7 KiB
OpenEdge ABL
187 lines
7 KiB
OpenEdge ABL
[KindCommands::] Kind Commands.
|
|
|
|
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 request@>;
|
|
|
|
@<Most kind commands simply set a field in the constructor structure@>;
|
|
@<A few kind commands contribute to linked lists in the constructor structure@>;
|
|
@<And the rest fill in fields in the constructor structure in miscellaneous other ways@>;
|
|
|
|
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)
|
|
}
|
|
|
|
@<Apply kind macros or transcribe kind templates on request@> =
|
|
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;
|
|
}
|
|
|
|
@
|
|
|
|
@d SET_BOOLEAN_FIELD(field) case field##_KCC: con->field = stc.boolean_argument; return;
|
|
@d SET_INTEGER_FIELD(field) case field##_KCC: con->field = stc.numeric_argument; return;
|
|
@d SET_TEXTUAL_FIELD(field) case field##_KCC: con->field = Str::duplicate(stc.textual_argument); return;
|
|
@d SET_CCM_FIELD(field) case field##_KCC: con->field = stc.ccm_argument; return;
|
|
|
|
@<Most kind commands simply set a field in the constructor structure@> =
|
|
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)
|
|
}
|
|
|
|
@<A few kind commands contribute to linked lists in the constructor structure@> =
|
|
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;
|
|
}
|
|
|
|
@<And the rest fill in fields in the constructor structure in miscellaneous other ways@> =
|
|
switch (tcc) {
|
|
case terms_KCC:
|
|
@<Parse the constructor arity text@>;
|
|
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;
|
|
}
|
|
}
|
|
|
|
@<Parse the constructor arity text@> =
|
|
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;
|