English Inflections -
diff --git a/docs/inflections-test/1-ut.html b/docs/inflections-test/1-ut.html
index 899bdd9bb..9a1a0378e 100644
--- a/docs/inflections-test/1-ut.html
+++ b/docs/inflections-test/1-ut.html
@@ -65,9 +65,9 @@ function togglePopup(material_id) {
if (Lexer::word(i) == PARBREAK_V) continue;
wording W = Wordings::one_word(i);
PRINT("%W --> ", W);
- PRINT("comparative: %W, ", Grading::make_comparative(W, InflectionDefns::default_nl(NULL)));
- PRINT("superlative: %W, ", Grading::make_superlative(W, InflectionDefns::default_nl(NULL)));
- PRINT("quiddity: %W\n", Grading::make_quiddity(W, InflectionDefns::default_nl(NULL)));
+ PRINT("comparative: %W, ", Grading::make_comparative(W, DefaultLanguage::get(NULL)));
+ PRINT("superlative: %W, ", Grading::make_superlative(W, DefaultLanguage::get(NULL)));
+ PRINT("quiddity: %W\n", Grading::make_quiddity(W, DefaultLanguage::get(NULL)));
}
}
}
@@ -86,7 +86,7 @@ function togglePopup(material_id) {
TEMPORARY_TEXT(T);
WRITE_TO(T, "%W", W);
TEMPORARY_TEXT(AT);
- ArticleInflection::preface_by_article(AT, T, InflectionDefns::default_nl(NULL));
+ ArticleInflection::preface_by_article(AT, T, DefaultLanguage::get(NULL));
PRINT("%S --> %S\n", T, AT);
DISCARD_TEXT(AT);
DISCARD_TEXT(T);
@@ -113,12 +113,12 @@ function togglePopup(material_id) {
if (Lexer::word(i) == f_V) { gen = FEMININE_GENDER; continue; }
if (Lexer::word(i) == n_V) { gen = NEUTER_GENDER; continue; }
wording W = Wordings::one_word(i);
- declension D = Declensions::decline(W, InflectionDefns::default_nl(NULL), gen, 1);
- declension AD = Declensions::decline_article(PW, InflectionDefns::default_nl(NULL), gen, 1);
+ declension D = Declensions::of_noun(W, DefaultLanguage::get(NULL), gen, 1);
+ declension AD = Declensions::of_article(PW, DefaultLanguage::get(NULL), gen, 1);
PRINT("%W --> ", W);
Declensions::writer(STDOUT, &D, &AD);
- D = Declensions::decline(W, InflectionDefns::default_nl(NULL), gen, 2);
- AD = Declensions::decline_article(PW, InflectionDefns::default_nl(NULL), gen, 2);
+ D = Declensions::of_noun(W, DefaultLanguage::get(NULL), gen, 2);
+ AD = Declensions::of_article(PW, DefaultLanguage::get(NULL), gen, 2);
PRINT("pl --> ");
Declensions::writer(STDOUT, &D, &AD);
PRINT("\n");
@@ -137,7 +137,7 @@ function togglePopup(material_id) {
LOOP_THROUGH_WORDING(i, sf->text_read) {
if (Lexer::word(i) == PARBREAK_V) continue;
wording W = Wordings::one_word(i);
- PRINT("%W --> %W\n", W, PastParticiples::pasturise_wording(W));
+ PRINT("%W --> %W\n", W, PastParticiples::pasturise_wording(W));
}
}
}
@@ -157,7 +157,7 @@ function togglePopup(material_id) {
TEMPORARY_TEXT(G);
WRITE_TO(G, "%W", W);
TEMPORARY_TEXT(ASAGIG);
- Pluralisation::regular(ASAGIG, G, InflectionDefns::default_nl(NULL));
+ Pluralisation::regular(ASAGIG, G, DefaultLanguage::get(NULL));
PRINT("%S --> %S\n", G, ASAGIG);
DISCARD_TEXT(ASAGIG);
DISCARD_TEXT(G);
@@ -180,12 +180,12 @@ function togglePopup(material_id) {
if (c++ < 10) {
PRINT("Verb %W -->\n", W);
TEMPORARY_TEXT(T);
- Conjugation::test(T, W, InflectionDefns::default_nl(NULL));
+ Conjugation::test(T, W, DefaultLanguage::get(NULL));
Regexp::replace(T, L"%^", L"\n", REP_REPEATING);
PRINT("%S\n", T);
DISCARD_TEXT(T);
} else {
- Conjugation::test_participle(STDOUT, W);
+ Conjugation::test_participle(STDOUT, W);
}
}
}
diff --git a/docs/kinds-module/2-dk.html b/docs/kinds-module/2-dk.html
index 4a1858c06..6e16bbfec 100644
--- a/docs/kinds-module/2-dk.html
+++ b/docs/kinds-module/2-dk.html
@@ -599,7 +599,7 @@ so on. For example:
void Kinds::Textual::write_articled(OUTPUT_STREAM, kind *K) {
TEMPORARY_TEXT(TEMP);
Kinds::Textual::write_inner(TEMP, K, FALSE, TRUE);
- ArticleInflection::preface_by_article(OUT, TEMP, InflectionDefns::default_nl(NULL));
+ ArticleInflection::preface_by_article(OUT, TEMP, DefaultLanguage::get(NULL));
DISCARD_TEXT(TEMP);
}
diff --git a/docs/linguistics-module/4-prp.html b/docs/linguistics-module/4-prp.html
index 1bc482a12..c806a382e 100644
--- a/docs/linguistics-module/4-prp.html
+++ b/docs/linguistics-module/4-prp.html
@@ -127,7 +127,7 @@ to one verb is the same preposition as the "for" attached to another one.
preposition_identity *Prepositions::make(word_assemblage wa, int unexpected_upper_casing_used) {
preposition_identity *prep = NULL;
LOOP_OVER(prep, preposition_identity)
- if (WordAssemblages::compare(&(prep->prep_text), &wa))
+ if (WordAssemblages::eq(&(prep->prep_text), &wa))
return prep;
prep = CREATE(preposition_identity);
diff --git a/docs/linguistics-module/4-vu.html b/docs/linguistics-module/4-vu.html
index 3f8742287..fd1264f0c 100644
--- a/docs/linguistics-module/4-vu.html
+++ b/docs/linguistics-module/4-vu.html
@@ -449,7 +449,7 @@ list, with lower priority numbers before higher ones.
int VerbUsages::is_foreign(verb_usage *vu) {
if ((vu->verb_used) &&
(vu->verb_used->conjugation->defined_in) &&
- (vu->verb_used->conjugation->defined_in != InflectionDefns::default_nl(NULL))) {
+ (vu->verb_used->conjugation->defined_in != DefaultLanguage::get(NULL))) {
return TRUE;
}
return FALSE;
diff --git a/docs/linguistics-test/1-ut.html b/docs/linguistics-test/1-ut.html
index 9f9914111..369a65c99 100644
--- a/docs/linguistics-test/1-ut.html
+++ b/docs/linguistics-test/1-ut.html
@@ -115,7 +115,7 @@ any text but then fail.
<stock> ::=
- verb <cardinal-number> ... ==> R[1]; *XP = Conjugation::conjugate(WordAssemblages::from_wording(FW[1]), InflectionDefns::default_nl(NULL));
+ verb <cardinal-number> ... ==> R[1]; *XP = Conjugation::conjugate(WordAssemblages::from_wording(FW[1]), DefaultLanguage::get(NULL));
- This is Preform grammar, not regular C code.
diff --git a/docs/supervisor-module/5-ls.html b/docs/supervisor-module/5-ls.html
index 7c1a6a2cc..d97977794 100644
--- a/docs/supervisor-module/5-ls.html
+++ b/docs/supervisor-module/5-ls.html
@@ -184,7 +184,7 @@ detect the language of play for a story file without actually running it.
void Languages::write_ISO_code(OUTPUT_STREAM, inform_language *L) {
#ifdef CORE_MODULE
- if (L == NULL) L = InflectionDefns::default_nl(NULL);
+ if (L == NULL) L = DefaultLanguage::get(NULL);
#endif
if (Wordings::nonempty(L->language_field[ISO_639_CODE_LFIELD]))
WRITE("%+W", L->language_field[ISO_639_CODE_LFIELD]);
diff --git a/docs/words-module/2-wa.html b/docs/words-module/2-wa.html
index f87344051..ef75c7855 100644
--- a/docs/words-module/2-wa.html
+++ b/docs/words-module/2-wa.html
@@ -217,7 +217,7 @@ frequently, since it consumes memory:
-int WordAssemblages::compare(word_assemblage *wa1, word_assemblage *wa2) {
+int WordAssemblages::eq(word_assemblage *wa1, word_assemblage *wa2) {
if (wa1 == wa2) return TRUE;
if ((wa1 == NULL) || (wa2 == NULL)) return FALSE;
if (wa1->no_indiv_words != wa2->no_indiv_words) return FALSE;
diff --git a/inbuild/supervisor-module/Chapter 5/Language Services.w b/inbuild/supervisor-module/Chapter 5/Language Services.w
index 768f57a96..e5c870982 100644
--- a/inbuild/supervisor-module/Chapter 5/Language Services.w
+++ b/inbuild/supervisor-module/Chapter 5/Language Services.w
@@ -107,7 +107,7 @@ detect the language of play for a story file without actually running it.
=
void Languages::write_ISO_code(OUTPUT_STREAM, inform_language *L) {
#ifdef CORE_MODULE
- if (L == NULL) L = InflectionDefns::default_nl(NULL);
+ if (L == NULL) L = DefaultLanguage::get(NULL);
#endif
if (Wordings::nonempty(L->language_field[ISO_639_CODE_LFIELD]))
WRITE("%+W", L->language_field[ISO_639_CODE_LFIELD]);
diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt
index 3a8822c05..d0f14c51b 100644
--- a/inform7/Figures/memory-diagnostics.txt
+++ b/inform7/Figures/memory-diagnostics.txt
@@ -1,18 +1,18 @@
-Total memory consumption was 253147K = 247 MB
+Total memory consumption was 256346K = 250 MB
-61.9% was used for 1324142 objects, in 262772 frames in 196 x 800K = 156800K = 153 MB:
+62.4% was used for 1335177 objects, in 267912 frames in 200 x 800K = 160000K = 156 MB:
- 10.0% inter_tree_node_array 36 x 8192 = 294912 objects, 25953408 bytes
- 5.6% text_stream_array 2588 x 100 = 258800 objects, 14575616 bytes
- 4.0% parse_node 130338 objects, 10427040 bytes
+ 9.8% inter_tree_node_array 36 x 8192 = 294912 objects, 25953408 bytes
+ 5.5% text_stream_array 2587 x 100 = 258700 objects, 14569984 bytes
+ 3.9% parse_node 130338 objects, 10427040 bytes
2.8% verb_conjugation 160 objects, 7425280 bytes
2.7% parse_node_annotation_array 445 x 500 = 222500 objects, 7134240 bytes
2.4% inter_symbol_array 70 x 1024 = 71680 objects, 6310080 bytes
+ 1.9% linked_list 9033 objects, 5058480 bytes
1.4% map_data 778 objects, 3690832 bytes
1.3% pcalc_prop_array 24 x 1000 = 24000 objects, 3456768 bytes
- 1.0% kind_array 65 x 1000 = 65000 objects, 2602080 bytes
- 0.8% linked_list 3897 objects, 2182320 bytes
- 0.8% inter_schema_token 14554 objects, 2095776 bytes
+ 0.9% kind_array 65 x 1000 = 65000 objects, 2602080 bytes
+ 0.7% inter_schema_token 14554 objects, 2095776 bytes
0.6% vocabulary_entry_array 161 x 100 = 16100 objects, 1808352 bytes
0.5% match_trie_array 10 x 1000 = 10000 objects, 1360320 bytes
0.4% phrase 940 objects, 1233280 bytes
@@ -21,13 +21,13 @@ Total memory consumption was 253147K = 247 MB
0.3% inter_name_array 20 x 1000 = 20000 objects, 960640 bytes
0.3% inter_package 13201 objects, 950472 bytes
0.3% inter_schema_node 9518 objects, 913728 bytes
- 0.3% production 3896 objects, 903872 bytes
+ 0.3% production 3895 objects, 903640 bytes
0.3% ptoken 8318 objects, 865072 bytes
0.3% inter_symbols_table 13201 objects, 844864 bytes
- 0.3% dictionary 16345 objects, 784560 bytes
+ 0.2% dictionary 16345 objects, 784560 bytes
0.2% dict_entry_array 236 x 100 = 23600 objects, 762752 bytes
- 0.2% individual_name 2623 objects, 713456 bytes
0.2% package_request 7928 objects, 697664 bytes
+ 0.2% individual_name 2623 objects, 692472 bytes
0.2% inter_name_generator_array 16 x 1000 = 16000 objects, 640512 bytes
0.2% verb_usage 1628 objects, 573056 bytes
0.1% inference_subject 781 objects, 512336 bytes
@@ -41,6 +41,7 @@ Total memory consumption was 253147K = 247 MB
---- action_name_list_array 3 x 1000 = 3000 objects, 240096 bytes
---- inter_annotation_array 1 x 8192 objects, 196640 bytes
---- inference 1703 objects, 177112 bytes
+ ---- linked_list_item_array 11 x 1000 = 11000 objects, 176352 bytes
---- stacked_variable_owner_list_array 38 x 100 = 3800 objects, 153216 bytes
---- action_pattern_array 6 x 100 = 600 objects, 144192 bytes
---- lexicon_entry 395 objects, 142200 bytes
@@ -50,7 +51,6 @@ Total memory consumption was 253147K = 247 MB
---- hierarchy_location 731 objects, 105264 bytes
---- preposition_identity 273 objects, 82992 bytes
---- name_cluster 2577 objects, 82464 bytes
- ---- linked_list_item_array 5 x 1000 = 5000 objects, 80160 bytes
---- pcalc_term_array 2 x 1000 = 2000 objects, 80064 bytes
---- kind_variable_declaration 1652 objects, 79296 bytes
---- inter_tree 6 objects, 78672 bytes
@@ -202,9 +202,9 @@ Total memory consumption was 253147K = 247 MB
---- kind_template_definition 1 object, 40 bytes
---- parse_name_notice 1 object, 40 bytes
-38.0% was used for memory not allocated for objects:
+37.5% was used for memory not allocated for objects:
- 16.2% text stream storage 42037656 bytes in 265104 claims
+ 16.0% text stream storage 42037080 bytes in 265076 claims
3.5% dictionary storage 9265152 bytes in 16345 claims
---- sorting 1112 bytes in 3 claims
2.7% source text 7200000 bytes in 3 claims
@@ -219,5 +219,5 @@ Total memory consumption was 253147K = 247 MB
---- emitter array storage 14368 bytes in 8 claims
---- code generation workspace for objects 9200 bytes in 9 claims
-20.1% was overhead - 52137560 bytes = 50915K = 49 MB
+19.9% was overhead - 52468856 bytes = 51239K = 50 MB
diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt
index 704cdc607..2f2af6df8 100644
--- a/inform7/Figures/timings-diagnostics.txt
+++ b/inform7/Figures/timings-diagnostics.txt
@@ -1,37 +1,45 @@
100.0% in inform7 run
- 66.2% in compilation to Inter
- 26.0% in //Phrases::Manager::compile_first_block//
- 8.6% in //Phrases::Manager::compile_as_needed//
- 6.9% in //Strings::compile_responses//
- 5.9% in //World::Compile::compile//
+ 66.6% in compilation to Inter
+ 26.2% in //Phrases::Manager::compile_first_block//
+ 8.5% in //Phrases::Manager::compile_as_needed//
+ 7.1% in //Strings::compile_responses//
+ 6.5% in //World::Compile::compile//
3.1% in //Assertions::Traverse::traverse1//
- 2.8% in //Sentences::VPs::traverse//
- 2.0% in //Phrases::Manager::RulePrintingRule_routine//
- 1.8% in //Phrases::Manager::rulebooks_array//
- 1.1% in //NewVerbs::ConjugateVerb//
+ 2.6% in //Sentences::VPs::traverse//
+ 2.2% in //Phrases::Manager::RulePrintingRule_routine//
+ 2.1% in //Phrases::Manager::rulebooks_array//
+ 1.0% in //NewVerbs::ConjugateVerb//
0.7% in //Phrases::Manager::traverse//
0.5% in //Phrases::Manager::parse_rule_parameters//
- 0.3% in //Phrases::Manager::compile_rulebooks//
+ 0.4% in //Phrases::Manager::compile_rulebooks//
0.3% in //Phrases::Manager::traverse_for_names//
0.3% in //Relations::compile_defined_relations//
- 0.1% in //Assertions::Traverse::traverse2//
- 0.1% in //BinaryPredicates::make_built_in_further//
+ 0.2% in //Assertions::Traverse::traverse2//
+ 0.2% in //BinaryPredicates::make_built_in_further//
+ 0.2% in //World::complete//
+ 0.1% in //Emit::begin//
+ 0.1% in //Index::DocReferences::read_xrefs//
+ 0.1% in //Kinds::Knowledge::include_templates_for_kinds//
+ 0.1% in //Kinds::RunTime::compile_data_type_support_routines//
0.1% in //PL::Parsing::Verbs::compile_all//
+ 0.1% in //PL::Parsing::traverse//
+ 0.1% in //Phrases::Manager::add_rules_to_rulebooks//
0.1% in //Sentences::RuleSubtrees::register_recently_lexed_phrases//
0.1% in //Task::load_types//
- 0.1% in //World::complete//
- 4.1% not specifically accounted for
- 31.2% in running Inter pipeline
- 10.2% in inter step 2/12: link
- 10.1% in step preparation
- 7.1% in inter step 12/12: generate inform6 -> auto.inf
+ 0.1% in //World::complete_additions//
+ 2.9% not specifically accounted for
+ 31.1% in running Inter pipeline
+ 10.6% in step preparation
+ 10.3% in inter step 2/12: link
+ 7.3% in inter step 12/12: generate inform6 -> auto.inf
+ 0.3% in inter step 10/12: reconcile-verbs
0.3% in inter step 9/12: make-identifiers-unique
- 0.1% in inter step 10/12: reconcile-verbs
- 0.1% in inter step 11/12: eliminate-redundant-labels
+ 0.2% in inter step 11/12: eliminate-redundant-labels
+ 0.2% in inter step 6/12: assimilate
+ 0.2% in inter step 7/12: resolve-external-symbols
+ 0.1% in inter step 4/12: parse-linked-matter
0.1% in inter step 5/12: resolve-conditional-compilation
- 0.1% in inter step 6/12: assimilate
- 0.1% in inter step 7/12: resolve-external-symbols
0.1% in inter step 8/12: inspect-plugs
- 2.2% not specifically accounted for
- 2.0% in supervisor
- 0.4% not specifically accounted for
+ 1.1% not specifically accounted for
+ 2.1% in supervisor
+ 0.2% not specifically accounted for
diff --git a/inform7/core-module/Chapter 1/What To Compile.w b/inform7/core-module/Chapter 1/What To Compile.w
index 4a8c62fbc..5b27fc38b 100644
--- a/inform7/core-module/Chapter 1/What To Compile.w
+++ b/inform7/core-module/Chapter 1/What To Compile.w
@@ -64,7 +64,7 @@ int Task::carry_out(build_step *S) {
inform7_task->stage_of_compilation = -1;
inform7_task->next_resource_number = 3;
- InflectionDefns::set_default_nl(Projects::get_language_of_syntax(project));
+ DefaultLanguage::set(Projects::get_language_of_syntax(project));
int rv = Sequence::carry_out(TargetVMs::debug_enabled(inform7_task->task->for_vm));
inform7_task = NULL;
diff --git a/inform7/core-module/Chapter 3/Plural Dictionary.w b/inform7/core-module/Chapter 3/Plural Dictionary.w
index 522a8b216..fa4109c6f 100644
--- a/inform7/core-module/Chapter 3/Plural Dictionary.w
+++ b/inform7/core-module/Chapter 3/Plural Dictionary.w
@@ -33,7 +33,7 @@ int Plurals::plural_SMF(int task, parse_node *V, wording *NPs) {
wording P = Node::get_text(V->next->next);
@;
if (Assertions::Creator::vet_name_for_noun(P) == FALSE) return TRUE;
- Pluralisation::register(S, P, InflectionDefns::default_nl(NULL));
+ Pluralisation::register(S, P, DefaultLanguage::get(NULL));
return TRUE;
}
break;
diff --git a/inform7/core-module/Chapter 4/Adjective Meanings.w b/inform7/core-module/Chapter 4/Adjective Meanings.w
index 501e18ed9..3ba747bd8 100644
--- a/inform7/core-module/Chapter 4/Adjective Meanings.w
+++ b/inform7/core-module/Chapter 4/Adjective Meanings.w
@@ -1283,7 +1283,7 @@ prefaced "(of a rulebook)", "(of an activity)", and so on.
=
internal {
- if (Projects::get_language_of_play(Task::project()) == InflectionDefns::default_nl(NULL)) return FALSE;
+ if (Projects::get_language_of_play(Task::project()) == DefaultLanguage::get(NULL)) return FALSE;
adjectival_phrase *aph;
LOOP_OVER(aph, adjectival_phrase) {
wording AW = Clusters::get_name_general(aph->adjective_names, Projects::get_language_of_play(Task::project()), 1, -1);
@@ -1298,7 +1298,7 @@ prefaced "(of a rulebook)", "(of an activity)", and so on.
=
void Adjectives::Meanings::agreements(void) {
- if (Projects::get_language_of_play(Task::project()) == InflectionDefns::default_nl(NULL)) return;
+ if (Projects::get_language_of_play(Task::project()) == DefaultLanguage::get(NULL)) return;
adjectival_phrase *aph;
LOOP_OVER(aph, adjectival_phrase) {
wording PW = Clusters::get_name_general(aph->adjective_names, Projects::get_language_of_play(Task::project()), 1, -1);
diff --git a/inform7/core-module/Chapter 5/Using Nametags.w b/inform7/core-module/Chapter 5/Using Nametags.w
index 474a83004..b89adcf9b 100644
--- a/inform7/core-module/Chapter 5/Using Nametags.w
+++ b/inform7/core-module/Chapter 5/Using Nametags.w
@@ -108,7 +108,7 @@ void UseNouns::nl_translates(parse_node *pn) {
inform_language *nl = Node::get_defn_language(pn->next->next);
int g = Annotations::read_int(pn->next->next, gender_reference_ANNOT);
if (nl == NULL) internal_error("No such NL");
- if (nl == InflectionDefns::default_nl(NULL)) {
+ if (nl == DefaultLanguage::get(NULL)) {
StandardProblems::sentence_problem(Task::syntax_tree(), _p_(PM_CantTranslateIntoEnglish),
"you can't translate into English",
"only out of it.");
diff --git a/inform7/core-module/Chapter 6/New Verbs.w b/inform7/core-module/Chapter 6/New Verbs.w
index 5f0cfd2d1..edf0acd10 100644
--- a/inform7/core-module/Chapter 6/New Verbs.w
+++ b/inform7/core-module/Chapter 6/New Verbs.w
@@ -89,7 +89,7 @@ as the object.
=
::=
in | ==> R[2]; <> = (inform_language *) (RP[1]);
- ==> R[1]; <> = InflectionDefns::default_nl(NULL);
+ ==> R[1]; <> = DefaultLanguage::get(NULL);
::=
to ( ... ) | ==> R[1]; <> = TRUE
@@ -552,7 +552,7 @@ foreign verbs (4).
binary_predicate *bp = VerbMeanings::get_relational_meaning(&vm);
if (bp == a_has_b_predicate) p = 1;
if (bp == R_equality) p = 2;
- if ((nl) && (nl != InflectionDefns::default_nl(NULL))) p = 5;
+ if ((nl) && (nl != DefaultLanguage::get(NULL))) p = 5;
++new_verb_sequence_count;
vi = Verbs::new_verb(vc, FALSE);
vc->vc_conjugates = vi;
@@ -634,13 +634,13 @@ void NewVerbs::bootstrap(void) {
NewVerbs::declare_sm(Sentences::VPs::omit_from_SMF, I"omit-from", 4);
word_assemblage infinitive = PreformUtilities::wording(, 0);
- verb_conjugation *vc = Conjugation::conjugate(infinitive, InflectionDefns::default_nl(NULL));
+ verb_conjugation *vc = Conjugation::conjugate(infinitive, DefaultLanguage::get(NULL));
verb_identity *vi = Verbs::new_verb(vc, TRUE);
vc->vc_conjugates = vi;
VerbUsages::register_all_usages_of_verb(vi, FALSE, 2);
infinitive = PreformUtilities::wording(, 1);
- vc = Conjugation::conjugate(infinitive, InflectionDefns::default_nl(NULL));
+ vc = Conjugation::conjugate(infinitive, DefaultLanguage::get(NULL));
vi = Verbs::new_verb(vc, FALSE);
vc->vc_conjugates = vi;
VerbUsages::register_all_usages_of_verb(vi, FALSE, 3);
@@ -930,11 +930,11 @@ void NewVerbs::ConjugateVerb(void) {
word_assemblage *wa = &(vc->tabulations[ACTIVE_MOOD].vc_text[tense][sense][part-1]);
if (WordAssemblages::nonempty(*wa)) {
if (some_exist) {
- if (WordAssemblages::compare(wa, common) == FALSE)
+ if (WordAssemblages::eq(wa, common) == FALSE)
some_differ = TRUE;
if (part != 3) {
if (common_except_3PS == NULL) common_except_3PS = wa;
- else if (WordAssemblages::compare(wa, common_except_3PS) == FALSE)
+ else if (WordAssemblages::eq(wa, common_except_3PS) == FALSE)
some_except_3PS_differ = TRUE;
}
} else {
diff --git a/inform7/if-module/Chapter 3/The Naming Thicket.w b/inform7/if-module/Chapter 3/The Naming Thicket.w
index f3c0448e0..f8fe6e9d8 100644
--- a/inform7/if-module/Chapter 3/The Naming Thicket.w
+++ b/inform7/if-module/Chapter 3/The Naming Thicket.w
@@ -189,7 +189,7 @@ from sentences, and this can include I6 properties with no I7 analogue.
this_is_named_for_something_with_a_printed_name = TRUE;
@;
if (this_has_a_printed_name == FALSE) @;
- if (Projects::get_language_of_play(Task::project()) != InflectionDefns::default_nl(NULL))
+ if (Projects::get_language_of_play(Task::project()) != DefaultLanguage::get(NULL))
@;
}
diff --git a/inform7/kinds-module/Chapter 2/Describing Kinds.w b/inform7/kinds-module/Chapter 2/Describing Kinds.w
index f3f5aa9f5..7578f25cc 100644
--- a/inform7/kinds-module/Chapter 2/Describing Kinds.w
+++ b/inform7/kinds-module/Chapter 2/Describing Kinds.w
@@ -468,7 +468,7 @@ void Kinds::Textual::write_plural(OUTPUT_STREAM, kind *K) {
void Kinds::Textual::write_articled(OUTPUT_STREAM, kind *K) {
TEMPORARY_TEXT(TEMP);
Kinds::Textual::write_inner(TEMP, K, FALSE, TRUE);
- ArticleInflection::preface_by_article(OUT, TEMP, InflectionDefns::default_nl(NULL));
+ ArticleInflection::preface_by_article(OUT, TEMP, DefaultLanguage::get(NULL));
DISCARD_TEXT(TEMP);
}
diff --git a/services/inflections-module/Chapter 1/Inflections Module.w b/services/inflections-module/Chapter 1/Inflections Module.w
index 63b35f4a6..978ddb6b6 100644
--- a/services/inflections-module/Chapter 1/Inflections Module.w
+++ b/services/inflections-module/Chapter 1/Inflections Module.w
@@ -23,30 +23,15 @@ DECLARE_CLASS(verb_conjugation)
@ Like all modules, this one must define a |start| and |end| function:
-=
-void InflectionsModule::start(void) {
- @;
- @;
- @;
- @;
-}
-void InflectionsModule::end(void) {
-}
-
-@ =
- ;
-
-@
-
@e CONSTRUCTED_PAST_PARTICIPLES_DA
@e CONSTRUCTED_PLURALS_DA
-@ =
- Log::declare_aspect(CONSTRUCTED_PAST_PARTICIPLES_DA, L"constructed past participles", FALSE, FALSE);
- Log::declare_aspect(CONSTRUCTED_PLURALS_DA, L"constructed plurals", FALSE, FALSE);
-
-@ =
- ;
-
-@ =
- ;
+=
+void InflectionsModule::start(void) {
+ Log::declare_aspect(CONSTRUCTED_PAST_PARTICIPLES_DA,
+ L"constructed past participles", FALSE, FALSE);
+ Log::declare_aspect(CONSTRUCTED_PLURALS_DA,
+ L"constructed plurals", FALSE, FALSE);
+}
+void InflectionsModule::end(void) {
+}
diff --git a/services/inflections-module/Chapter 3/Article Inflection.w b/services/inflections-module/Chapter 2/Article Inflection.w
similarity index 94%
rename from services/inflections-module/Chapter 3/Article Inflection.w
rename to services/inflections-module/Chapter 2/Article Inflection.w
index 23f9fe75d..67b6e9158 100644
--- a/services/inflections-module/Chapter 3/Article Inflection.w
+++ b/services/inflections-module/Chapter 2/Article Inflection.w
@@ -15,7 +15,7 @@ void ArticleInflection::preface_by_article(OUTPUT_STREAM,
indef_trie =
PreformUtilities::define_trie(
, TRIE_START,
- InflectionDefns::default_nl(NULL));
+ DefaultLanguage::get(NULL));
wchar_t *result = Tries::search_avinue(indef_trie, initial_text);
if (result == NULL) result = L"a";
WRITE("%w %S", result, initial_text);
diff --git a/services/inflections-module/Chapter 3/Grading Adjectives.w b/services/inflections-module/Chapter 2/Grading Adjectives.w
similarity index 86%
rename from services/inflections-module/Chapter 3/Grading Adjectives.w
rename to services/inflections-module/Chapter 2/Grading Adjectives.w
index 7e3784d72..3312cd6c9 100644
--- a/services/inflections-module/Chapter 3/Grading Adjectives.w
+++ b/services/inflections-module/Chapter 2/Grading Adjectives.w
@@ -20,11 +20,11 @@ wording Grading::make_comparative(wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl) {
WRITE_TO(comprised, "some-long-text");
else
WRITE_TO(comprised, "%N", Wordings::first_wn(W));
- nl = InflectionDefns::default_nl(nl);
+ nl = DefaultLanguage::get(nl);
match_avinue *comp_trie =
PreformUtilities::define_trie(, TRIE_END,
- InflectionDefns::default_nl(nl));
- Inflections::suffix_inflection(transformed, comp_trie, comprised);
+ DefaultLanguage::get(nl));
+ Inflect::suffix(transformed, comp_trie, comprised);
wording PW = Feeds::feed_text(transformed);
word_assemblage merged =
PreformUtilities::merge(, 0,
@@ -46,11 +46,11 @@ wording Grading::make_superlative(wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl) {
WRITE_TO(comprised, "some-long-text");
else
WRITE_TO(comprised, "%N", Wordings::first_wn(W));
- nl = InflectionDefns::default_nl(nl);
+ nl = DefaultLanguage::get(nl);
match_avinue *comp_trie =
PreformUtilities::define_trie(, TRIE_END,
- InflectionDefns::default_nl(nl));
- Inflections::suffix_inflection(transformed, comp_trie, comprised);
+ DefaultLanguage::get(nl));
+ Inflect::suffix(transformed, comp_trie, comprised);
wording PW = Feeds::feed_text(transformed);
LOGIF(CONSTRUCTED_PLURALS, "[Superlative of %W is %W]\n", W, PW);
DISCARD_TEXT(transformed);
@@ -71,11 +71,11 @@ wording Grading::make_quiddity(wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl) {
WRITE_TO(comprised, "some-long-text");
else
WRITE_TO(comprised, "%N", Wordings::first_wn(W));
- nl = InflectionDefns::default_nl(nl);
+ nl = DefaultLanguage::get(nl);
match_avinue *comp_trie =
PreformUtilities::define_trie(, TRIE_END,
- InflectionDefns::default_nl(nl));
- Inflections::suffix_inflection(transformed, comp_trie, comprised);
+ DefaultLanguage::get(nl));
+ Inflect::suffix(transformed, comp_trie, comprised);
wording PW = Feeds::feed_text(transformed);
LOGIF(CONSTRUCTED_PLURALS, "[Quiddity of %W is %W]\n", W, PW);
DISCARD_TEXT(transformed);
diff --git a/services/inflections-module/Chapter 3/Past Participles.w b/services/inflections-module/Chapter 2/Past Participles.w
similarity index 93%
rename from services/inflections-module/Chapter 3/Past Participles.w
rename to services/inflections-module/Chapter 2/Past Participles.w
index 68898fce6..b4631cf2e 100644
--- a/services/inflections-module/Chapter 3/Past Participles.w
+++ b/services/inflections-module/Chapter 2/Past Participles.w
@@ -39,6 +39,6 @@ above. It expects only a single word.
int PastParticiples::pasturise_text(OUTPUT_STREAM, text_stream *from) {
match_avinue *past_trie =
PreformUtilities::define_trie(, TRIE_START,
- InflectionDefns::default_nl(NULL));
- return Inflections::suffix_inflection(OUT, past_trie, from);
+ DefaultLanguage::get(NULL));
+ return Inflect::suffix(OUT, past_trie, from);
}
diff --git a/services/inflections-module/Chapter 3/Pluralisation.w b/services/inflections-module/Chapter 2/Pluralisation.w
similarity index 93%
rename from services/inflections-module/Chapter 3/Pluralisation.w
rename to services/inflections-module/Chapter 2/Pluralisation.w
index 2e4fd7355..47e2ae9cc 100644
--- a/services/inflections-module/Chapter 3/Pluralisation.w
+++ b/services/inflections-module/Chapter 2/Pluralisation.w
@@ -42,7 +42,7 @@ one not found in the dictionary).
=
plural_dictionary_entry *Pluralisation::make(wording W, wording *PW,
plural_dictionary_entry *search_from, NATURAL_LANGUAGE_WORDS_TYPE *nl) {
- nl = InflectionDefns::default_nl(nl);
+ nl = DefaultLanguage::get(nl);
plural_dictionary_entry *pde;
@@ -94,10 +94,11 @@ The following takes a single word, assumes it to be a noun which meaningfully
has a plural, and modifies it to the plural form.
=
-int Pluralisation::regular(OUTPUT_STREAM, text_stream *from, NATURAL_LANGUAGE_WORDS_TYPE *nl) {
- nl = InflectionDefns::default_nl(nl);
+int Pluralisation::regular(OUTPUT_STREAM, text_stream *from,
+ NATURAL_LANGUAGE_WORDS_TYPE *nl) {
+ nl = DefaultLanguage::get(nl);
match_avinue *plural_trie =
PreformUtilities::define_trie(, TRIE_END,
- InflectionDefns::default_nl(nl));
- return Inflections::suffix_inflection(OUT, plural_trie, from);
+ DefaultLanguage::get(nl));
+ return Inflect::suffix(OUT, plural_trie, from);
}
diff --git a/services/inflections-module/Chapter 2/Tries and Inflections.w b/services/inflections-module/Chapter 2/Tries and Inflections.w
index 54663c5a3..f361f9934 100644
--- a/services/inflections-module/Chapter 2/Tries and Inflections.w
+++ b/services/inflections-module/Chapter 2/Tries and Inflections.w
@@ -1,55 +1,70 @@
-[Inflections::] Tries and Inflections.
+[Inflect::] Tries and Inflections.
Using tries to inflect word endings.
@h Suffix inflections.
The following inflects the ending of the supplied text. It does so by
-running the text through an avinue (a sequence of tries), whose result
-is an instruction on how to modify that text: for example, the result
-|"3ize"| tells us to strike out the last 3 characters and add "ize".
-The special character |+| means "duplicate the last character" and
-is useful for inflections which double consonants, such as "big" to
-"bigger", which can be done with the instruction |"0+er"|.
-
-If there's no initial digit, the result replaces the original entirely;
-if the result is null, i.e., if the avinue finds nothing, the result is
-the same as the original.
+running the text through an avinue: see //foundation: Tries and Avinues//,
+which is where the asterisk notation is handled.
=
-int Inflections::suffix_inflection(OUTPUT_STREAM, match_avinue *T, text_stream *from) {
+int Inflect::suffix(OUTPUT_STREAM, match_avinue *T, text_stream *from) {
wchar_t *result = Tries::search_avinue(T, from);
- return Inflections::follow_suffix_instruction(OUT, from, result);
+ return Inflect::follow_suffix_instruction(OUT, from, result);
}
-int Inflections::follow_suffix_instruction(OUTPUT_STREAM, text_stream *from, wchar_t *instruction) {
+@ The //foundation// code returns a |result| which may be null, if no match
+was found. In that event, we leave the text unchanged, just as if the result
+had been |0| -- meaning "change nothing".
+
+=
+int Inflect::follow_suffix_instruction(OUTPUT_STREAM, text_stream *from,
+ wchar_t *instruction) {
int success = TRUE;
if (instruction == NULL) { success = FALSE; instruction = L"0"; }
- int back = instruction[0] - '0';
TEMPORARY_TEXT(outcome);
- if ((back < 0) || (back > 9)) {
- WRITE_TO(outcome, "%w", instruction);
- } else {
- for (int i = 0, len = Str::len(from); i;
+ @;
DISCARD_TEXT(outcome);
return success;
}
+@ In general the result either has an initial digit, in which case it removes
+that many terminal letters, or does not, in which case it removes all the
+letters (and thus the result text replaces the original entirely).
+The special character |+| after a digit means "duplicate the last character";
+in other contexts it means "break words here".
+
+For example, the result |3ize| tells us to strike out the last 3 characters and
+add "ize".
+
+@ =
+ int back = instruction[0] - '0';
+ if ((back < 0) || (back > 9)) {
+ WRITE_TO(outcome, "%w", instruction);
+ } else {
+ for (int i = 0, len = Str::len(from); i =
+ LOOP_THROUGH_TEXT(pos, outcome)
+ if (Str::get(pos) == '+') PUT(' ');
+ else PUT(Str::get(pos));
+
@h General tries.
Here we take a word assemblage and apply suffix inflection to the first word
-alone, preserving the rest. However, if the result of this inflection contains
-any |+| signs, those become word boundaries. This allows for inflections which
-do more than simply fiddle with the final letters.
+alone, preserving the rest: for example, "make the tea" might become "making
+the tea". However, if the result of this inflection contains any |+| signs,
+those once again become word boundaries.
=
-word_assemblage Inflections::apply_trie_to_wa(word_assemblage wa, match_avinue *T) {
+word_assemblage Inflect::first_word(word_assemblage wa, match_avinue *T) {
vocabulary_entry **words;
int no_words;
WordAssemblages::as_array(&wa, &words, &no_words);
@@ -58,7 +73,7 @@ word_assemblage Inflections::apply_trie_to_wa(word_assemblage wa, match_avinue *
TEMPORARY_TEXT(unsuffixed);
TEMPORARY_TEXT(suffixed);
WRITE_TO(unsuffixed, "%V", words[0]);
- int s = Inflections::suffix_inflection(suffixed, T, unsuffixed);
+ int s = Inflect::suffix(suffixed, T, unsuffixed);
if (s == FALSE) {
LOOP_THROUGH_TEXT(pos, unsuffixed)
if (Str::get(pos) == '+') PUT_TO(suffixed, ' ');
diff --git a/services/inflections-module/Chapter 3/Declensions.w b/services/inflections-module/Chapter 3/Declensions.w
index c33fb3dc2..0159eab6d 100644
--- a/services/inflections-module/Chapter 3/Declensions.w
+++ b/services/inflections-module/Chapter 3/Declensions.w
@@ -3,7 +3,16 @@
Declensions are sets of inflected variations of a common stem
according to grammatical case.
-@h Declension.
+@ The traditional term "declension" refers to the set of inflected forms of a
+word which does not serve as a verb: nouns, adjectives and pronouns all have
+"declensions". These forms generally vary according to gender, number and
+also "case", which expresses context.
+
+The //inflections// module uses the term "declension" in a more limited sense:
+it is just the set of variations by case. Variations by gender and number are
+taken care of by what are less elegantly called //Name Clusters//.
+
+At any rate, a //declension// object is a set of wordings, one for each case:
=
typedef struct declension {
@@ -11,174 +20,9 @@ typedef struct declension {
struct wording name_cased[MAX_GRAMMATICAL_CASES];
} declension;
-@ =
-declension Declensions::decline(wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl, int gen, int num) {
- nl = InflectionDefns::default_nl(nl);
- declension D = Declensions::decline_inner(W, nl, gen, num, );
- @;
- return D;
-}
-
-declension Declensions::decline_article(wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl, int gen, int num) {
- nl = InflectionDefns::default_nl(nl);
- declension D = Declensions::decline_inner(W, nl, gen, num, );
- @;
- return D;
-}
-
-@ =
- int nc = Declensions::no_cases(nl);
- for (int c = 0; c < nc; c++)
- LOOP_THROUGH_WORDING(i, D.name_cased[c])
- Lexer::set_word_location(i,
- Lexer::word_location(
- Wordings::first_wn(W)));
-
-@ =
-declension Declensions::decline_inner(wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl, int gen, int num, nonterminal *nt) {
- nl = InflectionDefns::default_nl(nl);
- declension D;
- D.within_language = nl;
- for (production_list *pl = nt->first_pl; pl; pl = pl->next_pl) {
- if ((pl->definition_language == NULL) || (pl->definition_language == nl)) {
- for (production *pr = pl->first_pr; pr; pr = pr->next_pr) {
- if ((pr->first_pt == NULL) ||
- (pr->first_pt->ptoken_category != FIXED_WORD_PTC) ||
- (pr->first_pt->next_pt == NULL) ||
- (pr->first_pt->next_pt->ptoken_category != NONTERMINAL_PTC))
- internal_error("line in malformed");
- wchar_t *gender_letter = Vocabulary::get_exemplar(pr->first_pt->ve_pt, FALSE);
- if ((gender_letter[0] == '*') ||
- ((gender_letter[0] == 'm') && (gen == MASCULINE_GENDER)) ||
- ((gender_letter[0] == 'f') && (gen == FEMININE_GENDER)) ||
- ((gender_letter[0] == 'n') && (gen == NEUTER_GENDER))) {
- int found = FALSE;
- nonterminal *gnt = pr->first_pt->next_pt->nt_pt;
- if (pr->first_pt->next_pt->next_pt == NULL) {
- D = Declensions::decline_from_irregulars(W, nl, gnt, num, &found);
- } else {
- if ((pr->first_pt->next_pt->next_pt->ptoken_category != NONTERMINAL_PTC) ||
- (pr->first_pt->next_pt->next_pt->next_pt != NULL))
- internal_error("this line must end with two nonterminals");
- nonterminal *tnt = pr->first_pt->next_pt->next_pt->nt_pt;
- D = Declensions::decline_from_groups(W, nl, gnt, tnt, num, &found);
- }
- if (found) return D;
- }
-
- }
- }
- }
- internal_error("no declension table terminated");
- return D;
-}
-
-declension Declensions::decline_from_irregulars(wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl,
- nonterminal *gnt, int num, int *found) {
- *found = FALSE;
- declension D;
- D.within_language = nl;
- if (Wordings::length(W) == 1)
- for (production_list *pl = gnt->first_pl; pl; pl = pl->next_pl)
- if ((pl->definition_language == NULL) || (pl->definition_language == nl))
- for (production *pr = pl->first_pr; pr; pr = pr->next_pr) {
- vocabulary_entry *stem = pr->first_pt->ve_pt;
- if (stem == Lexer::word(Wordings::first_wn(W))) {
- *found = TRUE;
- int c = 0, nc = Declensions::no_cases(nl);
- for (ptoken *pt = pr->first_pt->next_pt; pt; pt = pt->next_pt) {
- if (pt->ptoken_category != FIXED_WORD_PTC)
- internal_error("nonterminals are not allowed in irregular declensions");
- if (((num == 1) && (c < nc)) || ((num == 2) && (c >= nc))) {
- TEMPORARY_TEXT(stem);
- TEMPORARY_TEXT(result);
- WRITE_TO(stem, "%W", W);
- Inflections::follow_suffix_instruction(result, stem,
- Vocabulary::get_exemplar(pt->ve_pt, TRUE));
- D.name_cased[c%nc] = Feeds::feed_text(result);
- DISCARD_TEXT(stem);
- DISCARD_TEXT(result);
- }
- c++;
- }
- if (c < 2*nc) internal_error("too few cases in irregular declension");
- if (c > 2*nc) internal_error("too many cases in irregular declension");
- return D;
- }
- }
- return D;
-}
-
-declension Declensions::decline_from_groups(wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl,
- nonterminal *gnt, nonterminal *nt, int num, int *found) {
- declension D;
- D.within_language = nl;
- TEMPORARY_TEXT(from);
- WRITE_TO(from, "%+W", W);
- match_avinue *group_trie = PreformUtilities::define_trie(gnt, TRIE_END, InflectionDefns::default_nl(nl));
- wchar_t *result = Tries::search_avinue(group_trie, from);
- DISCARD_TEXT(from);
- if (result == NULL) {
- *found = FALSE;
- } else {
- *found = TRUE;
- int group = result[0] - '0';
- if ((group <= 0) || (group > 9))
- internal_error("noun declension nonterminal result not a group number");
- for (production_list *pl = nt->first_pl; pl; pl = pl->next_pl) {
- if ((pl->definition_language == NULL) || (pl->definition_language == nl)) {
- for (production *pr = pl->first_pr; pr; pr = pr->next_pr) {
- if ((pr->first_pt == NULL) ||
- (pr->first_pt->ptoken_category != NONTERMINAL_PTC) ||
- (pr->first_pt->next_pt != NULL))
- internal_error("noun declension nonterminal malformed");
- if (--group == 0)
- return Declensions::decline_from(W, nl, pr->first_pt->nt_pt, num);
- }
- }
- }
- internal_error("noun declension nonterminal has too few groups");
- }
- return D;
-}
-
-declension Declensions::decline_from(wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl, nonterminal *nt, int num) {
- int c = 0, nc = Declensions::no_cases(nl);
- declension D;
- D.within_language = nl;
- for (production_list *pl = nt->first_pl; pl; pl = pl->next_pl) {
- if ((pl->definition_language == NULL) || (pl->definition_language == nl)) {
- for (production *pr = pl->first_pr; pr; pr = pr->next_pr) {
- if ((pr->first_pt == NULL) ||
- (pr->first_pt->ptoken_category != FIXED_WORD_PTC) ||
- (pr->first_pt->next_pt != NULL))
- internal_error(" too complex");
- if (((c < nc) && (num == 1)) || ((c >= nc) && (num == 2))) {
- TEMPORARY_TEXT(stem);
- TEMPORARY_TEXT(result);
- WRITE_TO(stem, "%+W", W);
- Inflections::follow_suffix_instruction(result, stem,
- Vocabulary::get_exemplar(pr->first_pt->ve_pt, TRUE));
- D.name_cased[c%nc] = Feeds::feed_text(result);
- DISCARD_TEXT(stem);
- DISCARD_TEXT(result);
- }
- c++;
- }
- if (c < 2*nc) internal_error("too few cases in declension");
- if (c > 2*nc) internal_error("too many cases in declension");
- return D;
- }
- }
- internal_error("declination unavailable");
- return D;
-}
-
-wording Declensions::in_case(declension *D, int c) {
- if ((c < 0) || (c >= Declensions::no_cases(D->within_language))) internal_error("case out of range");
- return D->name_cased[c];
-}
+@ Cases in a language are itemised in the special nonterminal :
+=
int Declensions::no_cases(NATURAL_LANGUAGE_WORDS_TYPE *nl) {
nonterminal *nt = ;
for (production_list *pl = nt->first_pl; pl; pl = pl->next_pl) {
@@ -194,11 +38,15 @@ int Declensions::no_cases(NATURAL_LANGUAGE_WORDS_TYPE *nl) {
return -1;
}
+@ The following is useful for debugging:
+
+=
void Declensions::writer(OUTPUT_STREAM, declension *D, declension *AD) {
nonterminal *nt = ;
int nc = Declensions::no_cases(D->within_language);
for (production_list *pl = nt->first_pl; pl; pl = pl->next_pl) {
- if ((pl->definition_language == NULL) || (pl->definition_language == D->within_language)) {
+ if ((pl->definition_language == NULL) ||
+ (pl->definition_language == D->within_language)) {
int c = 0;
for (production *pr = pl->first_pr; pr; pr = pr->next_pr) {
if ((pr->first_pt == NULL) ||
@@ -217,3 +65,207 @@ void Declensions::writer(OUTPUT_STREAM, declension *D, declension *AD) {
}
internal_error(" not provided for this language");
}
+
+@ And this function extracts the right form for a given case |c|:
+
+=
+wording Declensions::in_case(declension *D, int c) {
+ if ((c < 0) || (c >= Declensions::no_cases(D->within_language)))
+ internal_error("case out of range");
+ return D->name_cased[c];
+}
+
+@ So much for using declensions; now to generate them. They are inflected from
+the stem by special Preform nonterminals:
+
+=
+declension Declensions::of_noun(wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl,
+ int gen, int num) {
+ nl = DefaultLanguage::get(nl);
+ declension D = Declensions::decline_inner(W, nl, gen, num, );
+ @;
+ return D;
+}
+
+declension Declensions::of_article(wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl,
+ int gen, int num) {
+ nl = DefaultLanguage::get(nl);
+ declension D = Declensions::decline_inner(W, nl, gen, num, );
+ @;
+ return D;
+}
+
+@ If a word comes from a given file and line number in the source text, then
+we will say that so does any inflected form of it:
+
+@ =
+ for (int c = 0; c < Declensions::no_cases(nl); c++)
+ LOOP_THROUGH_WORDING(i, D.name_cased[c])
+ Lexer::set_word_location(i, Lexer::word_location(Wordings::first_wn(W)));
+
+@ For the format of the table expressed by the nonterminal |nt|, see
+//What This Module Does//.
+
+=
+declension Declensions::decline_inner(wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl,
+ int gen, int num, nonterminal *nt) {
+ nl = DefaultLanguage::get(nl);
+ declension D;
+ D.within_language = nl;
+ for (production_list *pl = nt->first_pl; pl; pl = pl->next_pl) {
+ if ((pl->definition_language == NULL) || (pl->definition_language == nl)) {
+ for (production *pr = pl->first_pr; pr; pr = pr->next_pr) {
+ if ((pr->first_pt == NULL) ||
+ (pr->first_pt->ptoken_category != FIXED_WORD_PTC) ||
+ (pr->first_pt->next_pt == NULL) ||
+ (pr->first_pt->next_pt->ptoken_category != NONTERMINAL_PTC))
+ internal_error("line in malformed");
+ wchar_t *gender_letter = Vocabulary::get_exemplar(pr->first_pt->ve_pt, FALSE);
+ if ((gender_letter[0] == '*') ||
+ ((gender_letter[0] == 'm') && (gen == MASCULINE_GENDER)) ||
+ ((gender_letter[0] == 'f') && (gen == FEMININE_GENDER)) ||
+ ((gender_letter[0] == 'n') && (gen == NEUTER_GENDER)))
+ @;
+ }
+ }
+ }
+ internal_error("no declension table terminated");
+ return D;
+}
+
+@ =
+ int found = FALSE;
+ nonterminal *gnt = pr->first_pt->next_pt->nt_pt;
+ if (pr->first_pt->next_pt->next_pt == NULL) {
+ D = Declensions::decline_from_irregulars(W, nl, gnt, num, &found);
+ } else {
+ if ((pr->first_pt->next_pt->next_pt->ptoken_category != NONTERMINAL_PTC) ||
+ (pr->first_pt->next_pt->next_pt->next_pt != NULL))
+ internal_error("this line must end with two nonterminals");
+ nonterminal *tnt = pr->first_pt->next_pt->next_pt->nt_pt;
+ D = Declensions::decline_from_groups(W, nl, gnt, tnt, num, &found);
+ }
+ if (found) return D;
+
+@ This is for the two-token form of row, |gender table|:
+
+=
+declension Declensions::decline_from_irregulars(wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl,
+ nonterminal *gnt, int num, int *found) {
+ *found = FALSE;
+ declension D;
+ D.within_language = nl;
+ if (Wordings::length(W) == 1)
+ for (production_list *pl = gnt->first_pl; pl; pl = pl->next_pl)
+ if ((pl->definition_language == NULL) || (pl->definition_language == nl))
+ for (production *pr = pl->first_pr; pr; pr = pr->next_pr) {
+ vocabulary_entry *stem = pr->first_pt->ve_pt;
+ if (stem == Lexer::word(Wordings::first_wn(W))) {
+ *found = TRUE;
+ int c = 0, nc = Declensions::no_cases(nl);
+ for (ptoken *pt = pr->first_pt->next_pt; pt; pt = pt->next_pt) {
+ if (pt->ptoken_category != FIXED_WORD_PTC)
+ internal_error("NTs are not allowed in irregular decs");
+ if (((num == 1) && (c < nc)) || ((num == 2) && (c >= nc))) {
+ TEMPORARY_TEXT(stem);
+ TEMPORARY_TEXT(result);
+ WRITE_TO(stem, "%W", W);
+ Inflect::follow_suffix_instruction(result, stem,
+ Vocabulary::get_exemplar(pt->ve_pt, TRUE));
+ D.name_cased[c%nc] = Feeds::feed_text(result);
+ DISCARD_TEXT(stem);
+ DISCARD_TEXT(result);
+ }
+ c++;
+ }
+ if (c < 2*nc) internal_error("too few cases in irregular ded");
+ if (c > 2*nc) internal_error("too many cases in irregular dec");
+ return D;
+ }
+ }
+ return D;
+}
+
+@ And this is for the three-token form of row, |gender grouper table|:
+
+=
+declension Declensions::decline_from_groups(wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl,
+ nonterminal *gnt, nonterminal *nt, int num, int *found) {
+ declension D;
+ D.within_language = nl;
+ TEMPORARY_TEXT(from);
+ WRITE_TO(from, "%+W", W);
+ match_avinue *group_trie = PreformUtilities::define_trie(gnt, TRIE_END,
+ DefaultLanguage::get(nl));
+ wchar_t *result = Tries::search_avinue(group_trie, from);
+ DISCARD_TEXT(from);
+ if (result == NULL) {
+ *found = FALSE;
+ } else {
+ *found = TRUE;
+ int group;
+ @;
+ for (production_list *pl = nt->first_pl; pl; pl = pl->next_pl)
+ if ((pl->definition_language == NULL) || (pl->definition_language == nl))
+ for (production *pr = pl->first_pr; pr; pr = pr->next_pr) {
+ if ((pr->first_pt == NULL) ||
+ (pr->first_pt->ptoken_category != NONTERMINAL_PTC) ||
+ (pr->first_pt->next_pt != NULL))
+ internal_error("noun declension nonterminal malformed");
+ if (--group == 0)
+ return Declensions::decline_from(W, nl, pr->first_pt->nt_pt, num);
+ }
+ internal_error("noun declension nonterminal has too few groups");
+ }
+ return D;
+}
+
+@ =
+ group = result[0] - '0';
+ if ((group <= 0) || (group > 9))
+ internal_error("noun declension grouper result not a group number");
+ if (result[1]) {
+ int u = result[1] - '0';
+ if ((u < 0) || (u > 9))
+ internal_error("noun declension grouper result not a group number");
+ group = group*10 + u;
+ if (result[2]) internal_error("noun declension grouper result too high");
+ }
+
+@ We have now found the actual declension table NT; if there are $N$ cases
+in the language, there will be $2N$ productions in this table, each of which
+consists of a single word giving the rewriting instruction to use.
+
+=
+declension Declensions::decline_from(wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl,
+ nonterminal *nt, int num) {
+ int c = 0, nc = Declensions::no_cases(nl);
+ declension D;
+ D.within_language = nl;
+ for (production_list *pl = nt->first_pl; pl; pl = pl->next_pl) {
+ if ((pl->definition_language == NULL) || (pl->definition_language == nl)) {
+ for (production *pr = pl->first_pr; pr; pr = pr->next_pr) {
+ if ((pr->first_pt == NULL) ||
+ (pr->first_pt->ptoken_category != FIXED_WORD_PTC) ||
+ (pr->first_pt->next_pt != NULL))
+ internal_error(" too complex");
+ if (((c < nc) && (num == 1)) || ((c >= nc) && (num == 2))) {
+ TEMPORARY_TEXT(stem);
+ TEMPORARY_TEXT(result);
+ WRITE_TO(stem, "%+W", W);
+ Inflect::follow_suffix_instruction(result, stem,
+ Vocabulary::get_exemplar(pr->first_pt->ve_pt, TRUE));
+ D.name_cased[c%nc] = Feeds::feed_text(result);
+ DISCARD_TEXT(stem);
+ DISCARD_TEXT(result);
+ }
+ c++;
+ }
+ if (c < 2*nc) internal_error("too few cases in declension");
+ if (c > 2*nc) internal_error("too many cases in declension");
+ return D;
+ }
+ }
+ internal_error("declination unavailable");
+ return D;
+}
diff --git a/services/inflections-module/Chapter 2/Linguistic Definitions.w b/services/inflections-module/Chapter 3/Linguistic Constants.w
similarity index 68%
rename from services/inflections-module/Chapter 2/Linguistic Definitions.w
rename to services/inflections-module/Chapter 3/Linguistic Constants.w
index 2e9bee9a8..9314c7b30 100644
--- a/services/inflections-module/Chapter 2/Linguistic Definitions.w
+++ b/services/inflections-module/Chapter 3/Linguistic Constants.w
@@ -1,4 +1,4 @@
-[InflectionDefns::] Linguistic Definitions.
+[InflectionDefns::] Linguistic Constants.
Some basic linguistic constants are defined.
@@ -45,12 +45,12 @@ which is required to be case 0.
in English. Some languages can use optional extras; French, for example, uses
tense 5 for the past historic.
-@d NO_KNOWN_TENSES 7 /* allowing for two optional extras in non-English languages */
-@d IS_TENSE 0 /* Present */
-@d WAS_TENSE 1 /* Past */
-@d HASBEEN_TENSE 2 /* Present perfect */
-@d HADBEEN_TENSE 3 /* Past perfect */
-@d WILLBE_TENSE 4 /* Future (not used in assertions or conditions) */
+@d NO_KNOWN_TENSES 7
+@d IS_TENSE 0 /* Present */
+@d WAS_TENSE 1 /* Past */
+@d HASBEEN_TENSE 2 /* Present perfect */
+@d HADBEEN_TENSE 3 /* Past perfect */
+@d WILLBE_TENSE 4 /* Future (not used in assertions or conditions) */
@d CUSTOM1_TENSE 5
@d CUSTOM2_TENSE 6
@@ -67,19 +67,3 @@ void InflectionDefns::log_tense_number(OUTPUT_STREAM, int t) {
default: WRITE(""); break;
}
}
-
-@h A default language.
-The following is in effect also a constant; Inform sets it to English early
-in its run.
-
-=
-NATURAL_LANGUAGE_WORDS_TYPE *default_language_for_linguistics = NULL;
-
-void InflectionDefns::set_default_nl(NATURAL_LANGUAGE_WORDS_TYPE *nl) {
- default_language_for_linguistics = nl;
-}
-
-NATURAL_LANGUAGE_WORDS_TYPE *InflectionDefns::default_nl(NATURAL_LANGUAGE_WORDS_TYPE *nl) {
- if (nl) return nl;
- return default_language_for_linguistics;
-}
diff --git a/services/inflections-module/Chapter 3/Name Clusters.w b/services/inflections-module/Chapter 3/Name Clusters.w
index 7d4ffe775..7357339ce 100644
--- a/services/inflections-module/Chapter 3/Name Clusters.w
+++ b/services/inflections-module/Chapter 3/Name Clusters.w
@@ -41,10 +41,10 @@ name_cluster *Clusters::new(void) {
=
individual_name *Clusters::add_one(name_cluster *names, wording W,
NATURAL_LANGUAGE_WORDS_TYPE *nl, int gender, int number) {
- nl = InflectionDefns::default_nl(nl);
+ nl = DefaultLanguage::get(nl);
individual_name *in = CREATE(individual_name);
in->principal_meaning = NULL_GENERAL_POINTER;
- in->name = Declensions::decline(W, nl, gender, number);
+ in->name = Declensions::of_noun(W, nl, gender, number);
in->name_language = nl;
in->name_number = number;
in->name_gender = gender;
@@ -94,8 +94,8 @@ combinations. Here we only work through six, ignoring animation:
=
void Clusters::add_with_agreements(name_cluster *cl, wording W,
NATURAL_LANGUAGE_WORDS_TYPE *nl) {
- nl = InflectionDefns::default_nl(nl);
- if (nl == InflectionDefns::default_nl(NULL))
+ nl = DefaultLanguage::get(nl);
+ if (nl == DefaultLanguage::get(NULL))
Clusters::add(cl, W, nl, NEUTER_GENDER, 1, FALSE);
else
for (int gna = 0; gna < 6; gna++)
@@ -133,13 +133,13 @@ through one or two tries.
@ =
word_assemblage wa = WordAssemblages::from_wording(W);
if (step1)
- wa = Inflections::apply_trie_to_wa(wa,
+ wa = Inflect::first_word(wa,
PreformUtilities::define_trie(step1, TRIE_END,
- InflectionDefns::default_nl(nl)));
+ DefaultLanguage::get(nl)));
if (step2)
- wa = Inflections::apply_trie_to_wa(wa,
+ wa = Inflect::first_word(wa,
PreformUtilities::define_trie(step2, TRIE_END,
- InflectionDefns::default_nl(nl)));
+ DefaultLanguage::get(nl)));
FW = WordAssemblages::to_wording(&wa);
@h Plural fixing.
@@ -155,7 +155,7 @@ void Clusters::set_plural_name(name_cluster *cl, wording W,
individual_name *in;
LOOP_OVER_LINKED_LIST(in, individual_name, cl->listed)
if (in->name_number == 2) {
- in->name = Declensions::decline(W, nl, NEUTER_GENDER, 2);
+ in->name = Declensions::of_noun(W, nl, NEUTER_GENDER, 2);
return;
}
Clusters::add(cl, W, NULL, NEUTER_GENDER, 2, FALSE);
diff --git a/services/inflections-module/Chapter 3/Verb Conjugation.w b/services/inflections-module/Chapter 3/Verb Conjugation.w
index c2268a807..ce574ac58 100644
--- a/services/inflections-module/Chapter 3/Verb Conjugation.w
+++ b/services/inflections-module/Chapter 3/Verb Conjugation.w
@@ -34,12 +34,97 @@ typedef struct verb_tabulation {
int modal_auxiliary_usage[NO_KNOWN_TENSES][2][6];
} verb_tabulation;
+@h Finding.
+Most of the time, conjugations can be identified by their infinitives:
+
+=
+verb_conjugation *Conjugation::find_by_infinitive(word_assemblage infinitive) {
+ verb_conjugation *vc;
+ LOOP_OVER(vc, verb_conjugation)
+ if (WordAssemblages::eq(&infinitive, &(vc->infinitive)))
+ return vc;
+ return NULL;
+}
+
+@ But in fact multiple conjugations can be given with the same infinitive...
+
+=
+verb_conjugation *Conjugation::find_prior(verb_conjugation *nvc) {
+ if (nvc == NULL) return NULL;
+ verb_conjugation *vc;
+ LOOP_OVER(vc, verb_conjugation)
+ if ((vc != nvc) && (Conjugation::eq(nvc, vc)))
+ return vc;
+ return NULL;
+}
+
+@ ...and those may or may not be identical, so a more detailed test is:
+
+=
+int Conjugation::eq(verb_conjugation *nvc, verb_conjugation *vc) {
+ if ((WordAssemblages::eq(&(nvc->infinitive), &(vc->infinitive))) &&
+ (WordAssemblages::eq(&(nvc->past_participle), &(vc->past_participle))) &&
+ (WordAssemblages::eq(&(nvc->present_participle), &(vc->present_participle)))) {
+ for (int i=0; itabulations[i]);
+ verb_tabulation *vt = &(vc->tabulations[i]);
+ if (WordAssemblages::eq(
+ &(nvt->to_be_auxiliary), &(vt->to_be_auxiliary)) == FALSE) return FALSE;
+ for (int p=0; p<6; p++)
+ for (int s=0; s<2; s++)
+ for (int t=0; tvc_text[t][s][p]), &(vt->vc_text[t][s][p])) == FALSE)
+ return FALSE;
+ if (nvt->modal_auxiliary_usage[t][s][p] !=
+ vt->modal_auxiliary_usage[t][s][p]) return FALSE;
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+@ The following prints out a tidy form of a verb conjugation table:
+
+=
+void Conjugation::write(OUTPUT_STREAM, verb_conjugation *vc) {
+ WRITE("Infinitive: %A / Present participle: %A / Past participle: %A^",
+ &(vc->infinitive), &(vc->present_participle), &(vc->past_participle));
+ int mood_count = 2;
+ if (WordAssemblages::nonempty(vc->tabulations[PASSIVE_MOOD].to_be_auxiliary))
+ mood_count = 1;
+ int mood, sense, tense, person;
+ for (mood=0; moodtabulations[ACTIVE_MOOD].vc_text[tense][sense][person]);
+ else
+ wa = &(vc->tabulations[PASSIVE_MOOD].vc_text[tense][sense][person]);
+ if (person > 0) WRITE(" / ");
+ if (WordAssemblages::nonempty(*wa)) WRITE("%A", wa);
+ else WRITE("--");
+ }
+ WRITE("^");
+ }
+ }
+ }
+ if (WordAssemblages::nonempty(vc->tabulations[PASSIVE_MOOD].to_be_auxiliary))
+ WRITE("Form passive as to be + %A\n",
+ &(vc->tabulations[PASSIVE_MOOD].to_be_auxiliary));
+}
+
@h Making conjugations.
The following will make more sense if read alongside the examples in "English
-Inflections", which explains the format in full. In fact English itself is a
-little tame, though -- try the French Language extension for the real deal.
+Inflections", which explains the format in full.
-The crucial early step here is |Conjugation::follow_instructions|, which has
+The crucial early step here is //Conjugation::follow_instructions//, which has
two tasks to perform: it works out the numbered verb forms, and it chooses
which tabulation will be used. Verb form number 0 is always the base text,
and subsequent numbers include some which are universal across all verbs
@@ -54,7 +139,7 @@ verb_conjugation *Conjugation::conjugate(word_assemblage base_text,
verb_conjugation *Conjugation::conjugate_with_overrides(word_assemblage base_text,
word_assemblage *overrides, int no_overrides, NATURAL_LANGUAGE_WORDS_TYPE *nl) {
- nl = InflectionDefns::default_nl(nl);
+ nl = DefaultLanguage::get(nl);
if (WordAssemblages::nonempty(base_text) == FALSE)
internal_error("No base text for verb conjugation");
@@ -120,14 +205,16 @@ Note that verb form 0 can't be overridden: that was the base text.
for (tense=0; tensetabulations[ACTIVE_MOOD].vc_text[tense][sense][i] = WordAssemblages::lit_0();
- vc->tabulations[PASSIVE_MOOD].vc_text[tense][sense][i] = WordAssemblages::lit_0();
+ vc->tabulations[ACTIVE_MOOD].vc_text[tense][sense][i] =
+ WordAssemblages::lit_0();
+ vc->tabulations[PASSIVE_MOOD].vc_text[tense][sense][i] =
+ WordAssemblages::lit_0();
}
@ A tabulation is a sort of program laying out what to put in which slots,
active or passive. Each production is a step in this program, and it consists
of a "selector" followed by a "line". For example, the production:
-= (text as InC)
+= (text as Preform)
a3 ( t1 avoir ) 3+*
=
contains six tokens; the selector is |a3|, and the line is made up from the
@@ -141,7 +228,8 @@ rest. (The selector is always just a single token.)
for (pr = pl->first_pr; pr; pr = pr->next_pr) {
ptoken *selector = pr->first_pt;
ptoken *line = (selector)?(selector->next_pt):NULL;
- if ((selector) && (selector->ptoken_category == FIXED_WORD_PTC) && (line)) {
+ if ((selector) && (selector->ptoken_category == FIXED_WORD_PTC) &&
+ (line)) {
@;
} else Conjugation::error(base_text, tabulation, pr,
"tabulation row doesn't consist of a selector and then text");
@@ -157,22 +245,25 @@ rest. (The selector is always just a single token.)
vc->tabulations[PASSIVE_MOOD].to_be_auxiliary =
Conjugation::merge(line, 0, 0, 0, MAX_FORM_TYPES+1, verb_forms, nl, NULL);
- int person, tense, sense;
- for (tense=0; tense= 0) && (sense != sense_set)) continue;
if ((tense_set >= 0) && (tense != tense_set)) continue;
- if (active_set)
- vc->tabulations[ACTIVE_MOOD].vc_text[tense][sense][person] =
- Conjugation::merge(line, sense, tense, person, MAX_FORM_TYPES+1, verb_forms, nl,
- &(vc->tabulations[ACTIVE_MOOD].modal_auxiliary_usage[tense][sense][person]));
- else
- vc->tabulations[PASSIVE_MOOD].vc_text[tense][sense][person] =
- Conjugation::merge(line, sense, tense, person, MAX_FORM_TYPES+1, verb_forms, nl,
- &(vc->tabulations[PASSIVE_MOOD].modal_auxiliary_usage[tense][sense][person]));
+ if (active_set) @
+ else @;
}
+@ =
+ vc->tabulations[ACTIVE_MOOD].vc_text[tense][sense][person] =
+ Conjugation::merge(line, sense, tense, person, MAX_FORM_TYPES+1, verb_forms, nl,
+ &(vc->tabulations[ACTIVE_MOOD].modal_auxiliary_usage[tense][sense][person]));
+
+@ =
+ vc->tabulations[PASSIVE_MOOD].vc_text[tense][sense][person] =
+ Conjugation::merge(line, sense, tense, person, MAX_FORM_TYPES+1, verb_forms, nl,
+ &(vc->tabulations[PASSIVE_MOOD].modal_auxiliary_usage[tense][sense][person]));
+
@ The selector tells us which tense(s), sense(s) and mood(s) to apply the
line to; |a3|, for example, means active mood, tense 3, in both positive
and negative senses.
@@ -198,19 +289,24 @@ and negative senses.
"unrecognised selector in tabulation row");
}
-@ =
+@ This routine is really an interloper from //core//. It provides the run-time
+values representing verbs in story files compiled by Inform.
+
+=
#ifdef CORE_MODULE
inter_name *Conjugation::conj_iname(verb_conjugation *vc) {
if (vc->vc_iname == NULL) {
if (vc->vc_conjugates == NULL) {
- package_request *R = Hierarchy::package(Modules::find(vc->where_vc_created), MVERBS_HAP);
+ package_request *R =
+ Hierarchy::package(Modules::find(vc->where_vc_created), MVERBS_HAP);
TEMPORARY_TEXT(ANT);
WRITE_TO(ANT, "%A (modal)", vc->tabulations[ACTIVE_MOOD].vc_text[0][0][2]);
Hierarchy::markup(R, MVERB_NAME_HMD, ANT);
DISCARD_TEXT(ANT);
vc->vc_iname = Hierarchy::make_iname_in(MODAL_CONJUGATION_FN_HL, R);
} else {
- package_request *R = Verbs::verb_package(vc->vc_conjugates, vc->where_vc_created);
+ package_request *R =
+ Verbs::verb_package(vc->vc_conjugates, vc->where_vc_created);
TEMPORARY_TEXT(ANT);
WRITE_TO(ANT, "to %A", vc->infinitive);
Hierarchy::markup(R, VERB_NAME_HMD, ANT);
@@ -236,8 +332,9 @@ which chooses the conjugation ||, which in turn sets some
participles and then chooses the tabulation ||.
=
-nonterminal *Conjugation::follow_instructions(word_assemblage *verb_forms, int *highest_form_written,
- int *aux_len, int *avo_flag, int *niv_flag, NATURAL_LANGUAGE_WORDS_TYPE *nl) {
+nonterminal *Conjugation::follow_instructions(word_assemblage *verb_forms,
+ int *highest_form_written, int *aux_len, int *avo_flag, int *niv_flag,
+ NATURAL_LANGUAGE_WORDS_TYPE *nl) {
nonterminal *instructions_nt = ;
nonterminal *tabulation_nt = NULL, *conjugation_nt = NULL;
*highest_form_written = 1;
@@ -271,13 +368,13 @@ nonterminal *Conjugation::follow_instructions(word_assemblage *verb_forms, int *
@ Each production in this language's || grammar
consists of a (possibly empty) pattern to match, followed by the name of a
nonterminal to use as the conjugation if it matches. For example, in
-= (text as InC)
+= (text as Preform)
-querir
=
the pattern part is a single token, |-querir|, which matches if the base text
is a single word whose last six characters are "querir". A more complicated
case is:
-= (text as InC)
+= (text as Preform)
be able to ...
=
Here the wildcard |...| matches one or more words, and the "auxiliary
@@ -296,7 +393,8 @@ infinitive" form is set to the part matched by |...|: for example,
conjugation_nt = last->nt_pt;
verb_forms[ADJOINT_INFINITIVE_FORM_TYPE] = verb_forms[BASE_FORM_TYPE];
if (wildcard_from > 0)
- WordAssemblages::truncate(&(verb_forms[ADJOINT_INFINITIVE_FORM_TYPE]), wildcard_from);
+ WordAssemblages::truncate(
+ &(verb_forms[ADJOINT_INFINITIVE_FORM_TYPE]), wildcard_from);
*aux_len = wildcard_from;
}
}
@@ -376,9 +474,10 @@ example:
if (n > *highest_form_written) { *highest_form_written = n; }
if (content_token->ptoken_category == NONTERMINAL_PTC)
verb_forms[n] =
- Inflections::apply_trie_to_wa(
+ Inflect::first_word(
verb_forms[BASE_FORM_TYPE],
- PreformUtilities::define_trie(content_token->nt_pt, TRIE_END, InflectionDefns::default_nl(nl)));
+ PreformUtilities::define_trie(content_token->nt_pt,
+ TRIE_END, DefaultLanguage::get(nl)));
else if (content_token->ptoken_category == FIXED_WORD_PTC)
verb_forms[n] =
Conjugation::expand_with_endings(content_token->ve_pt, verb_forms);
@@ -392,11 +491,11 @@ and we have to copy that text into a word assemblage and return it.
In theory that's a one-line routine, but it's made complicated by the number
of special syntaxes which can go into the row of text. For example, if |row|
is only
-= (text as InC)
+= (text as Preform)
will not do
=
then the word assemblage comes out to just "will not do"; but if it is
-= (text as InC)
+= (text as Preform)
( t1 auxiliary-have ) done
=
then we consult tense 1 (present) of the verb "auxiliary-have", extract
@@ -432,7 +531,8 @@ and might expand |3+ed| to "trailed".
@ =
if (chunk->ptoken_category == FIXED_WORD_PTC) {
- wa = WordAssemblages::join(wa, Conjugation::expand_with_endings(chunk->ve_pt, ingredients));
+ wa = WordAssemblages::join(wa,
+ Conjugation::expand_with_endings(chunk->ve_pt, ingredients));
continue;
}
@@ -452,8 +552,8 @@ make use of the same fancy features we're allowing here.
for (pr = pl->first_pr; pr; pr = pr->next_pr) {
if (N == person)
wa = WordAssemblages::join(wa,
- Conjugation::merge(pr->first_pt,
- sense, tense, person, num_ingredients, ingredients, nl, NULL));
+ Conjugation::merge(pr->first_pt, sense, tense, person,
+ num_ingredients, ingredients, nl, NULL));
N++;
}
}
@@ -461,7 +561,7 @@ make use of the same fancy features we're allowing here.
}
@ A number followed by a verb in brackets, like so:
-= (text as InC)
+= (text as Preform)
3 ( avoir )
=
expands to verb form 3 of this verb -- the past participle of "avoir", which
@@ -480,15 +580,15 @@ on the next iteration.
set, in which case we should lift a verb form, or we might not, in which case
we should lift an ordinary usage, such as third-person singular in a particular
tense. A lift can optionally change tense or sense: for example,
-= (text as InC)
+= (text as Preform)
( t1 have )
=
lifts from the present tense of "to have". If there's no tense indicator,
the tense remains the current one. (It's also possible to change the sense from
positive to negative or vice versa with this, though I can't think of a
language where this would be useful.) Note that, once again, the text of the
-infinitive passes through |Conjugation::expand_with_endings|, so that it can make use
-of the numbered verb forms if we want it to.
+infinitive passes through |Conjugation::expand_with_endings|, so that it can
+make use of the numbered verb forms if we want it to.
@ =
if (Conjugation::ptoken_as_bracket(chunk) == 1) {
@@ -515,8 +615,8 @@ of the numbered verb forms if we want it to.
case 1: wa = WordAssemblages::join(wa, aux->infinitive); break;
case 2: wa = WordAssemblages::join(wa, aux->present_participle); break;
case 3: wa = WordAssemblages::join(wa, aux->past_participle); break;
- case -1: wa = WordAssemblages::join(wa, aux->tabulations[ACTIVE_MOOD].vc_text[T][S][person]);
- break;
+ case -1: wa = WordAssemblages::join(wa,
+ aux->tabulations[ACTIVE_MOOD].vc_text[T][S][person]); break;
default: internal_error("only parts 1, 2, 3 can be extracted");
}
continue;
@@ -525,7 +625,8 @@ of the numbered verb forms if we want it to.
@ =
if (chunk->ptoken_category == FIXED_WORD_PTC) {
wchar_t *p = Vocabulary::get_exemplar(chunk->ve_pt, TRUE);
- if ((p[0] == '+') && (p[1] == '+') && (Characters::isdigit(p[2])) && (p[3] == 0)) {
+ if ((p[0] == '+') && (p[1] == '+') && (Characters::isdigit(p[2])) &&
+ (p[3] == 0)) {
if (modal_following) {
*modal_following = ((int) p[2]) - ((int) '0');
}
@@ -540,7 +641,8 @@ participle); a plus sign joins two pieces together; and a tilde is a tie,
joining but with a space. Thus |fish~to~fry| becomes three words.
=
-word_assemblage Conjugation::expand_with_endings(vocabulary_entry *ve, word_assemblage *verb_forms) {
+word_assemblage Conjugation::expand_with_endings(vocabulary_entry *ve,
+ word_assemblage *verb_forms) {
if (ve == NULL) return WordAssemblages::lit_0();
wchar_t *p = Vocabulary::get_exemplar(ve, TRUE);
@@ -571,20 +673,20 @@ word_assemblage Conjugation::expand_with_endings(vocabulary_entry *ve, word_asse
@ The final step in merging verb material is to pass the result through the
following, which attends to contractions. (Most of the time it does nothing.)
For example, suppose we have:
-= (text as InC)
+= (text as Preform)
ne-' ai pas
=
The |-'| marker tells us that the word it attaches to should contract if a
vowel follows it. In this case that's what happens, so we convert to:
-= (text as InC)
+= (text as Preform)
n'ai pas
=
On the other hand,
-= (text as InC)
+= (text as Preform)
ne-' jette pas
=
would convert to
-= (text as InC)
+= (text as Preform)
ne jette pas
=
with no contraction. Either way, though, we have to take some action when
@@ -665,13 +767,15 @@ int Conjugation::ptoken_to_tense_indicator(ptoken *pt, int *set_sense) {
int N = p[1] - '1' + 1;
if ((N >= 1) && (N <= NO_KNOWN_TENSES)) return N;
}
- if ((p[0] == 't') && (Characters::isdigit(p[1])) && (p[2] == '+') && (p[3] == 0)) {
+ if ((p[0] == 't') && (Characters::isdigit(p[1])) &&
+ (p[2] == '+') && (p[3] == 0)) {
int N = p[1] - '1' + 1;
if ((N >= 1) && (N <= NO_KNOWN_TENSES)) {
*set_sense = 0; return N;
}
}
- if ((p[0] == 't') && (Characters::isdigit(p[1])) && (p[2] == '-') && (p[3] == 0)) {
+ if ((p[0] == 't') && (Characters::isdigit(p[1])) &&
+ (p[2] == '-') && (p[3] == 0)) {
int N = p[1] - '1' + 1;
if ((N >= 1) && (N <= NO_KNOWN_TENSES)) {
*set_sense = 1; return N;
@@ -735,76 +839,13 @@ void Conjugation::test(OUTPUT_STREAM, wording W, NATURAL_LANGUAGE_WORDS_TYPE *nl
DESTROY(vc, verb_conjugation);
}
-void Conjugation::write(OUTPUT_STREAM, verb_conjugation *vc) {
- WRITE("Infinitive: %A / Present participle: %A / Past participle: %A^",
- &(vc->infinitive), &(vc->present_participle), &(vc->past_participle));
- int mood_count = 2;
- if (WordAssemblages::nonempty(vc->tabulations[PASSIVE_MOOD].to_be_auxiliary)) mood_count = 1;
- int mood, sense, tense, person;
- for (mood=0; moodtabulations[ACTIVE_MOOD].vc_text[tense][sense][person]);
- else wa = &(vc->tabulations[PASSIVE_MOOD].vc_text[tense][sense][person]);
- if (person > 0) WRITE(" / ");
- if (WordAssemblages::nonempty(*wa)) WRITE("%A", wa);
- else WRITE("--");
- }
- WRITE("^");
- }
- }
- }
- if (WordAssemblages::nonempty(vc->tabulations[PASSIVE_MOOD].to_be_auxiliary))
- WRITE("Form passive as to be + %A\n", &(vc->tabulations[PASSIVE_MOOD].to_be_auxiliary));
-}
-
-verb_conjugation *Conjugation::find_by_infinitive(word_assemblage infinitive) {
- verb_conjugation *vc;
- LOOP_OVER(vc, verb_conjugation)
- if (WordAssemblages::compare(&infinitive, &(vc->infinitive)))
- return vc;
- return NULL;
-}
-
-verb_conjugation *Conjugation::find_prior(verb_conjugation *nvc) {
- if (nvc == NULL) return NULL;
- verb_conjugation *vc;
- LOOP_OVER(vc, verb_conjugation) {
- if (vc != nvc) {
- if (WordAssemblages::compare(&(nvc->infinitive), &(vc->infinitive)) == FALSE) continue;
- if (WordAssemblages::compare(&(nvc->past_participle), &(vc->past_participle)) == FALSE) continue;
- if (WordAssemblages::compare(&(nvc->present_participle), &(vc->present_participle)) == FALSE) continue;
- int match = TRUE;
- for (int i=0; itabulations[i]);
- verb_tabulation *vt = &(vc->tabulations[i]);
- if (WordAssemblages::compare(&(nvt->to_be_auxiliary), &(vt->to_be_auxiliary)) == FALSE) match = FALSE;
- for (int p=0; p<6; p++)
- for (int s=0; s<2; s++)
- for (int t=0; tvc_text[t][s][p]), &(vt->vc_text[t][s][p])) == FALSE) match = FALSE;
- if (nvt->modal_auxiliary_usage[t][s][p] != vt->modal_auxiliary_usage[t][s][p]) match = FALSE;
- }
- }
- if (match == FALSE) continue;
- return vc;
- }
- }
- return NULL;
-}
-
@ This is for testing English only; it helps with the test suite cases derived
from our dictionary of 14,000 or so present and past participles.
=
void Conjugation::test_participle(OUTPUT_STREAM, wording W) {
verb_conjugation *vc = Conjugation::conjugate(
- WordAssemblages::from_wording(W), InflectionDefns::default_nl(NULL));
+ WordAssemblages::from_wording(W), DefaultLanguage::get(NULL));
if (vc == NULL) { WRITE("Failed test\n"); return; }
Conjugation::write_participle(OUT, vc);
DESTROY(vc, verb_conjugation);
diff --git a/services/inflections-module/Chapter 4/Default Language.w b/services/inflections-module/Chapter 4/Default Language.w
new file mode 100644
index 000000000..63c3f6e08
--- /dev/null
+++ b/services/inflections-module/Chapter 4/Default Language.w
@@ -0,0 +1,17 @@
+[DefaultLanguage::] Default Language.
+
+To keep track of what the default natural language is.
+
+@ The following mechanism may become more sophisticated later.
+
+=
+NATURAL_LANGUAGE_WORDS_TYPE *default_language_for_linguistics = NULL;
+
+void DefaultLanguage::set(NATURAL_LANGUAGE_WORDS_TYPE *nl) {
+ default_language_for_linguistics = nl;
+}
+
+NATURAL_LANGUAGE_WORDS_TYPE *DefaultLanguage::get(NATURAL_LANGUAGE_WORDS_TYPE *nl) {
+ if (nl) return nl;
+ return default_language_for_linguistics;
+}
diff --git a/services/inflections-module/Chapter 4/English Inflections.w b/services/inflections-module/Chapter 4/English Inflections.w
index 7c0e5ac22..9489aa4a2 100644
--- a/services/inflections-module/Chapter 4/English Inflections.w
+++ b/services/inflections-module/Chapter 4/English Inflections.w
@@ -1,4 +1,4 @@
-[Inflections::] English Inflections.
+[Inflect::] English Inflections.
To define how English nouns and verbs are inflected.
@@ -21,138 +21,138 @@ dictionary and the "Official Scrabble Wordlist".
=
::=
- oneir* an |
- onero* an |
- ukiyo-e an | /* Japanese style of 17th-19th cent. printmaking */
- urao* an |
- urial* an |
- uvarovite* an /* a rare emerald-green garnet, Ca3Cr2(SiO4)3 */
+ oneir* an |
+ onero* an |
+ ukiyo-e an | /* Japanese style of 17th-19th cent. printmaking */
+ urao* an |
+ urial* an |
+ uvarovite* an /* a rare emerald-green garnet, Ca3Cr2(SiO4)3 */
@ Then the exceptions:
=
::=
- eu* a | /* e.g., euphoria, eulogy */
- ewe* a | /* female sheep */
- ewftes a | /* Spens. form of an eft lizard */
- ewghen a | /* made of yew, i.e., yewen */
- ewk a |
- houri a |
- once* a | /* a Once and Future King */
- one* a | /* but still use an for oneir- and onero- */
- onst a | /* dialect form of once */
- oui* a | /* e.g., a Ouija board or a ouistiti (a marmoset) */
- u a | /* the letter U */
- u-* a | /* e.g., U-boats */
- u'* a | /* e.g., u's */
- uakari a | /* the South American monkey */
- ub* a | /* e.g., ubiquitous */
- udal* a |
- udomet* a |
- uey a | /* colloquial for "U-turn", as in "he pulled a uey" */
- ueys a |
- ufo* a |
- uganda* a | /* the county Uganda */
- ugr* a |
- uint* a |
- uk* a |
- ulex a | /* the genus of gorse */
- uli* a |
- ulo* a |
- ulu* a |
- una a | /* from "una corda", the musical term */
- unabomb* a | /* the so-called Unabomber */
- unalist a |
- unanimit* a |
- unanimous* a |
- unesco a | /* the United Nations cultural body */
- unescos a |
- unia* a |
- unic* a |
- unif* a |
- unig* a |
- unil* a |
- unio* a |
- unip* a |
- uniq* a |
- unis* a |
- unit* a |
- univ* a |
- upas* a |
- ura* a |
- ure* a |
- uri* a |
- uru* a |
- usa* a |
- use* a |
- usi* a |
- usu* a |
- utas* a |
- ute* a |
- uti* a |
- uto* a |
- utr* a |
- uttoxeter* a | /* the English town of Uttoxeter */
- uva* a |
- uvu* a
+ eu* a | /* e.g., euphoria, eulogy */
+ ewe* a | /* female sheep */
+ ewftes a | /* Spens. form of an eft lizard */
+ ewghen a | /* made of yew, i.e., yewen */
+ ewk a |
+ houri a |
+ once* a | /* a Once and Future King */
+ one* a | /* but still use an for oneir- and onero- */
+ onst a | /* dialect form of once */
+ oui* a | /* e.g., a Ouija board or a ouistiti (a marmoset) */
+ u a | /* the letter U */
+ u-* a | /* e.g., U-boats */
+ u'* a | /* e.g., u's */
+ uakari a | /* the South American monkey */
+ ub* a | /* e.g., ubiquitous */
+ udal* a |
+ udomet* a |
+ uey a | /* colloquial for "U-turn", as in "he pulled a uey" */
+ ueys a |
+ ufo* a |
+ uganda* a | /* the country Uganda */
+ ugr* a |
+ uint* a |
+ uk* a |
+ ulex a | /* the genus of gorse */
+ uli* a |
+ ulo* a |
+ ulu* a |
+ una a | /* from "una corda", the musical term */
+ unabomb* a | /* the so-called Unabomber */
+ unalist a |
+ unanimit* a |
+ unanimous* a |
+ unesco a | /* the United Nations cultural body */
+ unescos a |
+ unia* a |
+ unic* a |
+ unif* a |
+ unig* a |
+ unil* a |
+ unio* a |
+ unip* a |
+ uniq* a |
+ unis* a |
+ unit* a |
+ univ* a |
+ upas* a |
+ ura* a |
+ ure* a |
+ uri* a |
+ uru* a |
+ usa* a |
+ use* a |
+ usi* a |
+ usu* a |
+ utas* a |
+ ute* a |
+ uti* a |
+ uto* a |
+ utr* a |
+ uttoxeter* a | /* the English town of Uttoxeter */
+ uva* a |
+ uvu* a
@ And finally the basic rules:
=
::=
- a* an |
- e* an |
- i* an |
- o* an |
- u* an |
- f an |
- f's an |
- f-* an |
- fbi an |
- fo an |
- frs an |
- h an |
- h's an |
- h-* an | /* e.g., H-bomb */
- haute* an | /* e.g., haute cuisine, hauteur */
- heir* an |
- hono* an | /* e.g., honorific, honorary doctorate */
- hour* an |
- l an |
- l's an |
- l-* an | /* e.g., L-plate */
- m an |
- m's an |
- m-* an | /* e.g., M-ration */
- n an |
- n's an |
- n-* an | /* e.g., N-dimensional manifold */
- r an |
- r's an |
- r-* an |
- rac an | /* Royal Automobile Club */
- raf an | /* Royal Air Force */
- rspca an | /* Royal Society for the Prevention of Cruelty to Animals */
- rsvp an |
- s an |
- s's an |
- s-* an |
- x an |
- x's an |
- x-* an | /* e.g., X-ray */
- xmas* an |
- yb* an | /* these are mostly obs., Spens., and/or arch. */
- yc* an |
- yd* an |
- yf* an |
- yg* an |
- ym* an |
- yn* an |
- yp* an | /* e.g., ypsilon */
- yr* an |
- ys* an |
- yt* an | /* e.g., Ytterbium, Yttrium */
- yw* an
+ a* an |
+ e* an |
+ i* an |
+ o* an |
+ u* an |
+ f an |
+ f's an |
+ f-* an |
+ fbi an |
+ fo an |
+ frs an |
+ h an |
+ h's an |
+ h-* an | /* e.g., H-bomb */
+ haute* an | /* e.g., haute cuisine, hauteur */
+ heir* an |
+ hono* an | /* e.g., honorific, honorary doctorate */
+ hour* an |
+ l an |
+ l's an |
+ l-* an | /* e.g., L-plate */
+ m an |
+ m's an |
+ m-* an | /* e.g., M-ration */
+ n an |
+ n's an |
+ n-* an | /* e.g., N-dimensional manifold */
+ r an |
+ r's an |
+ r-* an |
+ rac an | /* Royal Automobile Club */
+ raf an | /* Royal Air Force */
+ rspca an | /* Royal Society for the Prevention of Cruelty to Animals */
+ rsvp an |
+ s an |
+ s's an |
+ s-* an |
+ x an |
+ x's an |
+ x-* an | /* e.g., X-ray */
+ xmas* an |
+ yb* an | /* these are mostly obs., Spens., and/or arch. */
+ yc* an |
+ yd* an |
+ yf* an |
+ yg* an |
+ ym* an |
+ yn* an |
+ yp* an | /* e.g., ypsilon */
+ yr* an |
+ ys* an |
+ yt* an | /* e.g., Ytterbium, Yttrium */
+ yw* an
@h Plural inflections.
The following takes a single word, assumes it to be a noun which meaningfully
@@ -201,102 +201,102 @@ have the same plural as singular form: for example, chamois, salmon, goldfish.
=
::=
- *fish 0 |
- *ois 0 |
- *sheep 0 |
- *deer 0 |
- *pox 0 |
- *itis 0 |
- bison 0 |
- flounder 0 |
- pliers 0 |
- bream 0 |
- gallows 0 |
- proceedings 0 |
- breeches 0 |
- graffiti 0 |
- rabies 0 |
- britches 0 |
- headquarters 0 |
- salmon 0 |
- carp 0 |
- herpes 0 |
- scissors 0 |
- chassis 0 |
- high-jinks 0 |
- sea-bass 0 |
- clippers 0 |
- homework 0 |
- series 0 |
- cod 0 |
- innings 0 |
- shears 0 |
- contretemps 0 |
- jackanapes 0 |
- species 0 |
- corps 0 |
- mackerel 0 |
- swine 0 |
- debris 0 |
- measles 0 |
- trout 0 |
- diabetes 0 |
- mews 0 |
- tuna 0 |
- djinn 0 |
- mumps 0 |
- whiting 0 |
- eland 0 |
- news 0 |
- wildebeest 0 |
- elk 0 |
- pincers 0
+ *fish 0 |
+ *ois 0 |
+ *sheep 0 |
+ *deer 0 |
+ *pox 0 |
+ *itis 0 |
+ bison 0 |
+ flounder 0 |
+ pliers 0 |
+ bream 0 |
+ gallows 0 |
+ proceedings 0 |
+ breeches 0 |
+ graffiti 0 |
+ rabies 0 |
+ britches 0 |
+ headquarters 0 |
+ salmon 0 |
+ carp 0 |
+ herpes 0 |
+ scissors 0 |
+ chassis 0 |
+ high-jinks 0 |
+ sea-bass 0 |
+ clippers 0 |
+ homework 0 |
+ series 0 |
+ cod 0 |
+ innings 0 |
+ shears 0 |
+ contretemps 0 |
+ jackanapes 0 |
+ species 0 |
+ corps 0 |
+ mackerel 0 |
+ swine 0 |
+ debris 0 |
+ measles 0 |
+ trout 0 |
+ diabetes 0 |
+ mews 0 |
+ tuna 0 |
+ djinn 0 |
+ mumps 0 |
+ whiting 0 |
+ eland 0 |
+ news 0 |
+ wildebeest 0 |
+ elk 0 |
+ pincers 0
@ We may as well pluralise pronouns while we're at it.
=
::=
- i we |
- you you |
- thou you |
- she they |
- he they |
- it they |
- they they |
- me us |
- you you |
- thee you |
- her them |
- him them |
- it them |
- them them |
- myself ourselves |
- yourself yourself |
- thyself yourself |
- herself themselves |
- himself themselves |
- itself themselves |
- themself themselves |
- oneself oneselves
+ i we |
+ you you |
+ thou you |
+ she they |
+ he they |
+ it they |
+ they they |
+ me us |
+ you you |
+ thee you |
+ her them |
+ him them |
+ it them |
+ them them |
+ myself ourselves |
+ yourself yourself |
+ thyself yourself |
+ herself themselves |
+ himself themselves |
+ itself themselves |
+ themself themselves |
+ oneself oneselves
@ We now reach Conway step 4. These are irregular plurals mostly coming
from archaisms.
=
::=
- beef beefs | /* we neglect the classical "beeves" */
- brother brothers | /* and "brethren" */
- child children |
- cow cows | /* and "kine" */
- ephemeris ephemerides |
- genie genies | /* and "genii" */
- money moneys | /* and "monies" */
- mongoose mongooses |
- mythos mythoi |
- octopus octopuses | /* and "octopodes" */
- ox oxen |
- soliloquy soliloquies |
- trilby trilbys
+ beef beefs | /* we neglect the classical "beeves" */
+ brother brothers | /* and "brethren" */
+ child children |
+ cow cows | /* and "kine" */
+ ephemeris ephemerides |
+ genie genies | /* and "genii" */
+ money moneys | /* and "monies" */
+ mongoose mongooses |
+ mythos mythoi |
+ octopus octopuses | /* and "octopodes" */
+ ox oxen |
+ soliloquy soliloquies |
+ trilby trilbys
@ Step 5. Now we reach a batch of irregular but fairly general inflected
endings; for example, protozoon to protozoa, or metamorphosis to metamorphoses.
@@ -304,47 +304,47 @@ Note that we differ from Conway in pluralizing blouse as blouses, not blice.
=
::=
- *man 3men | /* Step 5 begins here */
- *blouse 2ses |
- *louse 5lice |
- *mouse 5mice |
- *tooth 5teeth |
- *goose 5geese |
- *foot 4feet |
- *zoon 4zoa |
- *cis 3ces |
- *sis 3ses |
- *xis 3xes
+ *man 3men | /* Step 5 begins here */
+ *blouse 2ses |
+ *louse 5lice |
+ *mouse 5mice |
+ *tooth 5teeth |
+ *goose 5geese |
+ *foot 4feet |
+ *zoon 4zoa |
+ *cis 3ces |
+ *sis 3ses |
+ *xis 3xes
@ Step 6. These are inflections from Latin and Greek which have survived
into modern English:
=
::=
- alumna alumnae | /* from table A.10 */
- alga algae |
- vertebra vertebrae |
- codex codices | /* from table A.14 */
- murex murices |
- silex silices |
- aphelion aphelia | /* from table A.19 */
- hyperbaton hyperbata |
- perihelion perihelia |
- asyndeton asyndeta |
- noumenon noumena |
- phenomenon phenomena |
- criterion criteria |
- organon organa |
- prolegomenon prolegomena |
- agendum agenda | /* from table A.20 */
- datum data |
- extremum extrema |
- bacterium bacteria |
- desideratum desiderata |
- stratum strata |
- candelabrum candelabra |
- erratum errata |
- ovum ova
+ alumna alumnae | /* from table A.10 */
+ alga algae |
+ vertebra vertebrae |
+ codex codices | /* from table A.14 */
+ murex murices |
+ silex silices |
+ aphelion aphelia | /* from table A.19 */
+ hyperbaton hyperbata |
+ perihelion perihelia |
+ asyndeton asyndeta |
+ noumenon noumena |
+ phenomenon phenomena |
+ criterion criteria |
+ organon organa |
+ prolegomenon prolegomena |
+ agendum agenda | /* from table A.20 */
+ datum data |
+ extremum extrema |
+ bacterium bacteria |
+ desideratum desiderata |
+ stratum strata |
+ candelabrum candelabra |
+ erratum errata |
+ ovum ova
@ Step 11a. (We're not implementing Conway's steps in sequence: see below.)
These -o endings are mostly loan words from Romance languages whose original
@@ -352,129 +352,129 @@ inflections are assimilated.
=
::=
- albino albinos |
- alto altos |
- archipelago archipelagos |
- armadillo armadillos |
- basso bassos |
- canto cantos |
- commando commandos |
- contralto contraltos |
- crescendo crescendos |
- ditto dittos |
- dynamo dynamos |
- embryo embryos |
- fiasco fiascos |
- generalissimo generalissimos |
- ghetto ghettos |
- guano guanos |
- inferno infernos |
- jumbo jumbos |
- lingo lingos |
- lumbago lumbagos |
- magneto magnetos |
- manifesto manifestos |
- medico medicos |
- octavo octavos |
- photo photos |
- pro pros |
- quarto quartos |
- rhino rhinos |
- solo solos |
- soprano sopranos |
- stylo stylos |
- tempo tempos
+ albino albinos |
+ alto altos |
+ archipelago archipelagos |
+ armadillo armadillos |
+ basso bassos |
+ canto cantos |
+ commando commandos |
+ contralto contraltos |
+ crescendo crescendos |
+ ditto dittos |
+ dynamo dynamos |
+ embryo embryos |
+ fiasco fiascos |
+ generalissimo generalissimos |
+ ghetto ghettos |
+ guano guanos |
+ inferno infernos |
+ jumbo jumbos |
+ lingo lingos |
+ lumbago lumbagos |
+ magneto magnetos |
+ manifesto manifestos |
+ medico medicos |
+ octavo octavos |
+ photo photos |
+ pro pros |
+ quarto quartos |
+ rhino rhinos |
+ solo solos |
+ soprano sopranos |
+ stylo stylos |
+ tempo tempos
@ Conway steps 8 to 11. These are regular inflections depending only on
word endings.
=
::=
- *ch 0es | /* Step 8: "church" to "churches" */
- *sh 0es | /* "rush" to "rushes" */
- *ss 0es | /* "dress" to "dresses" */
- *alf 1ves | /* Step 9: "calf" to "calves" */
- *elf 1ves | /* "self" to "selves" */
- *olf 1ves | /* "wolf" to "wolves" */
- *eaf 1ves | /* "sheaf" to "sheaves" */
- *arf 1ves | /* "wharf" to "wharves" */
- *nife 2ves | /* "knife" to "knives" */
- *life 2ves | /* "life" to "lives" */
- *wife 2ves | /* "wife" to "wives" */
- *ax 0es | /* Sibilant additions: "fax" to "faxes" */
- *ex 0es | /* "sex" to "sexes" */
- *ix 0es | /* "Weetabix" to "Weetabixes" */
- *ox 0es | /* "fox" to "foxes" */
- *ux 0es | /* "flux" to "fluxes" */
- *as 0es | /* "gas" to "gases" */
- *es 0es |
- *is 0es | /* "mantis" to "mantises" */
- *os 0es | /* "thermos" to "thermoses" */
- *us 0es | /* "abacus" to "abacuses" */
- *az 0es |
- *ez 0es | /* "fez" to "fezes" */
- *iz 0es |
- *oz 0es |
- *uz 0es |
- *ay 0s | /* Step 10 begins here */
- *by 1ies |
- *cy 1ies |
- *dy 1ies |
- *ey 0s |
- *fy 1ies |
- *gy 1ies |
- *hy 1ies |
- *iy 0s |
- *jy 1ies |
- *ky 1ies |
- *ly 1ies |
- *my 1ies |
- *ny 1ies |
- *oy 0s |
- *py 1ies |
- *qy 1ies |
- *ry 1ies |
- *sy 1ies |
- *ty 1ies |
- *uy 0s |
- *vy 1ies |
- *wy 1ies |
- *xy 1ies |
- *yy 1ies |
- *zy 1ies |
- *ao 0s | /* Step 11b begins here */
- *bo 1oes |
- *co 1oes |
- *do 1oes |
- *eo 0s |
- *fo 1oes |
- *go 1oes |
- *ho 1oes |
- *io 0s |
- *jo 1oes |
- *ko 1oes |
- *lo 1oes |
- *mo 1oes |
- *no 1oes |
- *oo 0s |
- *po 1oes |
- *qo 1oes |
- *ro 1oes |
- *so 0s |
- *to 1oes |
- *uo 0s |
- *vo 1oes |
- *wo 1oes |
- *xo 0s |
- *yo 1oes |
- *zo 0s
+ *ch 0es | /* Step 8: "church" to "churches" */
+ *sh 0es | /* "rush" to "rushes" */
+ *ss 0es | /* "dress" to "dresses" */
+ *alf 1ves | /* Step 9: "calf" to "calves" */
+ *elf 1ves | /* "self" to "selves" */
+ *olf 1ves | /* "wolf" to "wolves" */
+ *eaf 1ves | /* "sheaf" to "sheaves" */
+ *arf 1ves | /* "wharf" to "wharves" */
+ *nife 2ves | /* "knife" to "knives" */
+ *life 2ves | /* "life" to "lives" */
+ *wife 2ves | /* "wife" to "wives" */
+ *ax 0es | /* Sibilant additions: "fax" to "faxes" */
+ *ex 0es | /* "sex" to "sexes" */
+ *ix 0es | /* "Weetabix" to "Weetabixes" */
+ *ox 0es | /* "fox" to "foxes" */
+ *ux 0es | /* "flux" to "fluxes" */
+ *as 0es | /* "gas" to "gases" */
+ *es 0es |
+ *is 0es | /* "mantis" to "mantises" */
+ *os 0es | /* "thermos" to "thermoses" */
+ *us 0es | /* "abacus" to "abacuses" */
+ *az 0es |
+ *ez 0es | /* "fez" to "fezes" */
+ *iz 0es |
+ *oz 0es |
+ *uz 0es |
+ *ay 0s | /* Step 10 begins here */
+ *by 1ies |
+ *cy 1ies |
+ *dy 1ies |
+ *ey 0s |
+ *fy 1ies |
+ *gy 1ies |
+ *hy 1ies |
+ *iy 0s |
+ *jy 1ies |
+ *ky 1ies |
+ *ly 1ies |
+ *my 1ies |
+ *ny 1ies |
+ *oy 0s |
+ *py 1ies |
+ *qy 1ies |
+ *ry 1ies |
+ *sy 1ies |
+ *ty 1ies |
+ *uy 0s |
+ *vy 1ies |
+ *wy 1ies |
+ *xy 1ies |
+ *yy 1ies |
+ *zy 1ies |
+ *ao 0s | /* Step 11b begins here */
+ *bo 1oes |
+ *co 1oes |
+ *do 1oes |
+ *eo 0s |
+ *fo 1oes |
+ *go 1oes |
+ *ho 1oes |
+ *io 0s |
+ *jo 1oes |
+ *ko 1oes |
+ *lo 1oes |
+ *mo 1oes |
+ *no 1oes |
+ *oo 0s |
+ *po 1oes |
+ *qo 1oes |
+ *ro 1oes |
+ *so 0s |
+ *to 1oes |
+ *uo 0s |
+ *vo 1oes |
+ *wo 1oes |
+ *xo 0s |
+ *yo 1oes |
+ *zo 0s
@ Lastly, the fallback if none of the above cases match: append an -s, of
course.
=
::=
- * 0s /* Step 13 */
+ * 0s /* Step 13 */
@h Verb inflections.
"Le verbe est l'âme d'une langue" (attributed to Georges Duhamel). And the
@@ -594,31 +594,31 @@ Inform assertion sentences, but are needed for text substitutions.)
=
::=
- be |
- be able to ... |
- be able to |
- could |
- may |
- might |
- must |
- should |
- would |
- auxiliary-have |
- do |
- 're |
- 've |
- aren't |
- can't |
- don't |
- haven't |
- mayn't |
- mightn't |
- mustn't |
- wouldn't |
- couldn't |
- shouldn't |
- won't |
- ...
+ be |
+ be able to ... |
+ be able to |
+ could |
+ may |
+ might |
+ must |
+ should |
+ would |
+ auxiliary-have |
+ do |
+ 're |
+ 've |
+ aren't |
+ can't |
+ don't |
+ haven't |
+ mayn't |
+ mightn't |
+ mustn't |
+ wouldn't |
+ couldn't |
+ shouldn't |
+ won't |
+ ...
@ We will start with two auxiliary verbs, that is, verbs used to construct
forms of other verbs. The first is "to have"; as we'll see, English uses
@@ -753,10 +753,10 @@ A simple example, then, which uses only feature (d) of these exotica:
=
::=
- a1+ |
- a1- not |
- a2+ had |
- a2- had not
+ a1+ |
+ a1- not |
+ a2+ had |
+ a2- had not
@ And this is an example of splitting into cases for the six persons,
1PS, 2PS, 3PS, 1PP, 2PP, 3PP. I have, you have, he has, we have, you have,
@@ -801,20 +801,20 @@ may have to revisit this for languages other than English.)
=
::=
- 2 doing |
- 3 done |
+ 2 doing |
+ 3 done |
::=
- a1+ |
- a1- not |
- a2+ did |
- a2- did not |
- a3 ( t1 auxiliary-have ) done |
- a4 ( t2 auxiliary-have ) done |
- a5+ will do |
- a5- will not do |
- p* done by
+ a1+ |
+ a1- not |
+ a2+ did |
+ a2- did not |
+ a3 ( t1 auxiliary-have ) done |
+ a4 ( t2 auxiliary-have ) done |
+ a5+ will do |
+ a5- will not do |
+ p* done by
::=
do | do | does | do | do | do
@@ -840,10 +840,10 @@ to "grabs onto", "grabbing onto" and so on.
=
::=
- 2 |
- 3 |
- 5 |
- 6 |
+ 2 |
+ 3 |
+ 5 |
+ 6 |
@ Here we see our auxiliary verbs in use. For the negated present tense,
@@ -858,15 +858,15 @@ a bequest".)
=
::=
- a1+ |
- a1- ( do ) 1 |
- a2+ 6 |
- a2- ( do ) 1 |
- a3 ( t1 auxiliary-have ) 3 |
- a4 ( t2 auxiliary-have ) 3 |
- a5+ will 1 |
- a5- will not 1 |
- p* 3 by
+ a1+ |
+ a1- ( do ) 1 |
+ a2+ 6 |
+ a2- ( do ) 1 |
+ a3 ( t1 auxiliary-have ) 3 |
+ a4 ( t2 auxiliary-have ) 3 |
+ a5+ will 1 |
+ a5- will not 1 |
+ p* 3 by
@ This looks odd, but what it says is that the present tense of a regular
English verb is always the infinitive (I take, you take, we take, and so on)
@@ -887,14 +887,14 @@ as we'll see.)
::=
- a1+ |
- a1- not |
- a2+ |
- a2- not |
- a3 ( t1 auxiliary-have ) been |
- a4 ( t2 auxiliary-have ) been |
- a5+ will be |
- a5- will not be
+ a1+ |
+ a1- not |
+ a2+ |
+ a2- not |
+ a3 ( t1 auxiliary-have ) been |
+ a4 ( t2 auxiliary-have ) been |
+ a5+ will be |
+ a5- will not be
::=
am | are | is | are | are | are
@@ -922,19 +922,19 @@ to elide, so we always pronounce it that way and the spelling now follows.
=
::=
- 2 |
- 3 |
+ 2 |
+ 3 |
::=
- a1+ can ++1 |
- a1- cannot ++1 |
- a2+ could ++1 |
- a2- could not ++1 |
- a3 ( t1 auxiliary-have ) been able to ++1 |
- a4 ( t2 auxiliary-have ) been able to ++1 |
- a5+ will be able to ++1 |
- a5- will not be able to ++1
+ a1+ can ++1 |
+ a1- cannot ++1 |
+ a2+ could ++1 |
+ a2- could not ++1 |
+ a3 ( t1 auxiliary-have ) been able to ++1 |
+ a4 ( t2 auxiliary-have ) been able to ++1 |
+ a5+ will be able to ++1 |
+ a5- will not be able to ++1
@ Inform has only a simple understanding of what "can" means, so it doesn't
allow the source text to use "can" in combination with arbitrary verbs.
@@ -963,13 +963,13 @@ Jane".
=
::=
- 2 |
- 3 |
+ 2 |
+ 3 |
::=
- a ( be able to ) 4 |
- p ( be able to ) be 3 ( 4 ) by
+ a ( be able to ) 4 |
+ p ( be able to ) be 3 ( 4 ) by
@ The following handles the other English modal verbs ("might", "should"
and so on) surprisingly easily. The notation |++1| means that the verb
@@ -978,21 +978,21 @@ being modified should appear in verb form 1, and so on: for example,
=
::=
- 2 |
- 3 |
+ 2 |
+ 3 |
::=
- a1+ 4 ++1 |
- a1- 4 not ++1 |
- a2+ 4 have ++2 |
- a2- 4 not have ++2 |
- a3+ 4 have ++2 |
- a3- 4 not have ++2 |
- a4+ 4 have ++2 |
- a4- 4 not have ++2 |
- a5+ 4 ++1 |
- a5- 4 not ++1
+ a1+ 4 ++1 |
+ a1- 4 not ++1 |
+ a2+ 4 have ++2 |
+ a2- 4 not have ++2 |
+ a3+ 4 have ++2 |
+ a3- 4 not have ++2 |
+ a4+ 4 have ++2 |
+ a4- 4 not have ++2 |
+ a5+ 4 ++1 |
+ a5- 4 not ++1
@ That completes our basic kit of verbs nicely. What's left is used only
for generating text at run-time -- for printing adaptive messages, that is;
@@ -1028,16 +1028,16 @@ dialects -- and we aren't even going to try to cope with that.
::=
- a1+ |
- a1- not |
- a2+ |
- a2- |
- a3+ been |
- a3- not been |
- a4+ 'd been |
- a4- 'd not been |
- a5+ 'll be |
- a5- 'll not be
+ a1+ |
+ a1- not |
+ a2+ |
+ a2- |
+ a3+ been |
+ a3- not been |
+ a4+ 'd been |
+ a4- 'd not been |
+ a5+ 'll be |
+ a5- 'll not be
::=
'm | 're | 's | 're | 're | 're
@@ -1068,16 +1068,16 @@ go with those.
::=
- a1+ |
- a1- not |
- a2+ had |
- a2- hadn't |
- a3+ had |
- a3- not had |
- a4+ 'd had |
- a4- 'd not had |
- a5+ 'll have |
- a5- 'll not have
+ a1+ |
+ a1- not |
+ a2+ had |
+ a2- hadn't |
+ a3+ had |
+ a3- not had |
+ a4+ 'd had |
+ a4- 'd not had |
+ a5+ 'll have |
+ a5- 'll not have
::=
've | 've | 's | 've | 've | 've
@@ -1102,11 +1102,11 @@ that option here.)
::=
- a1+ |
- a2+ |
- a3+ |
- a4+ hadn't been |
- a5+ won't be
+ a1+ |
+ a2+ |
+ a3+ |
+ a4+ hadn't been |
+ a5+ won't be
::=
am not | aren't | isn't | aren't | aren't | aren't
@@ -1115,7 +1115,7 @@ that option here.)
wasn't | weren't | wasn't | weren't | weren't | weren't
::=
- haven't been | haven't been | hasn't been | haven't been | haven't been | haven't been
+ haven't been | haven't been | hasn't been | haven't been | haven't been | haven't been
@ And finally: the contracted informal negatives of various modal verbs which
it's useful to be able to print, like the "can't" in
@@ -1127,20 +1127,20 @@ of "modal" itself arguable. This is the best we can do.
=
::=
- 2 |
- 3 |
- 5 |
- 6 |
- 7 |
+ 2 |
+ 3 |
+ 5 |
+ 6 |
+ 7