diff --git a/README.md b/README.md index d894cfc09..3f8063f00 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inform 7 -v10.1.0-alpha.1+6U68 'Krypton' (26 March 2022) +v10.1.0-alpha.1+6U69 'Krypton' (27 March 2022) ## About Inform 7 diff --git a/build.txt b/build.txt index d14cbc6ca..33180cb87 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: alpha.1 -Build Date: 26 March 2022 -Build Number: 6U68 +Build Date: 27 March 2022 +Build Number: 6U69 diff --git a/docs/building-module/1-ls.html b/docs/building-module/1-ls.html index ca4d0e751..27f0c2bbe 100644 --- a/docs/building-module/1-ls.html +++ b/docs/building-module/1-ls.html @@ -275,21 +275,21 @@ many more of these.) inter_symbol *S = InterSymbolsTable::symbol_from_name(tab, N); if (S == NULL) { Ensure the on-demand dictionary exists8.1; - if (Dictionaries::find(create_these_architectural_symbols_on_demand, N)) { + if (Dictionaries::find(create_these_architectural_symbols_on_demand, N)) S = LargeScale::arch_constant_dec(I, N, InterTypes::unchecked(), 0); - } } return S; } int LargeScale::is_veneer_symbol(inter_symbol *con_name) { - if (con_name == NULL) return FALSE; - inter_tree_node *D = con_name->definition; - if (D == NULL) return FALSE; - if (Inode::get_package(D) == LargeScale::architecture_package(Inode::tree(D))) { - text_stream *N = InterSymbol::identifier(con_name); - if (Dictionaries::find(create_these_architectural_symbols_on_demand, N)) - return TRUE; + if (con_name) { + inter_package *home = InterSymbol::package(con_name); + inter_tree *I = InterPackage::tree(home); + if (home == LargeScale::architecture_package(I)) { + text_stream *N = InterSymbol::identifier(con_name); + if (Dictionaries::find(create_these_architectural_symbols_on_demand, N)) + return TRUE; + } } return FALSE; } diff --git a/docs/bytecode-module/2-pck.html b/docs/bytecode-module/2-pck.html index 54429dd03..70034baf9 100644 --- a/docs/bytecode-module/2-pck.html +++ b/docs/bytecode-module/2-pck.html @@ -169,7 +169,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 ddf6ed4ab..9b16ea822 100644 --- a/docs/bytecode-module/2-st.html +++ b/docs/bytecode-module/2-st.html @@ -387,7 +387,7 @@ to access this: one following equations, the other not.

-inter_symbol *InterSymbolsTable::symbol_from_ID_at_node(inter_tree_node *P, int x) {
+inter_symbol *InterSymbolsTable::symbol_from_ID_at_node(inter_tree_node *P, int x) {
     return InterSymbolsTable::symbol_from_ID(InterPackage::scope_of(P), P->W.instruction[x]);
 }
 
@@ -589,7 +589,7 @@ for packages as a special case of URLs for symbols.
 
define MAX_URL_SYMBOL_NAME_DEPTH 512
 
-void InterSymbolsTable::write_symbol_URL(OUTPUT_STREAM, inter_symbol *S) {
+void InterSymbolsTable::write_symbol_URL(OUTPUT_STREAM, inter_symbol *S) {
     inter_package *chain[MAX_URL_SYMBOL_NAME_DEPTH];
     int chain_length = 0;
     inter_package *P = InterSymbolsTable::package(S->owning_table);
diff --git a/docs/bytecode-module/2-sym.html b/docs/bytecode-module/2-sym.html
index 7ce07c7fa..56cd6ac4b 100644
--- a/docs/bytecode-module/2-sym.html
+++ b/docs/bytecode-module/2-sym.html
@@ -162,7 +162,7 @@ metadata symbol: in practice that means if its name begins with §3.  

-inter_package *InterSymbol::package(inter_symbol *S) {
+inter_package *InterSymbol::package(inter_symbol *S) {
     if (S == NULL) return NULL;
     return InterSymbolsTable::package(S->owning_table);
 }
@@ -406,7 +406,7 @@ might be the node holding the instruction:
     return S->definition;
 }
 
-int InterSymbol::is_defined(inter_symbol *S) {
+int InterSymbol::is_defined(inter_symbol *S) {
     if (S == NULL) return FALSE;
     if (InterSymbol::definition(S)) return TRUE;
     return FALSE;
@@ -466,7 +466,7 @@ in the current package. So:
 

§19. Identifier name.

-text_stream *InterSymbol::identifier(inter_symbol *S) {
+text_stream *InterSymbol::identifier(inter_symbol *S) {
     if (S == NULL) return NULL;
     return S->identifier;
 }
diff --git a/docs/bytecode-module/2-trn.html b/docs/bytecode-module/2-trn.html
index 852549695..05a0a7939 100644
--- a/docs/bytecode-module/2-trn.html
+++ b/docs/bytecode-module/2-trn.html
@@ -467,7 +467,9 @@ there are three bad possibilities:
     LOOP_OVER_SYMBOLS_TABLE(S, T) {
         if (Wiring::is_wired(S)) {
             inter_symbol *target = Wiring::cable_end(S);
-            if (pack == LargeScale::architecture_package(I))
+            inter_package *target_package = InterSymbol::package(target);
+            if (target_package ==
+                LargeScale::architecture_package(InterPackage::tree(target_package)))
                 S is wired to an architectural symbol in the origin tree4.2.2.1
             else if (InterSymbol::is_plug(target))
                 S is wired to a loose plug in the origin tree4.2.2.2
diff --git a/docs/bytecode-module/3-ic.html b/docs/bytecode-module/3-ic.html
index 252c8a249..d2bc0a974 100644
--- a/docs/bytecode-module/3-ic.html
+++ b/docs/bytecode-module/3-ic.html
@@ -338,6 +338,8 @@ but give it no syntax. If so, it will be inexpressible in textual Inter code.
             i += 5; WRITE_TO(regexp, "(%%d+)");
         } else if (Str::includes_wide_string_at(syntax, L"TOKENS", i)) {
             i += 5; WRITE_TO(regexp, "(%%c+)");
+        } else if (Str::includes_wide_string_at(syntax, L"MINTOKENS", i)) {
+            i += 8; WRITE_TO(regexp, "(%%c+?)");
         } else if (Str::includes_wide_string_at(syntax, L"TOKEN", i)) {
             i += 4; WRITE_TO(regexp, "(%%C+)");
         } else if (Str::includes_wide_string_at(syntax, L"TEXT", i)) {
diff --git a/docs/bytecode-module/3-idt.html b/docs/bytecode-module/3-idt.html
index 63987cb21..d9c96e315 100644
--- a/docs/bytecode-module/3-idt.html
+++ b/docs/bytecode-module/3-idt.html
@@ -700,7 +700,7 @@ just print that name, K_whate
 
 void InterTypes::write_type(OUTPUT_STREAM, inter_type type) {
     if (type.type_name) {
-        TextualInter::write_symbol(OUT, type.type_name);
+        InterSymbolsTable::write_symbol_URL(OUT, type.type_name);
     } else {
         InterTypes::write_type_longhand(OUT, type);
     }
@@ -759,7 +759,7 @@ just print that name, K_whate
 

-int InterTypes::is_enumerated(inter_type type) {
+int InterTypes::is_enumerated(inter_type type) {
     inter_type_constructor *itc = InterTypes::constructor(type);
     if (itc->is_enumerated) return TRUE;
     return FALSE;
@@ -770,6 +770,13 @@ just print that name, K_whate
     if ((N < itc->min_value) || (N > itc->max_value)) return FALSE;
     return TRUE;
 }
+
+
+int InterTypes::unsigned_literal_is_in_range(long long int N, inter_type type) {
+    inter_type_constructor *itc = InterTypes::constructor(type);
+    if ((N < 0) || (N > itc->max_value - itc->min_value)) return FALSE;
+    return TRUE;
+}
 

§22. This is what matters: whether we allow a value of type A to be used where a value of type B is expected. @@ -783,7 +790,7 @@ split into four cases as to whether they are the same or different.

-inter_error_message *InterTypes::can_be_used_as(inter_type A, inter_type B,
+inter_error_message *InterTypes::can_be_used_as(inter_type A, inter_type B,
     text_stream *S, inter_error_location *eloc) {
     inter_type_constructor *A_itc = InterTypes::constructor(A);
     inter_type_constructor *B_itc = InterTypes::constructor(B);
@@ -920,7 +927,7 @@ function arguments are contravariant.
 

-inter_type InterTypes::of_symbol(inter_symbol *symb) {
+inter_type InterTypes::of_symbol(inter_symbol *symb) {
     if (symb == NULL) return InterTypes::unchecked();
     inter_tree_node *D = InterSymbol::definition(symb);
     if (D == NULL) return InterTypes::unchecked();
@@ -931,7 +938,7 @@ function arguments are contravariant.
     return InterTypes::unchecked();
 }
 
-int InterTypes::expresses_value(inter_symbol *symb) {
+int InterTypes::expresses_value(inter_symbol *symb) {
     inter_tree_node *D = InterSymbol::definition(symb);
     if (D) {
         inter_construct *IC = NULL;
diff --git a/docs/bytecode-module/3-ie.html b/docs/bytecode-module/3-ie.html
index d200343c8..8e502fbd4 100644
--- a/docs/bytecode-module/3-ie.html
+++ b/docs/bytecode-module/3-ie.html
@@ -130,7 +130,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 57d9fc0de..325c69314 100644
--- a/docs/bytecode-module/3-iitf.html
+++ b/docs/bytecode-module/3-iitf.html
@@ -318,6 +318,7 @@ resolve forward references at the end of the parsing process — see below.
             Wiring::wire_to_name(S, name);
         }
         DISCARD_TEXT(leaf)
+        return S;
     }
 
  • This code is used in §5.
@@ -329,14 +330,10 @@ But it really doesn't need to catch every possible error; this is Inter, not Inf

-    inter_tree_node *D = InterSymbol::definition(S);
     if (InterSymbol::defined_elsewhere(S)) return S;
     if (InterSymbol::misc_but_undefined(S)) return S;
-    if (D == NULL) {
-        *E = InterErrors::quoted(I"undefined symbol", name, eloc); return NULL;
-    }
-    if ((Inode::isnt(D, construct)) &&
-        (InterSymbol::misc_but_undefined(S) == FALSE)) {
+    inter_tree_node *D = InterSymbol::definition(S);
+    if ((D) && (Inode::isnt(D, construct))) {
         text_stream *err = Str::new();
         WRITE_TO(err, "symbol has type %d not %d: ", Inode::get_construct_ID(D), construct);
         InterSymbolsTable::write_symbol_URL(err, S);
@@ -472,7 +469,7 @@ the filter test.
 

§10. Utility functions for writing construct lines.

-void TextualInter::write_symbol(OUTPUT_STREAM, inter_symbol *S) {
+void TextualInter::write_symbol(OUTPUT_STREAM, inter_symbol *S) {
     if (Wiring::is_wired(S)) {
         InterSymbolsTable::write_symbol_URL(OUT, Wiring::cable_end(S));
     } else if (S) {
@@ -482,7 +479,7 @@ the filter test.
     }
 }
 
-void TextualInter::write_symbol_from(OUTPUT_STREAM, inter_tree_node *P, int field) {
+void TextualInter::write_symbol_from(OUTPUT_STREAM, inter_tree_node *P, int field) {
     inter_symbol *S = InterSymbolsTable::symbol_from_ID_not_following(
         InterPackage::scope_of(P), P->W.instruction[field]);
     TextualInter::write_symbol(OUT, S);
@@ -564,7 +561,7 @@ outer structure:
     wchar_t first_char = Str::get_first_char(S);
     wchar_t last_char = Str::get_last_char(S);
     int is_identifier = FALSE;
-    if (Characters::isalpha(first_char)) {
+    if ((Characters::isalpha(first_char)) || (first_char == '_')) {
         is_identifier = TRUE;
         LOOP_THROUGH_TEXT(pos, S)
             if ((Characters::isalpha(Str::get(pos)) == FALSE) &&
@@ -583,6 +580,7 @@ outer structure:
                 break;
             }
     }
+    if ((Str::get_at(S, 0) == '#') && (Str::get_at(S, 1) == '#')) is_identifier = TRUE;
 
     Parse numeric literal syntax12.2;
     Parse text literal syntax12.4;
@@ -636,8 +634,13 @@ or (unsigned) binary, but cannot be printed back in binary.
             if (pos.index > 34) return InterErrors::quoted(I"value out of range", S, eloc);
         }
         N = sign*N;
-        if (InterTypes::literal_is_in_range(N, type_wanted) == FALSE)
-            return InterErrors::quoted(I"value out of range", S, eloc);
+        if (base == 10) {
+            if (InterTypes::literal_is_in_range(N, type_wanted) == FALSE)
+                return InterErrors::quoted(I"value out of range", S, eloc);
+        } else {
+            if (InterTypes::unsigned_literal_is_in_range(N, type_wanted) == FALSE)
+                return InterErrors::quoted(I"value out of range", S, eloc);
+        }
         if (sign == -1) *pair = InterValuePairs::signed_number((int) N);
         else *pair = InterValuePairs::number_in_base((inter_ti) N, base);
         return NULL;
@@ -820,8 +823,6 @@ one above.
 

-    if ((InterTypes::is_enumerated(type_wanted)) && (InterSymbol::is_defined(symb) == FALSE))
-        return InterErrors::quoted(I"undefined symbol", S, eloc);
     inter_type symbol_type = InterTypes::of_symbol(symb);
     inter_error_message *E = InterTypes::can_be_used_as(symbol_type, type_wanted, S, eloc);
     if (E) return E;
diff --git a/docs/bytecode-module/3-vi.html b/docs/bytecode-module/3-vi.html
index ec1f95a91..5b9e33a22 100644
--- a/docs/bytecode-module/3-vi.html
+++ b/docs/bytecode-module/3-vi.html
@@ -223,11 +223,7 @@ the program has not yet been loaded); but it cannot be the wrong sort of thing.
     inter_tree_node *D = InterSymbol::definition(S);
     if (InterSymbol::defined_elsewhere(S)) return NULL;
     if (InterSymbol::misc_but_undefined(S)) return NULL;
-    if (D == NULL) return Inode::error(P, I"undefined symbol", InterSymbol::identifier(S));
-    if ((construct != INVALID_IST) &&
-        (Inode::isnt(D, construct)) &&
-        (InterSymbol::defined_elsewhere(S) == FALSE) &&
-        (InterSymbol::misc_but_undefined(S) == FALSE)) {
+    if ((construct != INVALID_IST) && (D) && (Inode::isnt(D, construct))) {
         text_stream *err = Str::new();
         WRITE_TO(err, "symbol has type %d not %d: ", Inode::get_construct_ID(D), construct);
         InterSymbolsTable::write_symbol_URL(err, S);
diff --git a/docs/bytecode-module/4-tcc2.html b/docs/bytecode-module/4-tcc2.html
index d269d8fb7..7e3b60b7e 100644
--- a/docs/bytecode-module/4-tcc2.html
+++ b/docs/bytecode-module/4-tcc2.html
@@ -82,7 +82,7 @@ function togglePopup(material_id) {
 void ConstantInstruction::define_construct(void) {
     inter_construct *IC = InterInstruction::create_construct(CONSTANT_IST, I"constant");
     InterInstruction::defines_symbol_in_fields(IC, DEFN_CONST_IFLD, TYPE_CONST_IFLD);
-    InterInstruction::specify_syntax(IC, I"constant TOKENS = TOKENS");
+    InterInstruction::specify_syntax(IC, I"constant MINTOKENS = TOKENS");
     InterInstruction::data_extent_at_least(IC, 3);
     InterInstruction::permit(IC, INSIDE_PLAIN_PACKAGE_ICUP);
     METHOD_ADD(IC, CONSTRUCT_READ_MTID, ConstantInstruction::read);
diff --git a/docs/bytecode-module/4-tic2.html b/docs/bytecode-module/4-tic2.html
index cb2bc8061..e948459a5 100644
--- a/docs/bytecode-module/4-tic2.html
+++ b/docs/bytecode-module/4-tic2.html
@@ -191,8 +191,6 @@ the typename_s that it has a new instance.
     match_results mr = Regexp::create_mr();
     if (Regexp::match(&mr, type_text, L"%((%c+)%)"))
         inst_type = InterTypes::parse_simple(InterBookmark::scope(IBM), eloc, mr.exp[0], E);
-    if (InterTypes::is_enumerated(inst_type) == FALSE)
-        *E = InterErrors::quoted(I"not an enumerated type", type_text, eloc);
     Regexp::dispose_of(&mr);
     if (*E) return;
 
@@ -220,9 +218,9 @@ the typename_s that it has a new instance.
 void InstanceInstruction::write(inter_construct *IC, OUTPUT_STREAM, inter_tree_node *P) {
     inter_symbol *instance_s = InstanceInstruction::instance(P);
-    inter_symbol *typename_s = InterSymbolsTable::symbol_from_ID_at_node(P, TYPE_INST_IFLD);
-    WRITE("instance (%S) %S = ",
-        InterSymbol::identifier(typename_s), InterSymbol::identifier(instance_s));
+    WRITE("instance (");
+    TextualInter::write_symbol_from(OUT, P, TYPE_INST_IFLD);
+    WRITE(") %S = ", InterSymbol::identifier(instance_s));
     TextualInter::write_pair(OUT, P, InterValuePairs::get(P, VAL1_INST_IFLD));
 }
 
diff --git a/docs/bytecode-module/4-tpc3.html b/docs/bytecode-module/4-tpc3.html index 79ea88bab..376eb7377 100644 --- a/docs/bytecode-module/4-tpc3.html +++ b/docs/bytecode-module/4-tpc3.html @@ -206,30 +206,32 @@ the new permission to the list for the owner and for the property.
 void PermissionInstruction::write(inter_construct *IC, OUTPUT_STREAM, inter_tree_node *P) {
-    inter_symbol *prop_s = PermissionInstruction::property(P);
-    inter_symbol *owner_s = PermissionInstruction::owner(P);
-    inter_symbol *storage_s = PermissionInstruction::storage(P);
-    WRITE("permission for %S to have %S",
-        InterSymbol::identifier(owner_s), InterSymbol::identifier(prop_s));
-    if (storage_s) WRITE(" %S", InterSymbol::identifier(storage_s));
+    WRITE("permission for ");
+    TextualInter::write_symbol_from(OUT, P, OWNER_PERM_IFLD);
+    WRITE(" to have ");
+    TextualInter::write_symbol_from(OUT, P, PROP_PERM_IFLD);
+    if (PermissionInstruction::storage(P)) {
+        WRITE(" ");
+        TextualInter::write_symbol_from(OUT, P, STORAGE_PERM_IFLD);
+    }
 }
 

§6. Access functions.

-inter_symbol *PermissionInstruction::property(inter_tree_node *P) {
+inter_symbol *PermissionInstruction::property(inter_tree_node *P) {
     if (P == NULL) return NULL;
     if (Inode::isnt(P, PERMISSION_IST)) return NULL;
     return InterSymbolsTable::symbol_from_ID_at_node(P, PROP_PERM_IFLD);
 }
 
-inter_symbol *PermissionInstruction::owner(inter_tree_node *P) {
+inter_symbol *PermissionInstruction::owner(inter_tree_node *P) {
     if (P == NULL) return NULL;
     if (Inode::isnt(P, PERMISSION_IST)) return NULL;
     return InterSymbolsTable::symbol_from_ID_at_node(P, OWNER_PERM_IFLD);
 }
 
-inter_symbol *PermissionInstruction::storage(inter_tree_node *P) {
+inter_symbol *PermissionInstruction::storage(inter_tree_node *P) {
     if (P == NULL) return NULL;
     if (Inode::isnt(P, PERMISSION_IST)) return NULL;
     if (P->W.instruction[STORAGE_PERM_IFLD] == 0) return NULL;
diff --git a/docs/bytecode-module/4-tpc7.html b/docs/bytecode-module/4-tpc7.html
index 10e09b6e3..c563342e8 100644
--- a/docs/bytecode-module/4-tpc7.html
+++ b/docs/bytecode-module/4-tpc7.html
@@ -233,23 +233,24 @@ value to the list of properties of the owner.
 
 
 void PropertyValueInstruction::write(inter_construct *IC, OUTPUT_STREAM, inter_tree_node *P) {
-    inter_symbol *prop_s = PropertyValueInstruction::property(P);
-    inter_symbol *owner_s = PropertyValueInstruction::owner(P);
-    WRITE("propertyvalue %S of %S = ",
-        InterSymbol::identifier(prop_s), InterSymbol::identifier(owner_s));
+    WRITE("propertyvalue ");
+    TextualInter::write_symbol_from(OUT, P, PROP_PVAL_IFLD);
+    WRITE(" of ");
+    TextualInter::write_symbol_from(OUT, P, OWNER_PVAL_IFLD);
+    WRITE(" = ");
     TextualInter::write_pair(OUT, P, PropertyValueInstruction::value(P));
 }
 

§6. Access functions.

-inter_symbol *PropertyValueInstruction::property(inter_tree_node *P) {
+inter_symbol *PropertyValueInstruction::property(inter_tree_node *P) {
     if (P == NULL) return NULL;
     if (Inode::isnt(P, PROPERTYVALUE_IST)) return NULL;
     return InterSymbolsTable::symbol_from_ID_at_node(P, PROP_PVAL_IFLD);
 }
 
-inter_symbol *PropertyValueInstruction::owner(inter_tree_node *P) {
+inter_symbol *PropertyValueInstruction::owner(inter_tree_node *P) {
     if (P == NULL) return NULL;
     if (Inode::isnt(P, PROPERTYVALUE_IST)) return NULL;
     return InterSymbolsTable::symbol_from_ID_at_node(P, OWNER_PVAL_IFLD);
diff --git a/docs/bytecode-module/4-ttc.html b/docs/bytecode-module/4-ttc.html
index d848854a1..0c0ce8838 100644
--- a/docs/bytecode-module/4-ttc.html
+++ b/docs/bytecode-module/4-ttc.html
@@ -229,7 +229,8 @@ length is flexible: there can be any number of operands from 0 upwards.
     WRITE("typename %S ", InterSymbol::identifier(typename_s));
     inter_symbol *super = TypenameInstruction::super(typename_s);
     if (super) {
-        WRITE("<= %S", InterSymbol::identifier(super));
+        WRITE("<= ");
+        TextualInter::write_symbol_from(OUT, P, SUPER_TYPENAME_IFLD);
     } else {
         WRITE("= ");
         InterTypes::write_typename_definition(OUT, typename_s);
diff --git a/docs/inter/M-io.html b/docs/inter/M-io.html
index 416016513..13a65a77f 100644
--- a/docs/inter/M-io.html
+++ b/docs/inter/M-io.html
@@ -18,6 +18,7 @@
 
 
 
+
 		
 	
 	
@@ -70,7 +71,7 @@
     
 

The standard hierarchy of inter code generated by Inform.

-
+

§1. Status. The line between what is part of the Inter specification, and what is simply a convention about its use, is a fine one. For example, Inter allows @@ -271,6 +272,19 @@ stack frame is disposed of again. This is all transparent to the user, who simply calls call and doesn't need to know which mechanism is in play.

+

§9. Looking at the Inter produced. The following commands produce the final state of the Inter code for the test +case Acidity, in binary and textual form: +

+ +
+$ 'inform7/Tangled/inform7' -source inform7/Tests/Test\ Cases/Acidity.txt -o Acidity.interb -format=binary
+$ 'inform7/Tangled/inform7' -source inform7/Tests/Test\ Cases/Acidity.txt -o Acidity.intert -format=text
+
+

Be warned that they are large: they have several large kits linked into them +by the time they have reached this final state, and thus contain many modules. +Acidity.intert runs to about 250,000 lines of textual Inter. +

+ diff --git a/docs/runtime-module/2-hrr.html b/docs/runtime-module/2-hrr.html index bc3ec83ad..07ac82b5a 100644 --- a/docs/runtime-module/2-hrr.html +++ b/docs/runtime-module/2-hrr.html @@ -259,7 +259,7 @@ and The Standard Kits ( H_BEGIN_DECLARATIONS Establish locations for material created by the compiler8.1; Establish locations for material expected to be added by linking8.2; - Prevent arcbitectural symbols from being doubly defined8.3; + Prevent architectural symbols from being doubly defined8.3; H_END_DECLARATIONS }
@@ -299,7 +299,7 @@ and The Standard Kits (

-    Establish architecturak resources8.2.2;
+    Establish architectural resources8.2.2;
 
  • This code is used in §8.

§8.1.1. Basics.

@@ -2135,7 +2135,7 @@ ones which the //inform7//-compiled code needs to refer to. enum MAX_POSITIVE_NUMBER_HL enum MIN_NEGATIVE_NUMBER_HL
-

§8.2.2. Establish architecturak resources8.2.2 = +

§8.2.2. Establish architectural resources8.2.2 =

@@ -2153,11 +2153,12 @@ create a duplicate with a name like Prevent arcbitectural symbols from being doubly defined8.3 =
+

Prevent architectural symbols from being doubly defined8.3 =

-    InterNames::to_symbol(Hierarchy::find(SELF_HL));
+    inter_name *self_iname = Hierarchy::find(SELF_HL);
+    self_iname->symbol = LargeScale::find_architectural_symbol(I, I"self");
     InterNames::to_symbol(Hierarchy::find(MAX_POSITIVE_NUMBER_HL));
     InterNames::to_symbol(Hierarchy::find(MIN_NEGATIVE_NUMBER_HL));
     InterNames::to_symbol(Hierarchy::find(NULL_HL));
diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt
index 51eb3b020..0e0e3b2ee 100644
--- a/inform7/Figures/memory-diagnostics.txt
+++ b/inform7/Figures/memory-diagnostics.txt
@@ -1,4 +1,4 @@
-Total memory consumption was 379108K = 370 MB
+Total memory consumption was 379106K = 370 MB
 
 66.6% was used for 2005891 objects, in 360763 frames in 316 x 800K = 252800K = 246 MB:
 
@@ -237,7 +237,7 @@ Total memory consumption was 379108K = 370 MB
 
 33.3% was used for memory not allocated for objects:
 
-    19.7%  text stream storage                      76627004 bytes in 452128 claims
+    19.7%  text stream storage                      76624528 bytes in 452128 claims
      1.1%  dictionary storage                       4544512 bytes in 6619 claims
      ----  sorting                                  744 bytes in 3 claims
      1.8%  source text                              7200000 bytes in 3 claims
@@ -245,8 +245,8 @@ Total memory consumption was 379108K = 370 MB
      ----  documentation fragments                  262144 bytes in 1 claim
      ----  linguistic stock array                   81920 bytes in 2 claims
      ----  small word set array                     105600 bytes in 22 claims
-     1.1%  inter symbols storage                    4521792 bytes in 27920 claims
-     4.3%  inter bytecode storage                   16767756 bytes in 14 claims
+     1.1%  inter symbols storage                    4522288 bytes in 27921 claims
+     4.3%  inter bytecode storage                   16767476 bytes in 14 claims
      1.6%  inter links storage                      6222976 bytes in 11 claims
      ----  inter tree location list storage         191232 bytes in 32 claims
      0.4%  instance-of-kind counting                1695204 bytes in 1 claim
diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt
index c91d7a78d..cf96dc64c 100644
--- a/inform7/Figures/timings-diagnostics.txt
+++ b/inform7/Figures/timings-diagnostics.txt
@@ -1,12 +1,12 @@
 100.0% in inform7 run
-     68.1% in compilation to Inter
-         47.6% in //Sequence::undertake_queued_tasks//
-          4.5% in //MajorNodes::pre_pass//
-          3.3% in //MajorNodes::pass_1//
-          2.4% in //RTPhrasebook::compile_entries//
-          1.6% in //ImperativeDefinitions::assess_all//
+     68.6% in compilation to Inter
+         47.8% in //Sequence::undertake_queued_tasks//
+          4.6% in //MajorNodes::pre_pass//
+          3.2% in //MajorNodes::pass_1//
+          2.5% in //RTPhrasebook::compile_entries//
+          1.7% in //ImperativeDefinitions::assess_all//
           1.5% in //RTKindConstructors::compile//
-          1.1% in //Sequence::lint_inter//
+          0.9% in //Sequence::lint_inter//
           0.5% in //MajorNodes::pass_2//
           0.5% in //Sequence::undertake_queued_tasks//
           0.5% in //World::stage_V//
@@ -16,18 +16,17 @@
           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.4% not specifically accounted for
-     29.0% in running Inter pipeline
-         10.1% in step 14/14: generate inform6 -> auto.inf
-          7.7% in step 5/14: load-binary-kits
-          6.7% in step 6/14: make-synoptic-module
-          1.5% in step 9/14: make-identifiers-unique
+          2.8% not specifically accounted for
+     28.6% in running Inter pipeline
+         10.2% in step 14/14: generate inform6 -> auto.inf
+          7.5% in step 5/14: load-binary-kits
+          6.3% in step 6/14: make-synoptic-module
+          1.3% in step 9/14: make-identifiers-unique
           0.3% in step 12/14: eliminate-redundant-operations
           0.3% in step 4/14: compile-splats
           0.3% in step 7/14: shorten-wiring
           0.3% in step 8/14: detect-indirect-calls
           0.1% in step 11/14: eliminate-redundant-labels
-          1.2% not specifically accounted for
-      2.2% in supervisor
-      0.6% 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/Hierarchy.w b/inform7/runtime-module/Chapter 2/Hierarchy.w
index 1128be39a..acd245fae 100644
--- a/inform7/runtime-module/Chapter 2/Hierarchy.w	
+++ b/inform7/runtime-module/Chapter 2/Hierarchy.w	
@@ -166,7 +166,7 @@ void Hierarchy::establish(void) {
 	H_BEGIN_DECLARATIONS
 	@;
 	@;
-	@;
+	@;
 	H_END_DECLARATIONS
 }
 
@@ -199,7 +199,7 @@ void Hierarchy::establish(void) {
 	@;
 
 @ =
-	@;
+	@;
 
 @h Basics.
 
@@ -1950,7 +1950,7 @@ ones which the //inform7//-compiled code needs to refer to.
 @e MAX_POSITIVE_NUMBER_HL
 @e MIN_NEGATIVE_NUMBER_HL
 
-@ =
+@ =
 	H_BEGIN(LocationRequirements::architectural_package(I))
 		H_C_T(SELF_HL,                        I"self")
 		H_C_T(NULL_HL,                        I"NULL")
@@ -1963,8 +1963,9 @@ anyway, we need to make sure that a call to |Hierarchy::find| does not
 create a duplicate with a name like |NULL_1|. This is a race condition, and
 the easiest way to avoid it is to force the issue now:
 
-@ =
-	InterNames::to_symbol(Hierarchy::find(SELF_HL));
+@ =
+	inter_name *self_iname = Hierarchy::find(SELF_HL);
+	self_iname->symbol = LargeScale::find_architectural_symbol(I, I"self");
 	InterNames::to_symbol(Hierarchy::find(MAX_POSITIVE_NUMBER_HL));
 	InterNames::to_symbol(Hierarchy::find(MIN_NEGATIVE_NUMBER_HL));
 	InterNames::to_symbol(Hierarchy::find(NULL_HL));
diff --git a/inter/Manual/Inform Organisation.w b/inter/Manual/Inform Organisation.w
index d0ee76700..125db11f6 100644
--- a/inter/Manual/Inform Organisation.w	
+++ b/inter/Manual/Inform Organisation.w	
@@ -191,3 +191,14 @@ The "shell" function, |call|, creates a stack frame and then calls the "kernel"
 function, which does the actual work; when that returns to the "shell", the
 stack frame is disposed of again. This is all transparent to the user, who
 simply calls |call| and doesn't need to know which mechanism is in play.
+
+@h Looking at the Inter produced.
+The following commands produce the final state of the Inter code for the test
+case |Acidity|, in binary and textual form:
+= (text as ConsoleText)
+$ 'inform7/Tangled/inform7' -source inform7/Tests/Test\ Cases/Acidity.txt -o Acidity.interb -format=binary
+$ 'inform7/Tangled/inform7' -source inform7/Tests/Test\ Cases/Acidity.txt -o Acidity.intert -format=text
+=
+Be warned that they are large: they have several large kits linked into them
+by the time they have reached this final state, and thus contain many modules.
+|Acidity.intert| runs to about 250,000 lines of textual Inter.
diff --git a/inter/Tests/Valid/misc.intert b/inter/Tests/Valid/misc.intert
index efa656668..94622ee61 100644
--- a/inter/Tests/Valid/misc.intert
+++ b/inter/Tests/Valid/misc.intert
@@ -20,6 +20,7 @@ package main _plain
 	constant (K_number) cornelius = dw"frogs"
 	constant (K_number) gaius = dw"toads"
 	constant emptytext = ""
+	constant IMPROBABLE_VALUE = 0xdeadce11
 	splat "Sing a song of \"six splats\"...\nand don't wait up"
 	typename K_colour = enum
 	instance (K_colour) I_green = 1
@@ -85,3 +86,14 @@ package main _plain
 			inv !return
 				val (/main/K_colour) /main/I_red
 	constant (K_number) amount = sum{ 2, C_taxes }
+	package glk_buffer_to_upper_case_uni _code
+		local _vararg_count
+		local ret
+		code
+			inv @glk
+				val 289
+				val _vararg_count
+				val ret
+			inv !return
+				val ret
+	constant (text) ^text = "A = B"
diff --git a/inter/building-module/Chapter 1/Large-Scale Structure.w b/inter/building-module/Chapter 1/Large-Scale Structure.w
index 4f7f6b6e8..c6f585893 100644
--- a/inter/building-module/Chapter 1/Large-Scale Structure.w	
+++ b/inter/building-module/Chapter 1/Large-Scale Structure.w	
@@ -195,21 +195,21 @@ inter_symbol *LargeScale::find_architectural_symbol(inter_tree *I, text_stream *
 	inter_symbol *S = InterSymbolsTable::symbol_from_name(tab, N);
 	if (S == NULL) {
 		@;
-		if (Dictionaries::find(create_these_architectural_symbols_on_demand, N)) {
-			S = LargeScale::arch_constant_dec(I, N, InterTypes::unchecked(), 0);			
-		}	
+		if (Dictionaries::find(create_these_architectural_symbols_on_demand, N))
+			S = LargeScale::arch_constant_dec(I, N, InterTypes::unchecked(), 0);
 	}	
 	return S;
 }
 
 int LargeScale::is_veneer_symbol(inter_symbol *con_name) {
-	if (con_name == NULL) return FALSE;
-	inter_tree_node *D = con_name->definition;
-	if (D == NULL) return FALSE;
-	if (Inode::get_package(D) == LargeScale::architecture_package(Inode::tree(D))) {
-		text_stream *N = InterSymbol::identifier(con_name);
-		if (Dictionaries::find(create_these_architectural_symbols_on_demand, N))
-			return TRUE;
+	if (con_name) {
+		inter_package *home = InterSymbol::package(con_name);
+		inter_tree *I = InterPackage::tree(home);
+		if (home == LargeScale::architecture_package(I)) {
+			text_stream *N = InterSymbol::identifier(con_name);
+			if (Dictionaries::find(create_these_architectural_symbols_on_demand, N))
+				return TRUE;
+		}
 	}
 	return FALSE;
 }
diff --git a/inter/bytecode-module/Chapter 2/Transmigration.w b/inter/bytecode-module/Chapter 2/Transmigration.w
index 3321e8ba0..2334e06bf 100644
--- a/inter/bytecode-module/Chapter 2/Transmigration.w	
+++ b/inter/bytecode-module/Chapter 2/Transmigration.w	
@@ -326,7 +326,9 @@ there are three bad possibilities:
 	LOOP_OVER_SYMBOLS_TABLE(S, T) {
 		if (Wiring::is_wired(S)) {
 			inter_symbol *target = Wiring::cable_end(S);
-			if (pack == LargeScale::architecture_package(I))
+			inter_package *target_package = InterSymbol::package(target);
+			if (target_package ==
+				LargeScale::architecture_package(InterPackage::tree(target_package)))
 				@
 			else if (InterSymbol::is_plug(target))
 				@
diff --git a/inter/bytecode-module/Chapter 3/Inter Constructs.w b/inter/bytecode-module/Chapter 3/Inter Constructs.w
index 3d6d71b59..3578f974a 100644
--- a/inter/bytecode-module/Chapter 3/Inter Constructs.w	
+++ b/inter/bytecode-module/Chapter 3/Inter Constructs.w	
@@ -256,6 +256,8 @@ void InterInstruction::specify_syntax(inter_construct *IC, text_stream *syntax)
 			i += 5; WRITE_TO(regexp, "(%%d+)");
 		} else if (Str::includes_wide_string_at(syntax, L"TOKENS", i)) {
 			i += 5; WRITE_TO(regexp, "(%%c+)");
+		} else if (Str::includes_wide_string_at(syntax, L"MINTOKENS", i)) {
+			i += 8; WRITE_TO(regexp, "(%%c+?)");
 		} else if (Str::includes_wide_string_at(syntax, L"TOKEN", i)) {
 			i += 4; WRITE_TO(regexp, "(%%C+)");
 		} else if (Str::includes_wide_string_at(syntax, L"TEXT", i)) {
diff --git a/inter/bytecode-module/Chapter 3/Inter Data Types.w b/inter/bytecode-module/Chapter 3/Inter Data Types.w
index 45aa98e62..7636b3da9 100644
--- a/inter/bytecode-module/Chapter 3/Inter Data Types.w	
+++ b/inter/bytecode-module/Chapter 3/Inter Data Types.w	
@@ -562,7 +562,7 @@ just print that name, |K_whatever|.
 =
 void InterTypes::write_type(OUTPUT_STREAM, inter_type type) {
 	if (type.type_name) {
-		TextualInter::write_symbol(OUT, type.type_name);
+		InterSymbolsTable::write_symbol_URL(OUT, type.type_name);
 	} else {
 		InterTypes::write_type_longhand(OUT, type);
 	}
@@ -632,6 +632,13 @@ int InterTypes::literal_is_in_range(long long int N, inter_type type) {
 	return TRUE;
 }
 
+
+int InterTypes::unsigned_literal_is_in_range(long long int N, inter_type type) {
+	inter_type_constructor *itc = InterTypes::constructor(type);
+	if ((N < 0) || (N > itc->max_value - itc->min_value)) return FALSE;
+	return TRUE;
+}
+
 @ This is what matters: whether we allow a value of type |A| to be used where
 a value of type |B| is expected.
 
diff --git a/inter/bytecode-module/Chapter 3/Inter in Text Files.w b/inter/bytecode-module/Chapter 3/Inter in Text Files.w
index 078e9a5e6..f6532b50c 100644
--- a/inter/bytecode-module/Chapter 3/Inter in Text Files.w	
+++ b/inter/bytecode-module/Chapter 3/Inter in Text Files.w	
@@ -219,20 +219,17 @@ resolve forward references at the end of the parsing process -- see below.
 			Wiring::wire_to_name(S, name);
 		}
 		DISCARD_TEXT(leaf)
+		return S;
 	}
 
 @ This check is not foolproof. In particular, it is fooled by forward references.
 But it really doesn't need to catch every possible error; this is Inter, not Inform.
 
 @ =
-	inter_tree_node *D = InterSymbol::definition(S);
 	if (InterSymbol::defined_elsewhere(S)) return S;
 	if (InterSymbol::misc_but_undefined(S)) return S;
-	if (D == NULL) {
-		*E = InterErrors::quoted(I"undefined symbol", name, eloc); return NULL;
-	}
-	if ((Inode::isnt(D, construct)) &&
-		(InterSymbol::misc_but_undefined(S) == FALSE)) {
+	inter_tree_node *D = InterSymbol::definition(S);
+	if ((D) && (Inode::isnt(D, construct))) {
 		text_stream *err = Str::new();
 		WRITE_TO(err, "symbol has type %d not %d: ", Inode::get_construct_ID(D), construct);
 		InterSymbolsTable::write_symbol_URL(err, S);
@@ -446,7 +443,7 @@ inter_error_message *TextualInter::parse_pair(text_stream *line, inter_error_loc
 	wchar_t first_char = Str::get_first_char(S);
 	wchar_t last_char = Str::get_last_char(S);
 	int is_identifier = FALSE;
-	if (Characters::isalpha(first_char)) {
+	if ((Characters::isalpha(first_char)) || (first_char == '_')) {
 		is_identifier = TRUE;
 		LOOP_THROUGH_TEXT(pos, S)
 			if ((Characters::isalpha(Str::get(pos)) == FALSE) &&
@@ -465,6 +462,7 @@ inter_error_message *TextualInter::parse_pair(text_stream *line, inter_error_loc
 				break;
 			}
 	}
+	if ((Str::get_at(S, 0) == '#') && (Str::get_at(S, 1) == '#')) is_identifier = TRUE;
 
 	@;
 	@;
@@ -510,8 +508,13 @@ or (unsigned) binary, but cannot be printed back in binary.
 			if (pos.index > 34) return InterErrors::quoted(I"value out of range", S, eloc);
 		}
 		N = sign*N;
-		if (InterTypes::literal_is_in_range(N, type_wanted) == FALSE)
-			return InterErrors::quoted(I"value out of range", S, eloc);
+		if (base == 10) {
+			if (InterTypes::literal_is_in_range(N, type_wanted) == FALSE)
+				return InterErrors::quoted(I"value out of range", S, eloc);
+		} else {
+			if (InterTypes::unsigned_literal_is_in_range(N, type_wanted) == FALSE)
+				return InterErrors::quoted(I"value out of range", S, eloc);
+		}
 		if (sign == -1) *pair = InterValuePairs::signed_number((int) N);
 		else *pair = InterValuePairs::number_in_base((inter_ti) N, base);
 		return NULL;
@@ -637,8 +640,6 @@ one above.
 	}
 
 @ =
-	if ((InterTypes::is_enumerated(type_wanted)) && (InterSymbol::is_defined(symb) == FALSE))
-		return InterErrors::quoted(I"undefined symbol", S, eloc);
 	inter_type symbol_type = InterTypes::of_symbol(symb);
 	inter_error_message *E = InterTypes::can_be_used_as(symbol_type, type_wanted, S, eloc);
 	if (E) return E;
diff --git a/inter/bytecode-module/Chapter 3/Verifying Inter.w b/inter/bytecode-module/Chapter 3/Verifying Inter.w
index f76fcd654..570eec31c 100644
--- a/inter/bytecode-module/Chapter 3/Verifying Inter.w	
+++ b/inter/bytecode-module/Chapter 3/Verifying Inter.w	
@@ -124,11 +124,7 @@ inter_error_message *VerifyingInter::SID(inter_package *owner, inter_tree_node *
 	inter_tree_node *D = InterSymbol::definition(S);
 	if (InterSymbol::defined_elsewhere(S)) return NULL;
 	if (InterSymbol::misc_but_undefined(S)) return NULL;
-	if (D == NULL) return Inode::error(P, I"undefined symbol", InterSymbol::identifier(S));
-	if ((construct != INVALID_IST) &&
-		(Inode::isnt(D, construct)) &&
-		(InterSymbol::defined_elsewhere(S) == FALSE) &&
-		(InterSymbol::misc_but_undefined(S) == FALSE)) {
+	if ((construct != INVALID_IST) && (D) && (Inode::isnt(D, construct))) {
 		text_stream *err = Str::new();
 		WRITE_TO(err, "symbol has type %d not %d: ", Inode::get_construct_ID(D), construct);
 		InterSymbolsTable::write_symbol_URL(err, S);
diff --git a/inter/bytecode-module/Chapter 4/The Constant Construct.w b/inter/bytecode-module/Chapter 4/The Constant Construct.w
index c2ef01070..4bd917e04 100644
--- a/inter/bytecode-module/Chapter 4/The Constant Construct.w	
+++ b/inter/bytecode-module/Chapter 4/The Constant Construct.w	
@@ -9,7 +9,7 @@ For what this does and why it is used, see //inter: Textual Inter//.
 void ConstantInstruction::define_construct(void) {
 	inter_construct *IC = InterInstruction::create_construct(CONSTANT_IST, I"constant");
 	InterInstruction::defines_symbol_in_fields(IC, DEFN_CONST_IFLD, TYPE_CONST_IFLD);
-	InterInstruction::specify_syntax(IC, I"constant TOKENS = TOKENS");
+	InterInstruction::specify_syntax(IC, I"constant MINTOKENS = TOKENS");
 	InterInstruction::data_extent_at_least(IC, 3);
 	InterInstruction::permit(IC, INSIDE_PLAIN_PACKAGE_ICUP);
 	METHOD_ADD(IC, CONSTRUCT_READ_MTID, ConstantInstruction::read);
diff --git a/inter/bytecode-module/Chapter 4/The Instance Construct.w b/inter/bytecode-module/Chapter 4/The Instance Construct.w
index d5272950c..963dfeca3 100644
--- a/inter/bytecode-module/Chapter 4/The Instance Construct.w	
+++ b/inter/bytecode-module/Chapter 4/The Instance Construct.w	
@@ -114,8 +114,6 @@ void InstanceInstruction::read(inter_construct *IC, inter_bookmark *IBM, inter_l
 	match_results mr = Regexp::create_mr();
 	if (Regexp::match(&mr, type_text, L"%((%c+)%)"))
 		inst_type = InterTypes::parse_simple(InterBookmark::scope(IBM), eloc, mr.exp[0], E);
-	if (InterTypes::is_enumerated(inst_type) == FALSE)
-		*E = InterErrors::quoted(I"not an enumerated type", type_text, eloc);
 	Regexp::dispose_of(&mr);
 	if (*E) return;
 
@@ -138,9 +136,9 @@ void InstanceInstruction::read(inter_construct *IC, inter_bookmark *IBM, inter_l
 =
 void InstanceInstruction::write(inter_construct *IC, OUTPUT_STREAM, inter_tree_node *P) {
 	inter_symbol *instance_s = InstanceInstruction::instance(P);
-	inter_symbol *typename_s = InterSymbolsTable::symbol_from_ID_at_node(P, TYPE_INST_IFLD);
-	WRITE("instance (%S) %S = ",
-		InterSymbol::identifier(typename_s), InterSymbol::identifier(instance_s));
+	WRITE("instance (");
+	TextualInter::write_symbol_from(OUT, P, TYPE_INST_IFLD);
+	WRITE(") %S = ", InterSymbol::identifier(instance_s));
 	TextualInter::write_pair(OUT, P, InterValuePairs::get(P, VAL1_INST_IFLD));
 }
 
diff --git a/inter/bytecode-module/Chapter 4/The Permission Construct.w b/inter/bytecode-module/Chapter 4/The Permission Construct.w
index 898848d8a..6ff0d64b6 100644
--- a/inter/bytecode-module/Chapter 4/The Permission Construct.w	
+++ b/inter/bytecode-module/Chapter 4/The Permission Construct.w	
@@ -131,12 +131,14 @@ void PermissionInstruction::read(inter_construct *IC, inter_bookmark *IBM,
 
 =
 void PermissionInstruction::write(inter_construct *IC, OUTPUT_STREAM, inter_tree_node *P) {
-	inter_symbol *prop_s = PermissionInstruction::property(P);
-	inter_symbol *owner_s = PermissionInstruction::owner(P);
-	inter_symbol *storage_s = PermissionInstruction::storage(P);
-	WRITE("permission for %S to have %S",
-		InterSymbol::identifier(owner_s), InterSymbol::identifier(prop_s));
-	if (storage_s) WRITE(" %S", InterSymbol::identifier(storage_s));
+	WRITE("permission for ");
+	TextualInter::write_symbol_from(OUT, P, OWNER_PERM_IFLD);
+	WRITE(" to have ");
+	TextualInter::write_symbol_from(OUT, P, PROP_PERM_IFLD);
+	if (PermissionInstruction::storage(P)) {
+		WRITE(" ");
+		TextualInter::write_symbol_from(OUT, P, STORAGE_PERM_IFLD);
+	}
 }
 
 @h Access functions.
diff --git a/inter/bytecode-module/Chapter 4/The PropertyValue Construct.w b/inter/bytecode-module/Chapter 4/The PropertyValue Construct.w
index 27f114c37..db610d423 100644
--- a/inter/bytecode-module/Chapter 4/The PropertyValue Construct.w	
+++ b/inter/bytecode-module/Chapter 4/The PropertyValue Construct.w	
@@ -159,10 +159,11 @@ inter_symbol *PropertyValueInstruction::parse_owner(inter_error_location *eloc,
 
 =
 void PropertyValueInstruction::write(inter_construct *IC, OUTPUT_STREAM, inter_tree_node *P) {
-	inter_symbol *prop_s = PropertyValueInstruction::property(P);
-	inter_symbol *owner_s = PropertyValueInstruction::owner(P);
-	WRITE("propertyvalue %S of %S = ",
-		InterSymbol::identifier(prop_s), InterSymbol::identifier(owner_s));
+	WRITE("propertyvalue ");
+	TextualInter::write_symbol_from(OUT, P, PROP_PVAL_IFLD);
+	WRITE(" of ");
+	TextualInter::write_symbol_from(OUT, P, OWNER_PVAL_IFLD);
+	WRITE(" = ");
 	TextualInter::write_pair(OUT, P, PropertyValueInstruction::value(P));
 }
 
diff --git a/inter/bytecode-module/Chapter 4/The Typename Construct.w b/inter/bytecode-module/Chapter 4/The Typename Construct.w
index 38f718771..79fa10a02 100644
--- a/inter/bytecode-module/Chapter 4/The Typename Construct.w	
+++ b/inter/bytecode-module/Chapter 4/The Typename Construct.w	
@@ -155,7 +155,8 @@ void TypenameInstruction::write(inter_construct *IC, OUTPUT_STREAM, inter_tree_n
 	WRITE("typename %S ", InterSymbol::identifier(typename_s));
 	inter_symbol *super = TypenameInstruction::super(typename_s);
 	if (super) {
-		WRITE("<= %S", InterSymbol::identifier(super));
+		WRITE("<= ");
+		TextualInter::write_symbol_from(OUT, P, SUPER_TYPENAME_IFLD);
 	} else {
 		WRITE("= ");
 		InterTypes::write_typename_definition(OUT, typename_s);