From 9c7ccf6f1eb23d03213e139006e6f669ff34e7d3 Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Tue, 16 Apr 2024 23:53:34 +0100 Subject: [PATCH] Further drafting on kits --- README.md | 2 +- build.txt | 4 +- docs/supervisor-module/2-ce.html | 2 +- docs/supervisor-module/2-cps.html | 2 +- docs/supervisor-module/2-rqr.html | 2 +- docs/supervisor-module/2-wrk.html | 2 +- docs/supervisor-module/5-es.html | 88 ++++++++-- .../Chapter 5/Extension Services.w | 56 +++++++ inform7/Figures/memory-diagnostics.txt | 12 +- inform7/Figures/timings-diagnostics.txt | 17 +- .../Inter/Architecture16Kit/kit_metadata.json | 2 +- .../Inter/Architecture32Kit/kit_metadata.json | 2 +- .../Inter/BasicInformKit/kit_metadata.json | 2 +- .../Inter/CommandParserKit/kit_metadata.json | 2 +- .../EnglishLanguageKit/kit_metadata.json | 2 +- .../Inter/WorldModelKit/kit_metadata.json | 2 +- .../Documentation/Writing with Inform.md | 153 +++++++++++++++++- 17 files changed, 312 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 3588df4eb..cd947417f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inform 7 -[Version](notes/versioning.md): 10.2.0-beta+6X44 'Krypton' (15 April 2024) +[Version](notes/versioning.md): 10.2.0-beta+6X45 'Krypton' (16 April 2024) ## About Inform diff --git a/build.txt b/build.txt index fff74e895..d44cef3bd 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: beta -Build Date: 15 April 2024 -Build Number: 6X44 +Build Date: 16 April 2024 +Build Number: 6X45 diff --git a/docs/supervisor-module/2-ce.html b/docs/supervisor-module/2-ce.html index 2b14c1989..30e9d939e 100644 --- a/docs/supervisor-module/2-ce.html +++ b/docs/supervisor-module/2-ce.html @@ -126,7 +126,7 @@ fields are blank. return CE; } -copy_error *CopyErrors::new_T(int cat, int subcat, text_stream *NB) { +copy_error *CopyErrors::new_T(int cat, int subcat, text_stream *NB) { copy_error *CE = CopyErrors::new(cat, subcat); CE->details = Str::duplicate(NB); return CE; diff --git a/docs/supervisor-module/2-cps.html b/docs/supervisor-module/2-cps.html index 58407285c..8a03c0a02 100644 --- a/docs/supervisor-module/2-cps.html +++ b/docs/supervisor-module/2-cps.html @@ -155,7 +155,7 @@ for later reporting. These are stored in a list.

-void Copies::attach_error(inbuild_copy *C, copy_error *CE) {
+void Copies::attach_error(inbuild_copy *C, copy_error *CE) {
     if (C == NULL) internal_error("no copy to attach to");
     CopyErrors::supply_attached_copy(CE, C);
     ADD_TO_LINKED_LIST(CE, copy_error, C->errors_reading_source_text);
diff --git a/docs/supervisor-module/2-rqr.html b/docs/supervisor-module/2-rqr.html
index 76bdfb65d..4eabe77af 100644
--- a/docs/supervisor-module/2-rqr.html
+++ b/docs/supervisor-module/2-rqr.html
@@ -85,7 +85,7 @@ we can give a semantic version number range:
     return req;
 }
 
-inbuild_requirement *Requirements::any_version_of(inbuild_work *work) {
+inbuild_requirement *Requirements::any_version_of(inbuild_work *work) {
     return Requirements::new(work, VersionNumberRanges::any_range());
 }
 
diff --git a/docs/supervisor-module/2-wrk.html b/docs/supervisor-module/2-wrk.html
index 56a2c7f5b..99aba201b 100644
--- a/docs/supervisor-module/2-wrk.html
+++ b/docs/supervisor-module/2-wrk.html
@@ -91,7 +91,7 @@ not subsequently altered.
 

-inbuild_work *Works::new(inbuild_genre *genre, text_stream *ti, text_stream *an) {
+inbuild_work *Works::new(inbuild_genre *genre, text_stream *ti, text_stream *an) {
     return Works::new_inner(genre, ti, an, TRUE);
 }
 inbuild_work *Works::new_raw(inbuild_genre *genre, text_stream *ti, text_stream *an) {
diff --git a/docs/supervisor-module/5-es.html b/docs/supervisor-module/5-es.html
index be75f61af..b4d465ccf 100644
--- a/docs/supervisor-module/5-es.html
+++ b/docs/supervisor-module/5-es.html
@@ -118,11 +118,13 @@ compatibility notes given (such as "for Glulx only").
     if (Works::is_standard_rules(C->edition->work)) E->standard = TRUE;
     if (C->location_if_path) {
         text_stream *force_JSON_write = NULL;
+        linked_list *missing_kits = NEW_LINKED_LIST(text_stream);
         TEMPORARY_TEXT(JSON_author_name)
         TEMPORARY_TEXT(JSON_title)
         Scan the metadata file, if there is one2.4;
         Check that the JSON metadata agrees2.5;
-        if (force_JSON_write) Write a corrected JSON metadata file2.6;
+        Look for kits included in the extension2.6;
+        if (force_JSON_write) Write a corrected JSON metadata file2.7;
         DISCARD_TEXT(JSON_author_name)
         DISCARD_TEXT(JSON_title)
     }
@@ -648,12 +650,49 @@ need to detect that and either flag an error, or force a repair.
     }
 
-

§2.6. This is where incorrect or missing JSON metadata is repaired. If there was metadata +

§2.6. Look for kits included in the extension2.6 = +

+ +
+    if (repair_mode) {
+        pathname *P = C->location_if_path;
+        P = Pathnames::down(P, I"Materials");
+        if (Directories::exists(P)) {
+            P = Pathnames::down(P, I"Inter");
+            if (Directories::exists(P)) {
+                linked_list *L = Directories::listing(P);
+                text_stream *entry;
+                LOOP_OVER_LINKED_LIST(entry, text_stream, L) {
+                    if (Platform::is_folder_separator(Str::get_last_char(entry))) {
+                        Str::delete_last_character(entry);
+                        if (Str::ends_with(entry, I"Kit")) {
+                            text_stream *kit_title = entry;
+                            inbuild_work *work = Works::new(kit_genre, kit_title, NULL);
+                            inbuild_requirement *req;
+                            int found = FALSE;
+                            LOOP_OVER_LINKED_LIST(req, inbuild_requirement, E->kits)
+                                if (Str::eq_insensitive(req->work->title, kit_title))
+                                    found = TRUE;
+                            if (found == FALSE) {
+                                inbuild_requirement *req = Requirements::any_version_of(work);
+                                ADD_TO_LINKED_LIST(req, inbuild_requirement, E->kits);
+                                force_JSON_write = I"the JSON file omits one or more included kit(s)";
+                                ADD_TO_LINKED_LIST(kit_title, text_stream, missing_kits);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+ +

§2.7. This is where incorrect or missing JSON metadata is repaired. If there was metadata at all, we rewrite it with the correct author, title and version. If not, we create it in a minimal sort of way, with just an is object.

-

Write a corrected JSON metadata file2.6 = +

Write a corrected JSON metadata file2.7 =

@@ -662,12 +701,14 @@ in a minimal sort of way, with just an     if (C->location_if_path == NULL)
         internal_error("should not try to write JSON except for a directory extension");
     JSON_value *is_object = NULL;
-    Find or create the is-object2.6.1;
-    Populate the is-object with correct values2.6.2;
-    Write the JSON metadata back to the filing system2.6.3;
+    Find or create the is-object2.7.1;
+    Populate the is-object with correct values2.7.2;
+    if (LinkedLists::len(missing_kits) > 0)
+        Add any missing kits to the needs-object2.7.3;
+    Write the JSON metadata back to the filing system2.7.4;
 
-

§2.6.1. Find or create the is-object2.6.1 = +

§2.7.1. Find or create the is-object2.7.1 =

@@ -678,8 +719,8 @@ in a minimal sort of way, with just an         JSON::add_to_object(C->metadata_record, I"is", is_object);
     }
 
- -

§2.6.2. Populate the is-object with correct values2.6.2 = +

+

§2.7.2. Populate the is-object with correct values2.7.2 =

@@ -691,8 +732,31 @@ in a minimal sort of way, with just an     JSON::change_object(is_object, I"version", JSON::new_string(v));
     DISCARD_TEXT(v)
 
- -

§2.6.3. Write the JSON metadata back to the filing system2.6.3 = +

+

§2.7.3. Add any missing kits to the needs-object2.7.3 = +

+ +
+    JSON_value *needs_array = NULL;
+    if (C->metadata_record) needs_array = JSON::look_up_object(C->metadata_record, I"needs");
+    if (needs_array == NULL) {
+        needs_array = JSON::new_array();
+        JSON::add_to_object(C->metadata_record, I"needs", needs_array);
+    }
+    text_stream *kit_title;
+    LOOP_OVER_LINKED_LIST(kit_title, text_stream, missing_kits) {
+        JSON_value *need_object = JSON::new_object();
+        JSON_value *type_string = JSON::new_string(I"kit");
+        JSON::add_to_object(need_object, I"type", type_string);
+        JSON_value *title_string = JSON::new_string(kit_title);
+        JSON::add_to_object(need_object, I"title", title_string);
+        JSON_value *dep_object = JSON::new_object();
+        JSON::add_to_object(dep_object, I"need", need_object);
+        JSON::add_to_array(needs_array, dep_object);
+    }
+
+ +

§2.7.4. Write the JSON metadata back to the filing system2.7.4 =

@@ -711,7 +775,7 @@ in a minimal sort of way, with just an         WRITE_TO(STDERR, "(Writing JSON metadata file to %f, because %S)\n", F, force_JSON_write);
     }
 
- +

§3. Language elements can be activated or deactivated:

diff --git a/inbuild/supervisor-module/Chapter 5/Extension Services.w b/inbuild/supervisor-module/Chapter 5/Extension Services.w index 97480dcf3..0aaa48b07 100644 --- a/inbuild/supervisor-module/Chapter 5/Extension Services.w +++ b/inbuild/supervisor-module/Chapter 5/Extension Services.w @@ -58,10 +58,12 @@ void Extensions::scan(inbuild_copy *C) { if (Works::is_standard_rules(C->edition->work)) E->standard = TRUE; if (C->location_if_path) { text_stream *force_JSON_write = NULL; + linked_list *missing_kits = NEW_LINKED_LIST(text_stream); TEMPORARY_TEXT(JSON_author_name) TEMPORARY_TEXT(JSON_title) @; @; + @; if (force_JSON_write) @; DISCARD_TEXT(JSON_author_name) DISCARD_TEXT(JSON_title) @@ -494,6 +496,39 @@ need to detect that and either flag an error, or force a repair. } } +@ = + if (repair_mode) { + pathname *P = C->location_if_path; + P = Pathnames::down(P, I"Materials"); + if (Directories::exists(P)) { + P = Pathnames::down(P, I"Inter"); + if (Directories::exists(P)) { + linked_list *L = Directories::listing(P); + text_stream *entry; + LOOP_OVER_LINKED_LIST(entry, text_stream, L) { + if (Platform::is_folder_separator(Str::get_last_char(entry))) { + Str::delete_last_character(entry); + if (Str::ends_with(entry, I"Kit")) { + text_stream *kit_title = entry; + inbuild_work *work = Works::new(kit_genre, kit_title, NULL); + inbuild_requirement *req; + int found = FALSE; + LOOP_OVER_LINKED_LIST(req, inbuild_requirement, E->kits) + if (Str::eq_insensitive(req->work->title, kit_title)) + found = TRUE; + if (found == FALSE) { + inbuild_requirement *req = Requirements::any_version_of(work); + ADD_TO_LINKED_LIST(req, inbuild_requirement, E->kits); + force_JSON_write = I"the JSON file omits one or more included kit(s)"; + ADD_TO_LINKED_LIST(kit_title, text_stream, missing_kits); + } + } + } + } + } + } + } + @ This is where incorrect or missing JSON metadata is repaired. If there was metadata at all, we rewrite it with the correct author, title and version. If not, we create it in a minimal sort of way, with just an |is| object. @@ -506,6 +541,8 @@ in a minimal sort of way, with just an |is| object. JSON_value *is_object = NULL; @; @; + if (LinkedLists::len(missing_kits) > 0) + @; @; @ = @@ -525,6 +562,25 @@ in a minimal sort of way, with just an |is| object. JSON::change_object(is_object, I"version", JSON::new_string(v)); DISCARD_TEXT(v) +@ = + JSON_value *needs_array = NULL; + if (C->metadata_record) needs_array = JSON::look_up_object(C->metadata_record, I"needs"); + if (needs_array == NULL) { + needs_array = JSON::new_array(); + JSON::add_to_object(C->metadata_record, I"needs", needs_array); + } + text_stream *kit_title; + LOOP_OVER_LINKED_LIST(kit_title, text_stream, missing_kits) { + JSON_value *need_object = JSON::new_object(); + JSON_value *type_string = JSON::new_string(I"kit"); + JSON::add_to_object(need_object, I"type", type_string); + JSON_value *title_string = JSON::new_string(kit_title); + JSON::add_to_object(need_object, I"title", title_string); + JSON_value *dep_object = JSON::new_object(); + JSON::add_to_object(dep_object, I"need", need_object); + JSON::add_to_array(needs_array, dep_object); + } + @ = filename *F = Filenames::in(C->location_if_path, I"extension_metadata.json"); text_stream JSONF_struct; diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt index 725709987..35cc78adf 100644 --- a/inform7/Figures/memory-diagnostics.txt +++ b/inform7/Figures/memory-diagnostics.txt @@ -1,10 +1,10 @@ -Total memory consumption was 139941K = 137 MB +Total memory consumption was 139942K = 137 MB - ---- was used for 2134651 objects, in 375913 frames in 0 x 800K = 0K = 0 MB: + ---- was used for 2134652 objects, in 375914 frames in 0 x 800K = 0K = 0 MB: 30.1% inter_tree_node_array 60 x 8192 = 491520 objects, 43255680 bytes 19.4% text_stream_array 4952 x 100 = 495200 objects, 27889664 bytes - 17.9% linked_list 45909 objects, 25709040 bytes + 17.9% linked_list 45910 objects, 25709600 bytes 10.0% inter_symbol_array 135 x 1024 = 138240 objects, 14381280 bytes 9.6% inter_error_stash_array 106 x 1024 = 108544 objects, 13897024 bytes 7.4% parse_node 133914 objects, 10713120 bytes @@ -262,9 +262,9 @@ Total memory consumption was 139941K = 137 MB ---- loop_over_scope 1 object, 40 bytes ---- i6_memory_setting 1 object, 32 bytes -99.9% was used for memory not allocated for objects: +100.0% was used for memory not allocated for objects: - 62.4% text stream storage 89499836 bytes in 515308 claims + 62.4% text stream storage 89500736 bytes in 515311 claims 3.8% dictionary storage 5505088 bytes in 7779 claims ---- sorting 2624 bytes in 531 claims 5.0% source text 7200000 bytes in 3 claims @@ -282,5 +282,5 @@ Total memory consumption was 139941K = 137 MB ---- code generation workspace for objects 3536 bytes in 19 claims 0.2% emitter array storage 290048 bytes in 2074 claims --136.-7% was overhead - -196008448 bytes = -191414K = -186 MB +-136.-7% was overhead - -196009008 bytes = -191415K = -186 MB diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt index 136cb1d46..a99b5039f 100644 --- a/inform7/Figures/timings-diagnostics.txt +++ b/inform7/Figures/timings-diagnostics.txt @@ -1,6 +1,6 @@ 100.0% in inform7 run - 68.2% in compilation to Inter - 46.5% in //Sequence::undertake_queued_tasks// + 67.3% in compilation to Inter + 45.7% in //Sequence::undertake_queued_tasks// 4.2% in //MajorNodes::pre_pass// 3.4% in //MajorNodes::pass_1// 1.9% in //ImperativeDefinitions::assess_all// @@ -13,16 +13,17 @@ 0.3% in //Sequence::undertake_queued_tasks// 0.3% in //Sequence::undertake_queued_tasks// 0.3% in //World::stage_V// - 5.5% not specifically accounted for - 27.5% in running Inter pipeline - 8.9% in step 14/15: generate inform6 -> auto.inf + 5.4% not specifically accounted for + 28.0% in running Inter pipeline + 9.2% in step 14/15: generate inform6 -> auto.inf 6.9% in step 5/15: load-binary-kits - 5.8% in step 6/15: make-synoptic-module + 5.7% in step 6/15: make-synoptic-module 1.9% in step 9/15: make-identifiers-unique + 0.3% in step 11/15: eliminate-redundant-labels 0.3% in step 12/15: eliminate-redundant-operations 0.3% in step 4/15: compile-splats 0.3% in step 7/15: shorten-wiring 0.3% in step 8/15: detect-indirect-calls - 2.4% not specifically accounted for + 2.3% not specifically accounted for 3.8% in supervisor - 0.4% not specifically accounted for + 0.8% not specifically accounted for diff --git a/inform7/Internal/Inter/Architecture16Kit/kit_metadata.json b/inform7/Internal/Inter/Architecture16Kit/kit_metadata.json index f49c4cc09..703627986 100644 --- a/inform7/Internal/Inter/Architecture16Kit/kit_metadata.json +++ b/inform7/Internal/Inter/Architecture16Kit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "Architecture16Kit", - "version": "10.2.0-beta+6X44" + "version": "10.2.0-beta+6X45" }, "compatibility": "16-bit", "kit-details": { diff --git a/inform7/Internal/Inter/Architecture32Kit/kit_metadata.json b/inform7/Internal/Inter/Architecture32Kit/kit_metadata.json index eb2e2429e..ec3f26907 100644 --- a/inform7/Internal/Inter/Architecture32Kit/kit_metadata.json +++ b/inform7/Internal/Inter/Architecture32Kit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "Architecture32Kit", - "version": "10.2.0-beta+6X44" + "version": "10.2.0-beta+6X45" }, "compatibility": "32-bit", "kit-details": { diff --git a/inform7/Internal/Inter/BasicInformKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformKit/kit_metadata.json index 2cae25435..6287eb19d 100644 --- a/inform7/Internal/Inter/BasicInformKit/kit_metadata.json +++ b/inform7/Internal/Inter/BasicInformKit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "BasicInformKit", - "version": "10.2.0-beta+6X44" + "version": "10.2.0-beta+6X45" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/CommandParserKit/kit_metadata.json b/inform7/Internal/Inter/CommandParserKit/kit_metadata.json index 18a7706ce..2f90fb6be 100644 --- a/inform7/Internal/Inter/CommandParserKit/kit_metadata.json +++ b/inform7/Internal/Inter/CommandParserKit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "CommandParserKit", - "version": "10.2.0-beta+6X44" + "version": "10.2.0-beta+6X45" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json b/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json index a2a79fd4a..bf583cdde 100644 --- a/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json +++ b/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "EnglishLanguageKit", - "version": "10.2.0-beta+6X44" + "version": "10.2.0-beta+6X45" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/WorldModelKit/kit_metadata.json b/inform7/Internal/Inter/WorldModelKit/kit_metadata.json index c6f094779..1bbea8230 100644 --- a/inform7/Internal/Inter/WorldModelKit/kit_metadata.json +++ b/inform7/Internal/Inter/WorldModelKit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "WorldModelKit", - "version": "10.2.0-beta+6X44" + "version": "10.2.0-beta+6X45" }, "needs": [ { "need": { diff --git a/resources/Documentation/Writing with Inform.md b/resources/Documentation/Writing with Inform.md index e246c1e91..dbd4b6143 100644 --- a/resources/Documentation/Writing with Inform.md +++ b/resources/Documentation/Writing with Inform.md @@ -20510,7 +20510,158 @@ In particular: ## About kits -To follow. +A _kit_ is a body of code written entirely in I6 syntax. It is compiled independently from the source text of a story which uses it, and the two are then merged together (or _linked_). Kits can be quite large: `BasicInformKit`, which sits inside the `Basic Inform` extension, runs to over 12,000 lines. Equally, they do not have to be. It's fine to write a kit containing just a single function or two. + +Kits sit inside extensions, and provide them with support services. An extension can contain multiple kits, but of course does not need to contain any. Kits increase the power of extensions in a number of ways. They can access memory directly, and are not constrained by the kind-safety rules which would apply to higher-level code. For example, all the code to build, sort and dismantle lists is done by functions in `BasicInformKit`. Kits can also create new fundamental kinds of value for Inform. + +This chapter is the most technical in the book. It's aimed at writers of extensions who need more power, and it assumes the reader is comfortable with the material in the [Extensions] and [Low-Level Programming] chapters, together with at least a passing knowledge of Inform 6 syntax, since that's essentially the same thing as writing I6. + +## Adding a kit to an extension + +Suppose the extension `Roots of Equations by Peter Drake` wants to perform some mathematical algorithms which will be coded in I6. We will do this by placing the I6 material in `RootsOfEquationsKit`, which will live inside the extension like so: + +``` code +Ducking Action-v1.i7xd + extension_metadata.json + Materials + Inter + RootsOfEquationsKit + ... + Source + Ducking Action.i7x +``` + +All kits have to have names ending in `Kit`, and by convention if an extension contains a single kit then its name is the extension title in camel-casing with the spaces removed and `Kit` suffixed. So `Roots of Equations` becomes `RootsOfEquationsKit`. + +Note that kits live inside the `Inter` subdirectory of the `Materials` directory private to the extension. See [Images and other resources] for more on `Materials`, which can also include all manner of other good things. + +`RootsOfEquationsKit` is itself a directory, which looks like this: + +``` code +RootsOfEquationsKit + Contents.w + kit_metadata.json + Sections + Roots.w +``` + +The actual I6 source for the kit code is in the file `Roots.w`, but before we can get to that, we have to do some book-keeping. + +1) The `Contents.w` file doesn't look very interesting at first because there's only one source file, `Roots.w`, so this is currently like a contents page for a book with only one chapter: + + ``` code + Title: RootsOfEquationsKit + Author: Peter Drake + Purpose: Some Newton-Raphson approximation functions. + Language: Inform 6 + + Sections + Roots + ``` + +2) There must also be a `kit_metadata.json` file: + + ``` code + { + "is": { + "type": "kit", + "title": "RootsOfEquationsKit", + "version": "1" + } + } + ``` + + This should look very similar to the `extension_metadata.json` file found in extensions, and indeed it has a great deal in common, though as we shall see it can be considerably extended. + +Why are there two files like this, not one, given that both are basically descriptions of what the kit is? One answer is that they actually serve different purposes: `Contents.w` describes the _source code_ for the kit, whereas `kit_metadata.json` describes the resulting compiled kit. + +The other is that kits are designed to be compatible with the ```inweb``` system for "literate programming". This is how it is that annotated forms of the source for `BasicInformKit` and `WorldModelKit`, for example, are hosted at the Inform source code website. + +So-called _section files_ also have a marked-up format suitable for ```inweb```. (The ```.w``` at the end of the two filenames ```Contents.w``` and ```Roots.w``` means "web".) + +Here is a minimal but legal form for ```Roots.w```: + +``` code +Roots + +Some functions for finding roots of polynomials by Newton-Raphson approximation. + +@ Just one placeholder for now: + += +[ EvaluatePolynomial f x; + print "Not implemented yet.^"; +]; +``` + +Web files begin with a line giving the title of the section — here, ```Root``` — then skip a line, and give a sentence or two describing the content in slightly more detail. After that, they are a sequence of "paragraphs". Each paragraph begins with an ```@``` character on the left margin. There's then space for some commentary about what is coming up: authors usually use this space to document calling conventions for functions, or say why they work they way they do. + +There is then a line with an ```=``` character on the left margin. After that, the rest of the paragraph is I6 code. So the actual content of the above section, once all the annotations are peeled off, is just this: + +``` code +[ EvaluatePolynomial f x; + print "Not implemented yet.^"; +]; +``` + +In other words, the kit — which is now complete — provides just a single function. + +We can now use it. As established, `RootsOfEquationsKit` is sitting inside the extension `Roots of Equations by Peter Drake`. We call this the _wrapper extension_ for the kit. That extension might now contain this phrase definition: + + To decide which real number is the evaluation of (polynomial - list of real numbers) at (x - real number): + (- (EvaluatePolynomial({polynomial}, {x})) -). + +If we then run a test project which includes the extension, and if we are looking carefully, we might notice this message scroll by on the console: + +``` code +(Building RootsOfEquationsKit for architecture 16) +(Building RootsOfEquationsKit for architecture 16d) +(Building RootsOfEquationsKit for architecture 32) +(Building RootsOfEquationsKit for architecture 32d) +``` + +This is because Inform can only use `RootsOfEquationsKit` once it has been built (i.e., compiled): and since Inform could see the source code for the kit, it went ahead and built the thing. Inform builds kits only when necessary. If the timestamp on the source code files is later than that of the built form of the kit, then Inform assumes the source code has been changed since the last time the kit was built, so it rebuilds. Otherwise, if the kit source remains unchanged, Inform won't build the kit again. + +In fact, it builds the kit not once but four times, once for each possible architecture the kit will run on. (Once built, a kit is what is sometimes called a "fat binary", in that it contains multiple different compiled versions in one.) ```16``` and ```32``` refer to the 16-bit and 32-bit versions used on Z-machine and Glulx respectively, and ```16d``` and ```32d``` the same but with debugging features enabled — in effect, not-for-release features. By default, in the app, a project will use the ```32d``` architecture, and then when released, the ```32``` architecture. Inform handles all of this automatically. + +If we look back at the directory, we see that more files have appeared: + +``` code +RootsOfEquationsKit + arch-16.interb + arch-16d.interb + arch-32.interb + arch-32d.interb + Contents.w + kit_metadata.json + Sections + Roots.w +``` + +The ```.interb``` filename endings mean "Inter binary code", and there's one for each architecture. + +Something else happened on that first run: the `extension_metadata.json` file for the wrapper extension was quietly rewritten. It now includes a _dependency_ of the extension on the kit: + +``` code +{ + "is": { + "type": "extension", + "title": "Roots of Equations", + "author": "Peter Drake", + "version": "1" + }, + "needs": [ { + "need": { + "type": "kit", + "title": "RootsOfEquationsKit" + } + } ] +} +``` + +This tracking goes on automatically and authors can usually just let it happen all by itself, but if we decided against the kit after all and removed it from the extension, then this dependency would have to be removed from `extension_metadata.json` before the extension would work again. + +The full set of features of ```inweb``` is extensive and this is not the place to go into that. In brief, though, kit section files like ```Roots.w``` can't use any of the interesting tangling features (such as ```@d```, or ```@< ... >@```); but they can use all the weaving features. Inform users don't need to have ```inweb``` in order to write or use kits, and don't need to understand what the last sentence said. ## Run-time representations of Inform constructs