diff --git a/README.md b/README.md index f2e7e2c6a..1c161fac9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inform 7 -v10.1.0-beta+6V12 'Krypton' (23 May 2022) +v10.1.0-beta+6V13 'Krypton' (24 May 2022) ## About Inform 7 diff --git a/build.txt b/build.txt index e2f5aae42..88c5891d4 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: beta -Build Date: 23 May 2022 -Build Number: 6V12 +Build Date: 24 May 2022 +Build Number: 6V13 diff --git a/docs/bytecode-module/2-pck.html b/docs/bytecode-module/2-pck.html index f67f82dfa..7cbf1b889 100644 --- a/docs/bytecode-module/2-pck.html +++ b/docs/bytecode-module/2-pck.html @@ -155,7 +155,7 @@ outermost box, that is, the top level of the hierarchy. return pack->package_head; } -inter_tree *InterPackage::tree(inter_package *pack) { +inter_tree *InterPackage::tree(inter_package *pack) { if (pack == NULL) return NULL; return pack->package_head->tree; } diff --git a/docs/bytecode-module/2-st.html b/docs/bytecode-module/2-st.html index 1d0d3f4d7..9d5d4b031 100644 --- a/docs/bytecode-module/2-st.html +++ b/docs/bytecode-module/2-st.html @@ -129,7 +129,7 @@ function is the inverse of InterPacka

-inter_package *InterSymbolsTable::package(inter_symbols_table *ST) {
+inter_package *InterSymbolsTable::package(inter_symbols_table *ST) {
     if (ST) return ST->owning_package;
     return NULL;
 }
@@ -655,7 +655,7 @@ as a way of handling forward references.
 

-inter_symbol *InterSymbolsTable::wire_to_URL(inter_tree *I, text_stream *URL,
+inter_symbol *InterSymbolsTable::wire_to_URL(inter_tree *I, text_stream *URL,
     inter_symbols_table *T) {
     inter_symbol *S = InterSymbolsTable::URL_to_symbol(I, URL);
     if (S == NULL) {
diff --git a/docs/bytecode-module/3-idt.html b/docs/bytecode-module/3-idt.html
index ec62a928b..928557e3b 100644
--- a/docs/bytecode-module/3-idt.html
+++ b/docs/bytecode-module/3-idt.html
@@ -90,6 +90,7 @@ invalidate existing Inter binary files, necessitating a bump of enum TEXT_ITCONC
 enum ENUM_ITCONC
 enum LIST_ITCONC
+enum ACTIVITY_ITCONC
 enum COLUMN_ITCONC
 enum TABLE_ITCONC
 enum FUNCTION_ITCONC
@@ -145,6 +146,7 @@ initialise it:
     InterTypes::init_con(TEXT_ITCONC,        I"text",        -2147483648, 2147483647, FALSE,  TRUE, 0);
     InterTypes::init_con(ENUM_ITCONC,        I"enum",                  0, 2147483647,  TRUE,  TRUE, 0);
     InterTypes::init_con(LIST_ITCONC,        I"list",        -2147483648, 2147483647, FALSE, FALSE, 1);
+    InterTypes::init_con(ACTIVITY_ITCONC,    I"activity",    -2147483648, 2147483647, FALSE, FALSE, 1);
     InterTypes::init_con(COLUMN_ITCONC,      I"column",      -2147483648, 2147483647, FALSE, FALSE, 1);
     InterTypes::init_con(TABLE_ITCONC,       I"table",       -2147483648, 2147483647, FALSE, FALSE, 1);
     InterTypes::init_con(FUNCTION_ITCONC,    I"function",    -2147483648, 2147483647, FALSE, FALSE, 2);
@@ -188,7 +190,7 @@ that it's fine for textual lookups to be relatively slow.
     return NULL;
 }
 
-inter_type_constructor *InterTypes::constructor_from_name(text_stream *name) {
+inter_type_constructor *InterTypes::constructor_from_name(text_stream *name) {
     for (inter_ti ID = MIN_INTER_TYPE_CONSTRUCTOR; ID <= MAX_INTER_TYPE_CONSTRUCTOR; ID++) {
         inter_type_constructor *itc = &(inter_type_constructors[ID]);
         if (Str::eq(itc->constructor_keyword, name))
@@ -266,7 +268,7 @@ type name, and so can be stored in an 
 

-inter_type InterTypes::from_constructor_code(inter_ti constructor_code) {
+inter_type InterTypes::from_constructor_code(inter_ti constructor_code) {
     if (InterTypes::is_valid_constructor_code(constructor_code) == FALSE)
         internal_error("invalid constructor code");
     inter_type type;
@@ -275,7 +277,7 @@ type name, and so can be stored in an 
     return type;
 }
 
-inter_type InterTypes::from_type_name(inter_symbol *S) {
+inter_type InterTypes::from_type_name(inter_symbol *S) {
     if (S) {
         inter_type type;
         type.underlying_constructor = TypenameInstruction::constructor(S);
@@ -309,7 +311,7 @@ in which all data is unchecke
 

-inter_type InterTypes::unchecked(void) {
+inter_type InterTypes::unchecked(void) {
     return InterTypes::from_constructor_code(UNCHECKED_ITCONC);
 }
 
@@ -406,7 +408,7 @@ Inter because it's primarily designed as a language for programs to write.
     results->operand_TIDs = results->default_operand_TIDs;
 }
 
-void InterTypes::add_operand_to_isstd(inter_semisimple_type_description *results,
+void InterTypes::add_operand_to_isstd(inter_semisimple_type_description *results,
     inter_symbols_table *T, inter_type type) {
     inter_ti TID = InterTypes::to_TID(T, type);
     if (results->arity >= results->capacity) {
@@ -459,14 +461,15 @@ prevents a memory leak if really large results were returned.
 
     Parse rulebook syntax17.1;
     Parse list syntax17.2;
-    Parse column syntax17.3;
-    Parse table syntax17.4;
-    Parse description syntax17.5;
-    Parse relation syntax17.6;
-    Parse rule or function syntax17.7;
-    Parse struct syntax17.8;
-    Parse bare constructor-name syntax17.9;
-    Parse bare typename syntax17.10;
+    Parse activity syntax17.3;
+    Parse column syntax17.4;
+    Parse table syntax17.5;
+    Parse description syntax17.6;
+    Parse relation syntax17.7;
+    Parse rule or function syntax17.8;
+    Parse struct syntax17.9;
+    Parse bare constructor-name syntax17.10;
+    Parse bare typename syntax17.11;
 
     Regexp::dispose_of(&mr);
     return InterErrors::quoted(I"no such data type", text, eloc);
@@ -498,7 +501,20 @@ prevents a memory leak if really large results were returned.
     }
 
  • This code is used in §17.
-

§17.3. Parse column syntax17.3 = +

§17.3. Parse activity syntax17.3 = +

+ +
+    if (Regexp::match(&mr, text, L"activity on (%C+)")) {
+        results->constructor_code = ACTIVITY_ITCONC;
+        inter_type conts_type = InterTypes::parse_simple(T, eloc, mr.exp[0], &E);
+        InterTypes::add_operand_to_isstd(results, T, conts_type);
+        Regexp::dispose_of(&mr);
+        return E;
+    }
+
+
  • This code is used in §17.
+

§17.4. Parse column syntax17.4 =

@@ -511,7 +527,7 @@ prevents a memory leak if really large results were returned.
     }
 
  • This code is used in §17.
-

§17.4. Parse table syntax17.4 = +

§17.5. Parse table syntax17.5 =

@@ -524,7 +540,7 @@ prevents a memory leak if really large results were returned.
     }
 
  • This code is used in §17.
-

§17.5. Parse description syntax17.5 = +

§17.6. Parse description syntax17.6 =

@@ -537,7 +553,7 @@ prevents a memory leak if really large results were returned.
     }
 
  • This code is used in §17.
-

§17.6. Parse relation syntax17.6 = +

§17.7. Parse relation syntax17.7 =

@@ -556,7 +572,7 @@ prevents a memory leak if really large results were returned.
     }
 
  • This code is used in §17.
-

§17.7. Parse rule or function syntax17.7 = +

§17.8. Parse rule or function syntax17.8 =

@@ -592,7 +608,7 @@ prevents a memory leak if really large results were returned.
     }
 
  • This code is used in §17.
-

§17.8. Parse struct syntax17.8 = +

§17.9. Parse struct syntax17.9 =

@@ -612,7 +628,7 @@ prevents a memory leak if really large results were returned.
     }
 
  • This code is used in §17.
-

§17.9. Parse bare constructor-name syntax17.9 = +

§17.10. Parse bare constructor-name syntax17.10 =

@@ -626,7 +642,7 @@ prevents a memory leak if really large results were returned.
     }
 
  • This code is used in §17.
-

§17.10. Parse bare typename syntax17.10 = +

§17.11. Parse bare typename syntax17.11 =

@@ -658,7 +674,7 @@ useful error message in response to a semisimple but not simple piece of syntax.
 

-inter_type InterTypes::parse_simple(inter_symbols_table *T, inter_error_location *eloc,
+inter_type InterTypes::parse_simple(inter_symbols_table *T, inter_error_location *eloc,
     text_stream *text, inter_error_message **E) {
     if (Str::len(text) > 0) {
         inter_semisimple_type_description parsed_description;
@@ -722,6 +738,10 @@ just print that name, K_whate
             WRITE(" of ");
             InterTypes::write_type(OUT, InterTypes::type_operand(type, 0));
             break;
+        case ACTIVITY_ITCONC:
+            WRITE(" on ");
+            InterTypes::write_type(OUT, InterTypes::type_operand(type, 0));
+            break;
         case RELATION_ITCONC:
             WRITE(" of ");
             InterTypes::write_type(OUT, InterTypes::type_operand(type, 0));
diff --git a/docs/bytecode-module/3-ie.html b/docs/bytecode-module/3-ie.html
index 4b06506e9..01faced03 100644
--- a/docs/bytecode-module/3-ie.html
+++ b/docs/bytecode-module/3-ie.html
@@ -116,7 +116,7 @@ of ways.)
 

-inter_error_message *InterErrors::quoted(text_stream *err, text_stream *quote, inter_error_location *eloc) {
+inter_error_message *InterErrors::quoted(text_stream *err, text_stream *quote, inter_error_location *eloc) {
     inter_error_message *iem = InterErrors::plain(err, eloc);
     iem->error_quote = Str::duplicate(quote);
     return iem;
diff --git a/docs/bytecode-module/3-iitf.html b/docs/bytecode-module/3-iitf.html
index 75acb8620..bd932ae47 100644
--- a/docs/bytecode-module/3-iitf.html
+++ b/docs/bytecode-module/3-iitf.html
@@ -257,7 +257,7 @@ enables us to tell if it's, e.g., a variable, defined by <
     text_stream *name, inter_ti construct, inter_error_message **E) {
     return TextualInter::find_symbol_in_table(InterBookmark::scope(IBM), eloc, name, construct, E);
 }
-inter_symbol *TextualInter::find_symbol_in_table(inter_symbols_table *T, inter_error_location *eloc,
+inter_symbol *TextualInter::find_symbol_in_table(inter_symbols_table *T, inter_error_location *eloc,
     text_stream *name, inter_ti construct, inter_error_message **E) {
     *E = NULL;
     inter_symbol *S = NULL;
diff --git a/docs/inter/M-dpiti.html b/docs/inter/M-dpiti.html
index bc060d805..a3795d0d5 100644
--- a/docs/inter/M-dpiti.html
+++ b/docs/inter/M-dpiti.html
@@ -429,10 +429,10 @@ used, but void
 must be at least one of these, so struct void is not allowed.
 
  • enum, for which see below;
  • ● and then a raft of constructions convenient for Inform but which Inter -really knows nothing about: column of T, table of T, relation of T1 to T2, -description of T, rulebook of T, and rule T1 -> T2. Perhaps these ought -to work via a general way for users to create new constructors, but for now -they are hard-wired. They do nothing except to be distinct from each other, +really knows nothing about: activity on T, column of T, table of T, +relation of T1 to T2, description of T, rulebook of T, and rule T1 -> T2. +Perhaps these ought to work via a general way for users to create new constructors, +but for now they are hard-wired. They do nothing except to be distinct from each other, so that Inform can label its data.
  • Inter applies the usual rules of covariance and contravariance when matching diff --git a/docs/kinds-module/2-uk.html b/docs/kinds-module/2-uk.html index c772304a0..1e8c09eea 100644 --- a/docs/kinds-module/2-uk.html +++ b/docs/kinds-module/2-uk.html @@ -148,8 +148,8 @@ checks that we aren't doing that: int Kinds::Behaviour::definite(kind *K) { if (K == NULL) return TRUE; if (KindConstructors::is_definite(K->construct) == FALSE) return FALSE; - int i, arity = KindConstructors::arity(K->construct); - for (i=0; i<arity; i++) + int arity = KindConstructors::arity(K->construct); + for (int i=0; i<arity; i++) if (Kinds::Behaviour::definite(K->kc_args[i]) == FALSE) return FALSE; return TRUE; @@ -160,15 +160,15 @@ checks that we aren't doing that: if (K->construct == CON_KIND_VARIABLE) return TRUE; if (K->construct == CON_NIL) return FALSE; if (KindConstructors::is_definite(K->construct) == FALSE) return FALSE; - int i, arity = KindConstructors::arity(K->construct); + int arity = KindConstructors::arity(K->construct); if ((K->construct == CON_TUPLE_ENTRY) && (Kinds::eq(K->kc_args[1], K_void))) arity = 1; - if (K->construct == CON_phrase) { - for (i=0; i<arity; i++) + if ((K->construct == CON_phrase) || (K->construct == CON_activity)) { + for (int i=0; i<arity; i++) if ((Kinds::eq(K->kc_args[i], K_nil) == FALSE) && (Kinds::Behaviour::semidefinite(K->kc_args[i]) == FALSE)) return FALSE; } else { - for (i=0; i<arity; i++) + for (int i=0; i<arity; i++) if (Kinds::Behaviour::semidefinite(K->kc_args[i]) == FALSE) return FALSE; } diff --git a/docs/runtime-module/2-kd.html b/docs/runtime-module/2-kd.html index 5e88cf1f8..caa52cde2 100644 --- a/docs/runtime-module/2-kd.html +++ b/docs/runtime-module/2-kd.html @@ -233,11 +233,12 @@ source text. inter_ti icon = 0; if (Kinds::get_construct(K) == CON_description) Run out inter kind for description9.2 else if (Kinds::get_construct(K) == CON_list_of) Run out inter kind for list9.1 - else if (Kinds::get_construct(K) == CON_phrase) Run out inter kind for phrase9.5 - else if (Kinds::get_construct(K) == CON_rule) Run out inter kind for rule9.6 - else if (Kinds::get_construct(K) == CON_rulebook) Run out inter kind for rulebook9.7 + else if (Kinds::get_construct(K) == CON_phrase) Run out inter kind for phrase9.6 + else if (Kinds::get_construct(K) == CON_rule) Run out inter kind for rule9.7 + else if (Kinds::get_construct(K) == CON_rulebook) Run out inter kind for rulebook9.8 else if (Kinds::get_construct(K) == CON_table_column) Run out inter kind for column9.3 else if (Kinds::get_construct(K) == CON_relation) Run out inter kind for relation9.4 + else if (Kinds::get_construct(K) == CON_activity) Run out inter kind for activity9.5 else { LOG("Unfortunate kind is: %u\n", K); internal_error("unable to represent kind in inter"); @@ -282,7 +283,16 @@ source text. icon = RELATION_ITCONC;

    • This code is used in §9.
    -

    §9.5. Run out inter kind for phrase9.5 = +

    §9.5. Run out inter kind for activity9.5 = +

    + +
    +    arity = 1;
    +    operands[0] = Kinds::unary_construction_material(K);
    +    icon = ACTIVITY_ITCONC;
    +
    +
    • This code is used in §9.
    +

    §9.6. Run out inter kind for phrase9.6 =

    @@ -300,7 +310,7 @@ source text.
         operands[arity++] = result;
     
    • This code is used in §9.
    -

    §9.6. Run out inter kind for rule9.6 = +

    §9.7. Run out inter kind for rule9.7 =

    @@ -309,7 +319,7 @@ source text.
         icon = RULE_ITCONC;
     
    • This code is used in §9.
    -

    §9.7. Run out inter kind for rulebook9.7 = +

    §9.8. Run out inter kind for rulebook9.8 =

    diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt
    index 653ea2ce0..2b241403a 100644
    --- a/inform7/Figures/memory-diagnostics.txt
    +++ b/inform7/Figures/memory-diagnostics.txt
    @@ -1,47 +1,47 @@
    -Total memory consumption was 129458K = 126 MB
    +Total memory consumption was 123375K = 120 MB
     
      ---- was used for 2044964 objects, in 362887 frames in 0 x 800K = 0K = 0 MB:
     
    -    31.5%  inter_tree_node_array                    58 x 8192 = 475136 objects, 41813824 bytes
    -    19.5%  text_stream_array                        4605 x 100 = 460500 objects, 25935360 bytes
    -    18.3%  linked_list                              43461 objects, 24338160 bytes
    -    10.6%  inter_symbol_array                       132 x 1024 = 135168 objects, 14061696 bytes
    -     9.9%  inter_error_stash_array                  101 x 1024 = 103424 objects, 13241504 bytes
    -     7.8%  parse_node                               129722 objects, 10377760 bytes
    -     5.6%  verb_conjugation                         160 objects, 7425280 bytes
    -     4.1%  parse_node_annotation_array              346 x 500 = 173000 objects, 5547072 bytes
    -     2.5%  pcalc_prop_array                         25 x 1000 = 25000 objects, 3400800 bytes
    -     2.4%  inter_name_array                         67 x 1000 = 67000 objects, 3218144 bytes
    -     1.9%  kind_array                               66 x 1000 = 66000 objects, 2642112 bytes
    -     1.5%  inter_name_generator_array               51 x 1000 = 51000 objects, 2041632 bytes
    +    33.0%  inter_tree_node_array                    58 x 8192 = 475136 objects, 41813824 bytes
    +    20.5%  text_stream_array                        4605 x 100 = 460500 objects, 25935360 bytes
    +    19.2%  linked_list                              43461 objects, 24338160 bytes
    +    11.1%  inter_symbol_array                       132 x 1024 = 135168 objects, 14061696 bytes
    +    10.4%  inter_error_stash_array                  101 x 1024 = 103424 objects, 13241504 bytes
    +     8.2%  parse_node                               129722 objects, 10377760 bytes
    +     5.8%  verb_conjugation                         160 objects, 7425280 bytes
    +     4.3%  parse_node_annotation_array              346 x 500 = 173000 objects, 5547072 bytes
    +     2.6%  pcalc_prop_array                         25 x 1000 = 25000 objects, 3400800 bytes
    +     2.5%  inter_name_array                         67 x 1000 = 67000 objects, 3218144 bytes
    +     2.0%  kind_array                               66 x 1000 = 66000 objects, 2642112 bytes
    +     1.6%  inter_name_generator_array               51 x 1000 = 51000 objects, 2041632 bytes
          1.5%  inter_schema_token                       13969 objects, 2011536 bytes
          1.4%  package_request                          21153 objects, 1861464 bytes
    -     1.3%  vocabulary_entry_array                   161 x 100 = 16100 objects, 1808352 bytes
    -     1.1%  dict_entry_array                         470 x 100 = 47000 objects, 1519040 bytes
    +     1.4%  vocabulary_entry_array                   161 x 100 = 16100 objects, 1808352 bytes
    +     1.2%  dict_entry_array                         470 x 100 = 47000 objects, 1519040 bytes
          1.1%  match_trie_array                         11 x 1000 = 11000 objects, 1496352 bytes
          1.1%  inter_symbols_table                      26592 objects, 1489152 bytes
          1.0%  i6_schema_array                          23 x 100 = 2300 objects, 1380736 bytes
    -     0.9%  scan_directory                           314 objects, 1296192 bytes
    -     0.9%  inter_package                            26592 objects, 1276416 bytes
    +     1.0%  scan_directory                           314 objects, 1296192 bytes
    +     1.0%  inter_package                            26592 objects, 1276416 bytes
          0.8%  map_data                                 671 objects, 1127280 bytes
          0.8%  id_body                                  942 objects, 1077648 bytes
          0.7%  adjective_meaning                        202 objects, 1000304 bytes
          0.7%  excerpt_meaning                          3102 objects, 967824 bytes
    -     0.6%  production                               3878 objects, 899696 bytes
    +     0.7%  production                               3878 objects, 899696 bytes
          0.6%  ptoken                                   8397 objects, 873288 bytes
          0.6%  grammatical_usage                        3613 objects, 867120 bytes
          0.6%  individual_form                          2563 objects, 861168 bytes
          0.6%  inter_schema_node                        8920 objects, 856320 bytes
    -     0.4%  unary_predicate_array                    16 x 1000 = 16000 objects, 640512 bytes
    +     0.5%  unary_predicate_array                    16 x 1000 = 16000 objects, 640512 bytes
          0.3%  local_variable_array                     47 x 100 = 4700 objects, 452704 bytes
    -     0.2%  verb_usage                               1128 objects, 388032 bytes
    +     0.3%  verb_usage                               1128 objects, 388032 bytes
          0.2%  rule                                     470 objects, 368480 bytes
          0.2%  dictionary                               7520 objects, 360960 bytes
          0.2%  verb_form                                386 objects, 348944 bytes
          0.2%  noun                                     2382 objects, 285840 bytes
          0.2%  compilation_subtask                      3355 objects, 268400 bytes
    -     0.1%  inter_annotation_array                   2 x 8192 = 16384 objects, 262208 bytes
    -     0.1%  inference_subject                        666 objects, 261072 bytes
    +     0.2%  inter_annotation_array                   2 x 8192 = 16384 objects, 262208 bytes
    +     0.2%  inference_subject                        666 objects, 261072 bytes
          0.1%  vanilla_function                         3683 objects, 235712 bytes
          0.1%  binary_predicate                         322 objects, 170016 bytes
          0.1%  hierarchy_location                       1122 objects, 161568 bytes
    @@ -237,23 +237,23 @@ Total memory consumption was 129458K = 126 MB
     
     100.0% was used for memory not allocated for objects:
     
    -    59.7%  text stream storage                      79163588 bytes in 478472 claims
    -     3.9%  dictionary storage                       5228544 bytes in 7520 claims
    +    57.7%  text stream storage                      72934504 bytes in 478023 claims
    +     4.1%  dictionary storage                       5228544 bytes in 7520 claims
          ----  sorting                                  1448 bytes in 149 claims
    -     5.4%  source text                              7200000 bytes in 3 claims
    -     8.1%  source text details                      10800000 bytes in 2 claims
    -     0.1%  documentation fragments                  262144 bytes in 1 claim
    +     5.6%  source text                              7200000 bytes in 3 claims
    +     8.5%  source text details                      10800000 bytes in 2 claims
    +     0.2%  documentation fragments                  262144 bytes in 1 claim
          ----  linguistic stock array                   81920 bytes in 2 claims
          ----  small word set array                     105600 bytes in 22 claims
    -     3.4%  inter symbols storage                    4520272 bytes in 27949 claims
    -    12.6%  inter bytecode storage                   16767680 bytes in 14 claims
    -     4.6%  inter links storage                      6222976 bytes in 11 claims
    +     3.5%  inter symbols storage                    4520272 bytes in 27949 claims
    +    13.2%  inter bytecode storage                   16767680 bytes in 14 claims
    +     4.9%  inter links storage                      6222976 bytes in 11 claims
          0.1%  inter tree location list storage         191232 bytes in 32 claims
    -     1.2%  instance-of-kind counting                1700416 bytes in 1 claim
    +     1.3%  instance-of-kind counting                1700416 bytes in 1 claim
          ----  compilation workspace for objects        21896 bytes in 25 claims
          ----  lists for type-checking invocations      16000 bytes in 1 claim
          ----  code generation workspace for objects    1336 bytes in 4 claims
          0.2%  emitter array storage                    280288 bytes in 1999 claims
     
    --139.-2% was overhead - -184656920 bytes = -180329K = -176 MB
    +-146.-1% was overhead - -184656920 bytes = -180329K = -176 MB
     
    diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt
    index accfaed95..3d4e2f6a6 100644
    --- a/inform7/Figures/timings-diagnostics.txt
    +++ b/inform7/Figures/timings-diagnostics.txt
    @@ -1,33 +1,33 @@
     100.0% in inform7 run
    -     72.1% in compilation to Inter
    -         51.0% in //Sequence::undertake_queued_tasks//
    -          4.6% in //MajorNodes::pre_pass//
    -          3.4% in //MajorNodes::pass_1//
    -          2.5% in //RTPhrasebook::compile_entries//
    -          1.9% in //ImperativeDefinitions::assess_all//
    +     71.3% in compilation to Inter
    +         50.7% in //Sequence::undertake_queued_tasks//
    +          4.5% in //MajorNodes::pre_pass//
    +          3.3% in //MajorNodes::pass_1//
    +          1.9% in //RTPhrasebook::compile_entries//
    +          1.7% in //ImperativeDefinitions::assess_all//
               1.3% in //RTKindConstructors::compile//
    -          0.9% in //Sequence::lint_inter//
    +          1.1% in //Sequence::lint_inter//
               0.5% in //MajorNodes::pass_2//
               0.5% in //Sequence::undertake_queued_tasks//
    +          0.5% in //Sequence::undertake_queued_tasks//
               0.5% in //World::stage_V//
               0.3% in //ImperativeDefinitions::compile_first_block//
    -          0.3% in //Sequence::undertake_queued_tasks//
               0.1% in //CompletionModule::compile//
               0.1% in //InferenceSubjects::emit_all//
               0.1% in //RTKindConstructors::compile_permissions//
               0.1% in //Task::make_built_in_kind_constructors//
               0.1% in //World::stages_II_and_III//
    -          2.7% not specifically accounted for
    -     25.1% in running Inter pipeline
    -          9.8% in step 14/15: generate inform6 -> auto.inf
    -          5.6% in step 5/15: load-binary-kits
    -          5.4% in step 6/15: make-synoptic-module
    +          2.6% not specifically accounted for
    +     25.8% in running Inter pipeline
    +         10.0% in step 14/15: generate inform6 -> auto.inf
    +          5.7% in step 5/15: load-binary-kits
    +          5.5% in step 6/15: make-synoptic-module
               1.3% in step 9/15: make-identifiers-unique
               0.3% in step 12/15: eliminate-redundant-operations
               0.3% in step 4/15: compile-splats
               0.3% in step 7/15: shorten-wiring
               0.3% in step 8/15: detect-indirect-calls
               0.1% in step 11/15: eliminate-redundant-labels
    -          1.2% not specifically accounted for
    +          1.3% not specifically accounted for
           2.3% in supervisor
           0.4% not specifically accounted for
    diff --git a/inform7/runtime-module/Chapter 2/Kind Declarations.w b/inform7/runtime-module/Chapter 2/Kind Declarations.w
    index 9ce271d91..e9efc78c6 100644
    --- a/inform7/runtime-module/Chapter 2/Kind Declarations.w	
    +++ b/inform7/runtime-module/Chapter 2/Kind Declarations.w	
    @@ -167,6 +167,7 @@ void RTKindDeclarations::declare_constructed_kind(cached_kind_declaration *dec)
     	else if (Kinds::get_construct(K) == CON_rulebook)     @
     	else if (Kinds::get_construct(K) == CON_table_column) @
     	else if (Kinds::get_construct(K) == CON_relation)     @
    +	else if (Kinds::get_construct(K) == CON_activity)     @
     	else {
     		LOG("Unfortunate kind is: %u\n", K);
     		internal_error("unable to represent kind in inter");
    @@ -195,6 +196,11 @@ void RTKindDeclarations::declare_constructed_kind(cached_kind_declaration *dec)
     	Kinds::binary_construction_material(K, &operands[0], &operands[1]);
     	icon = RELATION_ITCONC;
     
    +@ =
    +	arity = 1;
    +	operands[0] = Kinds::unary_construction_material(K);
    +	icon = ACTIVITY_ITCONC;
    +
     @ =
     	icon = FUNCTION_ITCONC;
     	kind *X = NULL, *result = NULL;
    diff --git a/inter/Manual/Data Packages in Textual Inter.w b/inter/Manual/Data Packages in Textual Inter.w
    index 2b2ea0315..c307dcdec 100644
    --- a/inter/Manual/Data Packages in Textual Inter.w	
    +++ b/inter/Manual/Data Packages in Textual Inter.w	
    @@ -330,10 +330,10 @@ must be at least one of these, so |struct void| is not allowed.
     (*) |enum|, for which see below;
     
     (*) and then a raft of constructions convenient for Inform but which Inter
    -really knows nothing about: |column of T|, |table of T|, |relation of T1 to T2|,
    -|description of T|, |rulebook of T|, and |rule T1 -> T2|. Perhaps these ought
    -to work via a general way for users to create new constructors, but for now
    -they are hard-wired. They do nothing except to be distinct from each other,
    +really knows nothing about: |activity on T|, |column of T|, |table of T|,
    +|relation of T1 to T2|, |description of T|, |rulebook of T|, and |rule T1 -> T2|.
    +Perhaps these ought to work via a general way for users to create new constructors,
    +but for now they are hard-wired. They do nothing except to be distinct from each other,
     so that Inform can label its data.
     
     Inter applies the usual rules of covariance and contravariance when matching
    diff --git a/inter/bytecode-module/Chapter 3/Inter Data Types.w b/inter/bytecode-module/Chapter 3/Inter Data Types.w
    index fd4a0cf72..e2fd0abb1 100644
    --- a/inter/bytecode-module/Chapter 3/Inter Data Types.w	
    +++ b/inter/bytecode-module/Chapter 3/Inter Data Types.w	
    @@ -24,6 +24,7 @@ invalidate existing Inter binary files, necessitating a bump of //The Inter Vers
     @e TEXT_ITCONC
     @e ENUM_ITCONC
     @e LIST_ITCONC
    +@e ACTIVITY_ITCONC
     @e COLUMN_ITCONC
     @e TABLE_ITCONC
     @e FUNCTION_ITCONC
    @@ -76,6 +77,7 @@ void InterTypes::initialise_constructors(void) {
     	InterTypes::init_con(TEXT_ITCONC,        I"text",        -2147483648, 2147483647, FALSE,  TRUE, 0);
     	InterTypes::init_con(ENUM_ITCONC,        I"enum",                  0, 2147483647,  TRUE,  TRUE, 0);
     	InterTypes::init_con(LIST_ITCONC,        I"list",        -2147483648, 2147483647, FALSE, FALSE, 1);
    +	InterTypes::init_con(ACTIVITY_ITCONC,    I"activity",    -2147483648, 2147483647, FALSE, FALSE, 1);
     	InterTypes::init_con(COLUMN_ITCONC,      I"column",      -2147483648, 2147483647, FALSE, FALSE, 1);
     	InterTypes::init_con(TABLE_ITCONC,       I"table",       -2147483648, 2147483647, FALSE, FALSE, 1);
     	InterTypes::init_con(FUNCTION_ITCONC,    I"function",    -2147483648, 2147483647, FALSE, FALSE, 2);
    @@ -376,6 +378,7 @@ inter_error_message *InterTypes::parse_semisimple(text_stream *text, inter_symbo
     	
     	@;
     	@;
    +	@;
     	@;
     	@;
     	@;
    @@ -407,6 +410,15 @@ inter_error_message *InterTypes::parse_semisimple(text_stream *text, inter_symbo
     		return E;
     	}
     
    +@ =
    +	if (Regexp::match(&mr, text, L"activity on (%C+)")) {
    +		results->constructor_code = ACTIVITY_ITCONC;
    +		inter_type conts_type = InterTypes::parse_simple(T, eloc, mr.exp[0], &E);
    +		InterTypes::add_operand_to_isstd(results, T, conts_type);
    +		Regexp::dispose_of(&mr);
    +		return E;
    +	}
    +
     @ =
     	if (Regexp::match(&mr, text, L"column of (%C+)")) {
     		results->constructor_code = COLUMN_ITCONC;
    @@ -597,6 +609,10 @@ void InterTypes::write_type_longhand(OUTPUT_STREAM, inter_type type) {
     			WRITE(" of ");
     			InterTypes::write_type(OUT, InterTypes::type_operand(type, 0));
     			break;
    +		case ACTIVITY_ITCONC:
    +			WRITE(" on ");
    +			InterTypes::write_type(OUT, InterTypes::type_operand(type, 0));
    +			break;
     		case RELATION_ITCONC:
     			WRITE(" of ");
     			InterTypes::write_type(OUT, InterTypes::type_operand(type, 0));
    diff --git a/services/kinds-module/Chapter 2/Using Kinds.w b/services/kinds-module/Chapter 2/Using Kinds.w
    index e2a23187c..32470eb61 100644
    --- a/services/kinds-module/Chapter 2/Using Kinds.w	
    +++ b/services/kinds-module/Chapter 2/Using Kinds.w	
    @@ -75,8 +75,8 @@ checks that we aren't doing that:
     int Kinds::Behaviour::definite(kind *K) {
     	if (K == NULL) return TRUE;
     	if (KindConstructors::is_definite(K->construct) == FALSE) return FALSE;
    -	int i, arity = KindConstructors::arity(K->construct);
    -	for (i=0; iconstruct);
    +	for (int i=0; ikc_args[i]) == FALSE)
     			return FALSE;
     	return TRUE;
    @@ -87,15 +87,15 @@ int Kinds::Behaviour::semidefinite(kind *K) {
     	if (K->construct == CON_KIND_VARIABLE) return TRUE;
     	if (K->construct == CON_NIL) return FALSE;
     	if (KindConstructors::is_definite(K->construct) == FALSE) return FALSE;
    -	int i, arity = KindConstructors::arity(K->construct);
    +	int arity = KindConstructors::arity(K->construct);
     	if ((K->construct == CON_TUPLE_ENTRY) && (Kinds::eq(K->kc_args[1], K_void))) arity = 1;
    -	if (K->construct == CON_phrase) {
    -		for (i=0; iconstruct == CON_phrase) || (K->construct == CON_activity)) {
    +		for (int i=0; ikc_args[i], K_nil) == FALSE) &&
     				(Kinds::Behaviour::semidefinite(K->kc_args[i]) == FALSE))
     				return FALSE;
     	} else {
    -		for (i=0; ikc_args[i]) == FALSE)
     				return FALSE;
     	}