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:-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@@ -299,7 +299,7 @@ and The Standard Kits (-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; }@@ -329,14 +330,10 @@ But it really doesn't need to catch every possible error; this is Inter, not Inf
- This code is used in §5.
- 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); + } }-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)); }-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 @@
- Home
- Compiler Tools
- inter
- Manual
- Inform Organisation
The standard hierarchy of inter code generated by Inform.
-
+
- §1. Status
- §2. Global area and main
- §3. Compilation modules
- §8. Function packages
- §9. Looking at the Inter produced
§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 }- Establish architecturak resources8.2.2; + Establish architectural resources8.2.2;@@ -2135,7 +2135,7 @@ ones which the //inform7//-compiled code needs to refer to. enum MAX_POSITIVE_NUMBER_HL enum MIN_NEGATIVE_NUMBER_HL
- This code is used in §8.
§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. } @