I6 Template Layer

Inform 7 6M62ContentsIntroductionFunction IndexRules Index

Output.i6t

Output contents

ICL Commands.

The Inform Control Language is a mini-language for controlling the I6 compiler, able to set command-line switches, memory settings and so on. I6 ordinarily discards lines beginning with exclamation marks as comments, but at the very top of the file, lines beginning !% are read as ICL commands: as soon as any line (including a blank line) doesn't have this signature, I6 exits ICL mode. So, basically, we'd better do this here:

17{-call:UseOptions::compile_icl_commands}

Other Configuration.

Setting the Grammar__Version constant is a rather creaky old way to tell the I6 compiler to use more detailed grammar tables: GV1 has not in fact been used since about 1994.

25Constant Grammar__Version 2;

Identification.

Both of the compiler and template layer, and of the story file to be produced.

The "library" identifying texts are now a little anachronistic, since the template layer is not strictly speaking an I6 library in the same way as the original: but it is surely the spiritual successor to 6/11N, so we may as well mark it 6/12N.

36! This file was compiled by Inform 7: the build number and version of the 37! I6 template layer used are as follows. 38{-call:TemplateFiles::compile_build_number} 39Constant LibSerial = "080126"; 40Constant LibRelease = "6/12N"; 41Constant LIBRARY_VERSION = 612; 42 43{-call:Plugins::Manage::define_IFDEF_symbols} 44 45{-array:PL::Bibliographic::IFID::UUID_ARRAY} 46{-call:PL::Bibliographic::compile_constants} 47Default Story 0; 48Default Headline 0; 49 50{-routine:Extensions::Files::ShowExtensionVersions}

Use options.

Use options are translated into I6 constant declarations, and NI puts them here:

57{-call:UseOptions::compile} 58 59#Ifndef USE_SCORING; 60Constant USE_SCORING = {-value:default_scoring_setting}; 61#Endif;

Constants.

66{-segment:Definitions.i6t}

Global Variables.

These are not the only global variables defined in the template layer: those needed locally only by single sections (and not used in definitions of phrases in the Standard Rules, or referred to by NI directly) are defined within those sections – they can be regarded as unimportant implementation details, subject to change at whim. The variables here, on the other hand, are more important to understand.

(1) The first three variables to be defined are special in that they are significant to very early-style Z-machine interpreters, where they are used to produce the status line display (hence sline1 and sline2). The first variable must always equal a valid object number, which is why we – pretty weirdly – set it equal to the placeholder object InformLibrary, which takes no part in play, and is not a valid I7 object. This is not typesafe in I7 terms, but that doesn't matter because initialisation will correct it to a typesafe value before any I7 source text can execute. (sline1 and sline2 are entirely unused on when we target Glulx.) Once these variables are defined, the sequence of definition of the rest is not significant.

(2) The say__* are used for the finite state machine used in printing text, which keeps track of automatic paragraph breaking and the like. For details see the Printing.i6t section.

(3) standard_interpreter is used only for the Z-machine VM, and is always 0 for Glulx. For Z, a non-zero value here is the version number of the Z-Machine Standards Document which the interpreter claims to support, in the form (upper byte).(lower). undo_flag, similarly, behaves slightly differently on the two platforms according to whether they support multiple consecutive UNDOs. UNDO basically works by taking memory snapshots of the whole VM ("saving UNDO") to revert to at a later point ("performing UNDO"), so it is expensive on memory, and traditional VMs can only store a single memory snapshot – making two UNDOs in a row, going back two steps, impossible. Given this, undo_flag has three possible states: 0 means UNDO is not available at all, 1 means it is not available now because there is no further saved state to go back to from here, and 2 means it is available.

(4) deadflag in normally 0, or false, meaning play continues; 1 means the game ended in death; 2 for ended in victory; higher numbers represent exotic endings. (As from May 2010, the use of 2 for victory is deprecated, and a separate flag, story_complete, records whether the story is "complete" in the sense that we don't expect the player to replay.) deadflag switching state normally triggers an end to rulebook processing, so is the single most important global variable to the running of a story file.

(5) At present, time_rate is not made use of in I7: if positive, it is the number of minutes which pass each turn; if negative, the number of turns which pass each minute. This is quite a neat way to approximate a wide range of time steps with an integer such that fractions are exact and we can approximate any duration to a fair accuracy (the worst case being 3/4 minute, where we have to choose between 1 minute or 1/2 minute).

(6) Note that notify_mode is irrelevant if the use option "Use no scoring" is in force: it isn't looked at, and can't be changed, and shouldn't have an effect anyway since score will never be altered.

(7) player is a variable, not a constant, since the focus of play can change. SACK_OBJECT is likewise an unexpected variable: in the I6 library, there could only be one player's holdall, a single rucksack-like possession which had to be the value of the constant SACK_OBJECT. Here we define SACK_OBJECT as a global variable instead, the value of which is the player's holdall currently in use. visibility_ceiling is the highest object in the tree visible from the player's point of view: usually the room, but sometimes nothing (in darkness), and sometimes a closed non-transparent container.

(8) See OrderOfPlay.i6t for the meaning of action variables.

(9) This is a slate of global variables used by the parser to give some context to the general parsing routines (GPRs) which it calls; in the I6 design, any object can provide its own GPR, in the form of a parse_name property. GPRs are in effect parser plug-ins, and I7 makes extensive use of them.

(10) Similarly, variables for the parser to give context to another sort of plug-in routine: a scope filter. I7 uses these too.

(11) The move_* variables are specific to the ##Going action.

(12) These variables hold current settings for listing objects and, more elaborately, performing room descriptions.

(13) The current colour scheme is stored in variables in order that it can be saved in the save game state, and changed correctly on an UNDO: if it were a transient state inside the VM interpreter's screen model, then a RESTORE or UNDO will upset what the original author may have intended the appearance of text in particular scenes to be. (Cf. Adam Cadre's I6 patch L61007.)

(14) These pixel dimensions are used both for the Glulx and v6 Z-machines, but not for the more commonly used versions 5 or 8, whose screen model is based on character cells.

(15) For debugging. debug_flag is traditionally called so, but is actually now a bitmap of flags for tracing actions, calls to object routines, and so on.

168! [1] 169Global location = InformLibrary; ! does not = I7 "location": see below 170Global sline1; Global sline2; 171 172! [2] 173Global say__p = 1; Global say__pc = 0; Global say__pc_save = 0; 174Global say__n; Global say__comp; 175Global los_rv = false; 176Global parameter_object; ! = I7 "parameter-object" = I7 "container in question" 177Global parameter_value; ! not typesafe in I7 178Array deferred_calling_list --> 27; 179Global property_to_be_totalled; ! used to implement "total P of..." 180Global property_loop_sign; ! $+1$ for increasing order, $-1$ for decreasing 181Global suppress_scope_loops; 182Global temporary_value; ! can be used anywhere side-effects can't occur 183 184#ifdef TARGET_ZCODE; 185Constant BLOCKV_STACK_SIZE = 224; 186#ifnot; 187Constant BLOCKV_STACK_SIZE = DynamicMemoryAllocation/4; 188#endif; 189 190Array blockv_stack --> BLOCKV_STACK_SIZE; 191Global I7SFRAME; 192 193Global TEXT_TY_RE_Err = 0; 194 195Array LocalParking --> 64; 196 197! [3] 198Global standard_interpreter = 0; 199Global undo_flag; 200 201! [4] 202Global deadflag = 0; 203Global story_complete = 0; 204Global resurrect_please = false; 205 206! [5] 207Global not_yet_in_play = true; ! set false when first command received 208Global turns = 1; ! = I7 "turn count" 209Global the_time = NULL; ! = I7 "time of day" 210Global time_rate = 1; 211 212Constant NUMBER_SCENES_CREATED = {-value:NUMBER_CREATED(scene)}; 213Constant SCENE_ARRAY_SIZE = (NUMBER_SCENES_CREATED+2); 214Array scene_started --> SCENE_ARRAY_SIZE; 215Array scene_ended --> SCENE_ARRAY_SIZE; 216Array scene_status --> SCENE_ARRAY_SIZE; 217Array scene_endings --> SCENE_ARRAY_SIZE; 218Array scene_latest_ending --> SCENE_ARRAY_SIZE; 219 220! [6] 221Global score; ! = I7 "score" 222Global last_score; ! = I7 "last notified score" 223Global notify_mode = 1; ! score notification on or off 224Global left_hand_status_line = T_SL_Location; ! = I7 "left hand status line" 225Global right_hand_status_line = T_SL_Score_Moves; ! = I7 "right hand status line" 226 227! [7] 228Global player; ! = I7 "player" 229Global real_location; ! = I7 "location" 230Global visibility_ceiling; ! highest object in tree visible to player 231Global visibility_levels; ! distance in tree to that 232 233Global SACK_OBJECT; ! current player's holdall item in use 234 235! [8] 236Global act_requester; 237Global actor; ! = I7 "person asked" = I7 "person reaching" 238Global actors_location; ! like real_location, but for the actor 239Global actor_location; ! = I7 "actor-location" 240Global action; 241Global meta; ! action is out of world 242Global inp1; 243Global inp2; 244Array multiple_object --> MATCH_LIST_WORDS; ! multiple-object list (I6 table array) 245Global toomany_flag; ! multiple-object list overflowed 246Global multiflag; ! multiple-object being processed 247Global multiple_object_item; ! item currently being processed in multiple-object list 248Global noun; ! = I7 "noun" 249Global second; ! = I7 "second noun" 250Global keep_silent; ! true if current action is being tried silently 251Global etype; ! parser error number if command not recognised 252Global trace_actions = 0; 253 254Global untouchable_object; 255Global untouchable_silence; 256Global touch_persona; 257 258Global special_word; ! dictionary address of first word in "[text]" token 259Global consult_from; ! word number of start of "[text]" token 260Global consult_words; ! number of words in "[text]" token 261Global parsed_number; ! value from any token not an object 262Global special_number1; ! first value, if token not an object 263Global special_number2; ! second value, if token not an object 264 265Array parser_results --> 16; ! for parser to write its results in 266Global parser_trace = 0; ! normally 0, but 1 to 5 traces parser workings 267Global pronoun_word; ! records which pronoun ("it", "them", ...) caused an error 268Global pronoun_obj; ! and what object it was thought to refer to 269 270Global players_command = 100; ! = I7 "player's command" 271Global matched_text; ! = I7 "matched text" 272Global reason_the_action_failed; ! = I7 "reason the action failed" 273Global understand_as_mistake_number; ! which form of "Understand... as a mistake" 274Global particular_possession; ! = I7 "particular possession" 275 276! [9] 277Global parser_action; ! written by the parser for the benefit of GPRs 278Global parser_one; 279Global parser_two; 280Global parameters; ! number of I7 tokens parsed on the current line 281Global action_to_be; ! (if the current line were accepted) 282Global action_reversed; ! (parameters would be reversed in order) 283Global wn; ! word number within "parse" buffer (from 1) 284Global num_words; ! number of words in buffer 285Global verb_word; ! dictionary address of command verb 286Global verb_wordnum; ! word number of command verb 287 288! [10] 289Global scope_reason = PARSING_REASON; ! current reason for searching scope 290Global scope_token; ! for "scope=Routine" grammar tokens 291Global scope_error; 292Global scope_stage; ! 1, 2 then 3 293Global advance_warning; ! what a later-named thing will be 294Global reason_code = NULL; ! for the I6 veneer 295 296Global ats_flag = 0; ! for AddToScope routines 297Global ats_hls; 298 299! [11] 300Global move_pushing; 301Global move_from; 302Global move_to; 303Global move_by; 304Global move_through; 305 306! [12] 307#Ifdef DEFAULT_BRIEF_DESCRIPTIONS; 308Global lookmode = 1; ! 1 = BRIEF, 2 = VERBOSE, 3 = SUPERBRIEF 309#Endif; 310#Ifdef DEFAULT_VERBOSE_DESCRIPTIONS; 311Global lookmode = 2; ! 1 = BRIEF, 2 = VERBOSE, 3 = SUPERBRIEF 312#Endif; 313#Ifdef DEFAULT_SUPERBRIEF_DESCRIPTIONS; 314Global lookmode = 3; ! 1 = BRIEF, 2 = VERBOSE, 3 = SUPERBRIEF 315#Endif; 316#Ifndef lookmode; 317Global lookmode = 2; ! 1 = BRIEF, 2 = VERBOSE, 3 = SUPERBRIEF 318#Endif; 319Global c_style; ! current list-writer style 320Global c_depth; ! current recursion depth 321Global c_iterator; ! current iteration function 322Global lt_value = EMPTY_TEXT_VALUE; ! common value of list_together 323Global listing_together; ! object number of one member of a group being listed together 324Global listing_size; ! size of such a group 325Global c_margin; ! current level of indentation printed by WriteListFrom() 326Global inventory_stage = 1; ! 1 or 2 according to the context in which list_together uses 327Global prior_named_noun; ! for adaptive text generation 328Global prior_named_list; ! ditto: length of list of items 329Global prior_named_list_gender; ! ditto: common gender of list of items, or -1 330Global story_tense = 1; ! ditto: present tense 331Global story_viewpoint = 2; ! ditto: second person singular 332 333! [13] 334Global clr_fg = 1; ! foreground colour 335Global clr_bg = 1; ! background colour 336Global clr_fgstatus = 1; ! foreground colour of statusline 337Global clr_bgstatus = 1; ! background colour of statusline 338Global clr_on; ! has colour been enabled by the player? 339Global statuswin_current; ! if writing to top window 340 341! [14] 342Global statuswin_cursize = 0; 343Global statuswin_size = 1; 344 345! [16] 346Global debug_flag = 0; 347Global debug_rules = 0; 348Global debug_scenes = 0; 349Global debug_rule_nesting;

VM-Specific Code.

These sections of code contain different definitions of the same routines, and in some cases the same arrays, to handle low-level functions in the virtual machine – saving the game, performing UNDO, parsing typed text into dictionary word addresses and so on.

358#Ifdef TARGET_GLULX; 359{-segment:Glulx.i6t} 360#Endif; 361 362#Ifdef TARGET_ZCODE; 363{-segment:ZMachine.i6t} 364#Endif;

Compass.

I6 identified compass directions as being children of the pseudo-object Compass, so we define it. (Note that Compass is not a valid I7 object, and is used for no other purpose.) Because of the traditional structure of language definitions, this needs to come first.

373Object Compass "compass" has concealed;

Language of Play.

The equivalent of I6's language definition file, though here the idea is that a translation should have an inclusion to replace the Language.i6t segment, which contains the English definition.

381{-segment:Language.i6t} 382 383Default LanguageCases 1;

The Old Library.

The I6 library consisted essentially of the parser, the verb routines, and a pile of utilities and world-modelling code, of which the biggest single component was the list-writer. The parser lives on below; the verb routines are gone, with the equivalent functionality having moved upstairs into I7 source text in the Standard Rules; and the rest of the library largely lives here:

394{-segment:Light.i6t} 395{-segment:ListWriter.i6t} 396{-segment:Utilities.i6t}

Parser.

The largest single block of code in the traditional I6 library part of the template layer is the parser.

The two pseudo-objects InformParser and InformLibrary are relics of the object-oriented approach in I6, and are used only very slightly in the template layer; they are not used at all in I7, and are not valid for the "object" kind of value.

The parser includes arrays for typed text and some parsing information derived from it, and if these should overrun it would cause enigmatic bugs, as the next arrays in memory would be corrupted: as a tripwire, the Protect_I7_Arrays array consists of two magic values in sequence. If it is ever discovered to contain the wrong data, the alarm sounds.

414Object InformParser "(Inform Parser)" has proper; 415 416{-segment:Parser.i6t} 417 418[ ParserError error_type; 419    if (error_type) PrintSingleParagraph(error_type); 420    rfalse; 421]; 422 423Object InformLibrary "(Inform Library)" has proper; 424 425Array Protect_I7_Arrays --> 16339 12345;

Order of Play.

The Main routine, where execution begins, and the primitive rules in the principal rulebooks.

432{-segment:OrderOfPlay.i6t}

Properties.

Some either/or properties are compiled to I6 attributes, which must be predeclared, so we do that first. (All other properties can simply be used without declaration.)

What then follows is a table of property metadata: in particular, specifying which properties can be used with which I6 classes or objects. Policing this at run-time costs a little speed, but traps many errors of programming, and keeps everything typesafe. It is the price we pay for the relatively lenient compile-time checking of I7's "object" kind of value. To make it as efficient as possible, we calculate offsets into the metadata: this has to be done (once) at run-time, with the routine compiled.

448{-call:Properties::alias_translations} 449{-call:Properties::ObjectImplementation::compile_attributes} 450{-array:Properties::ObjectImplementation::property_metadata} 451Constant attributed_property_offsets_SIZE 48; 452Array attributed_property_offsets --> attributed_property_offsets_SIZE; 453Constant valued_property_offsets_SIZE (100 + {-value:NUMBER_CREATED(property)} + INDIV_PROP_START-48); 454Array valued_property_offsets --> valued_property_offsets_SIZE; 455 456{-routine:Properties::ObjectImplementation::CreatePropertyOffsets}

Activities.

These are numbered upwards from 0 in order of creation. The following arrays taken together provide, for each activity number: (i) the rulebook numbers for the before, for, and after stages of the activity, and (ii) a flag indicating whether the activity is "future action"-capable, that is, is a parsing activity allowed to make use of the action which conjecturally might result from the current grammar line being parsed. (This is called the "action to be", hence "atb".)

468Constant NUMBER_RULEBOOKS_CREATED = {-value:NUMBER_CREATED(rulebook)}; 469{-call:Activities::compile_activity_constants} 470{-array:Activities::Activity_before_rulebooks} 471{-array:Activities::Activity_for_rulebooks} 472{-array:Activities::Activity_after_rulebooks} 473{-array:Activities::Activity_atb_rulebooks}

Relations.

478{-call:Relations::compile_defined_relation_constants}

Printing Routines.

483{-call:Kinds::RunTime::compile_data_type_support_routines} 484{-routine:Kinds::RunTime::I7_Kind_Name} 485{-routine:Rulebooks::Outcomes::RulebookOutcomePrintingRule}

Object Tree.

The I6 object tree contains Class definitions as well as objects, but we precede both with a pseudo-object called property_numberspace_forcer. It does nothing except to ensure that properties are declared in I6 in the same sequence as I7 (which need not otherwise happen); it plays no part in play, and is not a valid I7 "object" value.

495{-log:Compiling the storage for the model world} 496{-call:World::Compile::compile}

Tables.

The initial state of the I6 arrays corresponding to each I7 table: see Tables.i6t for details.

503{-log:Compiling the tables} 504{-callv:Tables::complete} 505{-call:Tables::Support::compile}

Equations.

Routines to evaluate from equations.

511{-log:Compiling the equations} 512{-call:Equations::compile}

Actions.

517{-log:Compiling the named action patterns} 518{-call:PL::Actions::Patterns::Named::compile} 519{-log:Compiling the action routines} 520{-array:PL::Actions::ActionData} 521{-array:PL::Actions::ActionCoding} 522{-array:PL::Actions::ActionHappened} 523{-call:PL::Actions::compile_action_routines} 524{-routine:PL::Parsing::Lines::MistakeActionSub}

Phrases.

The following innocent-looking commands tell NI to compile I6 definitions for all of the rules which are not I6-written primitives, and also for adjective definitions, so it results in a fairly enormous cataract of code.

532{-log:Compiling first block of phrases} 533{-call:Phrases::Manager::compile_first_block}

Timed Events.

Some of the phrases are simply called in the course of other phrases, but some are rules in rulebooks or in the table of timed events, so those come next:

541{-array:Phrases::Manager::TimedEventsTable} 542{-array:Phrases::Manager::TimedEventTimesTable}

Rulebooks.

The literally hundreds of rulebooks are set up here. (In the end a rulebook is only a (word) array of rule addresses, terminated with a NULL.)

549{-log:Compiling the rulebooks} 550{-array:Phrases::Manager::rulebooks_array} 551{-call:Phrases::Manager::compile_rulebooks}

Scenes.

556{-log:Compiling scene details} 557{-routine:PL::Scenes::DetectSceneChange} 558#IFDEF DEBUG; 559{-routine:PL::Scenes::ShowSceneStatus} 560#ENDIF;

The New Library.

The gleaming, aluminium and glass extension to the library: almost all of it material new in I7 usage.

567{-log:CTNL} 568 569{-segment:Actions.i6t} 570{-segment:Activities.i6t} 571{-segment:Figures.i6t} 572{-segment:FileIO.i6t} 573{-segment:MStack.i6t} 574{-segment:OutOfWorld.i6t} 575{-segment:Printing.i6t} 576{-segment:Relations.i6t} 577{-segment:RTP.i6t} 578{-segment:Rulebooks.i6t} 579{-segment:Sort.i6t} 580{-segment:Tables.i6t} 581{-segment:WorldModel.i6t}

Parsing Tokens.

GPRs, scope and noun filters to be used in grammar lines, but no actual grammar lines as yet.

588{-callv:PL::Parsing::Verbs::prepare} 589{-call:PL::Parsing::Verbs::compile_conditions} 590 591{-log:Compiling GPR tokens for parsing various kinds of value} 592{-segment:Number.i6t} 593{-segment:RealNumber.i6t} 594{-segment:Time.i6t} 595{-call:PL::Parsing::Tokens::Values::compile_type_gprs}

Text generation.

600{-routine:Verbs::ConjugateVerb} 601{-call:Adjectives::Meanings::agreements}

Testing commands.

606#IFDEF DEBUG; 607{-call:PL::Parsing::TestScripts::write_text} 608{-segment:Tests.i6t} 609{-routine:PL::Parsing::TestScripts::InternalTestCases} 610#ENDIF; ! DEBUG

I6 Inclusions.

This paragraph contains no code, by default: it's a hook on which to hang verbatim I6 material.

617! "Include (- ... -)" inclusions with no specified position appear here.

Entries in constant lists.

Well: most of them, anyway. In particular, all of those which are lists of texts with substitution will be swept up, which is important for timing reasons. A second round later on will catch any later ones.

625{-call:Lists::check} 626{-call:Lists::compile}

To Phrases.

We now compile all of the remaining code in the source text: the "To..." phrases and all of their attendant text routines, loop-over-scope routines and so on.

We now have to be quite careful about the sequence of events. Compiling the text routines is an irrevocable step, after which we must not compile any new text with substitutions. On the other hand we mustn't leave it any later, because a text substitution might contain references to the past, or involve propositions which must be deferred into routines.

640{-log:Compiling second block of phrases} 641{-call:Phrases::Manager::compile_as_needed} 642{-call:Strings::compile_responses} 643{-call:Lists::check} 644{-call:Lists::compile} 645{-call:Relations::compile_defined_relations} 646{-call:Phrases::Manager::compile_as_needed} 647 648{-callv:Strings::TextSubstitutions::allow_no_further_text_subs} 649 650{-log:Compiling noun and scope filter tokens} 651{-call:PL::Parsing::Tokens::Filters::compile}

Chronology.

Similarly, this is where we wrap up all references to past tenses: after this point, we cannot safely compile any I7 condition in the past tense.

658{-log:Compiling chronology} 659{-segment:Chronology.i6t} 660{-callv:Chronology::allow_no_further_past_tenses}

Grammar.

This is the trickiest matter of timing. We had to leave the grammar lines until now because the past-tense code above might have needed to investigate whether the player's command matched a given pattern at some time in the past (a case which arose naturally in one of the example games, so which should not be dismissed as an aberration). This is therefore the earliest point at which we can know for sure that no further grammar lines are needed.

672{-log:Compiling I6 Verb directives} 673{-call:PL::Parsing::Verbs::compile_all} 674 675{-log:Compiling noun and scope filter tokens} 676{-call:PL::Parsing::Tokens::Filters::compile} 677 678#IFTRUE ({-value:no_verb_verb_defined} == 1); 679[ UnknownVerb; verb_wordnum = 0; return 'no.verb'; ]; 680[ PrintVerb v; 681    if (v == 'no.verb') { print "do something to"; rtrue; } 682    rfalse; 683]; 684#Ifnot; 685[ UnknownVerb; rfalse; ]; [ PrintVerb v; rfalse; ]; 686#ENDIF;

Deferred Propositions.

Most conditions, such as "the score is 10", and descriptions, such as "open doors which are in lighted rooms", are translated by NI into propositions in a form of predicate calculus. Sometimes these can be compiled immediately to I6 code, but other times they involve complicated searches and have to be "deferred" into special routines which will perform them. This is where we compile those routines.

697{-log:Compiling routines from predicate calculus} 698{-call:Properties::Measurement::compile_MADJ_routines} 699{-call:Calculus::Propositions::Deferred::compile_remaining_deferred} 700{-callv:Calculus::Deferrals::allow_no_further_deferrals}

Miscellaneous Loose Ends.

And we still aren't done, because we still have:

(1) Routines which switch between possible interpretations of phrases by performing run-time type checking. (Note that these cannot involve grammar, or the past tenses, or text substitutions, or deferred propositions.)

(2) Arrays holding constant lists, such as {2, 3, 4}, if any.

(3) The string constants, named in the pattern SC_*, in alphabetical order. (This ensures that their packed addresses will have unsigned comparison ordering equivalent to alphabetical order.)

(4) "Stub" I6 constants for property names where properties aren't used, to prevent them causing errors if they are referred to in code but not actually present in any object (as can easily happen with extensions presenting optional features which the user chooses not to employ). cap_short_name is similarly stubbed: this doesn't correspond to any I7 property, but is used by NI to record capitalised forms of the printed name (which in turn goes into short_name).

(5) Counters are used to allocate cells of storage to inline phrases which need a permanent state associated with them: see the Standard Rules. Since all I7 source text has been compiled by now, we know the final values of the counters, and therefore the amount of storage we need to allocate.

(6) Similarly, each "quotation" box needs its own cell of memory.

731{-call:Lists::check} 732{-call:Lists::compile} 733{-call:Strings::TextLiterals::compile} 734{-call:Properties::ObjectImplementation::compile_stub_properties} 735#IFNDEF cap_short_name; 736Constant cap_short_name = short_name; 737#ENDIF; 738{-call:JumpLabels::compile_necessary_storage} 739Array Runtime_Quotations_Displayed --> {-value:extent_of_runtime_quotations_array};

Block Values.

These are values which are pointers to more elaborate data on the memory heap, rather than values in themselves: they point to "blocks". A section of code handles the heap, and there is then one further section to support each of the kinds of value in question.

748{-call:Kinds::RunTime::compile_heap_allocator} 749{-call:Phrases::Constants::compile_closures} 750{-call:Kinds::RunTime::compile_structures} 751 752{-segment:Flex.i6t} 753{-segment:BlockValues.i6t} 754{-segment:Text.i6t} 755{-segment:RegExp.i6t} 756{-segment:StoredAction.i6t} 757{-segment:Lists.i6t} 758{-segment:Combinations.i6t} 759{-segment:RelationKind.i6t} 760 761{-array:PL::Figures::tableoffigures} 762{-array:PL::Sounds::tableofsounds} 763 764{-callv:Rules::check_response_usages} 765{-call:Kinds::RunTime::compile_block_constants} 766{-callv:Phrases::Timed::check_for_unused}

Signing off.

And that's all, folks.

772! End of automatically generated I6 source 773! --------------------------------------------------------------------------