From 5c790b9f23f74529f3f5366f4b99a835e1d383d0 Mon Sep 17 00:00:00 2001 From: Zed Lopez Date: Tue, 18 Apr 2023 09:14:30 -0700 Subject: [PATCH 001/113] initial commit --- .../WorldModelKit/Sections/ListWriter.i6t | 43 +++++++---- .../standard_rules/Sections/Actions.w | 14 ++-- .../standard_rules/Sections/Activities.w | 77 +++++++++++++++++++ .../Sections/Physical World Model.w | 10 +++ 4 files changed, 124 insertions(+), 20 deletions(-) diff --git a/inform7/Internal/Inter/WorldModelKit/Sections/ListWriter.i6t b/inform7/Internal/Inter/WorldModelKit/Sections/ListWriter.i6t index 2a041c3ef..cc9f31076 100644 --- a/inform7/Internal/Inter/WorldModelKit/Sections/ListWriter.i6t +++ b/inform7/Internal/Inter/WorldModelKit/Sections/ListWriter.i6t @@ -341,6 +341,24 @@ account. rfalse; ]; +@h Having Evident Content +This is true when something has at least one unconcealed thing in it. +It's false when something is truly empty or when all the things in +it are concealed, and is used to ensure that output is consistent +in both those cases. + += +[ HasEvidentContent o x; +if (~~((o ofclass K5_container) || (o ofclass K6_supporter))) rfalse; +if (o has container && (o hasnt open) && (o hasnt transparent)) rfalse; ! opaque closed container's status never be obvious +x = child(o); +while (x) { +if (~~ConcealedFromLists(x)) rtrue; +x = sibling(x); +} +rfalse; +]; + @h Coalesce Marked List. The return value is the new first entry in the raw list. @@ -582,21 +600,16 @@ by Inform. But this seems to be sound. = [ ListEqual o1 o2; - if ((o1.plural == 0) || (o2.plural == 0)) rfalse; - if (child(o1) ~= 0 && WillRecurs(o1) ~= 0) rfalse; - if (child(o2) ~= 0 && WillRecurs(o2) ~= 0) rfalse; - if (c_style & (FULLINV_BIT + PARTINV_BIT) ~= 0) { - if ((o1 hasnt worn && o2 has worn) || (o2 hasnt worn && o1 has worn)) rfalse; - if ((o1 hasnt light && o2 has light) || (o2 hasnt light && o1 has light)) rfalse; - if (o1 has container) { - if (o2 hasnt container) rfalse; - if ((o1 has open && o2 hasnt open) || (o2 has open && o1 hasnt open)) - rfalse; - } - else if (o2 has container) - rfalse; - } - return Identical(o1, o2); + if (o1.KD_Count ~= o2.KD_Count) rfalse; + if ((o1.plural == 0) || (o2.plural == 0)) rfalse; + if (HasEvidentContent(o1) && WillRecurs(o1)) rfalse; + if (HasEvidentContent(o2) && WillRecurs(o2)) rfalse; + if (c_style & (FULLINV_BIT + PARTINV_BIT) ~= 0) { + if ((o1 hasnt worn && o2 has worn) || (o2 hasnt worn && o1 has worn)) rfalse; + if ((o1 hasnt light && o2 has light) || (o2 hasnt light && o1 has light)) rfalse; + if ((o1 has open && o2 hasnt open) || (o2 has open && o1 hasnt open)) rfalse; + } + return Identical(o1, o2); ]; [ WillRecurs o; diff --git a/inform7/extensions/standard_rules/Sections/Actions.w b/inform7/extensions/standard_rules/Sections/Actions.w index 9b1b81e8e..6f68f53cb 100644 --- a/inform7/extensions/standard_rules/Sections/Actions.w +++ b/inform7/extensions/standard_rules/Sections/Actions.w @@ -65,8 +65,9 @@ Carry out taking inventory (this is the print empty inventory rule): Carry out taking inventory (this is the print standard inventory rule): say "[We] [are] carrying:[line break]" (A); - list the contents of the player, with newlines, indented, including contents, - giving inventory information, with extra indentation. + now all things enclosed by the player are unmarked for listing; + now all things held by the player are marked for listing; + list the contents of the player, with newlines, indented, giving inventory information, with extra indentation, listing marked items only, not listing concealed items, including contents. @ Report. @@ -1183,7 +1184,10 @@ Carry out examining (this is the examine directions rule): Carry out examining (this is the examine containers rule): if the noun is a container: - if the noun is open or the noun is transparent: + if the noun is falsely empty: + say "[The noun] [are] empty." (C); + now examine text printed is true; + else if the noun is open or the noun is transparent: if something described which is not scenery is in the noun and something which is not the player is in the noun: say "In [the noun] " (A); @@ -1198,7 +1202,7 @@ Carry out examining (this is the examine containers rule): now examine text printed is true; Carry out examining (this is the examine supporters rule): - if the noun is a supporter: + if the noun is a supporter and the noun is not falsely empty: if something described which is not scenery is on the noun and something which is not the player is on the noun: say "On [the noun] " (A); @@ -1657,7 +1661,7 @@ Carry out an actor opening (this is the standard opening rule): Report an actor opening (this is the reveal any newly visible interior rule): if the actor is the player and the noun is an opaque container and - the first thing held by the noun is not nothing and + the noun is clearly non-empty and the noun does not enclose the actor: if the action is not silent: if the actor is the player: diff --git a/inform7/extensions/standard_rules/Sections/Activities.w b/inform7/extensions/standard_rules/Sections/Activities.w index 62091cf96..039890030 100644 --- a/inform7/extensions/standard_rules/Sections/Activities.w +++ b/inform7/extensions/standard_rules/Sections/Activities.w @@ -65,9 +65,57 @@ supplemented by details: = Printing room description details of something (documented at act_details) is an activity. The printing room description details activity is accessible to Inter as "PRINTING_ROOM_DESC_DETAILS_ACT". + +For printing room description details of a container (called the box) when the box is falsely empty (this is the falsely empty container room description details rule): + say text of list writer internal rule response (A); [ " (" ] + if the box is lit and the location is unlit begin; + if the box is closed, say text of list writer internal rule response (J); [ "closed, empty[if serial comma option is active],[end if] and providing light" ] + else say text of list writer internal rule response (I); [ "empty and providing light" ] + else; + if the box is closed, say text of list writer internal rule response (E); [ "closed" ] + else say text of list writer internal rule response (F); [ "empty" ] + end if; + say text of list writer internal rule response (B); [ ")" ] + Printing inventory details of something (documented at act_idetails) is an activity. The printing inventory details activity is accessible to Inter as "PRINTING_INVENTORY_DETAILS_ACT". + +To say the deceitfully empty inventory details of (box - a container): + let inventory text printed be false; + if the box is lit begin; + if the box is worn, say text of list writer internal rule response (K); [ "providing light and being worn" ] + else say text of list writer internal rule response (D); [ "providing light" ] + now inventory text printed is true; + else if the box is worn; + say text of list writer internal rule response (L); [ "being worn" ] + now inventory text printed is true; + end if; + if the box is openable begin; + if inventory text printed is true begin; + if the serial comma option is active, say ","; + say text of list writer internal rule response (C); [ "and" ] + end if; + if the box is open begin; + say text of list writer internal rule response (N); [ "open but empty" ] + else; [ it's closed ] + if the box is locked, say text of list writer internal rule response (P); [ "closed and locked" ] + else say text of list writer internal rule response (O); [ "closed" ] + now inventory text printed is true; + end if; + else; [ it's not openable ] + if the box is transparent begin; + if inventory text printed is true, say text of list writer internal rule response (C); [ "and" ] + say text of list writer internal rule response (F); [ "empty" ] + now inventory text printed is true; [ not relevant unless code is added ] + end if; + end if; + +For printing inventory details of a container (called the box) when the box is falsely empty (this is the falsely empty container inventory details rule): + say text of list writer internal rule response (A); [ "(" ] + say the deceitfully empty inventory details of box; + say text of list writer internal rule response (B); [ ")" ] + @ Names of things are often formed up into lists, in which they are sometimes grouped together: @@ -711,6 +759,34 @@ For printing a locale paragraph about a supporter (called the tabletop) Definition: a thing (called the item) is locale-supportable if the item is not scenery and the item is not mentioned and the item is not undescribed. +For printing a locale paragraph about a thing (called the platform) + (this is the describe what's on scenery supporters in room descriptions rule): + if the platform is not a scenery supporter that does not enclose the player, continue the activity; + let print a paragraph be false; + let item be the first thing held by the platform; + while item is not nothing begin; + if the item is not scenery and the item is described and the platform does not conceal the item begin; + if the item is mentioned begin; + now the item is not marked for listing; + else; + now the item is marked for listing; + now print a paragraph is true; + end if; + end if; + now the item is the next thing held after the item; + end while; + if print a paragraph is true begin; + set pronouns from the platform; + increase the locale paragraph count by 1; + say "On [the platform] " (A); + list the contents of the platform, as a sentence, including contents, + giving brief inventory information, tersely, not listing + concealed items, prefacing with is/are, listing marked items only; + say ".[paragraph break]"; + end if; + continue the activity + +[ For printing a locale paragraph about a thing (called the item) (this is the describe what's on scenery supporters in room descriptions rule): if the item is scenery and the item does not enclose the player: @@ -727,6 +803,7 @@ For printing a locale paragraph about a thing (called the item) concealed items, prefacing with is/are, listing marked items only; say ".[paragraph break]"; continue the activity. +] For printing a locale paragraph about a thing (called the item) (this is the describe what's on mentioned supporters in room descriptions rule): diff --git a/inform7/extensions/standard_rules/Sections/Physical World Model.w b/inform7/extensions/standard_rules/Sections/Physical World Model.w index 5b82a9b0f..4700f91a2 100644 --- a/inform7/extensions/standard_rules/Sections/Physical World Model.w +++ b/inform7/extensions/standard_rules/Sections/Physical World Model.w @@ -92,6 +92,16 @@ The verb to conceal (he conceals, they conceal, he concealed, it is concealed, he is concealing) means the concealment relation. Definition: Something is concealed rather than unconcealed if the holder of it conceals it. +@ Something is obviously not empty if it has at least one obvious (unconcealed) thing in it. + Something is apparently empty if it's either truly empty or everything in it is concealed. + += +Definition: a container is clearly non-empty rather than possibly empty if I6 routine "HasEvidentContent" says so (it contains at least one unconcealed thing). +Definition: a supporter is clearly non-empty rather than possibly empty if I6 routine "HasEvidentContent" says so (it supports at least one unconcealed thing). + +Definition: a container is falsely empty if I6 condition "(child(*1) && (~~HasEvidentContent(*1)))" says so (it contains at least one thing and everything in it is concealed). +Definition: a supporter is falsely empty if I6 condition "(child(*1) && (~~HasEvidentContent(*1)))" says so (it supports at least one thing and everything in it is concealed). + @ A final sort of pseudo-containment: does the entire world contain something, or not? (For things destroyed during play, or not yet created, the answer would be no.) From 877a876e0f5c2f22f338181962fd8861e24caa6e Mon Sep 17 00:00:00 2001 From: Zed Lopez Date: Thu, 20 Apr 2023 21:35:26 -0700 Subject: [PATCH 002/113] believed to be working concealment patches --- .../WorldModelKit/Sections/ListWriter.i6t | 26 +++++----- inform7/Tests/Test Cases/Concealment.txt | 50 +++++++++++++++++++ .../standard_rules/Sections/Actions.w | 10 ++-- .../standard_rules/Sections/Activities.w | 5 +- .../Sections/Physical World Model.w | 50 ++++++++++++++++--- resources/Documentation/The Recipe Book.txt | 2 + 6 files changed, 117 insertions(+), 26 deletions(-) create mode 100644 inform7/Tests/Test Cases/Concealment.txt diff --git a/inform7/Internal/Inter/WorldModelKit/Sections/ListWriter.i6t b/inform7/Internal/Inter/WorldModelKit/Sections/ListWriter.i6t index cc9f31076..8f44cd594 100644 --- a/inform7/Internal/Inter/WorldModelKit/Sections/ListWriter.i6t +++ b/inform7/Internal/Inter/WorldModelKit/Sections/ListWriter.i6t @@ -345,18 +345,20 @@ account. This is true when something has at least one unconcealed thing in it. It's false when something is truly empty or when all the things in it are concealed, and is used to ensure that output is consistent -in both those cases. +in both those cases. The player shouldn't count for these purposes, +but since the player has the concealed attribute, the player gets +excluded anyway. = -[ HasEvidentContent o x; -if (~~((o ofclass K5_container) || (o ofclass K6_supporter))) rfalse; -if (o has container && (o hasnt open) && (o hasnt transparent)) rfalse; ! opaque closed container's status never be obvious -x = child(o); -while (x) { -if (~~ConcealedFromLists(x)) rtrue; -x = sibling(x); -} -rfalse; +[ ObviouslyOccupied o x; + if (~~((o ofclass K5_container) || (o ofclass K6_supporter))) rfalse; + if (o has container && o hasnt open && o hasnt transparent) rfalse; ! opaque closed container's status can never be obvious + x = child(o); + while (x) { + if ((x hasnt concealed) && (~~TestConcealment(o, x))) rtrue; + x = sibling(x); + } + rfalse; ]; @h Coalesce Marked List. @@ -602,8 +604,8 @@ by Inform. But this seems to be sound. [ ListEqual o1 o2; if (o1.KD_Count ~= o2.KD_Count) rfalse; if ((o1.plural == 0) || (o2.plural == 0)) rfalse; - if (HasEvidentContent(o1) && WillRecurs(o1)) rfalse; - if (HasEvidentContent(o2) && WillRecurs(o2)) rfalse; + if (ObviouslyOccupied(o1) && WillRecurs(o1)) rfalse; + if (ObviouslyOccupied(o2) && WillRecurs(o2)) rfalse; if (c_style & (FULLINV_BIT + PARTINV_BIT) ~= 0) { if ((o1 hasnt worn && o2 has worn) || (o2 hasnt worn && o1 has worn)) rfalse; if ((o1 hasnt light && o2 has light) || (o2 hasnt light && o1 has light)) rfalse; diff --git a/inform7/Tests/Test Cases/Concealment.txt b/inform7/Tests/Test Cases/Concealment.txt new file mode 100644 index 000000000..68092c014 --- /dev/null +++ b/inform7/Tests/Test Cases/Concealment.txt @@ -0,0 +1,50 @@ +Lab is a room. + +A thing can be occulted. + +For deciding the concealed possessions of a thing when the particular possession is occulted: rule succeeds. + +The table is a scenery supporter in the lab. +The plans are an occulted thing. The plans are on the table. +The journal is an occulted thing. The journal is on the table. + +The desk is a scenery supporter in the lab. +The letter is an occulted thing. The letter is on the desk. + +The settee is a scenery supporter in the lab. +The postcard is an occulted thing. The postcard is on the settee. +The cushion is on the settee. + +The stool is a scenery supporter in the lab. +The shoe is on the stool. + +The lava floor is a scenery supporter in the lab. + +The cardboard box is a closed openable container. The limited edition She-Ra action figure is an occulted thing in the cardboard box. The Power of Greyskull is an occulted thing in the cardboard box. The cardboard box is in the lab. + +The pouch is a closed openable container. The love letter is an occulted thing in the pouch. The pouch is in the lab. + +The gift box is a closed openable container. The card is an occulted thing. The card is in the gift box. The ball is in the gift box. The gift box is in the lab. + +The jar is a closed openable container. The cookie is a thing. The jar contains the cookie. The jar is in the lab. + +The crate is a closed openable enterable container. The crate is in the lab. + +The tray is a portable supporter. The wine glass is an occulted thing on the tray. The player carries the tray. + +The platform is an enterable supporter. It is in the Lab. + +The deck is an enterable supporter. It is in the Lab. +The invisible jet is an occulted thing. +The invisible jet is on the deck. + +The stage is an enterable supporter. It is in the Lab. +The mask is on the stage. + +The beam is an enterable supporter. It is in the Lab. +The wrench is on the beam. +The tape is an occulted thing. +The tape is on the beam. + +Test me with "x table / x desk / x settee / x stool / x lava floor / open cardboard box / open pouch / open gift box / open jar / open crate / x cardboard box / x pouch / x gift box / x jar / x crate / l / i / x tray / get glass / x deck / stand on deck / x deck / l / exit / x platform / stand on platform / x platform / l / exit / x stage / stand on stage / x stage / l / exit / x beam / stand on beam / x beam / l / exit". + diff --git a/inform7/extensions/standard_rules/Sections/Actions.w b/inform7/extensions/standard_rules/Sections/Actions.w index 6f68f53cb..b02bb16f1 100644 --- a/inform7/extensions/standard_rules/Sections/Actions.w +++ b/inform7/extensions/standard_rules/Sections/Actions.w @@ -1184,10 +1184,8 @@ Carry out examining (this is the examine directions rule): Carry out examining (this is the examine containers rule): if the noun is a container: - if the noun is falsely empty: - say "[The noun] [are] empty." (C); - now examine text printed is true; - else if the noun is open or the noun is transparent: + if the noun is closed and the noun is opaque, make no decision; + if the noun is not falsely-unoccupied: if something described which is not scenery is in the noun and something which is not the player is in the noun: say "In [the noun] " (A); @@ -1202,7 +1200,7 @@ Carry out examining (this is the examine containers rule): now examine text printed is true; Carry out examining (this is the examine supporters rule): - if the noun is a supporter and the noun is not falsely empty: + if the noun is a supporter and the noun is not falsely-unoccupied: if something described which is not scenery is on the noun and something which is not the player is on the noun: say "On [the noun] " (A); @@ -1661,7 +1659,7 @@ Carry out an actor opening (this is the standard opening rule): Report an actor opening (this is the reveal any newly visible interior rule): if the actor is the player and the noun is an opaque container and - the noun is clearly non-empty and + the noun is obviously-occupied and the noun does not enclose the actor: if the action is not silent: if the actor is the player: diff --git a/inform7/extensions/standard_rules/Sections/Activities.w b/inform7/extensions/standard_rules/Sections/Activities.w index 039890030..0ff66fece 100644 --- a/inform7/extensions/standard_rules/Sections/Activities.w +++ b/inform7/extensions/standard_rules/Sections/Activities.w @@ -66,7 +66,7 @@ supplemented by details: Printing room description details of something (documented at act_details) is an activity. The printing room description details activity is accessible to Inter as "PRINTING_ROOM_DESC_DETAILS_ACT". -For printing room description details of a container (called the box) when the box is falsely empty (this is the falsely empty container room description details rule): +For printing room description details of a container (called the box) when the box is falsely-unoccupied (this is the falsely-unoccupied container room description details rule): say text of list writer internal rule response (A); [ " (" ] if the box is lit and the location is unlit begin; if the box is closed, say text of list writer internal rule response (J); [ "closed, empty[if serial comma option is active],[end if] and providing light" ] @@ -111,7 +111,7 @@ To say the deceitfully empty inventory details of (box - a container): end if; end if; -For printing inventory details of a container (called the box) when the box is falsely empty (this is the falsely empty container inventory details rule): +For printing inventory details of a container (called the box) when the box is falsely-unoccupied (this is the falsely-unoccupied container inventory details rule): say text of list writer internal rule response (A); [ "(" ] say the deceitfully empty inventory details of box; say text of list writer internal rule response (B); [ ")" ] @@ -559,6 +559,7 @@ For printing the locale description (this is the interesting locale paragraphs r For printing the locale description (this is the you-can-also-see rule): let the domain be the parameter-object; let the mentionable count be 0; + if the domain is a thing and the domain holds the player and the domain is falsely-unoccupied, continue the activity; repeat with item running through things: now the item is not marked for listing; repeat through the Table of Locale Priorities: diff --git a/inform7/extensions/standard_rules/Sections/Physical World Model.w b/inform7/extensions/standard_rules/Sections/Physical World Model.w index 4700f91a2..bc5e6fcb7 100644 --- a/inform7/extensions/standard_rules/Sections/Physical World Model.w +++ b/inform7/extensions/standard_rules/Sections/Physical World Model.w @@ -92,15 +92,53 @@ The verb to conceal (he conceals, they conceal, he concealed, it is concealed, he is concealing) means the concealment relation. Definition: Something is concealed rather than unconcealed if the holder of it conceals it. -@ Something is obviously not empty if it has at least one obvious (unconcealed) thing in it. - Something is apparently empty if it's either truly empty or everything in it is concealed. +@ If a supporter or container has something on/in it, but all the contents are concealed or +undescribed, default behavior should be the same to what it would be if it were empty. The +following adjectives assist the maintenance of the deceit. + +Something is obviously-occupied if it has at least one obvious (neither concealed nor +undescribed) thing in it, but closed opaque containers the player is outside of aren't +obviously-occupied because their status isn't obvious. The player is undescribed and so +the player's own presence in an enterable supporter or container doesn't count toward it +being considered occupied. The opposite of obviously-occupied is possibly-unoccupied. +Something is possibly-unoccupied if it's truly empty, or the only things in it are concealed +or undescribed (or both), or it's a closed opaque container the player is outside of. + +Something is falsely-unoccupied if it's not a closed opaque continer the player is outside +of and it's not truly empty but everything in it is concealed or undescribed. Note that +falsely-unoccupied is not the opposite of obviously-occupied. Possibly-occupied is the +opposite of obviously-occupied; falsely-occupied is something different. + +None of this considers visibility per se and they behave the same way in light or +darkness. The presumption is that if the game is evaluating whether the player can perceive +the contents of a thing, it has already been determined that they can perceive that +thing. + +These tests only consider what's directly contained or supported. If there's an obvious +thing its contents can't make it any less obvious; if something is undescribed or +concealed, it's assumed that the game shouldn't be calling attention to their contents. + +These adjectives are not defined for people. Things directly held by the player are always +perceptible by the player. Things possessed by other people aren't mentioned by default +in room descriptions or when searching or examining them, but only through whatever rules +an author adds to do so, so the details are left to the author. = -Definition: a container is clearly non-empty rather than possibly empty if I6 routine "HasEvidentContent" says so (it contains at least one unconcealed thing). -Definition: a supporter is clearly non-empty rather than possibly empty if I6 routine "HasEvidentContent" says so (it supports at least one unconcealed thing). +Definition: a container is obviously-occupied rather than possibly-unoccupied if +I6 routine "ObviouslyOccupied" says so (it contains at least one obvious thing). -Definition: a container is falsely empty if I6 condition "(child(*1) && (~~HasEvidentContent(*1)))" says so (it contains at least one thing and everything in it is concealed). -Definition: a supporter is falsely empty if I6 condition "(child(*1) && (~~HasEvidentContent(*1)))" says so (it supports at least one thing and everything in it is concealed). +Definition: a supporter is obviously-occupied rather than possibly-unoccupied if +I6 routine "ObviouslyOccupied" says so (it supports at least one obvious thing). + +Definition: a container (called c) is falsely-unoccupied: + if the first thing held by it is nothing, no; + if it is closed and it is opaque and it does not enclose the player, no; + decide on whether or not it is possibly-unoccupied; + +Definition: a supporter is falsely-unoccupied: + if the first thing held by it is nothing, no; + if the first thing held by it is the player and the next thing held after the player is nothing, no; + decide on whether or not it is possibly-unoccupied; @ A final sort of pseudo-containment: does the entire world contain something, or not? (For things destroyed during play, or not yet created, the diff --git a/resources/Documentation/The Recipe Book.txt b/resources/Documentation/The Recipe Book.txt index 37c20f328..87a841fa4 100644 --- a/resources/Documentation/The Recipe Book.txt +++ b/resources/Documentation/The Recipe Book.txt @@ -259,6 +259,8 @@ When the story compiles the list of nondescript items, it adds tags such as "(op Rule for printing room description details: stop. +The "(empty)" tag can appear when something is not truly empty if everything within is concealed or undescribed. + And we can suppress the "(open)" and "(on which is...)" sorts of tags with the "omit the contents in listing" phrase, as in Rule for printing the name of the bottle while not inserting or removing: From c9f6ea9b38c36aa34964a2b6800cb9430e0c2c8e Mon Sep 17 00:00:00 2001 From: Zed Lopez Date: Sat, 22 Apr 2023 16:13:31 -0700 Subject: [PATCH 003/113] completed concealment fixes --- .../WorldModelKit/Sections/ListWriter.i6t | 8 +-- inform7/Tests/Test Cases/Concealment.txt | 50 ------------------- .../Test Cases/_Results_Ideal/Undescribed.txt | 10 ++-- .../standard_rules/Sections/Actions.w | 10 ++-- .../standard_rules/Sections/Activities.w | 10 ++-- 5 files changed, 21 insertions(+), 67 deletions(-) delete mode 100644 inform7/Tests/Test Cases/Concealment.txt diff --git a/inform7/Internal/Inter/WorldModelKit/Sections/ListWriter.i6t b/inform7/Internal/Inter/WorldModelKit/Sections/ListWriter.i6t index 8f44cd594..33e5253e0 100644 --- a/inform7/Internal/Inter/WorldModelKit/Sections/ListWriter.i6t +++ b/inform7/Internal/Inter/WorldModelKit/Sections/ListWriter.i6t @@ -344,10 +344,10 @@ account. @h Having Evident Content This is true when something has at least one unconcealed thing in it. It's false when something is truly empty or when all the things in -it are concealed, and is used to ensure that output is consistent -in both those cases. The player shouldn't count for these purposes, -but since the player has the concealed attribute, the player gets -excluded anyway. +it are concealed or undescribed, and is used to ensure that output +is consistent in both those cases. The player shouldn't count for +these purposes, but since the player is undescribed, they're excluded +anyway. = [ ObviouslyOccupied o x; diff --git a/inform7/Tests/Test Cases/Concealment.txt b/inform7/Tests/Test Cases/Concealment.txt deleted file mode 100644 index 68092c014..000000000 --- a/inform7/Tests/Test Cases/Concealment.txt +++ /dev/null @@ -1,50 +0,0 @@ -Lab is a room. - -A thing can be occulted. - -For deciding the concealed possessions of a thing when the particular possession is occulted: rule succeeds. - -The table is a scenery supporter in the lab. -The plans are an occulted thing. The plans are on the table. -The journal is an occulted thing. The journal is on the table. - -The desk is a scenery supporter in the lab. -The letter is an occulted thing. The letter is on the desk. - -The settee is a scenery supporter in the lab. -The postcard is an occulted thing. The postcard is on the settee. -The cushion is on the settee. - -The stool is a scenery supporter in the lab. -The shoe is on the stool. - -The lava floor is a scenery supporter in the lab. - -The cardboard box is a closed openable container. The limited edition She-Ra action figure is an occulted thing in the cardboard box. The Power of Greyskull is an occulted thing in the cardboard box. The cardboard box is in the lab. - -The pouch is a closed openable container. The love letter is an occulted thing in the pouch. The pouch is in the lab. - -The gift box is a closed openable container. The card is an occulted thing. The card is in the gift box. The ball is in the gift box. The gift box is in the lab. - -The jar is a closed openable container. The cookie is a thing. The jar contains the cookie. The jar is in the lab. - -The crate is a closed openable enterable container. The crate is in the lab. - -The tray is a portable supporter. The wine glass is an occulted thing on the tray. The player carries the tray. - -The platform is an enterable supporter. It is in the Lab. - -The deck is an enterable supporter. It is in the Lab. -The invisible jet is an occulted thing. -The invisible jet is on the deck. - -The stage is an enterable supporter. It is in the Lab. -The mask is on the stage. - -The beam is an enterable supporter. It is in the Lab. -The wrench is on the beam. -The tape is an occulted thing. -The tape is on the beam. - -Test me with "x table / x desk / x settee / x stool / x lava floor / open cardboard box / open pouch / open gift box / open jar / open crate / x cardboard box / x pouch / x gift box / x jar / x crate / l / i / x tray / get glass / x deck / stand on deck / x deck / l / exit / x platform / stand on platform / x platform / l / exit / x stage / stand on stage / x stage / l / exit / x beam / stand on beam / x beam / l / exit". - diff --git a/inform7/Tests/Test Cases/_Results_Ideal/Undescribed.txt b/inform7/Tests/Test Cases/_Results_Ideal/Undescribed.txt index caff7729a..9f108ec97 100644 --- a/inform7/Tests/Test Cases/_Results_Ideal/Undescribed.txt +++ b/inform7/Tests/Test Cases/_Results_Ideal/Undescribed.txt @@ -1,23 +1,23 @@ Bar Welcome An Interactive Fiction - Release 1 / Serial number 150512 / Inform 7 build 6M22 (I6/v6.33 lib 6/12N) SD + Release 1 / Serial number 160428 / Inform 7 v10.2.0 / D Bar - You can see a counter (on which is a glass jar) and an obvious item here. + You can see a counter (on which is a glass jar (empty)) and an obvious item here. > > Bar (Testing.) >[1] x jar - The glass jar is empty. + You see nothing special about the glass jar. >[2] x hidden object You see nothing special about the hidden object. >[3] look Bar - You can see a counter (on which is a glass jar) and an obvious item here. + You can see a counter (on which is a glass jar (empty)) and an obvious item here. >[4] take all obvious item: Taken. @@ -102,7 +102,7 @@ Dropped. >[23] x glass jar - The glass jar is empty. + You see nothing special about the glass jar. >[24] search glass jar The glass jar is empty. diff --git a/inform7/extensions/standard_rules/Sections/Actions.w b/inform7/extensions/standard_rules/Sections/Actions.w index b02bb16f1..8f0aa0fdb 100644 --- a/inform7/extensions/standard_rules/Sections/Actions.w +++ b/inform7/extensions/standard_rules/Sections/Actions.w @@ -1193,11 +1193,11 @@ Carry out examining (this is the examine containers rule): concealed items, prefacing with is/are; say "."; now examine text printed is true; - otherwise if examine text printed is false: - if the player is in the noun: - make no decision; - say "[The noun] [are] empty." (B); - now examine text printed is true; + otherwise if examine text printed is false and the first thing held by the noun is nothing: + if the player is in the noun: + make no decision; + say "[The noun] [are] empty." (B); + now examine text printed is true; Carry out examining (this is the examine supporters rule): if the noun is a supporter and the noun is not falsely-unoccupied: diff --git a/inform7/extensions/standard_rules/Sections/Activities.w b/inform7/extensions/standard_rules/Sections/Activities.w index 0ff66fece..4e46d3059 100644 --- a/inform7/extensions/standard_rules/Sections/Activities.w +++ b/inform7/extensions/standard_rules/Sections/Activities.w @@ -112,9 +112,12 @@ To say the deceitfully empty inventory details of (box - a container): end if; For printing inventory details of a container (called the box) when the box is falsely-unoccupied (this is the falsely-unoccupied container inventory details rule): - say text of list writer internal rule response (A); [ "(" ] - say the deceitfully empty inventory details of box; - say text of list writer internal rule response (B); [ ")" ] + let the tag be "[the deceitfully empty inventory details of box]"; + if tag is not empty begin; + say text of list writer internal rule response (A); [ "(" ] + say tag; + say text of list writer internal rule response (B); [ ")" ] + end if; @ Names of things are often formed up into lists, in which they are sometimes grouped together: @@ -127,6 +130,7 @@ The standard contents listing rule is defined by Inter as "STANDARD_CONTENTS_LIS Grouping together something (documented at act_gt) is an activity. The grouping together activity is accessible to Inter as "GROUPING_TOGETHER_ACT". + @ And such lists of names are formed up in turn into room descriptions. Something which is visible in a room can either have a paragraph of its own or can be relegated to the list of "nondescript" items at the end. From d34efdab5249d80b34021aad892016362ac8f391 Mon Sep 17 00:00:00 2001 From: Zed Lopez Date: Sat, 22 Apr 2023 16:18:14 -0700 Subject: [PATCH 004/113] removing commented out code --- .../standard_rules/Sections/Activities.w | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/inform7/extensions/standard_rules/Sections/Activities.w b/inform7/extensions/standard_rules/Sections/Activities.w index 4e46d3059..69b4a4eab 100644 --- a/inform7/extensions/standard_rules/Sections/Activities.w +++ b/inform7/extensions/standard_rules/Sections/Activities.w @@ -791,25 +791,6 @@ For printing a locale paragraph about a thing (called the platform) end if; continue the activity -[ -For printing a locale paragraph about a thing (called the item) - (this is the describe what's on scenery supporters in room descriptions rule): - if the item is scenery and the item does not enclose the player: - if a locale-supportable thing is on the item: - set pronouns from the item; - repeat with possibility running through things on the item: - now the possibility is marked for listing; - if the possibility is mentioned: - now the possibility is not marked for listing; - increase the locale paragraph count by 1; - say "On [the item] " (A); - list the contents of the item, as a sentence, including contents, - giving brief inventory information, tersely, not listing - concealed items, prefacing with is/are, listing marked items only; - say ".[paragraph break]"; - continue the activity. -] - For printing a locale paragraph about a thing (called the item) (this is the describe what's on mentioned supporters in room descriptions rule): if the item is mentioned and the item is not undescribed and the item is From 56fd1565220b6d92f065afd0f7b823b479104ec6 Mon Sep 17 00:00:00 2001 From: Zed Lopez Date: Sat, 22 Apr 2023 17:50:59 -0700 Subject: [PATCH 005/113] fix to examining containers; reblessing Undescribed --- .../Test Cases/_Results_Ideal/Undescribed.txt | 4 ++-- .../standard_rules/Sections/Actions.w | 19 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/inform7/Tests/Test Cases/_Results_Ideal/Undescribed.txt b/inform7/Tests/Test Cases/_Results_Ideal/Undescribed.txt index 9f108ec97..54015b8ce 100644 --- a/inform7/Tests/Test Cases/_Results_Ideal/Undescribed.txt +++ b/inform7/Tests/Test Cases/_Results_Ideal/Undescribed.txt @@ -10,7 +10,7 @@ (Testing.) >[1] x jar - You see nothing special about the glass jar. + The glass jar is empty. >[2] x hidden object You see nothing special about the hidden object. @@ -102,7 +102,7 @@ Dropped. >[23] x glass jar - You see nothing special about the glass jar. + The glass jar is empty. >[24] search glass jar The glass jar is empty. diff --git a/inform7/extensions/standard_rules/Sections/Actions.w b/inform7/extensions/standard_rules/Sections/Actions.w index 8f0aa0fdb..a36f38a3e 100644 --- a/inform7/extensions/standard_rules/Sections/Actions.w +++ b/inform7/extensions/standard_rules/Sections/Actions.w @@ -1184,16 +1184,15 @@ Carry out examining (this is the examine directions rule): Carry out examining (this is the examine containers rule): if the noun is a container: - if the noun is closed and the noun is opaque, make no decision; - if the noun is not falsely-unoccupied: - if something described which is not scenery is in the noun and something which - is not the player is in the noun: - say "In [the noun] " (A); - list the contents of the noun, as a sentence, tersely, not listing - concealed items, prefacing with is/are; - say "."; - now examine text printed is true; - otherwise if examine text printed is false and the first thing held by the noun is nothing: + if the noun is closed and the noun is opaque, make no decision; + if something described which is not scenery is in the noun and something which + is not the player is in the noun and the noun is not falsely-unoccupied: + say "In [the noun] " (A); + list the contents of the noun, as a sentence, tersely, not listing + concealed items, prefacing with is/are; + say "."; + now examine text printed is true; + otherwise if examine text printed is false: if the player is in the noun: make no decision; say "[The noun] [are] empty." (B); From 9881c2eb099042191cd229c0d2c3a48ab74ec407 Mon Sep 17 00:00:00 2001 From: Zed Lopez Date: Sun, 23 Apr 2023 01:39:46 -0700 Subject: [PATCH 006/113] initial commit toward deactivate_clarification --- inform7/Internal/Inter/CommandParserKit/Sections/Parser.i6t | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/inform7/Internal/Inter/CommandParserKit/Sections/Parser.i6t b/inform7/Internal/Inter/CommandParserKit/Sections/Parser.i6t index 7b6a1445a..9491d04b7 100644 --- a/inform7/Internal/Inter/CommandParserKit/Sections/Parser.i6t +++ b/inform7/Internal/Inter/CommandParserKit/Sections/Parser.i6t @@ -98,6 +98,8 @@ Global hb_wn; ! left over? (And a save value for wn.) Global usual_grammar_after; ! Point from which usual grammar is parsed (it may vary from ! the above if user's routines match multi-word verbs) +Global dont_ask_for_clarification; ! Allows deactivating clarification question + @h Grammar Token Variables. More globals, but dealing at the level of individual tokens now. @@ -1750,7 +1752,7 @@ Parse an object name. #Ifdef DEBUG; if (parser_trace >= 3) print " [Calling NounDomain on location and actor]^"; #Endif; ! DEBUG - l = NounDomain(actors_location, actor, token); + l = NounDomain(actors_location, actor, token, dont_ask_for_clarification); if (l == REPARSE_CODE) return l; ! Reparse after Q&A if (indef_wanted == INDEF_ALL_WANTED && l == 0 && number_matched == 0) l = 1; ! ReviseMulti if TAKE ALL FROM empty container @@ -1834,7 +1836,7 @@ Parse an object name. ! Case 2: token is "held" (which fortunately can't take multiple objects) ! and may generate an implicit take - l = NounDomain(actor,actors_location,token); ! Same as above... + l = NounDomain(actor,actors_location,token,dont_ask_for_clarification); ! Same as above... if (l == REPARSE_CODE) return l; if (l == 0) { if (indef_possambig) { From 32064e9d248838b9baac5440b9044cf705c4d307 Mon Sep 17 00:00:00 2001 From: Zed Lopez Date: Sun, 23 Apr 2023 07:13:52 -0700 Subject: [PATCH 007/113] clarification deactivation commitification --- inform7/Tests/Test Cases/Clarified.txt | 15 +++++++++ .../Test Cases/_Results_Ideal/Clarified.txt | 33 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 inform7/Tests/Test Cases/Clarified.txt create mode 100644 inform7/Tests/Test Cases/_Results_Ideal/Clarified.txt diff --git a/inform7/Tests/Test Cases/Clarified.txt b/inform7/Tests/Test Cases/Clarified.txt new file mode 100644 index 000000000..d9b95d942 --- /dev/null +++ b/inform7/Tests/Test Cases/Clarified.txt @@ -0,0 +1,15 @@ +"The Clarified Ancients of Mu Mu" + +Lab is a room. + +no-clarifications is a truth state that varies. +The no-clarifications variable translates into Inter as "dont_ask_for_clarification". + +The red box is a thing in the Lab. +The blue box is a thing in the Lab. + +After dropping: + now no-clarifications is true; + continue the action. + +Test me with "get box / red / drop box / l / get box / i". diff --git a/inform7/Tests/Test Cases/_Results_Ideal/Clarified.txt b/inform7/Tests/Test Cases/_Results_Ideal/Clarified.txt new file mode 100644 index 000000000..22d4af022 --- /dev/null +++ b/inform7/Tests/Test Cases/_Results_Ideal/Clarified.txt @@ -0,0 +1,33 @@ + Lab + The Clarified Ancients of Mu Mu + An Interactive Fiction + Release 1 / Serial number 160428 / Inform 7 v10.2.0 / D + + Lab + You can see a red box and a blue box here. + +> > Lab + (Testing.) + + >[1] get box + Which do you mean, the red box or the blue box? + + >[2] red + Taken. + + >[3] drop box + (the red box) + Dropped. + + >[4] l + Lab + You can see a red box and a blue box here. + + >[5] get box + Taken. + + >[6] i + You are carrying: + a red box + +> > \ No newline at end of file From 4ec7fb8e294ab920d87721d0ec5a5ec64b97b2db Mon Sep 17 00:00:00 2001 From: Zed Lopez Date: Sun, 23 Apr 2023 07:20:30 -0700 Subject: [PATCH 008/113] clarification reactivation commitification --- inform7/Tests/Test Cases/Clarified.txt | 6 +++++- inform7/Tests/Test Cases/_Results_Ideal/Clarified.txt | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/inform7/Tests/Test Cases/Clarified.txt b/inform7/Tests/Test Cases/Clarified.txt index d9b95d942..4f5af876d 100644 --- a/inform7/Tests/Test Cases/Clarified.txt +++ b/inform7/Tests/Test Cases/Clarified.txt @@ -12,4 +12,8 @@ After dropping: now no-clarifications is true; continue the action. -Test me with "get box / red / drop box / l / get box / i". +After taking the blue box: + now no-clarifications is false; + continue the action. + +Test me with "get box / red / drop box / l / get box / i / get blue box / drop box". diff --git a/inform7/Tests/Test Cases/_Results_Ideal/Clarified.txt b/inform7/Tests/Test Cases/_Results_Ideal/Clarified.txt index 22d4af022..20c5977de 100644 --- a/inform7/Tests/Test Cases/_Results_Ideal/Clarified.txt +++ b/inform7/Tests/Test Cases/_Results_Ideal/Clarified.txt @@ -30,4 +30,10 @@ You are carrying: a red box + >[7] get blue box + Taken. + + >[8] drop box + Which do you mean, the blue box or the red box? + > > \ No newline at end of file From 4fb6e57b866eacd84d27e4752c7d0147fc982ac0 Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Sun, 23 Apr 2023 21:16:45 +0100 Subject: [PATCH 009/113] Fix for Jira bug I7-2297 --- README.md | 2 +- build.txt | 4 +- docs/pipeline-module/2-pe.html | 2 +- docs/pipeline-module/3-css.html | 12 ++++ inform7/Figures/timings-diagnostics.txt | 57 ++++++++++--------- .../BasicInformExtrasKit/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 +- .../Chapter 3/Compile Splats Stage.w | 12 ++++ 11 files changed, 62 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index fb892e0ce..a6edab434 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inform 7 -[Version](notes/versioning.md): 10.2.0-beta+6W35 'Krypton' (22 April 2023) +[Version](notes/versioning.md): 10.2.0-beta+6W36 'Krypton' (23 April 2023) ## About Inform diff --git a/build.txt b/build.txt index a39ec3e66..b42abe7dc 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: beta -Build Date: 22 April 2023 -Build Number: 6W35 +Build Date: 23 April 2023 +Build Number: 6W36 diff --git a/docs/pipeline-module/2-pe.html b/docs/pipeline-module/2-pe.html index 8cc149e4d..8397d6d83 100644 --- a/docs/pipeline-module/2-pe.html +++ b/docs/pipeline-module/2-pe.html @@ -216,7 +216,7 @@ what the red button marked "danger" does.
 int pipeline_error_count = 0;
 
-void PipelineErrors::kit_error(char *message, text_stream *quote) {
+void PipelineErrors::kit_error(char *message, text_stream *quote) {
     #ifdef PROBLEMS_MODULE
     TEMPORARY_TEXT(M)
     WRITE_TO(M, message, quote);
diff --git a/docs/pipeline-module/3-css.html b/docs/pipeline-module/3-css.html
index ee7e1db3d..3e854cc99 100644
--- a/docs/pipeline-module/3-css.html
+++ b/docs/pipeline-module/3-css.html
@@ -1012,6 +1012,18 @@ which contains the actual code.
         TEMPORARY_TEXT(value)
         Extract a token3.1.3.1.4.5.2.2;
         if (Str::len(value) == 0) break;
+        int invalid = FALSE;
+        for (int i=0; i<Str::len(value); i++) {
+            wchar_t c = Str::get_at(value, i);
+            if ((c != '_') && (Characters::isalnum(c) == FALSE) &&
+                ((i > 0) || (Characters::isdigit(c) == FALSE)))
+                invalid = TRUE;
+        }
+        if (invalid) {
+            text_stream *err = Str::new();
+            WRITE_TO(err, "'%S' in function '%S'", value, identifier);
+            PipelineErrors::kit_error("invalid Inform 6 local variable name: %S", err);
+        }
         inter_symbol *loc_name =
             InterSymbolsTable::create_with_unique_name(InterPackage::scope(IP), value);
         InterSymbol::make_local(loc_name);
diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt
index 22dff5f8d..8428455dc 100644
--- a/inform7/Figures/timings-diagnostics.txt
+++ b/inform7/Figures/timings-diagnostics.txt
@@ -1,32 +1,33 @@
 100.0% in inform7 run
-     70.0% in compilation to Inter
-         49.4% in //Sequence::undertake_queued_tasks//
+     70.5% in compilation to Inter
+         49.6% in //Sequence::undertake_queued_tasks//
           4.9% in //MajorNodes::pre_pass//
-          3.3% in //MajorNodes::pass_1//
-          1.7% in //ImperativeDefinitions::assess_all//
-          1.5% in //RTPhrasebook::compile_entries//
-          1.3% in //RTKindConstructors::compile//
-          1.1% in //Sequence::lint_inter//
-          0.5% in //MajorNodes::pass_2//
-          0.5% in //Sequence::undertake_queued_tasks//
-          0.5% in //Sequence::undertake_queued_tasks//
-          0.5% in //World::stage_V//
-          0.3% in //ImperativeDefinitions::compile_first_block//
-          0.1% in //CompletionModule::compile//
-          0.1% in //InferenceSubjects::emit_all//
-          0.1% in //RTKindConstructors::compile_permissions//
-          0.1% in //Task::make_built_in_kind_constructors//
+          3.5% in //MajorNodes::pass_1//
+          1.8% in //ImperativeDefinitions::assess_all//
+          1.4% in //RTKindConstructors::compile//
+          1.4% in //RTPhrasebook::compile_entries//
+          1.0% in //Sequence::lint_inter//
+          0.6% in //MajorNodes::pass_2//
+          0.6% in //Sequence::undertake_queued_tasks//
+          0.6% in //World::stage_V//
+          0.4% in //ImperativeDefinitions::compile_first_block//
+          0.4% in //Sequence::undertake_queued_tasks//
+          0.2% in //CompletionModule::compile//
+          0.2% in //InferenceSubjects::emit_all//
+          0.2% in //RTKindConstructors::compile_permissions//
+          0.2% in //Task::make_built_in_kind_constructors//
+          0.2% in //World::stages_II_and_III//
           2.9% not specifically accounted for
-     26.3% in running Inter pipeline
-         10.2% in step 14/15: generate inform6 -> auto.inf
+     25.9% in running Inter pipeline
+          9.8% in step 14/15: generate inform6 -> auto.inf
           5.7% in step 5/15: load-binary-kits
-          5.5% in step 6/15: make-synoptic-module
-          1.7% in step 9/15: make-identifiers-unique
-          0.3% in step 12/15: eliminate-redundant-operations
-          0.3% in step 4/15: compile-splats
-          0.3% in step 7/15: shorten-wiring
-          0.3% in step 8/15: detect-indirect-calls
-          0.1% in step 11/15: eliminate-redundant-labels
-          1.3% not specifically accounted for
-      3.1% in supervisor
-      0.4% not specifically accounted for
+          5.3% in step 6/15: make-synoptic-module
+          1.8% in step 9/15: make-identifiers-unique
+          0.4% in step 12/15: eliminate-redundant-operations
+          0.4% in step 4/15: compile-splats
+          0.4% in step 7/15: shorten-wiring
+          0.2% in step 11/15: eliminate-redundant-labels
+          0.2% in step 8/15: detect-indirect-calls
+          1.4% not specifically accounted for
+      3.0% in supervisor
+      0.5% not specifically accounted for
diff --git a/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json
index 065be9583..7659513e0 100644
--- a/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json
+++ b/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json
@@ -2,7 +2,7 @@
     "is": {
         "type": "kit",
         "title": "BasicInformExtrasKit",
-        "version": "10.2.0-beta+6W35"
+        "version": "10.2.0-beta+6W36"
     },
     "kit-details": {
         "has-priority": 1
diff --git a/inform7/Internal/Inter/BasicInformKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformKit/kit_metadata.json
index 132488c33..4f1c182ea 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+6W35"
+        "version": "10.2.0-beta+6W36"
     },
     "needs": [ {
         "unless": {
diff --git a/inform7/Internal/Inter/CommandParserKit/kit_metadata.json b/inform7/Internal/Inter/CommandParserKit/kit_metadata.json
index c3dc033bb..6fc33fb98 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+6W35"
+        "version": "10.2.0-beta+6W36"
     },
     "needs": [ {
         "need": {
diff --git a/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json b/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json
index 6dd0e9946..0fd67aeb4 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+6W35"
+        "version": "10.2.0-beta+6W36"
     },
     "needs": [ {
         "need": {
diff --git a/inform7/Internal/Inter/WorldModelKit/kit_metadata.json b/inform7/Internal/Inter/WorldModelKit/kit_metadata.json
index b1fdae91d..f86f634cc 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+6W35"
+        "version": "10.2.0-beta+6W36"
     },
     "needs": [ {
         "need": {
diff --git a/inter/pipeline-module/Chapter 3/Compile Splats Stage.w b/inter/pipeline-module/Chapter 3/Compile Splats Stage.w
index 404ff39a2..bbe2a0bc4 100644
--- a/inter/pipeline-module/Chapter 3/Compile Splats Stage.w	
+++ b/inter/pipeline-module/Chapter 3/Compile Splats Stage.w	
@@ -757,6 +757,18 @@ These have package types |_function| and |_code| respectively.
 		TEMPORARY_TEXT(value)
 		@;
 		if (Str::len(value) == 0) break;
+		int invalid = FALSE;
+		for (int i=0; i 0) || (Characters::isdigit(c) == FALSE)))
+				invalid = TRUE;
+		}
+		if (invalid) {
+			text_stream *err = Str::new();
+			WRITE_TO(err, "'%S' in function '%S'", value, identifier);
+			PipelineErrors::kit_error("invalid Inform 6 local variable name: %S", err);
+		}
 		inter_symbol *loc_name =
 			InterSymbolsTable::create_with_unique_name(InterPackage::scope(IP), value);
 		InterSymbol::make_local(loc_name);

From c9f22044b542110fbfef81e3c250a9b5d84c2c1b Mon Sep 17 00:00:00 2001
From: Graham Nelson 
Date: Sun, 23 Apr 2023 21:18:14 +0100
Subject: [PATCH 010/113] Updated notes

---
 notes/release/pending.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/notes/release/pending.md b/notes/release/pending.md
index fd9f6dbd6..f552b9c21 100644
--- a/notes/release/pending.md
+++ b/notes/release/pending.md
@@ -30,6 +30,9 @@ These will be added to release notes when the release is made.
 - Fix for Jira bug [I7-2304](https://inform7.atlassian.net/browse/I7-2304)
 	"switch(): first branch can't start with negative number"
 	([commit 1c18007](https://github.com/ganelson/inform/commit/1c18007326bf6fb15c74a1d5742827a4d76a0c20))
+- Fix for Jira bug [I7-2297](https://inform7.atlassian.net/browse/I7-2297)
+	"Missing semicolon after I6 routine crashed compiler without explanation"
+	([commit 4fb6e57](https://github.com/ganelson/inform/commit/4fb6e57b866eacd84d27e4752c7d0147fc982ac0))
 - Fix for Jira bug [I7-2284](https://inform7.atlassian.net/browse/I7-2284)
 	"Inter error" - arising from a sentence trying to use an either-or property
 	in a way which would make it unheld by default, when an existing sentence

From 4d97b499cfd3e15650d1bba1e6e8c70c24a01fb2 Mon Sep 17 00:00:00 2001
From: Graham Nelson 
Date: Sun, 23 Apr 2023 23:15:44 +0100
Subject: [PATCH 011/113] Fix for Jira bug I7-2335

---
 docs/pipeline-module/2-pe.html                |   2 +-
 docs/pipeline-module/3-css.html               | 159 +++++++++++++-----
 inform7/Figures/timings-diagnostics.txt       |  60 +++----
 .../Chapter 3/Compile Splats Stage.w          | 117 +++++++++----
 4 files changed, 230 insertions(+), 108 deletions(-)

diff --git a/docs/pipeline-module/2-pe.html b/docs/pipeline-module/2-pe.html
index 8397d6d83..ad4163462 100644
--- a/docs/pipeline-module/2-pe.html
+++ b/docs/pipeline-module/2-pe.html
@@ -216,7 +216,7 @@ what the red button marked "danger" does.
 
 int pipeline_error_count = 0;
 
-void PipelineErrors::kit_error(char *message, text_stream *quote) {
+void PipelineErrors::kit_error(char *message, text_stream *quote) {
     #ifdef PROBLEMS_MODULE
     TEMPORARY_TEXT(M)
     WRITE_TO(M, message, quote);
diff --git a/docs/pipeline-module/3-css.html b/docs/pipeline-module/3-css.html
index 3e854cc99..47077261f 100644
--- a/docs/pipeline-module/3-css.html
+++ b/docs/pipeline-module/3-css.html
@@ -255,21 +255,21 @@ meaningfully have a value, even though a third token is present.
 
     text_stream *S = SplatInstruction::splatter(P);
     if (directive == VERB_PLM) {
-        if (Regexp::match(&mr, S, L" *%C+ (%c*?) *;%c*")) {
+        if (Regexp::match(&mr, S, L" *%C+ (%c*?) *; *")) {
             raw_identifier = I"assim_gv"; value = mr.exp[0];
         } else {
             LOG("Unable to parse start of VERB_PLM: '%S'\n", S); proceed = FALSE;
         }
     } else {
-        if (Regexp::match(&mr, S, L" *%C+ *(%C+?)(--> *%c*?) *;%c*")) {
+        if (Regexp::match(&mr, S, L" *%C+ *(%C+?)(--> *%c*?) *; *")) {
             raw_identifier = mr.exp[0]; value = mr.exp[1];
-        } else if (Regexp::match(&mr, S, L" *%C+ *(%C+?)(-> *%c*?) *;%c*")) {
+        } else if (Regexp::match(&mr, S, L" *%C+ *(%C+?)(-> *%c*?) *; *")) {
             raw_identifier = mr.exp[0]; value = mr.exp[1];
-        } else if (Regexp::match(&mr, S, L" *%C+ (%C*?) *;%c*")) {
+        } else if (Regexp::match(&mr, S, L" *%C+ (%C*?) *; *")) {
             raw_identifier = mr.exp[0];
-        } else if (Regexp::match(&mr, S, L" *%C+ (%C*) *= *(%c*?) *;%c*")) {
+        } else if (Regexp::match(&mr, S, L" *%C+ (%C*) *= *(%c*?) *; *")) {
             raw_identifier = mr.exp[0]; value = mr.exp[1];
-        } else if (Regexp::match(&mr, S, L" *%C+ (%C*) (%c*?) *;%c*")) {
+        } else if (Regexp::match(&mr, S, L" *%C+ (%C*) (%c*?) *; *")) {
             raw_identifier = mr.exp[0]; value = mr.exp[1];
         } else {
             LOG("Unable to parse start of constant: '%S'\n", S); proceed = FALSE;
@@ -596,6 +596,9 @@ first to work out which of the several array formats this is, then the contents
             conts = mr.exp[0]; bounded = TRUE;
         } else if (Regexp::match(&mr, value, L" *buffer *(%c*?) *")) {
             conts = mr.exp[0]; as_bytes = TRUE; bounded = TRUE;
+        } else if (Regexp::match(&mr, value, L" *string *(%c*?) *")) {
+            LOG("Identifier = <%S>, Value = <%S>", identifier, value);
+            PipelineErrors::kit_error("Inform 6 'string' arrays are unsupported", NULL);
         } else {
             LOG("Identifier = <%S>, Value = <%S>", identifier, value);
             PipelineErrors::kit_error("invalid Inform 6 array declaration", NULL);
@@ -622,35 +625,99 @@ see why other kits would, either.
 

Compile the string of array contents into the pile of values3.1.3.1.4.5.2 =

+
+    match_results mr = Regexp::create_mr();
+    if (Regexp::match(&mr, conts, L" *%[ *(%c*?) *%] *"))
+        Parse the new-style I6 array entry notation3.1.3.1.4.5.2.1
+    else
+        Parse the old-style I6 array entry notation3.1.3.1.4.5.2.2;
+    Regexp::dispose_of(&mr);
+
+ +

§3.1.3.1.4.5.2.1. Parse the new-style I6 array entry notation3.1.3.1.4.5.2.1 = +

+ +
+    text_stream *entries = mr.exp[0];
+    int sq = FALSE, dq = FALSE, from = 0;
+    for (int i=0; i<Str::len(entries); i++) {
+        wchar_t c = Str::get_at(entries, i);
+        if ((c == ';') && (sq == FALSE) && (dq == FALSE)) {
+            int to = i-1;
+            Eat off a chunk3.1.3.1.4.5.2.1.1;
+            from = i+1;
+        }
+        if ((c == '\'') && (dq == FALSE)) {
+            if (sq == FALSE) sq = TRUE;
+            else if ((sq) && (Str::get_at(entries, i-1) != '\\')) sq = FALSE;
+        }
+        if ((c == '\"') && (sq == FALSE)) {
+            if (dq == FALSE) dq = TRUE;
+            else dq = FALSE;
+        }
+    }
+    if (Str::len(entries) > from) {
+        int to = Str::len(entries) - 1;
+        Eat off a chunk3.1.3.1.4.5.2.1.1;
+    }
+
+ +

§3.1.3.1.4.5.2.1.1. Eat off a chunk3.1.3.1.4.5.2.1.1 = +

+ +
+    text_stream *full_conts = entries;
+    if (from > to) {
+        PipelineErrors::kit_error("Inform 6 array contains empty entry", NULL);
+    } else {
+        int count_before = no_assimilated_array_entries;
+        TEMPORARY_TEXT(conts)
+        for (int j=from; j<=to; j++) PUT_TO(conts, Str::get_at(full_conts, j));
+        Parse the old-style I6 array entry notation3.1.3.1.4.5.2.2
+        DISCARD_TEXT(conts)
+        if (no_assimilated_array_entries > count_before+1)
+            PipelineErrors::kit_error(
+                "Multiple entries between ';' markers in a '[ ...; ...; ... ]' array", NULL);
+    }
+
+ +

§3.1.3.1.4.5.2.2. Parse the old-style I6 array entry notation3.1.3.1.4.5.2.2 = +

+
     string_position spos = Str::start(conts);
     int finished = FALSE;
     while (finished == FALSE) {
         TEMPORARY_TEXT(value)
-        Extract a token3.1.3.1.4.5.2.2;
-        if (Str::eq(value, I"+"))
-            PipelineErrors::kit_error("Inform 6 array declaration using operator '+' "
-                "(use brackets '(' ... ')' around the size for a calculated array size)", NULL);
-        else if (Str::eq(value, I"-"))
-            PipelineErrors::kit_error("Inform 6 array declaration using operator '-' "
-                "(use brackets '(' ... ')' around the size for a calculated array size)", NULL);
-        else if (Str::eq(value, I"*"))
-            PipelineErrors::kit_error("Inform 6 array declaration using operator '*' "
-                "(use brackets '(' ... ')' around the size for a calculated array size)", NULL);
-        else if (Str::eq(value, I"/"))
-            PipelineErrors::kit_error("Inform 6 array declaration using operator '/' "
-                "(use brackets '(' ... ')' around the size for a calculated array size)", NULL);
-        else {
-            if (Str::len(value) > 0) {
-                inter_pair val = InterValuePairs::undef();
-                Assimilate a value3.1.3.1.4.1.1;
-                Add value to the entry pile3.1.3.1.4.5.2.1;
-            } else finished = TRUE;
-        }
+        Extract a token3.1.3.1.4.5.2.2.2;
+        if (Str::len(value) > 0) Process the token3.1.3.1.4.5.2.2.1 else finished = TRUE;
         DISCARD_TEXT(value)
     }
 
- + +

§3.1.3.1.4.5.2.2.1. Process the token3.1.3.1.4.5.2.2.1 = +

+ +
+    if (Str::eq(value, I"+"))
+        PipelineErrors::kit_error("Inform 6 array declaration using operator '+' "
+            "(use brackets '(' ... ')' around the size for a calculated array size)", NULL);
+    else if (Str::eq(value, I"-"))
+        PipelineErrors::kit_error("Inform 6 array declaration using operator '-' "
+            "(use brackets '(' ... ')' around the size for a calculated array size)", NULL);
+    else if (Str::eq(value, I"*"))
+        PipelineErrors::kit_error("Inform 6 array declaration using operator '*' "
+            "(use brackets '(' ... ')' around the size for a calculated array size)", NULL);
+    else if (Str::eq(value, I"/"))
+        PipelineErrors::kit_error("Inform 6 array declaration using operator '/' "
+            "(use brackets '(' ... ')' around the size for a calculated array size)", NULL);
+    else {
+        inter_pair val = InterValuePairs::undef();
+        Assimilate a value3.1.3.1.4.1.1;
+        Add value to the entry pile3.1.3.1.4.5.2.2.1.1;
+    }
+
+

§3.1.3.1.4.5.3. In command grammar introduced by Verb, the tokens * and / can occur without having any arithmetic meaning, so they must not be rejected. That's really why we treat this case as different, though we also treat keywords @@ -674,14 +741,14 @@ for the action. while (finished == FALSE) { TEMPORARY_TEXT(value) if (next_is_action) WRITE_TO(value, "##"); - Extract a token3.1.3.1.4.5.2.2; + Extract a token3.1.3.1.4.5.2.2.2; if (next_is_action) Ensure that a socket exists for this action name3.1.3.1.4.5.3.1; next_is_action = FALSE; if ((NT++ == 0) && (Str::eq(value, I"meta"))) { inter_pair val = InterValuePairs::symbolic(IBM, RunningPipelines::ensure_symbol(step, verb_directive_meta_RPSYM, I"VERB_DIRECTIVE_META")); - Add value to the entry pile3.1.3.1.4.5.2.1; + Add value to the entry pile3.1.3.1.4.5.2.2.1.1; } else if (Str::len(value) > 0) { inter_pair val = InterValuePairs::undef(); int marker = NOT_APPLICABLE; Assimilate a value in grammar3.1.3.1.4.5.3.2; @@ -689,14 +756,14 @@ for the action. inter_pair val = InterValuePairs::symbolic(IBM, RunningPipelines::ensure_symbol(step, verb_directive_noun_filter_RPSYM, I"VERB_DIRECTIVE_NOUN_FILTER")); - Add value to the entry pile3.1.3.1.4.5.2.1; + Add value to the entry pile3.1.3.1.4.5.2.2.1.1; } else if (marker == FALSE) { inter_pair val = InterValuePairs::symbolic(IBM, RunningPipelines::ensure_symbol(step, verb_directive_scope_filter_RPSYM, I"VERB_DIRECTIVE_SCOPE_FILTER")); - Add value to the entry pile3.1.3.1.4.5.2.1; + Add value to the entry pile3.1.3.1.4.5.2.2.1.1; } - Add value to the entry pile3.1.3.1.4.5.2.1; + Add value to the entry pile3.1.3.1.4.5.2.2.1.1; if (Str::eq(value, I"->")) next_is_action = TRUE; } else finished = TRUE; DISCARD_TEXT(value) @@ -814,7 +881,7 @@ equating it to a function definition elsewhere. val = InterValuePairs::number(0); }

- +

§3.1.3.1.4.5.3.2. Assimilate a value in grammar3.1.3.1.4.5.3.2 =

@@ -827,7 +894,7 @@ equating it to a function definition elsewhere. }
-

§3.1.3.1.4.5.2.1. Add value to the entry pile3.1.3.1.4.5.2.1 = +

§3.1.3.1.4.5.2.2.1.1. Add value to the entry pile3.1.3.1.4.5.2.2.1.1 =

@@ -838,8 +905,8 @@ equating it to a function definition elsewhere.
     val_pile[no_assimilated_array_entries] = val;
     no_assimilated_array_entries++;
 
- -

§3.1.3.1.4.5.2.2. Extract a token3.1.3.1.4.5.2.2 = +

+

§3.1.3.1.4.5.2.2.2. Extract a token3.1.3.1.4.5.2.2.2 =

@@ -858,7 +925,7 @@ equating it to a function definition elsewhere.
         spos = Str::forward(spos);
     }
 
- +

§3.2. How functions are assimilated. Functions in Inform 6 are usually called "routines", and have a syntax like so:

@@ -1010,7 +1077,7 @@ which contains the actual code. string_position spos = Str::start(local_var_names); while (TRUE) { TEMPORARY_TEXT(value) - Extract a token3.1.3.1.4.5.2.2; + Extract a token3.1.3.1.4.5.2.2.2; if (Str::len(value) == 0) break; int invalid = FALSE; for (int i=0; i<Str::len(value); i++) { @@ -1430,8 +1497,9 @@ before they are needed.
     inter_schema *sch = ParsingSchemas::from_text(S);
+    int excess_tokens = FALSE;
     inter_symbol *result_s =
-        CompileSplatsStage::compute_r(step, IBM, sch->node_tree);
+        CompileSplatsStage::compute_r(step, IBM, sch->node_tree, &excess_tokens);
     if (result_s == NULL) {
         PipelineErrors::kit_error("Inform 6 constant too complex", S);
         return InterValuePairs::number(1);
@@ -1445,9 +1513,10 @@ reducing unary subtraction to a case of binary subtraction.
 
 
 inter_symbol *CompileSplatsStage::compute_r(pipeline_step *step,
-    inter_bookmark *IBM, inter_schema_node *isn) {
+    inter_bookmark *IBM, inter_schema_node *isn, int *excess_tokens) {
+    if (isn == NULL) return NULL;
     if (isn->isn_type == SUBEXPRESSION_ISNT)
-        return CompileSplatsStage::compute_r(step, IBM, isn->child_node);
+        return CompileSplatsStage::compute_r(step, IBM, isn->child_node, excess_tokens);
     if (isn->isn_type == OPERATION_ISNT) {
         inter_ti op = 0;
         if (isn->isn_clarifier == PLUS_BIP) op = CONST_LIST_FORMAT_SUM;
@@ -1460,7 +1529,7 @@ reducing unary subtraction to a case of binary subtraction.
     }
     if (isn->isn_type == EXPRESSION_ISNT) {
         inter_schema_token *t = isn->expression_tokens;
-        if ((t == NULL) || (t->next)) internal_error("malformed EXPRESSION_ISNT");
+        if ((t == NULL) || (t->next)) { *excess_tokens = TRUE; return NULL; }
         return CompileSplatsStage::compute_eval(step, IBM, t);
     }
     return NULL;
@@ -1470,8 +1539,8 @@ reducing unary subtraction to a case of binary subtraction.
 

-    inter_symbol *i1 = CompileSplatsStage::compute_r(step, IBM, isn->child_node);
-    inter_symbol *i2 = CompileSplatsStage::compute_r(step, IBM, isn->child_node->next_node);
+    inter_symbol *i1 = CompileSplatsStage::compute_r(step, IBM, isn->child_node, excess_tokens);
+    inter_symbol *i2 = CompileSplatsStage::compute_r(step, IBM, isn->child_node->next_node, excess_tokens);
     if ((i1 == NULL) || (i2 == NULL)) return NULL;
     return CompileSplatsStage::compute_binary_op(op, step, IBM, i1, i2);
 
@@ -1480,7 +1549,7 @@ reducing unary subtraction to a case of binary subtraction.

-    inter_symbol *i2 = CompileSplatsStage::compute_r(step, IBM, isn->child_node);
+    inter_symbol *i2 = CompileSplatsStage::compute_r(step, IBM, isn->child_node, excess_tokens);
     if (i2 == NULL) return NULL;
     return CompileSplatsStage::compute_binary_op(CONST_LIST_FORMAT_DIFFERENCE, step, IBM, NULL, i2);
 
diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt index 8428455dc..7df9fb478 100644 --- a/inform7/Figures/timings-diagnostics.txt +++ b/inform7/Figures/timings-diagnostics.txt @@ -1,33 +1,33 @@ 100.0% in inform7 run - 70.5% in compilation to Inter - 49.6% in //Sequence::undertake_queued_tasks// - 4.9% in //MajorNodes::pre_pass// - 3.5% in //MajorNodes::pass_1// - 1.8% in //ImperativeDefinitions::assess_all// - 1.4% in //RTKindConstructors::compile// - 1.4% in //RTPhrasebook::compile_entries// - 1.0% in //Sequence::lint_inter// - 0.6% in //MajorNodes::pass_2// - 0.6% in //Sequence::undertake_queued_tasks// - 0.6% in //World::stage_V// - 0.4% in //ImperativeDefinitions::compile_first_block// - 0.4% in //Sequence::undertake_queued_tasks// - 0.2% in //CompletionModule::compile// - 0.2% in //InferenceSubjects::emit_all// - 0.2% in //RTKindConstructors::compile_permissions// - 0.2% in //Task::make_built_in_kind_constructors// - 0.2% in //World::stages_II_and_III// + 70.0% in compilation to Inter + 49.7% in //Sequence::undertake_queued_tasks// + 4.8% in //MajorNodes::pre_pass// + 3.3% in //MajorNodes::pass_1// + 1.7% in //ImperativeDefinitions::assess_all// + 1.5% in //RTPhrasebook::compile_entries// + 1.3% in //RTKindConstructors::compile// + 0.9% in //Sequence::lint_inter// + 0.5% in //MajorNodes::pass_2// + 0.5% in //Sequence::undertake_queued_tasks// + 0.5% in //Sequence::undertake_queued_tasks// + 0.5% in //World::stage_V// + 0.3% in //ImperativeDefinitions::compile_first_block// + 0.1% in //CompletionModule::compile// + 0.1% in //InferenceSubjects::emit_all// + 0.1% in //RTKindConstructors::compile_permissions// + 0.1% in //Task::make_built_in_kind_constructors// + 0.1% in //World::stages_II_and_III// 2.9% not specifically accounted for - 25.9% in running Inter pipeline - 9.8% in step 14/15: generate inform6 -> auto.inf - 5.7% in step 5/15: load-binary-kits - 5.3% in step 6/15: make-synoptic-module - 1.8% in step 9/15: make-identifiers-unique - 0.4% in step 12/15: eliminate-redundant-operations - 0.4% in step 4/15: compile-splats - 0.4% in step 7/15: shorten-wiring - 0.2% in step 11/15: eliminate-redundant-labels - 0.2% in step 8/15: detect-indirect-calls + 26.2% in running Inter pipeline + 10.0% in step 14/15: generate inform6 -> auto.inf + 5.8% in step 5/15: load-binary-kits + 5.4% in step 6/15: make-synoptic-module + 1.7% in step 9/15: make-identifiers-unique + 0.3% in step 12/15: eliminate-redundant-operations + 0.3% in step 4/15: compile-splats + 0.3% in step 7/15: shorten-wiring + 0.3% in step 8/15: detect-indirect-calls + 0.1% in step 11/15: eliminate-redundant-labels 1.4% not specifically accounted for - 3.0% in supervisor - 0.5% not specifically accounted for + 3.1% in supervisor + 0.6% not specifically accounted for diff --git a/inter/pipeline-module/Chapter 3/Compile Splats Stage.w b/inter/pipeline-module/Chapter 3/Compile Splats Stage.w index bbe2a0bc4..561912b75 100644 --- a/inter/pipeline-module/Chapter 3/Compile Splats Stage.w +++ b/inter/pipeline-module/Chapter 3/Compile Splats Stage.w @@ -165,21 +165,21 @@ meaningfully have a value, even though a third token is present. @ = text_stream *S = SplatInstruction::splatter(P); if (directive == VERB_PLM) { - if (Regexp::match(&mr, S, L" *%C+ (%c*?) *;%c*")) { + if (Regexp::match(&mr, S, L" *%C+ (%c*?) *; *")) { raw_identifier = I"assim_gv"; value = mr.exp[0]; } else { LOG("Unable to parse start of VERB_PLM: '%S'\n", S); proceed = FALSE; } } else { - if (Regexp::match(&mr, S, L" *%C+ *(%C+?)(--> *%c*?) *;%c*")) { + if (Regexp::match(&mr, S, L" *%C+ *(%C+?)(--> *%c*?) *; *")) { raw_identifier = mr.exp[0]; value = mr.exp[1]; - } else if (Regexp::match(&mr, S, L" *%C+ *(%C+?)(-> *%c*?) *;%c*")) { + } else if (Regexp::match(&mr, S, L" *%C+ *(%C+?)(-> *%c*?) *; *")) { raw_identifier = mr.exp[0]; value = mr.exp[1]; - } else if (Regexp::match(&mr, S, L" *%C+ (%C*?) *;%c*")) { + } else if (Regexp::match(&mr, S, L" *%C+ (%C*?) *; *")) { raw_identifier = mr.exp[0]; - } else if (Regexp::match(&mr, S, L" *%C+ (%C*) *= *(%c*?) *;%c*")) { + } else if (Regexp::match(&mr, S, L" *%C+ (%C*) *= *(%c*?) *; *")) { raw_identifier = mr.exp[0]; value = mr.exp[1]; - } else if (Regexp::match(&mr, S, L" *%C+ (%C*) (%c*?) *;%c*")) { + } else if (Regexp::match(&mr, S, L" *%C+ (%C*) (%c*?) *; *")) { raw_identifier = mr.exp[0]; value = mr.exp[1]; } else { LOG("Unable to parse start of constant: '%S'\n", S); proceed = FALSE; @@ -431,6 +431,9 @@ first to work out which of the several array formats this is, then the contents conts = mr.exp[0]; bounded = TRUE; } else if (Regexp::match(&mr, value, L" *buffer *(%c*?) *")) { conts = mr.exp[0]; as_bytes = TRUE; bounded = TRUE; + } else if (Regexp::match(&mr, value, L" *string *(%c*?) *")) { + LOG("Identifier = <%S>, Value = <%S>", identifier, value); + PipelineErrors::kit_error("Inform 6 'string' arrays are unsupported", NULL); } else { LOG("Identifier = <%S>, Value = <%S>", identifier, value); PipelineErrors::kit_error("invalid Inform 6 array declaration", NULL); @@ -450,33 +453,81 @@ support that here: the standard Inform kits do not need it, and it's hard to see why other kits would, either. @ = + match_results mr = Regexp::create_mr(); + if (Regexp::match(&mr, conts, L" *%[ *(%c*?) *%] *")) + @ + else + @; + Regexp::dispose_of(&mr); + +@ = + text_stream *entries = mr.exp[0]; + int sq = FALSE, dq = FALSE, from = 0; + for (int i=0; i; + from = i+1; + } + if ((c == '\'') && (dq == FALSE)) { + if (sq == FALSE) sq = TRUE; + else if ((sq) && (Str::get_at(entries, i-1) != '\\')) sq = FALSE; + } + if ((c == '\"') && (sq == FALSE)) { + if (dq == FALSE) dq = TRUE; + else dq = FALSE; + } + } + if (Str::len(entries) > from) { + int to = Str::len(entries) - 1; + @; + } + +@ = + text_stream *full_conts = entries; + if (from > to) { + PipelineErrors::kit_error("Inform 6 array contains empty entry", NULL); + } else { + int count_before = no_assimilated_array_entries; + TEMPORARY_TEXT(conts) + for (int j=from; j<=to; j++) PUT_TO(conts, Str::get_at(full_conts, j)); + @ + DISCARD_TEXT(conts) + if (no_assimilated_array_entries > count_before+1) + PipelineErrors::kit_error( + "Multiple entries between ';' markers in a '[ ...; ...; ... ]' array", NULL); + } + +@ = string_position spos = Str::start(conts); int finished = FALSE; while (finished == FALSE) { TEMPORARY_TEXT(value) @; - if (Str::eq(value, I"+")) - PipelineErrors::kit_error("Inform 6 array declaration using operator '+' " - "(use brackets '(' ... ')' around the size for a calculated array size)", NULL); - else if (Str::eq(value, I"-")) - PipelineErrors::kit_error("Inform 6 array declaration using operator '-' " - "(use brackets '(' ... ')' around the size for a calculated array size)", NULL); - else if (Str::eq(value, I"*")) - PipelineErrors::kit_error("Inform 6 array declaration using operator '*' " - "(use brackets '(' ... ')' around the size for a calculated array size)", NULL); - else if (Str::eq(value, I"/")) - PipelineErrors::kit_error("Inform 6 array declaration using operator '/' " - "(use brackets '(' ... ')' around the size for a calculated array size)", NULL); - else { - if (Str::len(value) > 0) { - inter_pair val = InterValuePairs::undef(); - @; - @; - } else finished = TRUE; - } + if (Str::len(value) > 0) @ else finished = TRUE; DISCARD_TEXT(value) } +@ = + if (Str::eq(value, I"+")) + PipelineErrors::kit_error("Inform 6 array declaration using operator '+' " + "(use brackets '(' ... ')' around the size for a calculated array size)", NULL); + else if (Str::eq(value, I"-")) + PipelineErrors::kit_error("Inform 6 array declaration using operator '-' " + "(use brackets '(' ... ')' around the size for a calculated array size)", NULL); + else if (Str::eq(value, I"*")) + PipelineErrors::kit_error("Inform 6 array declaration using operator '*' " + "(use brackets '(' ... ')' around the size for a calculated array size)", NULL); + else if (Str::eq(value, I"/")) + PipelineErrors::kit_error("Inform 6 array declaration using operator '/' " + "(use brackets '(' ... ')' around the size for a calculated array size)", NULL); + else { + inter_pair val = InterValuePairs::undef(); + @; + @; + } + @ In command grammar introduced by |Verb|, the tokens |*| and |/| can occur without having any arithmetic meaning, so they must not be rejected. That's really why we treat this case as different, though we also treat keywords @@ -1117,8 +1168,9 @@ before they are needed. @ = inter_schema *sch = ParsingSchemas::from_text(S); + int excess_tokens = FALSE; inter_symbol *result_s = - CompileSplatsStage::compute_r(step, IBM, sch->node_tree); + CompileSplatsStage::compute_r(step, IBM, sch->node_tree, &excess_tokens); if (result_s == NULL) { PipelineErrors::kit_error("Inform 6 constant too complex", S); return InterValuePairs::number(1); @@ -1130,9 +1182,10 @@ reducing unary subtraction to a case of binary subtraction. = inter_symbol *CompileSplatsStage::compute_r(pipeline_step *step, - inter_bookmark *IBM, inter_schema_node *isn) { + inter_bookmark *IBM, inter_schema_node *isn, int *excess_tokens) { + if (isn == NULL) return NULL; if (isn->isn_type == SUBEXPRESSION_ISNT) - return CompileSplatsStage::compute_r(step, IBM, isn->child_node); + return CompileSplatsStage::compute_r(step, IBM, isn->child_node, excess_tokens); if (isn->isn_type == OPERATION_ISNT) { inter_ti op = 0; if (isn->isn_clarifier == PLUS_BIP) op = CONST_LIST_FORMAT_SUM; @@ -1145,20 +1198,20 @@ inter_symbol *CompileSplatsStage::compute_r(pipeline_step *step, } if (isn->isn_type == EXPRESSION_ISNT) { inter_schema_token *t = isn->expression_tokens; - if ((t == NULL) || (t->next)) internal_error("malformed EXPRESSION_ISNT"); + if ((t == NULL) || (t->next)) { *excess_tokens = TRUE; return NULL; } return CompileSplatsStage::compute_eval(step, IBM, t); } return NULL; } @ = - inter_symbol *i1 = CompileSplatsStage::compute_r(step, IBM, isn->child_node); - inter_symbol *i2 = CompileSplatsStage::compute_r(step, IBM, isn->child_node->next_node); + inter_symbol *i1 = CompileSplatsStage::compute_r(step, IBM, isn->child_node, excess_tokens); + inter_symbol *i2 = CompileSplatsStage::compute_r(step, IBM, isn->child_node->next_node, excess_tokens); if ((i1 == NULL) || (i2 == NULL)) return NULL; return CompileSplatsStage::compute_binary_op(op, step, IBM, i1, i2); @ = - inter_symbol *i2 = CompileSplatsStage::compute_r(step, IBM, isn->child_node); + inter_symbol *i2 = CompileSplatsStage::compute_r(step, IBM, isn->child_node, excess_tokens); if (i2 == NULL) return NULL; return CompileSplatsStage::compute_binary_op(CONST_LIST_FORMAT_DIFFERENCE, step, IBM, NULL, i2); From a1d0a7bda8dbba39257f33ff17619f3f732371dc Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Sun, 23 Apr 2023 23:17:56 +0100 Subject: [PATCH 012/113] Updated notes --- notes/release/pending.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/notes/release/pending.md b/notes/release/pending.md index f552b9c21..2dd8f1d07 100644 --- a/notes/release/pending.md +++ b/notes/release/pending.md @@ -18,6 +18,9 @@ These will be added to release notes when the release is made. ## Bug fixes +- Fix for Jira bug [I7-2335](https://inform7.atlassian.net/browse/I7-2335) + "Several previously-legal forms of the Array directive no longer work in I6 inclusions in 10.1.2" + ([commit 4d97b49](https://github.com/ganelson/inform/commit/4d97b499cfd3e15650d1bba1e6e8c70c24a01fb2)) - Fix for Jira bug [I7-2334](https://inform7.atlassian.net/browse/I7-2334) "imbalanced parentheses in Definition by I6 Condition causes abject failure" ([commit 5d45863](https://github.com/ganelson/inform/commit/5d4586387c6b7405cd45e43f04c984583cd76bb3)) From 8d9283124995c5675dd5acfb5fa306d114ea7909 Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Tue, 25 Apr 2023 10:37:50 +0100 Subject: [PATCH 013/113] Improved error reporting on kit and insertion code --- README.md | 2 +- build.txt | 4 +- docs/bytecode-module/1-tiv.html | 6 +- docs/bytecode-module/2-in.html | 6 +- docs/bytecode-module/3-ie.html | 2 +- docs/bytecode-module/4-tic.html | 64 +++++++++--- docs/bytecode-module/5-tsc.html | 45 +++++++-- docs/core-module/1-wtc.html | 4 +- docs/core-module/2-pwst.html | 93 ++++++++++++++++++ docs/pipeline-module/2-pe.html | 52 +++++----- docs/pipeline-module/3-css.html | 13 +++ docs/pipeline-module/3-ps.html | 84 ++++++++++++---- docs/problems-module/2-pl1.html | 35 ++++++- docs/problems-module/2-pl2.html | 78 ++++++++++----- docs/runtime-module/2-emt.html | 11 ++- docs/supervisor-module/3-is.html | 10 +- docs/supervisor-module/6-st.html | 16 ++- docs/words-module/3-lxr.html | 4 + .../supervisor-module/Chapter 3/Inter Skill.w | 10 +- .../supervisor-module/Chapter 6/Source Text.w | 16 ++- inform7/Figures/memory-diagnostics.txt | 16 +-- inform7/Figures/timings-diagnostics.txt | 56 +++++------ .../BasicInformExtrasKit/kit_metadata.json | 2 +- .../Inter/BasicInformKit/kit_metadata.json | 2 +- .../Inter/CommandParserKit/kit_metadata.json | 2 +- .../Internal/Inter/DialogueKit/arch-16.interb | Bin 112240 -> 112240 bytes .../Inter/DialogueKit/arch-16d.interb | Bin 112261 -> 112261 bytes .../Internal/Inter/DialogueKit/arch-32.interb | Bin 112404 -> 112404 bytes .../Inter/DialogueKit/arch-32d.interb | Bin 112425 -> 112425 bytes .../Inter/EnglishLanguageKit/arch-16.interb | Bin 20753 -> 20753 bytes .../Inter/EnglishLanguageKit/arch-16d.interb | Bin 20774 -> 20774 bytes .../Inter/EnglishLanguageKit/arch-32.interb | Bin 20759 -> 20759 bytes .../Inter/EnglishLanguageKit/arch-32d.interb | Bin 20780 -> 20780 bytes .../EnglishLanguageKit/kit_metadata.json | 2 +- .../Inter/WorldModelKit/kit_metadata.json | 2 +- .../Chapter 2/Problems With Source Text.w | 92 +++++++++++++++++ inform7/runtime-module/Chapter 2/Emit.w | 11 ++- .../Invalid/_Results_Ideal/inversion.txt | 2 +- .../Chapter 1/The Inter Version.w | 5 +- .../Chapter 4/The Insert Construct.w | 62 +++++++++--- .../Chapter 5/The Splat Construct.w | 45 +++++++-- .../Chapter 2/Pipeline Errors.w | 42 ++++---- .../Chapter 3/Compile Splats Stage.w | 13 +++ .../Chapter 3/Parsing Stages.w | 53 +++++++++- .../Chapter 2/Problems, Level 1.w | 25 +++++ .../Chapter 2/Problems, Level 2.w | 31 +++++- services/words-module/Chapter 3/Lexer.w | 4 + 47 files changed, 824 insertions(+), 198 deletions(-) diff --git a/README.md b/README.md index a6edab434..1cbd09bb8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inform 7 -[Version](notes/versioning.md): 10.2.0-beta+6W36 'Krypton' (23 April 2023) +[Version](notes/versioning.md): 10.2.0-beta+6W37 'Krypton' (25 April 2023) ## About Inform diff --git a/build.txt b/build.txt index b42abe7dc..69d40f175 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: beta -Build Date: 23 April 2023 -Build Number: 6W36 +Build Date: 25 April 2023 +Build Number: 6W37 diff --git a/docs/bytecode-module/1-tiv.html b/docs/bytecode-module/1-tiv.html index 5cb01a73c..087e7cd89 100644 --- a/docs/bytecode-module/1-tiv.html +++ b/docs/bytecode-module/1-tiv.html @@ -121,12 +121,16 @@ represent new data structures with custom kind constructors from Neptune files in Inform kits.

+

5.0.0 (24 April 2023) added (further) new fields to SPLAT_IST instructions, to +record their provenance and so make better error reporting possible. +

+

§3. Anyway, the implementation, such as it is:

 semantic_version_number InterVersion::current(void) {
-    semantic_version_number V = VersionNumbers::from_text(I"4.0.0");
+    semantic_version_number V = VersionNumbers::from_text(I"5.0.0");
     if (VersionNumbers::is_null(V)) internal_error("malformed version number");
     return V;
 }
diff --git a/docs/bytecode-module/2-in.html b/docs/bytecode-module/2-in.html
index abfdfc0ca..320ad9fc6 100644
--- a/docs/bytecode-module/2-in.html
+++ b/docs/bytecode-module/2-in.html
@@ -190,7 +190,7 @@ call those creator functions, not these.
     return P;
 }
 
-inter_tree_node *Inode::new_with_2_data_fields(inter_bookmark *IBM, int S,
+inter_tree_node *Inode::new_with_2_data_fields(inter_bookmark *IBM, int S,
     inter_ti V1, inter_ti V2, inter_error_location *eloc, inter_ti level) {
     inter_tree *I = InterBookmark::tree(IBM);
     inter_tree_node *P = Inode::new_node(InterTree::warehouse(I), I, 4,
@@ -215,7 +215,7 @@ call those creator functions, not these.
     return P;
 }
 
-inter_tree_node *Inode::new_with_4_data_fields(inter_bookmark *IBM, int S,
+inter_tree_node *Inode::new_with_4_data_fields(inter_bookmark *IBM, int S,
     inter_ti V1, inter_ti V2, inter_ti V3, inter_ti V4, inter_error_location *eloc,
     inter_ti level) {
     inter_tree *I = InterBookmark::tree(IBM);
@@ -246,7 +246,7 @@ call those creator functions, not these.
     return P;
 }
 
-inter_tree_node *Inode::new_with_6_data_fields(inter_bookmark *IBM, int S,
+inter_tree_node *Inode::new_with_6_data_fields(inter_bookmark *IBM, int S,
     inter_ti V1, inter_ti V2, inter_ti V3, inter_ti V4, inter_ti V5, inter_ti V6,
     inter_error_location *eloc, inter_ti level) {
     inter_tree *I = InterBookmark::tree(IBM);
diff --git a/docs/bytecode-module/3-ie.html b/docs/bytecode-module/3-ie.html
index 78aa2a37f..03dbe057c 100644
--- a/docs/bytecode-module/3-ie.html
+++ b/docs/bytecode-module/3-ie.html
@@ -71,7 +71,7 @@ where an error has occurred, in reading in Inter either from a text or binary fi
     size_t error_offset;
 } inter_error_location;
 
-
  • The structure inter_error_location is accessed in 2/it, 3/iibf and here.
+
  • The structure inter_error_location is accessed in 2/it, 3/iibf, 5/tsc and here.

§2. These two possibilities have two creators. Note that neither of these requires any memory to be allocated, so they return quickly and cannot cause memory leaks. So it's no problem to manufacture an inter_error_location for each location diff --git a/docs/bytecode-module/4-tic.html b/docs/bytecode-module/4-tic.html index cc2090515..2a1df780d 100644 --- a/docs/bytecode-module/4-tic.html +++ b/docs/bytecode-module/4-tic.html @@ -59,7 +59,7 @@ function togglePopup(material_id) {

Defining the insert construct.

-
+

§1. Definition. For what this does and why it is used, see Data Packages in Textual Inter (in inter). But please use it as little as possible: in an ideal world it would be abolished. @@ -68,8 +68,8 @@ But please use it as little as possible: in an ideal world it would be abolished

 void InsertInstruction::define_construct(void) {
     inter_construct *IC = InterInstruction::create_construct(INSERT_IST, I"insert");
-    InterInstruction::specify_syntax(IC, I"insert TEXT TEXT");
-    InterInstruction::data_extent_always(IC, 2);
+    InterInstruction::specify_syntax(IC, I"insert TEXT TEXT TEXT NUMBER");
+    InterInstruction::data_extent_always(IC, 4);
     InterInstruction::permit(IC, INSIDE_PLAIN_PACKAGE_ICUP);
     METHOD_ADD(IC, CONSTRUCT_READ_MTID, InsertInstruction::read);
     METHOD_ADD(IC, CONSTRUCT_TRANSPOSE_MTID, InsertInstruction::transpose);
@@ -82,21 +82,30 @@ compulsory words — see Inter Nodes
 
 
define TEXT_INSERT_IFLD (DATA_IFLD + 0)
-define REPLACING_IFLD (DATA_IFLD + 1)
+define REPLACING_INSERT_IFLD (DATA_IFLD + 1)
+define PROVENANCEFILE_INSERT_IFLD (DATA_IFLD + 2)
+define PROVENANCELINE_INSERT_IFLD (DATA_IFLD + 3)
 
 inter_error_message *InsertInstruction::new(inter_bookmark *IBM,
-    text_stream *text, text_stream *replacing, inter_ti level,
-    struct inter_error_location *eloc) {
+    text_stream *text, text_stream *replacing,
+    filename *file, inter_ti line_number,
+    inter_ti level, struct inter_error_location *eloc) {
+    TEMPORARY_TEXT(file_as_text)
+    if (file) WRITE_TO(file_as_text, "%f", file);
     inter_warehouse *warehouse = InterBookmark::warehouse(IBM);
     inter_package *pack = InterBookmark::package(IBM);
     inter_ti ID = InterWarehouse::create_text(warehouse, pack);
     Str::copy(InterWarehouse::get_text(warehouse, ID), text);
     inter_ti RID = InterWarehouse::create_text(warehouse, pack);
     Str::copy(InterWarehouse::get_text(warehouse, RID), replacing);
-    inter_tree_node *P = Inode::new_with_2_data_fields(IBM, INSERT_IST,
-        /* TEXT_INSERT_IFLD: */ ID,
-        /* REPLACING_IFLD: */ RID,
+    inter_ti FID = InterWarehouse::create_text(warehouse, pack);
+    Str::copy(InterWarehouse::get_text(warehouse, FID), file_as_text);
+    inter_tree_node *P = Inode::new_with_4_data_fields(IBM, INSERT_IST,
+        /* TEXT_INSERT_IFLD: */           ID,
+        /* REPLACING_INSERT_IFLD: */      RID,
+        /* PROVENANCEFILE_INSERT_IFLD: */ FID,
+        /* PROVENANCELINE_INSERT_IFLD: */ line_number,
         eloc, level);
     inter_error_message *E = VerifyingInter::instruction(pack, P); if (E) return E;
     NodePlacement::move_to_moving_bookmark(P, IBM);
@@ -116,7 +125,9 @@ compulsory words — see Inter Nodes    inter_package *owner, inter_error_message **E) {
     *E = VerifyingInter::text_field(owner, P, TEXT_INSERT_IFLD);
     if (*E) return;
-    *E = VerifyingInter::text_field(owner, P, REPLACING_IFLD);
+    *E = VerifyingInter::text_field(owner, P, REPLACING_INSERT_IFLD);
+    if (*E) return;
+    *E = VerifyingInter::text_field(owner, P, PROVENANCEFILE_INSERT_IFLD);
     if (*E) return;
 }
 
@@ -127,15 +138,27 @@ compulsory words — see Inter Nodes inter_error_location *eloc, inter_error_message **E) { text_stream *rq = ilp->mr.exp[0]; text_stream *repq = ilp->mr.exp[1]; + text_stream *fn = ilp->mr.exp[2]; + text_stream *lc = ilp->mr.exp[3]; TEMPORARY_TEXT(raw) TEMPORARY_TEXT(replacing) + TEMPORARY_TEXT(file_as_text) *E = TextualInter::parse_literal_text(raw, rq, 0, Str::len(rq), eloc); if (*E == NULL) *E = TextualInter::parse_literal_text(replacing, repq, 0, Str::len(repq), eloc); if (*E == NULL) - *E = InsertInstruction::new(IBM, raw, replacing, (inter_ti) ilp->indent_level, eloc); + *E = TextualInter::parse_literal_text(file_as_text, fn, 0, Str::len(fn), eloc); + if (*E == NULL) { + filename *F = NULL; + if (Str::len(file_as_text) > 0) F = Filenames::from_text(file_as_text); + inter_ti line_number = 0; + if (Str::len(lc) > 0) line_number = (inter_ti) Str::atoi(lc, 0); + *E = InsertInstruction::new(IBM, raw, replacing, F, line_number, + (inter_ti) ilp->indent_level, eloc); + } DISCARD_TEXT(raw) DISCARD_TEXT(replacing) + DISCARD_TEXT(file_as_text) }

§5. Writing to textual Inter syntax.

@@ -148,9 +171,12 @@ compulsory words — see Inter Nodes TextualInter::write_text(OUT, insertion); WRITE(" "); TextualInter::write_text(OUT, replacing); + WRITE(" "); + TextualInter::write_text(OUT, InsertInstruction::file_provenance(P)); + WRITE(" %d", InsertInstruction::line_provenance(P)); }
-

§6. Access function.

+

§6. Access functions.

 text_stream *InsertInstruction::insertion(inter_tree_node *P) {
@@ -162,7 +188,19 @@ compulsory words — see Inter Nodestext_stream *InsertInstruction::replacing(inter_tree_node *P) {
     if (P == NULL) return NULL;
     if (Inode::isnt(P, INSERT_IST)) return NULL;
-    return Inode::ID_to_text(P, P->W.instruction[REPLACING_IFLD]);
+    return Inode::ID_to_text(P, P->W.instruction[REPLACING_INSERT_IFLD]);
+}
+
+text_stream *InsertInstruction::file_provenance(inter_tree_node *P) {
+    if (P == NULL) return NULL;
+    if (Inode::isnt(P, INSERT_IST)) return NULL;
+    return Inode::ID_to_text(P, P->W.instruction[PROVENANCEFILE_INSERT_IFLD]);
+}
+
+inter_ti InsertInstruction::line_provenance(inter_tree_node *P) {
+    if (P == NULL) return 0;
+    if (Inode::isnt(P, INSERT_IST)) return 0;
+    return P->W.instruction[PROVENANCELINE_INSERT_IFLD];
 }
 
+

§3. And these are errors (mostly) from parsing the Inform 6-syntax content +in Include (- ... -) insertions of low-level code: +

+ +
+text_stream *notified_kit_name = NULL;
+text_stream *notified_architecture_name = NULL;
+int general_kit_notice_issued = FALSE;
+int trigger_kit_notice = FALSE;
+
+void SourceProblems::kit_notification(text_stream *kit_name, text_stream *architecture_name) {
+    if (Str::len(kit_name) > 0) trigger_kit_notice = TRUE;
+    else trigger_kit_notice = FALSE;
+    notified_kit_name = Str::duplicate(kit_name);
+    notified_architecture_name = Str::duplicate(architecture_name);
+}
+
+void SourceProblems::I6_level_error(char *message, text_stream *quote,
+    text_stream *file_ref, int line) {
+    TEMPORARY_TEXT(file)
+    WRITE_TO(file, "%S", file_ref);
+    TEMPORARY_TEXT(kit)
+    TEMPORARY_TEXT(M)
+    WRITE_TO(M, message, quote);
+    filename *F = Filenames::from_text(file);
+    TEMPORARY_TEXT(EX)
+    Filenames::write_extension(EX, F);
+    if (Str::eq_insensitive(EX, I".i6t")) {
+        pathname *P = Filenames::up(F);
+        if (Str::eq_insensitive(Pathnames::directory_name(P), I"Sections"))
+            P = Pathnames::up(P);
+        WRITE_TO(kit, "%S", Pathnames::directory_name(P));
+        Str::clear(file);
+        WRITE_TO(file, "%S", Filenames::get_leafname(F));
+    }
+    DISCARD_TEXT(EX)
+    if (trigger_kit_notice) {
+        if (general_kit_notice_issued == FALSE) {
+            StandardProblems::handmade_problem(Task::syntax_tree(), _p_(...));
+            Problems::issue_problem_segment(
+                "Before the project could be translated, one of the 'kits' of low-level "
+                "Inter code which it uses needed to be built first. This is seldom "
+                "necessary and normally happens silently when it is, but this time errors "
+                "occurred and therefore translation had to be abandoned. If you are "
+                "currently tinkering with a kit, you'll often see errors like this, "
+                "but otherwise it probably means that a new extension you're using "
+                "(and which contains a kit) isn't properly working.");
+            general_kit_notice_issued = TRUE;
+            Problems::issue_problem_end();
+        }
+        WRITE_TO(problems_file, "<h3>Building %S for architecture %S</h3>\n",
+            notified_kit_name, notified_architecture_name);
+        trigger_kit_notice = FALSE;
+    }
+    StandardProblems::handmade_problem(Task::syntax_tree(), _p_(...));
+    Problems::quote_stream(1, M);
+    if (Str::len(kit) > 0) {
+        Problems::quote_stream(2, file);
+        Problems::quote_number(3, &line);
+        Problems::quote_stream(4, kit);
+        if (general_kit_notice_issued) Problems::issue_problem_segment("%2, near line %3: %1.");
+        else Problems::issue_problem_segment("Near line %3 of file %2 in %4: %1.");
+    } else if (Str::len(file) > 0) {
+        LOG("%S, line %d:\n", file, line);
+        Problems::problem_quote_file(2, file, line);
+        Problems::issue_problem_segment(
+            "A mistake was found in the Inform 6-syntax code near here %2: %1.");
+    } else {
+        Problems::issue_problem_segment(
+            "My low-level reader of source code reported a mistake - \"%1\". "
+            "%PLow-level material written in Inform 6 syntax occurs either in kits or "
+            "in matter written inside 'Include (- ... -)' in source text, either in "
+            "the main source or in an extension used by it.");
+    }
+    Problems::issue_problem_end();
+    if ((Str::len(kit) > 0) && (general_kit_notice_issued)) {
+        WRITE_TO(problems_file, "<p>Path: ");
+        pathname *P = NULL, *Q = NULL, *MAT = NULL, *EXT = NULL, *INT = NULL;
+        for (Q = Filenames::up(F); Q; Q = Pathnames::up(Q)) {
+            text_stream *name = Pathnames::directory_name(Q);
+            if (Str::eq_insensitive(name, I"Extensions")) EXT = Q;
+            if (Str::eq_insensitive(name, I"Inter")) INT = Q;
+            if (Str::suffix_eq(name, I".materials", 10)) MAT = Q;
+        }
+        if (MAT) P = MAT; else if (EXT) P = EXT; else if (INT) P = INT;
+        if (P) Filenames::to_text_relative(problems_file, F, Pathnames::up(P));
+        else WRITE_TO(problems_file, "%f", F);
+        WRITE_TO(problems_file, "</p>");
+    }
+    DISCARD_TEXT(M)
+    DISCARD_TEXT(kit)
+}
+
diff --git a/docs/pipeline-module/2-pe.html b/docs/pipeline-module/2-pe.html index ad4163462..ad64bb6a6 100644 --- a/docs/pipeline-module/2-pe.html +++ b/docs/pipeline-module/2-pe.html @@ -214,34 +214,40 @@ what the red button marked "danger" does.

-int pipeline_error_count = 0;
+int kit_error_count = 0;
+text_stream *kit_error_filename = NULL;
+int kit_error_line_number = 0;
 
-void PipelineErrors::kit_error(char *message, text_stream *quote) {
-    #ifdef PROBLEMS_MODULE
-    TEMPORARY_TEXT(M)
-    WRITE_TO(M, message, quote);
-    Problems::quote_stream(1, M);
-    StandardProblems::handmade_problem(Task::syntax_tree(), _p_(...));
-    Problems::issue_problem_segment(
-        "My low-level reader of source code reported a mistake - \"%1\". "
-        "%PLow-level material written in Inform 6 syntax occurs either in kits or "
-        "in matter written inside 'Include (- ... -)' in source text, either in "
-        "the main source or in an extension used by it.");
-    Problems::issue_problem_end();
-    DISCARD_TEXT(M)
-    #endif
-    #ifndef PROBLEMS_MODULE
-    Errors::with_text(message, quote);
-    #endif
-    pipeline_error_count++;
+void PipelineErrors::set_kit_error_location(text_stream *file, inter_ti line) {
+    kit_error_filename = file;
+    kit_error_line_number = (int) line;
 }
 
-void PipelineErrors::reset_errors(void) {
-    pipeline_error_count = 0;
+void PipelineErrors::kit_error(char *message, text_stream *quote) {
+    #ifdef CORE_MODULE
+    SourceProblems::I6_level_error(message, quote, kit_error_filename,
+        kit_error_line_number);
+    #endif
+    #ifndef CORE_MODULE
+    if (Str::len(kit_error_filename) > 0) {
+        filename *F = Filenames::from_text(kit_error_filename);
+        TEMPORARY_TEXT(M)
+        WRITE_TO(M, message, quote);
+        Errors::at_position_S(M, F, kit_error_line_number);
+        DISCARD_TEXT(M)
+    } else {
+        Errors::with_text(message, quote);
+    }
+    #endif
+    kit_error_count++;
 }
 
-int PipelineErrors::errors_occurred(void) {
-    if (pipeline_error_count != 0) return TRUE;
+void PipelineErrors::reset_errors(void) {
+    kit_error_count = 0;
+}
+
+int PipelineErrors::errors_occurred(void) {
+    if (kit_error_count != 0) return TRUE;
     return FALSE;
 }
 
diff --git a/docs/pipeline-module/3-css.html b/docs/pipeline-module/3-css.html index 47077261f..ff49d384c 100644 --- a/docs/pipeline-module/3-css.html +++ b/docs/pipeline-module/3-css.html @@ -106,14 +106,17 @@ function definition, that is quite a lot of work.
 int CompileSplatsStage::run(pipeline_step *step) {
     PipelineErrors::reset_errors();
+    PipelineErrors::set_kit_error_location(NULL, 0);
     compile_splats_state css;
     Initialise the CS state2.2;
     inter_tree *I = step->ephemera.tree;
     InterTree::traverse(I, CompileSplatsStage::visitor1, &css, NULL, SPLAT_IST);
     InterTree::traverse(I, CompileSplatsStage::visitor2, &css, NULL, 0);
+    PipelineErrors::set_kit_error_location(NULL, 0);
     int errors_found = CompileSplatsStage::function_bodies(step, &css, I);
     if (errors_found) return FALSE;
     InterTree::traverse(I, CompileSplatsStage::visitor3, &css, NULL, SPLAT_IST);
+    PipelineErrors::set_kit_error_location(NULL, 0);
     if (PipelineErrors::errors_occurred()) return FALSE;
     return TRUE;
 }
@@ -217,6 +220,11 @@ is being compiled.
 

+    if (SplatInstruction::line_provenance(P) > 0)
+        PipelineErrors::set_kit_error_location(
+            SplatInstruction::file_provenance(P), SplatInstruction::line_provenance(P));
+    else
+        PipelineErrors::set_kit_error_location(NULL, 0);
     match_results mr = Regexp::create_mr();
     text_stream *raw_identifier = NULL, *value = NULL;
     int proceed = TRUE;
@@ -943,6 +951,11 @@ in this section.
 

+    if (SplatInstruction::line_provenance(P) > 0)
+        PipelineErrors::set_kit_error_location(
+            SplatInstruction::file_provenance(P), SplatInstruction::line_provenance(P));
+    else
+        PipelineErrors::set_kit_error_location(NULL, 0);
     text_stream *raw_identifier = NULL, *local_var_names = NULL, *body = NULL;
     match_results mr = Regexp::create_mr();
     if (SplatInstruction::plm(P) == ROUTINE_PLM) Parse the routine header3.2.1;
diff --git a/docs/pipeline-module/3-ps.html b/docs/pipeline-module/3-ps.html
index 9c371c9e1..7d05370ad 100644
--- a/docs/pipeline-module/3-ps.html
+++ b/docs/pipeline-module/3-ps.html
@@ -161,6 +161,8 @@ it from there.
     inter_bookmark here = InterBookmark::after_this_node(P);
     rpi_docket_state *docket_state = (rpi_docket_state *) docket->state;
     docket_state->assimilation_point = &here;
+    docket_state->file_provenance = InsertInstruction::file_provenance(P);
+    docket_state->line_provenance = InsertInstruction::line_provenance(P);
     SimpleTangler::tangle_text(docket, insertion);
     text_stream *replacing = InsertInstruction::replacing(P);
     if (Str::len(replacing) > 0) {
@@ -191,6 +193,8 @@ in K/Sections.
 typedef struct rpi_docket_state {
     struct inter_bookmark *assimilation_point;
     struct text_stream *namespace;
+    struct text_stream *file_provenance;
+    inter_ti line_provenance;
 } rpi_docket_state;
 
  • The structure rpi_docket_state is accessed in 3/css and here.
@@ -206,10 +210,13 @@ in K/Sections. rpi_docket_state state; state.assimilation_point = &assimilation_point; state.namespace = namespacename; + state.file_provenance = NULL; + state.line_provenance = 0; docket = SimpleTangler::new_docket( - &(ParsingStages::receive_raw), + &(ParsingStages::receive_raw), &(ParsingStages::receive_command), &(ParsingStages::receive_bplus), + &(ParsingStages::line_marker), &(PipelineErrors::kit_error), step->ephemera.the_kit, &state);
@@ -271,7 +278,15 @@ in kit files: "use of (+ ... +) in kit source has been withdrawn: '%S'", material); }
-

§5. We very much do not ignore the raw I6 code read in, though. When the reader +

§5. This is used to place I6 comments showing the provenance of the tangled text: +

+ +
+void ParsingStages::line_marker(text_stream *material, simple_tangle_docket *docket) {
+    WRITE_TO(material, "! LINEMARKER %d %f\n", docket->current_start_line, docket->current_filename);
+}
+
+

§6. We very much do not ignore the raw I6 code read in, though. When the reader gives us a chunk of this, we parse through it with a simple finite-state machine. This can be summarised as "divide the code up at ; boundaries, sending each piece in turn to //ParsingStages::splat//". But of course we do not want to @@ -310,12 +325,32 @@ functions). So for example (COMMENTED_I6TBIT + SQUOTED_I6TBIT + DQUOTED_I6TBIT + ROUTINED_I6TBIT)

-void ParsingStages::receive_raw(text_stream *S, simple_tangle_docket *docket) {
+void ParsingStages::receive_raw(text_stream *S, simple_tangle_docket *docket) {
     text_stream *R = Str::new();
     int mode = IGNORE_WS_I6TBIT;
-    LOOP_THROUGH_TEXT(pos, S) {
-        wchar_t c = Str::get(pos);
-        if ((c == 10) || (c == 13)) c = '\n';
+    rpi_docket_state *state = (rpi_docket_state *) docket->state;
+    inter_ti lc = state->line_provenance;
+    for (int pos = 0; pos < Str::len(S); pos++) {
+        wchar_t c = Str::get_at(S, pos);
+        if ((c == 10) || (c == 13)) { c = '\n'; lc++; }
+        if ((c == '!') && (Str::includes_at(S, pos, I"! LINEMARKER "))) {
+            text_stream *file_text = Str::new();
+            TEMPORARY_TEXT(number_text)
+            int in_number = TRUE;
+            for (pos = pos + 13; pos < Str::len(S); pos++) {
+                wchar_t c = Str::get_at(S, pos);
+                if ((c == 10) || (c == 13)) break;
+                if ((c == ' ') && (in_number)) { in_number = FALSE; continue; }
+                if (in_number) PUT_TO(number_text, c);
+                else PUT_TO(file_text, c);
+            }
+            state->line_provenance = (inter_ti) Str::atoi(number_text, 0);
+            lc = state->line_provenance;
+            state->file_provenance = file_text;
+            LOG("Spotted %d and <%S>\n", state->line_provenance, state->file_provenance);
+            DISCARD_TEXT(number_text)
+            continue;
+        }
         if (mode & IGNORE_WS_I6TBIT) {
             if ((c == '\n') || (Characters::is_whitespace(c))) continue;
             mode -= IGNORE_WS_I6TBIT;
@@ -354,15 +389,17 @@ functions). So for example
         }
         PUT_TO(R, c);
         if ((c == ';') && (!(mode & SUBORDINATE_I6TBITS))) {
-            ParsingStages::splat(R, docket);
+            ParsingStages::splat(R, docket);
+            state->line_provenance = lc;
             mode = IGNORE_WS_I6TBIT;
         }
     }
-    ParsingStages::splat(R, docket);
+    ParsingStages::splat(R, docket);
+    state->line_provenance = lc;
     Str::clear(S);
 }
 
-

§6. Each of those "splats", provided it is not entirely white space, becomes a +

§7. Each of those "splats", provided it is not entirely white space, becomes a SPLAT_IST node in the tree at the current insertion point recorded in the state being carried in the docket.

@@ -371,19 +408,28 @@ state being carried in the docket.

-void ParsingStages::splat(text_stream *R, simple_tangle_docket *docket) {
+void ParsingStages::splat(text_stream *R, simple_tangle_docket *docket) {
     if (Str::len(R) > 0) {
         TEMPORARY_TEXT(A)
-        Find annotation, if any6.1;
+        Find annotation, if any7.1;
         inter_ti I6_dir = 0;
 
-        Find directive6.2;
+        Find directive7.2;
         if (I6_dir != WHITESPACE_PLM) {
             rpi_docket_state *state = (rpi_docket_state *) docket->state;
             inter_bookmark *IBM = state->assimilation_point;
             PUT_TO(R, '\n');
+            filename *F = NULL;
+            inter_ti lc = 0;
+            if (Str::len(state->file_provenance) > 0) {
+                F = Filenames::from_text(state->file_provenance);
+                lc = state->line_provenance + 1;
+            } else if (docket->current_filename) {
+                F = docket->current_filename;
+                lc = 25;
+            }
             Produce::guard(SplatInstruction::new(IBM, R, I6_dir, A, state->namespace,
-                (inter_ti) (InterBookmark::baseline(IBM) + 1), NULL));
+                F, lc, (inter_ti) (InterBookmark::baseline(IBM) + 1), NULL));
         } else if (A) {
             I6_annotation *IA = I6Annotations::parse(A);
             if ((IA) && (Str::eq_insensitive(IA->identifier, I"namespace"))) {
@@ -438,7 +484,7 @@ state being carried in the docket.
     }
 }
 
-

§6.1. Find annotation, if any6.1 = +

§7.1. Find annotation, if any7.1 =

@@ -452,14 +498,14 @@ state being carried in the docket.
         Str::delete_n_characters(R, verdict);
     }
 
-
  • This code is used in §6.
-

§6.2. A SPLAT_IST node should record which sort of Inform 6 directive it contains, +

  • This code is used in §7.
+

§7.2. A SPLAT_IST node should record which sort of Inform 6 directive it contains, assuming we know that. We will recognise only the following set, and use MYSTERY_PLM for anything else. If the splat doesn't appear to be a directive at all, we leave the directive type as 0.

-

Find directive6.2 = +

Find directive7.2 =

@@ -496,8 +542,8 @@ the directive type as 0.
             "this Inform 6 directive is not supported in kits or '(-' inclusions: '%S'", R);
     Regexp::dispose_of(&mr);
 
-
  • This code is used in §6.
-

§7. And that's it: the result of these stages is just to break the I6T source they +

  • This code is used in §7.
+

§8. And that's it: the result of these stages is just to break the I6T source they found up into individual directives, and put them into the tree as SPLAT_IST nodes. No effort has been made yet to see what directives they are. Subsequent stages will handle that. diff --git a/docs/problems-module/2-pl1.html b/docs/problems-module/2-pl1.html index 0ac98120b..51fd1172d 100644 --- a/docs/problems-module/2-pl1.html +++ b/docs/problems-module/2-pl1.html @@ -88,7 +88,7 @@ any sentence in one go:

define QUOTATION_TOLERANCE_LIMIT 100
 
-void ProblemBuffer::copy_text(wording W) {
+void ProblemBuffer::copy_text(wording W) {
     W = Wordings::truncate(W, QUOTATION_TOLERANCE_LIMIT);
     WRITE_TO(PBUFF, "%<W", W);
 }
@@ -113,7 +113,7 @@ mask out angle brackets and quotation marks which we don't want to interpret as
 define PROTECTED_QUOT_CHAR L'\x03'
 
-void ProblemBuffer::copy_source_reference(wording W) {
+void ProblemBuffer::copy_source_reference(wording W) {
     if (Wordings::empty(W)) { WRITE_TO(PBUFF, "<no text>"); return; }
     source_file *referred = Lexer::file_of_origin(Wordings::first_wn(W));
     TEMPORARY_TEXT(file)
@@ -154,6 +154,31 @@ mask out angle brackets and quotation marks which we don't want to interpret as
     }
     DISCARD_TEXT(file)
 }
+
+void ProblemBuffer::copy_file_reference(text_stream *file_ref, int line) {
+    TEMPORARY_TEXT(file)
+    WRITE_TO(file, "%S", file_ref);
+    pathname *proj = HTML::get_link_abbreviation_path();
+    if (proj) {
+        TEMPORARY_TEXT(project_prefix)
+        WRITE_TO(project_prefix, "%p", proj);
+        if (Str::prefix_eq(file, project_prefix, Str::len(project_prefix)))
+            Str::delete_n_characters(file, Str::len(project_prefix));
+        DISCARD_TEXT(project_prefix)
+    } else {
+        WRITE_TO(file, "(no file)");
+    }
+    text_stream *paraphrase = file;
+    #ifdef DESCRIBE_SOURCE_FILE_PROBLEMS_CALLBACK
+    paraphrase = DESCRIBE_SOURCE_FILE_PROBLEMS_CALLBACK(paraphrase, NULL, file);
+    #endif
+    WRITE_TO(PBUFF, " %c%S%c%S%c%d%c",
+        SOURCE_REF_CHAR, paraphrase,
+        SOURCE_REF_CHAR, file,
+        SOURCE_REF_CHAR, line,
+        SOURCE_REF_CHAR);
+    DISCARD_TEXT(file)
+}
 

§5. Once the error message is fully constructed, we will want to output it to a file: in fact, by default it will go in three directions, to @@ -176,7 +201,7 @@ HTML, they are dealt with elsewhere. #define PROBLEMS_HTML_EMITTER PUT_TO #endif -void ProblemBuffer::output_problem_buffer_to(OUTPUT_STREAM, int indentation) { +void ProblemBuffer::output_problem_buffer_to(OUTPUT_STREAM, int indentation) { int line_width = 0, html_flag = FALSE; int sig_mode = FALSE, break_width = PROBLEM_WORD_WRAP_WIDTH; filename *fallback = NULL; #ifdef FORMAT_CONSOLE_PROBLEMS_CALLBACK @@ -414,7 +439,7 @@ our choice. telemetry_recording = TRUE; } -void ProblemBuffer::output_problem_buffer(int indentation) { +void ProblemBuffer::output_problem_buffer(int indentation) { if (redirected_problem_text == NULL) { ProblemBuffer::output_problem_buffer_to(problems_file, indentation); WRITE_TO(problems_file, "\n"); @@ -442,7 +467,7 @@ system without an error code.

 int tail_of_report_written = FALSE;
-void ProblemBuffer::write_reports(int disaster_struck) {
+void ProblemBuffer::write_reports(int disaster_struck) {
     if (tail_of_report_written) return;
     tail_of_report_written = TRUE;
 
diff --git a/docs/problems-module/2-pl2.html b/docs/problems-module/2-pl2.html
index 27ef32d90..0f072b1dd 100644
--- a/docs/problems-module/2-pl2.html
+++ b/docs/problems-module/2-pl2.html
@@ -151,7 +151,7 @@ the two possibilities.
         #endif
         for (i=0; i<NO_HEADING_LEVELS; i++) last_problem_headings[i] = NULL;
     }
-    if (do_not_locate_problems) return;
+    if ((T == NULL) || (do_not_locate_problems)) return;
     Problems::find_headings_at(T, current_sentence, problem_headings);
     for (i=0; i<NO_HEADING_LEVELS; i++) if (problem_headings[i] != NULL) f = TRUE;
     if (f)
@@ -213,6 +213,8 @@ easily be changed, but there seems no reason to.)
     void *structure_quoted;  if false
     void (*expander)(text_stream *, void *);  if false
     struct wording text_quoted;  if true
+    struct text_stream *file;  relevant only to 'F' file references
+    int line;  relevant only to 'F' file references
 } problem_quotation;
 
 problem_quotation problem_quotations[10];
@@ -233,6 +235,8 @@ printed as the inference SP    problem_quotations[t].quotation_type = '?';
     problem_quotations[t].wording_based = FALSE;
     problem_quotations[t].text_quoted = EMPTY_WORDING;
+    problem_quotations[t].file = NULL;
+    problem_quotations[t].line = 0;
 }
 
 void Problems::problem_quote_tinted(int t, void *v, void (*f)(text_stream *, void *), char type) {
@@ -242,6 +246,8 @@ printed as the inference SP    problem_quotations[t].quotation_type = type;
     problem_quotations[t].wording_based = FALSE;
     problem_quotations[t].text_quoted = EMPTY_WORDING;
+    problem_quotations[t].file = NULL;
+    problem_quotations[t].line = 0;
 }
 
 void Problems::problem_quote_textual(int t, char type, wording W) {
@@ -250,6 +256,18 @@ printed as the inference SP    problem_quotations[t].quotation_type = type;
     problem_quotations[t].wording_based = TRUE;
     problem_quotations[t].text_quoted = W;
+    problem_quotations[t].file = NULL;
+    problem_quotations[t].line = 0;
+}
+
+void Problems::problem_quote_file(int t, text_stream *file, int line) {
+    if ((t<0) || (t > 10)) internal_error("problem quotation number out of range");
+    problem_quotations[t].structure_quoted = NULL;
+    problem_quotations[t].quotation_type = 'F';
+    problem_quotations[t].wording_based = FALSE;
+    problem_quotations[t].text_quoted = EMPTY_WORDING;
+    problem_quotations[t].file = Str::duplicate(file);
+    problem_quotations[t].line = line;
 }
 

§6. Here are the three public routines for quoting from text: either via a node @@ -396,7 +414,7 @@ to remember whether to use the short or long form. } else if (strcmp(message, "**") == 0) { this_is_a_subsequent_use_of_problem = FALSE; } else { - if (T) Problems::show_problem_location(T); + Problems::show_problem_location(T); problem_count++; WRITE_TO(PBUFF, ">--> "); this_is_a_subsequent_use_of_problem = @@ -434,10 +452,10 @@ to remember whether to use the short or long form.

 wording appended_source = EMPTY_WORDING;
-void Problems::append_source(wording W) {
+void Problems::append_source(wording W) {
     appended_source = W;
 }
-void Problems::transcribe_appended_source(void) {
+void Problems::transcribe_appended_source(void) {
     if (Wordings::nonempty(appended_source))
         ProblemBuffer::copy_source_reference(appended_source);
 }
@@ -486,10 +504,12 @@ on when the shortened form is the one being issued).
         if (Characters::isdigit((wchar_t) message[i+1])) {
             int t = ((int) (message[i+1]))-((int) '0'); i++;
             if ((t>=1) && (t<=9)) {
-                if (problem_quotations[t].wording_based)
-                    Expand wording-based escape12.1.1
+                if (problem_quotations[t].quotation_type == 'F')
+                    Expand file reference12.1.1
+                else if (problem_quotations[t].wording_based)
+                    Expand wording-based escape12.1.2
                 else
-                    Expand structure-based escape12.1.2
+                    Expand structure-based escape12.1.3
             }
             continue;
         }
@@ -497,11 +517,21 @@ on when the shortened form is the one being issued).
     PUT_TO(PBUFF, message[i]);
 
  • This code is used in §12.
-

§12.1.1. This is where a quotation escape, such as %2, is expanded: by looking up +

§12.1.1. This is where there is an explicit reference to a filename and line number. +

+ +

Expand file reference12.1.1 = +

+ +
+    ProblemBuffer::copy_file_reference(problem_quotations[t].file, problem_quotations[t].line);
+
+ +

§12.1.2. This is where a quotation escape, such as %2, is expanded: by looking up its type, stored internally as a single character.

-

Expand wording-based escape12.1.1 = +

Expand wording-based escape12.1.2 =

@@ -515,18 +545,18 @@ its type, stored internally as a single character.
             break;
 
          Tinted wording
-        case 'r': Quote a red-tinted word range in a problem message12.1.1.1;
+        case 'r': Quote a red-tinted word range in a problem message12.1.2.1;
             break;
-        case 'g': Quote a green-tinted word range in a problem message12.1.1.2;
+        case 'g': Quote a green-tinted word range in a problem message12.1.2.2;
             break;
         default: internal_error("unknown error token type");
     }
 
-

§12.1.1.1. Tinting text involves some HTML, of course: +

§12.1.2.1. Tinting text involves some HTML, of course:

-

Quote a red-tinted word range in a problem message12.1.1.1 = +

Quote a red-tinted word range in a problem message12.1.2.1 =

@@ -534,14 +564,14 @@ its type, stored internally as a single character.
     HTML::begin_span(OUT, I"problemred");
     WRITE("%W", problem_quotations[t].text_quoted);
     HTML::end_span(OUT);
-    Spool temporary stream text to the problem buffer12.1.1.1.1;
+    Spool temporary stream text to the problem buffer12.1.2.1.1;
     DISCARD_TEXT(OUT)
 
- -

§12.1.1.2. And: +

+

§12.1.2.2. And:

-

Quote a green-tinted word range in a problem message12.1.1.2 = +

Quote a green-tinted word range in a problem message12.1.2.2 =

@@ -549,15 +579,15 @@ its type, stored internally as a single character.
     HTML::begin_span(OUT, I"problemgreen");
     WRITE("%W", problem_quotations[t].text_quoted);
     HTML::end_span(OUT);
-    Spool temporary stream text to the problem buffer12.1.1.1.1;
+    Spool temporary stream text to the problem buffer12.1.2.1.1;
     DISCARD_TEXT(OUT)
 
- -

§12.1.2. More generally, the reference is to some structure we can't write +

+

§12.1.3. More generally, the reference is to some structure we can't write ourselves, and must delegate to:

-

Expand structure-based escape12.1.2 = +

Expand structure-based escape12.1.3 =

@@ -568,12 +598,12 @@ ourselves, and must delegate to:
     (problem_quotations[t].expander)(OUT, problem_quotations[t].structure_quoted);
     if (problem_quotations[t].quotation_type == 'r') HTML::end_span(OUT);
     if (problem_quotations[t].quotation_type == 'g') HTML::end_span(OUT);
-    Spool temporary stream text to the problem buffer12.1.1.1.1;
+    Spool temporary stream text to the problem buffer12.1.2.1.1;
     DISCARD_TEXT(OUT)
     Problems::transcribe_appended_source();
 
-

§12.1.1.1.1. Spool temporary stream text to the problem buffer12.1.1.1.1 = +

§12.1.2.1.1. Spool temporary stream text to the problem buffer12.1.2.1.1 =

@@ -585,7 +615,7 @@ ourselves, and must delegate to:
         PUT_TO(PBUFF, c);
     }
 
- +

§13. This version is much shorter, since escapes aren't allowed:

diff --git a/docs/runtime-module/2-emt.html b/docs/runtime-module/2-emt.html index c6429a5bf..45b11543f 100644 --- a/docs/runtime-module/2-emt.html +++ b/docs/runtime-module/2-emt.html @@ -387,8 +387,17 @@ assimilating during linking.
 void Emit::intervention(text_stream *raw_matter, text_stream *replacing) {
+    filename *F = NULL;
+    inter_ti lc = 0;
+    if (current_sentence) {
+        wording W = current_sentence->text_parsed;
+        source_file *sf = Lexer::file_of_origin(Wordings::first_wn(W));
+        if (sf) F = TextFromFiles::get_filename(sf);
+        lc = (inter_ti) Lexer::line_of_origin(Wordings::first_wn(W));
+    }
     Produce::guard(
-        InsertInstruction::new(Emit::at(), raw_matter, replacing, Emit::baseline(), NULL));
+        InsertInstruction::new(Emit::at(), raw_matter, replacing, F, lc,
+        Emit::baseline(), NULL));
 }
 

§17. And this is a similarly inelegant construction: diff --git a/docs/supervisor-module/3-is.html b/docs/supervisor-module/3-is.html index 8e28171ef..74f10c4c5 100644 --- a/docs/supervisor-module/3-is.html +++ b/docs/supervisor-module/3-is.html @@ -149,11 +149,19 @@ should be, so the effect is the same. WRITE_TO(STDOUT, "(Building %S for architecture %S)\n", S->associated_copy->edition->work->title, Architectures::to_codename(A)); + #ifdef CORE_MODULE + SourceProblems::kit_notification(S->associated_copy->edition->work->title, + Architectures::to_codename(A)); + #endif linked_list *requirements_list = NEW_LINKED_LIST(attachment_instruction); + PipelineErrors::reset_errors(); RunningPipelines::run(NULL, SS, NULL, S->associated_copy->location_if_path, requirements_list, S->for_vm, FALSE); PipelineModule::set_architecture_to(saved_A); - return TRUE; + #ifdef CORE_MODULE + SourceProblems::kit_notification(NULL, NULL); + #endif + return (PipelineErrors::errors_occurred())?FALSE:TRUE; } else { Errors::nowhere("build-kit pipeline could not be parsed"); return FALSE; diff --git a/docs/supervisor-module/6-st.html b/docs/supervisor-module/6-st.html index d2f29d38b..45522fe29 100644 --- a/docs/supervisor-module/6-st.html +++ b/docs/supervisor-module/6-st.html @@ -157,7 +157,21 @@ source files. text_stream *SourceText::describe_source_file(text_stream *paraphrase, source_file *referred, text_stream *file) { paraphrase = I"source text"; - inform_extension *E = Extensions::corresponding_to(referred); + inform_extension *E = NULL; + if (referred) { + E = Extensions::corresponding_to(referred); + } else { + TEMPORARY_TEXT(matched_filename) + inform_extension *F; + LOOP_OVER(F, inform_extension) { + if (F->read_into_file) { + Str::clear(matched_filename); + WRITE_TO(matched_filename, "%f", + TextFromFiles::get_filename(F->read_into_file)); + if (Str::eq(matched_filename, file)) E = F; + } + } + } if (E) { inbuild_work *work = E->as_copy->edition->work; if ((work) && (Works::is_standard_rules(work))) diff --git a/docs/words-module/3-lxr.html b/docs/words-module/3-lxr.html index 023f36673..194f1c00b 100644 --- a/docs/words-module/3-lxr.html +++ b/docs/words-module/3-lxr.html @@ -505,6 +505,10 @@ distinguished. We'll do this with the letters return lw_array[wn].lw_source.file_of_origin; } +int Lexer::line_of_origin(int wn) { + return lw_array[wn].lw_source.line_number; +} + source_location Lexer::word_location(int wn) { if (wn < 0) { source_location nowhere; diff --git a/inbuild/supervisor-module/Chapter 3/Inter Skill.w b/inbuild/supervisor-module/Chapter 3/Inter Skill.w index 95070d4a1..75ffd6e14 100644 --- a/inbuild/supervisor-module/Chapter 3/Inter Skill.w +++ b/inbuild/supervisor-module/Chapter 3/Inter Skill.w @@ -89,11 +89,19 @@ int InterSkill::build_kit_internally(build_skill *skill, build_step *S, WRITE_TO(STDOUT, "(Building %S for architecture %S)\n", S->associated_copy->edition->work->title, Architectures::to_codename(A)); + #ifdef CORE_MODULE + SourceProblems::kit_notification(S->associated_copy->edition->work->title, + Architectures::to_codename(A)); + #endif linked_list *requirements_list = NEW_LINKED_LIST(attachment_instruction); + PipelineErrors::reset_errors(); RunningPipelines::run(NULL, SS, NULL, S->associated_copy->location_if_path, requirements_list, S->for_vm, FALSE); PipelineModule::set_architecture_to(saved_A); - return TRUE; + #ifdef CORE_MODULE + SourceProblems::kit_notification(NULL, NULL); + #endif + return (PipelineErrors::errors_occurred())?FALSE:TRUE; } else { Errors::nowhere("build-kit pipeline could not be parsed"); return FALSE; diff --git a/inbuild/supervisor-module/Chapter 6/Source Text.w b/inbuild/supervisor-module/Chapter 6/Source Text.w index d00a1bfb1..1683295fd 100644 --- a/inbuild/supervisor-module/Chapter 6/Source Text.w +++ b/inbuild/supervisor-module/Chapter 6/Source Text.w @@ -86,7 +86,21 @@ source files. text_stream *SourceText::describe_source_file(text_stream *paraphrase, source_file *referred, text_stream *file) { paraphrase = I"source text"; - inform_extension *E = Extensions::corresponding_to(referred); + inform_extension *E = NULL; + if (referred) { + E = Extensions::corresponding_to(referred); + } else { + TEMPORARY_TEXT(matched_filename) + inform_extension *F; + LOOP_OVER(F, inform_extension) { + if (F->read_into_file) { + Str::clear(matched_filename); + WRITE_TO(matched_filename, "%f", + TextFromFiles::get_filename(F->read_into_file)); + if (Str::eq(matched_filename, file)) E = F; + } + } + } if (E) { inbuild_work *work = E->as_copy->edition->work; if ((work) && (Works::is_standard_rules(work))) diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt index 3ec358896..39c22887a 100644 --- a/inform7/Figures/memory-diagnostics.txt +++ b/inform7/Figures/memory-diagnostics.txt @@ -1,9 +1,9 @@ -Total memory consumption was 121577K = 119 MB +Total memory consumption was 121595K = 119 MB - ---- was used for 2059368 objects, in 367407 frames in 0 x 800K = 0K = 0 MB: + ---- was used for 2059550 objects, in 367490 frames in 0 x 800K = 0K = 0 MB: 33.5% inter_tree_node_array 58 x 8192 = 475136 objects, 41813824 bytes - 21.0% text_stream_array 4654 x 100 = 465400 objects, 26211328 bytes + 21.0% text_stream_array 4655 x 100 = 465500 objects, 26216960 bytes 19.9% linked_list 44435 objects, 24883600 bytes 11.3% inter_symbol_array 133 x 1024 = 136192 objects, 14168224 bytes 10.7% inter_error_stash_array 102 x 1024 = 104448 objects, 13372608 bytes @@ -94,14 +94,14 @@ Total memory consumption was 121577K = 119 MB ---- parse_node_tree 33 objects, 28776 bytes ---- action_pattern_array 7 x 100 = 700 objects, 28224 bytes ---- shared_variable_set_array 6 x 100 = 600 objects, 24192 bytes - ---- filename 591 objects, 23640 bytes + ---- filename 601 objects, 24040 bytes + ---- pathname 559 objects, 22360 bytes ---- property 146 objects, 22192 bytes ---- backdrops_data 672 objects, 21504 bytes ---- inter_node_list 646 objects, 20672 bytes ---- nonlocal_variable 94 objects, 20304 bytes ---- pipeline_step 15 objects, 20280 bytes ---- action_name 90 objects, 20160 bytes - ---- pathname 487 objects, 19480 bytes ---- timed_rules_rfd_data 401 objects, 19248 bytes ---- method 390 objects, 18720 bytes ---- pcalc_prop_deferral 86 objects, 17888 bytes @@ -248,7 +248,7 @@ Total memory consumption was 121577K = 119 MB 100.0% was used for memory not allocated for objects: - 56.9% text stream storage 70960008 bytes in 482750 claims + 57.0% text stream storage 70976924 bytes in 482872 claims 4.2% dictionary storage 5315584 bytes in 7623 claims ---- sorting 2720 bytes in 387 claims 5.7% source text 7200000 bytes in 3 claims @@ -257,7 +257,7 @@ Total memory consumption was 121577K = 119 MB ---- linguistic stock array 81920 bytes in 2 claims ---- small word set array 105600 bytes in 22 claims 3.6% inter symbols storage 4559120 bytes in 27994 claims - 13.4% inter bytecode storage 16766964 bytes in 14 claims + 13.4% inter bytecode storage 16768036 bytes in 14 claims 4.9% inter links storage 6222976 bytes in 11 claims 0.1% inter tree location list storage 191232 bytes in 32 claims 1.3% instance-of-kind counting 1705636 bytes in 1 claim @@ -266,5 +266,5 @@ Total memory consumption was 121577K = 119 MB ---- code generation workspace for objects 3480 bytes in 19 claims 0.2% emitter array storage 280544 bytes in 2001 claims --151.-4% was overhead - -188601360 bytes = -184181K = -179 MB +-151.-4% was overhead - -188610272 bytes = -184189K = -179 MB diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt index 7df9fb478..134acd738 100644 --- a/inform7/Figures/timings-diagnostics.txt +++ b/inform7/Figures/timings-diagnostics.txt @@ -1,33 +1,33 @@ 100.0% in inform7 run - 70.0% in compilation to Inter - 49.7% in //Sequence::undertake_queued_tasks// + 69.8% in compilation to Inter + 49.2% in //Sequence::undertake_queued_tasks// 4.8% in //MajorNodes::pre_pass// - 3.3% in //MajorNodes::pass_1// - 1.7% in //ImperativeDefinitions::assess_all// - 1.5% in //RTPhrasebook::compile_entries// - 1.3% in //RTKindConstructors::compile// - 0.9% in //Sequence::lint_inter// - 0.5% in //MajorNodes::pass_2// - 0.5% in //Sequence::undertake_queued_tasks// - 0.5% in //Sequence::undertake_queued_tasks// - 0.5% in //World::stage_V// - 0.3% in //ImperativeDefinitions::compile_first_block// - 0.1% in //CompletionModule::compile// - 0.1% in //InferenceSubjects::emit_all// - 0.1% in //RTKindConstructors::compile_permissions// - 0.1% in //Task::make_built_in_kind_constructors// - 0.1% in //World::stages_II_and_III// - 2.9% not specifically accounted for - 26.2% in running Inter pipeline + 3.4% in //MajorNodes::pass_1// + 1.8% in //ImperativeDefinitions::assess_all// + 1.6% in //RTPhrasebook::compile_entries// + 1.4% in //RTKindConstructors::compile// + 1.0% in //Sequence::lint_inter// + 0.6% in //MajorNodes::pass_2// + 0.6% in //Sequence::undertake_queued_tasks// + 0.6% in //Sequence::undertake_queued_tasks// + 0.6% in //World::stage_V// + 0.4% in //ImperativeDefinitions::compile_first_block// + 0.2% in //CompletionModule::compile// + 0.2% in //InferenceSubjects::emit_all// + 0.2% in //RTKindConstructors::compile_permissions// + 0.2% in //Task::make_built_in_kind_constructors// + 2.8% not specifically accounted for + 26.7% in running Inter pipeline 10.0% in step 14/15: generate inform6 -> auto.inf - 5.8% in step 5/15: load-binary-kits + 6.0% in step 5/15: load-binary-kits 5.4% in step 6/15: make-synoptic-module - 1.7% in step 9/15: make-identifiers-unique - 0.3% in step 12/15: eliminate-redundant-operations - 0.3% in step 4/15: compile-splats - 0.3% in step 7/15: shorten-wiring - 0.3% in step 8/15: detect-indirect-calls - 0.1% in step 11/15: eliminate-redundant-labels + 1.8% in step 9/15: make-identifiers-unique + 0.4% in step 12/15: eliminate-redundant-operations + 0.4% in step 4/15: compile-splats + 0.4% in step 7/15: shorten-wiring + 0.4% in step 8/15: detect-indirect-calls + 0.2% in step 10/15: reconcile-verbs + 0.2% in step 11/15: eliminate-redundant-labels 1.4% not specifically accounted for - 3.1% in supervisor - 0.6% not specifically accounted for + 3.0% in supervisor + 0.5% not specifically accounted for diff --git a/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json index 7659513e0..aaf86b61b 100644 --- a/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json +++ b/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "BasicInformExtrasKit", - "version": "10.2.0-beta+6W36" + "version": "10.2.0-beta+6W37" }, "kit-details": { "has-priority": 1 diff --git a/inform7/Internal/Inter/BasicInformKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformKit/kit_metadata.json index 4f1c182ea..33b6ef69b 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+6W36" + "version": "10.2.0-beta+6W37" }, "needs": [ { "unless": { diff --git a/inform7/Internal/Inter/CommandParserKit/kit_metadata.json b/inform7/Internal/Inter/CommandParserKit/kit_metadata.json index 6fc33fb98..254faeeca 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+6W36" + "version": "10.2.0-beta+6W37" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/DialogueKit/arch-16.interb b/inform7/Internal/Inter/DialogueKit/arch-16.interb index cc85c666e27d78e03edc526e4e8e2f9b021d69ad..cb76ee7b91e9cb95468925bc927341b9e617cffc 100644 GIT binary patch delta 26 dcmezHhV8=}HlED9k|G8OU~S~t%EOql4FH1Z2mAm4 delta 26 dcmezHhV8=}HlED9k|G8OU}@yp%EOql4FH1R2m1g3 diff --git a/inform7/Internal/Inter/DialogueKit/arch-16d.interb b/inform7/Internal/Inter/DialogueKit/arch-16d.interb index 860185729fe1920e05bca0317f4bcfddca5d79e5..ab57032c96669823d502f4e388c32cb156cd9ece 100644 GIT binary patch delta 26 dcmZpD%hvjqjVCj&q=*3mSQ~k^@-S9z0|0Ku2R#4) delta 26 dcmZpD%hvjqjVCj&q=*3mSQ>e@@-S9z0|0Km2Rr}( diff --git a/inform7/Internal/Inter/DialogueKit/arch-32.interb b/inform7/Internal/Inter/DialogueKit/arch-32.interb index eaa69fd403427b265b86ccbc31d8d2056379b508..ed7cb0b5a2f6a67e76bf356f90b81400c1231eec 100644 GIT binary patch delta 26 dcmbR8j%~_2HlED9k|G8OU~S~t%EQR99RP6i2JHX< delta 26 dcmbR8j%~_2HlED9k|G8OU}@yp%EQR99RP6a2J8R; diff --git a/inform7/Internal/Inter/DialogueKit/arch-32d.interb b/inform7/Internal/Inter/DialogueKit/arch-32d.interb index e3381e229b61dd0b4617d50f38d67a5cb3c04a19..ea9d0d968d0403be5e13233c31480ae8eb687c25 100644 GIT binary patch delta 26 dcmZ4aj&0>THlED9k|G8OU~S~t%EKtT9RPJA2P^;p delta 26 dcmZ4aj&0>THlED9k|G8OU}@yp%EKtT9RPJ22P*&o diff --git a/inform7/Internal/Inter/EnglishLanguageKit/arch-16.interb b/inform7/Internal/Inter/EnglishLanguageKit/arch-16.interb index 1fa61e1cf36e181f92dbcce136a96afc5b055213..cefefe051426a87bd0978da14196cffba0a89cfc 100644 GIT binary patch delta 23 acmbQZh;iZ~MxM;Pk|G8OVBN^W8VCSS*9A%d delta 23 acmbQZh;iZ~MxM;Pk|G8OVA;sS8VCSS(gjHX diff --git a/inform7/Internal/Inter/EnglishLanguageKit/arch-16d.interb b/inform7/Internal/Inter/EnglishLanguageKit/arch-16d.interb index b957835c9f75c630df79cbd85c5aa5d9db255981..1c387fa241e55135c088b1b87c4ac88f36676349 100644 GIT binary patch delta 23 acmZ3sh;i8>MxM;Pk|G8OVBN?g6$k)Rhy{rN delta 23 acmZ3sh;i8>MxM;Pk|G8OVA;qc6$k)Rg9V5H diff --git a/inform7/Internal/Inter/EnglishLanguageKit/arch-32.interb b/inform7/Internal/Inter/EnglishLanguageKit/arch-32.interb index decda5bce4f38607287592f0ce093b659b5a2111..aa34c29256741c82e31d610687f4179e1f274124 100644 GIT binary patch delta 23 acmbQfh;jNNMxM;Pk|G8OVBN^W9S8tW- delta 23 acmbQfh;jNNMxM;Pk|G8OVA;sS9S8tW;00R% diff --git a/inform7/Internal/Inter/EnglishLanguageKit/arch-32d.interb b/inform7/Internal/Inter/EnglishLanguageKit/arch-32d.interb index 136282930ada26f1c7f22510c6a2ccc68a2f291e..adc273d7d50f0b29196955f9ddf23696e853ee38 100644 GIT binary patch delta 23 acmZ3ph;hv#MxM;Pk|G8OVBN^05C{NNmIa#t delta 23 acmZ3ph;hv#MxM;Pk|G8OVA;r{5C{NNkp-Fn diff --git a/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json b/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json index 0fd67aeb4..3555483d5 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+6W36" + "version": "10.2.0-beta+6W37" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/WorldModelKit/kit_metadata.json b/inform7/Internal/Inter/WorldModelKit/kit_metadata.json index f86f634cc..3b8a0ef58 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+6W36" + "version": "10.2.0-beta+6W37" }, "needs": [ { "need": { diff --git a/inform7/core-module/Chapter 2/Problems With Source Text.w b/inform7/core-module/Chapter 2/Problems With Source Text.w index 5d3a962bc..831fa1a4e 100644 --- a/inform7/core-module/Chapter 2/Problems With Source Text.w +++ b/inform7/core-module/Chapter 2/Problems With Source Text.w @@ -617,3 +617,95 @@ void SourceProblems::inter_schema_errors(inter_schema *sch) { } Problems::issue_problem_end(); } + +@ And these are errors (mostly) from parsing the Inform 6-syntax content +in |Include (- ... -)| insertions of low-level code: + += +text_stream *notified_kit_name = NULL; +text_stream *notified_architecture_name = NULL; +int general_kit_notice_issued = FALSE; +int trigger_kit_notice = FALSE; + +void SourceProblems::kit_notification(text_stream *kit_name, text_stream *architecture_name) { + if (Str::len(kit_name) > 0) trigger_kit_notice = TRUE; + else trigger_kit_notice = FALSE; + notified_kit_name = Str::duplicate(kit_name); + notified_architecture_name = Str::duplicate(architecture_name); +} + +void SourceProblems::I6_level_error(char *message, text_stream *quote, + text_stream *file_ref, int line) { + TEMPORARY_TEXT(file) + WRITE_TO(file, "%S", file_ref); + TEMPORARY_TEXT(kit) + TEMPORARY_TEXT(M) + WRITE_TO(M, message, quote); + filename *F = Filenames::from_text(file); + TEMPORARY_TEXT(EX) + Filenames::write_extension(EX, F); + if (Str::eq_insensitive(EX, I".i6t")) { + pathname *P = Filenames::up(F); + if (Str::eq_insensitive(Pathnames::directory_name(P), I"Sections")) + P = Pathnames::up(P); + WRITE_TO(kit, "%S", Pathnames::directory_name(P)); + Str::clear(file); + WRITE_TO(file, "%S", Filenames::get_leafname(F)); + } + DISCARD_TEXT(EX) + if (trigger_kit_notice) { + if (general_kit_notice_issued == FALSE) { + StandardProblems::handmade_problem(Task::syntax_tree(), _p_(...)); + Problems::issue_problem_segment( + "Before the project could be translated, one of the 'kits' of low-level " + "Inter code which it uses needed to be built first. This is seldom " + "necessary and normally happens silently when it is, but this time errors " + "occurred and therefore translation had to be abandoned. If you are " + "currently tinkering with a kit, you'll often see errors like this, " + "but otherwise it probably means that a new extension you're using " + "(and which contains a kit) isn't properly working."); + general_kit_notice_issued = TRUE; + Problems::issue_problem_end(); + } + WRITE_TO(problems_file, "

Building %S for architecture %S

\n", + notified_kit_name, notified_architecture_name); + trigger_kit_notice = FALSE; + } + StandardProblems::handmade_problem(Task::syntax_tree(), _p_(...)); + Problems::quote_stream(1, M); + if (Str::len(kit) > 0) { + Problems::quote_stream(2, file); + Problems::quote_number(3, &line); + Problems::quote_stream(4, kit); + if (general_kit_notice_issued) Problems::issue_problem_segment("%2, near line %3: %1."); + else Problems::issue_problem_segment("Near line %3 of file %2 in %4: %1."); + } else if (Str::len(file) > 0) { + LOG("%S, line %d:\n", file, line); + Problems::problem_quote_file(2, file, line); + Problems::issue_problem_segment( + "A mistake was found in the Inform 6-syntax code near here %2: %1."); + } else { + Problems::issue_problem_segment( + "My low-level reader of source code reported a mistake - \"%1\". " + "%PLow-level material written in Inform 6 syntax occurs either in kits or " + "in matter written inside 'Include (- ... -)' in source text, either in " + "the main source or in an extension used by it."); + } + Problems::issue_problem_end(); + if ((Str::len(kit) > 0) && (general_kit_notice_issued)) { + WRITE_TO(problems_file, "

Path: "); + pathname *P = NULL, *Q = NULL, *MAT = NULL, *EXT = NULL, *INT = NULL; + for (Q = Filenames::up(F); Q; Q = Pathnames::up(Q)) { + text_stream *name = Pathnames::directory_name(Q); + if (Str::eq_insensitive(name, I"Extensions")) EXT = Q; + if (Str::eq_insensitive(name, I"Inter")) INT = Q; + if (Str::suffix_eq(name, I".materials", 10)) MAT = Q; + } + if (MAT) P = MAT; else if (EXT) P = EXT; else if (INT) P = INT; + if (P) Filenames::to_text_relative(problems_file, F, Pathnames::up(P)); + else WRITE_TO(problems_file, "%f", F); + WRITE_TO(problems_file, "

"); + } + DISCARD_TEXT(M) + DISCARD_TEXT(kit) +} diff --git a/inform7/runtime-module/Chapter 2/Emit.w b/inform7/runtime-module/Chapter 2/Emit.w index 3d7939d91..c6e999b33 100644 --- a/inform7/runtime-module/Chapter 2/Emit.w +++ b/inform7/runtime-module/Chapter 2/Emit.w @@ -322,8 +322,17 @@ assimilating during linking. = void Emit::intervention(text_stream *raw_matter, text_stream *replacing) { + filename *F = NULL; + inter_ti lc = 0; + if (current_sentence) { + wording W = current_sentence->text_parsed; + source_file *sf = Lexer::file_of_origin(Wordings::first_wn(W)); + if (sf) F = TextFromFiles::get_filename(sf); + lc = (inter_ti) Lexer::line_of_origin(Wordings::first_wn(W)); + } Produce::guard( - InsertInstruction::new(Emit::at(), raw_matter, replacing, Emit::baseline(), NULL)); + InsertInstruction::new(Emit::at(), raw_matter, replacing, F, lc, + Emit::baseline(), NULL)); } @ And this is a similarly inelegant construction: diff --git a/inter/Tests/Invalid/_Results_Ideal/inversion.txt b/inter/Tests/Invalid/_Results_Ideal/inversion.txt index 764c51351..a76c90f6b 100644 --- a/inter/Tests/Invalid/_Results_Ideal/inversion.txt +++ b/inter/Tests/Invalid/_Results_Ideal/inversion.txt @@ -1,2 +1,2 @@ -inter: inter/Tests/Invalid/inversion.intert, line 1: file holds Inter written for specification v0.1.2, but I expect v4.0.0 +inter: inter/Tests/Invalid/inversion.intert, line 1: file holds Inter written for specification v0.1.2, but I expect v5.0.0 >--> version 0.1.2 diff --git a/inter/bytecode-module/Chapter 1/The Inter Version.w b/inter/bytecode-module/Chapter 1/The Inter Version.w index 9b070c6a1..2dbda626a 100644 --- a/inter/bytecode-module/Chapter 1/The Inter Version.w +++ b/inter/bytecode-module/Chapter 1/The Inter Version.w @@ -55,11 +55,14 @@ to directives. represent new data structures with custom kind constructors from Neptune files in Inform kits. +5.0.0 (24 April 2023) added (further) new fields to |SPLAT_IST| instructions, to +record their provenance and so make better error reporting possible. + @ Anyway, the implementation, such as it is: = semantic_version_number InterVersion::current(void) { - semantic_version_number V = VersionNumbers::from_text(I"4.0.0"); + semantic_version_number V = VersionNumbers::from_text(I"5.0.0"); if (VersionNumbers::is_null(V)) internal_error("malformed version number"); return V; } diff --git a/inter/bytecode-module/Chapter 4/The Insert Construct.w b/inter/bytecode-module/Chapter 4/The Insert Construct.w index fc2ba493f..d571375cf 100644 --- a/inter/bytecode-module/Chapter 4/The Insert Construct.w +++ b/inter/bytecode-module/Chapter 4/The Insert Construct.w @@ -9,8 +9,8 @@ But please use it as little as possible: in an ideal world it would be abolished = void InsertInstruction::define_construct(void) { inter_construct *IC = InterInstruction::create_construct(INSERT_IST, I"insert"); - InterInstruction::specify_syntax(IC, I"insert TEXT TEXT"); - InterInstruction::data_extent_always(IC, 2); + InterInstruction::specify_syntax(IC, I"insert TEXT TEXT TEXT NUMBER"); + InterInstruction::data_extent_always(IC, 4); InterInstruction::permit(IC, INSIDE_PLAIN_PACKAGE_ICUP); METHOD_ADD(IC, CONSTRUCT_READ_MTID, InsertInstruction::read); METHOD_ADD(IC, CONSTRUCT_TRANSPOSE_MTID, InsertInstruction::transpose); @@ -23,21 +23,30 @@ In bytecode, the frame of an |insert| instruction is laid out with the compulsory words -- see //Inter Nodes// -- followed by: @d TEXT_INSERT_IFLD (DATA_IFLD + 0) -@d REPLACING_IFLD (DATA_IFLD + 1) +@d REPLACING_INSERT_IFLD (DATA_IFLD + 1) +@d PROVENANCEFILE_INSERT_IFLD (DATA_IFLD + 2) +@d PROVENANCELINE_INSERT_IFLD (DATA_IFLD + 3) = inter_error_message *InsertInstruction::new(inter_bookmark *IBM, - text_stream *text, text_stream *replacing, inter_ti level, - struct inter_error_location *eloc) { + text_stream *text, text_stream *replacing, + filename *file, inter_ti line_number, + inter_ti level, struct inter_error_location *eloc) { + TEMPORARY_TEXT(file_as_text) + if (file) WRITE_TO(file_as_text, "%f", file); inter_warehouse *warehouse = InterBookmark::warehouse(IBM); inter_package *pack = InterBookmark::package(IBM); inter_ti ID = InterWarehouse::create_text(warehouse, pack); Str::copy(InterWarehouse::get_text(warehouse, ID), text); inter_ti RID = InterWarehouse::create_text(warehouse, pack); Str::copy(InterWarehouse::get_text(warehouse, RID), replacing); - inter_tree_node *P = Inode::new_with_2_data_fields(IBM, INSERT_IST, - /* TEXT_INSERT_IFLD: */ ID, - /* REPLACING_IFLD: */ RID, + inter_ti FID = InterWarehouse::create_text(warehouse, pack); + Str::copy(InterWarehouse::get_text(warehouse, FID), file_as_text); + inter_tree_node *P = Inode::new_with_4_data_fields(IBM, INSERT_IST, + /* TEXT_INSERT_IFLD: */ ID, + /* REPLACING_INSERT_IFLD: */ RID, + /* PROVENANCEFILE_INSERT_IFLD: */ FID, + /* PROVENANCELINE_INSERT_IFLD: */ line_number, eloc, level); inter_error_message *E = VerifyingInter::instruction(pack, P); if (E) return E; NodePlacement::move_to_moving_bookmark(P, IBM); @@ -56,7 +65,9 @@ void InsertInstruction::verify(inter_construct *IC, inter_tree_node *P, inter_package *owner, inter_error_message **E) { *E = VerifyingInter::text_field(owner, P, TEXT_INSERT_IFLD); if (*E) return; - *E = VerifyingInter::text_field(owner, P, REPLACING_IFLD); + *E = VerifyingInter::text_field(owner, P, REPLACING_INSERT_IFLD); + if (*E) return; + *E = VerifyingInter::text_field(owner, P, PROVENANCEFILE_INSERT_IFLD); if (*E) return; } @@ -67,15 +78,27 @@ void InsertInstruction::read(inter_construct *IC, inter_bookmark *IBM, inter_lin inter_error_location *eloc, inter_error_message **E) { text_stream *rq = ilp->mr.exp[0]; text_stream *repq = ilp->mr.exp[1]; + text_stream *fn = ilp->mr.exp[2]; + text_stream *lc = ilp->mr.exp[3]; TEMPORARY_TEXT(raw) TEMPORARY_TEXT(replacing) + TEMPORARY_TEXT(file_as_text) *E = TextualInter::parse_literal_text(raw, rq, 0, Str::len(rq), eloc); if (*E == NULL) *E = TextualInter::parse_literal_text(replacing, repq, 0, Str::len(repq), eloc); if (*E == NULL) - *E = InsertInstruction::new(IBM, raw, replacing, (inter_ti) ilp->indent_level, eloc); + *E = TextualInter::parse_literal_text(file_as_text, fn, 0, Str::len(fn), eloc); + if (*E == NULL) { + filename *F = NULL; + if (Str::len(file_as_text) > 0) F = Filenames::from_text(file_as_text); + inter_ti line_number = 0; + if (Str::len(lc) > 0) line_number = (inter_ti) Str::atoi(lc, 0); + *E = InsertInstruction::new(IBM, raw, replacing, F, line_number, + (inter_ti) ilp->indent_level, eloc); + } DISCARD_TEXT(raw) DISCARD_TEXT(replacing) + DISCARD_TEXT(file_as_text) } @h Writing to textual Inter syntax. @@ -88,9 +111,12 @@ void InsertInstruction::write(inter_construct *IC, OUTPUT_STREAM, inter_tree_nod TextualInter::write_text(OUT, insertion); WRITE(" "); TextualInter::write_text(OUT, replacing); + WRITE(" "); + TextualInter::write_text(OUT, InsertInstruction::file_provenance(P)); + WRITE(" %d", InsertInstruction::line_provenance(P)); } -@h Access function. +@h Access functions. = text_stream *InsertInstruction::insertion(inter_tree_node *P) { @@ -102,5 +128,17 @@ text_stream *InsertInstruction::insertion(inter_tree_node *P) { text_stream *InsertInstruction::replacing(inter_tree_node *P) { if (P == NULL) return NULL; if (Inode::isnt(P, INSERT_IST)) return NULL; - return Inode::ID_to_text(P, P->W.instruction[REPLACING_IFLD]); + return Inode::ID_to_text(P, P->W.instruction[REPLACING_INSERT_IFLD]); +} + +text_stream *InsertInstruction::file_provenance(inter_tree_node *P) { + if (P == NULL) return NULL; + if (Inode::isnt(P, INSERT_IST)) return NULL; + return Inode::ID_to_text(P, P->W.instruction[PROVENANCEFILE_INSERT_IFLD]); +} + +inter_ti InsertInstruction::line_provenance(inter_tree_node *P) { + if (P == NULL) return 0; + if (Inode::isnt(P, INSERT_IST)) return 0; + return P->W.instruction[PROVENANCELINE_INSERT_IFLD]; } diff --git a/inter/bytecode-module/Chapter 5/The Splat Construct.w b/inter/bytecode-module/Chapter 5/The Splat Construct.w index 3c5d47349..4858af037 100644 --- a/inter/bytecode-module/Chapter 5/The Splat Construct.w +++ b/inter/bytecode-module/Chapter 5/The Splat Construct.w @@ -9,7 +9,7 @@ For what this does and why it is used, see //inter: Textual Inter//. void SplatInstruction::define_construct(void) { inter_construct *IC = InterInstruction::create_construct(SPLAT_IST, I"splat"); InterInstruction::specify_syntax(IC, I"splat OPTIONALIDENTIFIER TEXT TEXT TEXT"); - InterInstruction::data_extent_always(IC, 4); + InterInstruction::data_extent_always(IC, 6); InterInstruction::allow_in_depth_range(IC, 0, INFINITELY_DEEP); InterInstruction::permit(IC, OUTSIDE_OF_PACKAGES_ICUP); InterInstruction::permit(IC, INSIDE_PLAIN_PACKAGE_ICUP); @@ -24,23 +24,31 @@ void SplatInstruction::define_construct(void) { In bytecode, the frame of a |splat| instruction is laid out with the compulsory words -- see //Inter Nodes// -- followed by: -@d MATTER_SPLAT_IFLD (DATA_IFLD + 0) -@d PLM_SPLAT_IFLD (DATA_IFLD + 1) -@d I6ANNOTATION_SPLAT_IFLD (DATA_IFLD + 2) -@d NAMESPACE_SPLAT_IFLD (DATA_IFLD + 3) +@d MATTER_SPLAT_IFLD (DATA_IFLD + 0) +@d PLM_SPLAT_IFLD (DATA_IFLD + 1) +@d I6ANNOTATION_SPLAT_IFLD (DATA_IFLD + 2) +@d NAMESPACE_SPLAT_IFLD (DATA_IFLD + 3) +@d PROVENANCEFILE_SPLAT_IFLD (DATA_IFLD + 4) +@d PROVENANCELINE_SPLAT_IFLD (DATA_IFLD + 5) = inter_error_message *SplatInstruction::new(inter_bookmark *IBM, text_stream *splatter, - inter_ti plm, text_stream *annotation, text_stream *namespace, inter_ti level, - inter_error_location *eloc) { - inter_tree_node *P = Inode::new_with_4_data_fields(IBM, SPLAT_IST, + inter_ti plm, text_stream *annotation, text_stream *namespace, + filename *file, inter_ti line_number, inter_ti level, inter_error_location *eloc) { + TEMPORARY_TEXT(file_as_text) + if (file) WRITE_TO(file_as_text, "%f", file); + inter_tree_node *P = Inode::new_with_6_data_fields(IBM, SPLAT_IST, /* MATTER_SPLAT_IFLD: */ InterWarehouse::create_text_at(IBM, splatter), /* PLM_SPLAT_IFLD: */ plm, /* I6ANNOTATION_SPLAT_IFLD: */ (Str::len(annotation) > 0)?(InterWarehouse::create_text_at(IBM, annotation)):0, /* NAMESPACE_SPLAT_IFLD: */ (Str::len(namespace) > 0)?(InterWarehouse::create_text_at(IBM, namespace)):0, + /* PROVENANCEFILE_SPLAT_IFLD: */ + (Str::len(file_as_text) > 0)?(InterWarehouse::create_text_at(IBM, file_as_text)):0, + /* PROVENANCELINE_SPLAT_IFLD: */ line_number, eloc, level); + DISCARD_TEXT(file_as_text) inter_error_message *E = VerifyingInter::instruction(InterBookmark::package(IBM), P); if (E) return E; NodePlacement::move_to_moving_bookmark(P, IBM); @@ -93,7 +101,14 @@ void SplatInstruction::read(inter_construct *IC, inter_bookmark *IBM, if (*E == NULL) { *E = TextualInter::parse_literal_text(raw_ns, namespace_text, 0, Str::len(annot_text), eloc); if (*E == NULL) { - *E = SplatInstruction::new(IBM, raw, plm, raw_annot, raw_ns, (inter_ti) ilp->indent_level, eloc); + filename *F = NULL; + inter_ti lc = 0; + if (eloc) { + F = eloc->error_tfp->text_file_filename; + lc = (inter_ti) eloc->error_tfp->line_count; + } + *E = SplatInstruction::new(IBM, raw, plm, raw_annot, raw_ns, F, lc, + (inter_ti) ilp->indent_level, eloc); } } } @@ -142,6 +157,18 @@ text_stream *SplatInstruction::namespace(inter_tree_node *P) { return Inode::ID_to_text(P, P->W.instruction[NAMESPACE_SPLAT_IFLD]); } +text_stream *SplatInstruction::file_provenance(inter_tree_node *P) { + if (P == NULL) return NULL; + if (Inode::isnt(P, SPLAT_IST)) return NULL; + return Inode::ID_to_text(P, P->W.instruction[PROVENANCEFILE_SPLAT_IFLD]); +} + +inter_ti SplatInstruction::line_provenance(inter_tree_node *P) { + if (P == NULL) return 0; + if (Inode::isnt(P, SPLAT_IST)) return 0; + return P->W.instruction[PROVENANCELINE_SPLAT_IFLD]; +} + @h PLMs. At some point PLM stood for something, but what it was is now forgotten -- perhaps "parse linked matter"? -- so it is now a nonsense-word pronounced diff --git a/inter/pipeline-module/Chapter 2/Pipeline Errors.w b/inter/pipeline-module/Chapter 2/Pipeline Errors.w index ae53279cf..2094dd602 100644 --- a/inter/pipeline-module/Chapter 2/Pipeline Errors.w +++ b/inter/pipeline-module/Chapter 2/Pipeline Errors.w @@ -139,33 +139,39 @@ power tools just lying around, people will eventually pick them up and wonder what the red button marked "danger" does. = -int pipeline_error_count = 0; +int kit_error_count = 0; +text_stream *kit_error_filename = NULL; +int kit_error_line_number = 0; + +void PipelineErrors::set_kit_error_location(text_stream *file, inter_ti line) { + kit_error_filename = file; + kit_error_line_number = (int) line; +} void PipelineErrors::kit_error(char *message, text_stream *quote) { - #ifdef PROBLEMS_MODULE - TEMPORARY_TEXT(M) - WRITE_TO(M, message, quote); - Problems::quote_stream(1, M); - StandardProblems::handmade_problem(Task::syntax_tree(), _p_(...)); - Problems::issue_problem_segment( - "My low-level reader of source code reported a mistake - \"%1\". " - "%PLow-level material written in Inform 6 syntax occurs either in kits or " - "in matter written inside 'Include (- ... -)' in source text, either in " - "the main source or in an extension used by it."); - Problems::issue_problem_end(); - DISCARD_TEXT(M) + #ifdef CORE_MODULE + SourceProblems::I6_level_error(message, quote, kit_error_filename, + kit_error_line_number); #endif - #ifndef PROBLEMS_MODULE - Errors::with_text(message, quote); + #ifndef CORE_MODULE + if (Str::len(kit_error_filename) > 0) { + filename *F = Filenames::from_text(kit_error_filename); + TEMPORARY_TEXT(M) + WRITE_TO(M, message, quote); + Errors::at_position_S(M, F, kit_error_line_number); + DISCARD_TEXT(M) + } else { + Errors::with_text(message, quote); + } #endif - pipeline_error_count++; + kit_error_count++; } void PipelineErrors::reset_errors(void) { - pipeline_error_count = 0; + kit_error_count = 0; } int PipelineErrors::errors_occurred(void) { - if (pipeline_error_count != 0) return TRUE; + if (kit_error_count != 0) return TRUE; return FALSE; } diff --git a/inter/pipeline-module/Chapter 3/Compile Splats Stage.w b/inter/pipeline-module/Chapter 3/Compile Splats Stage.w index 561912b75..54c3fe6bc 100644 --- a/inter/pipeline-module/Chapter 3/Compile Splats Stage.w +++ b/inter/pipeline-module/Chapter 3/Compile Splats Stage.w @@ -31,14 +31,17 @@ void CompileSplatsStage::create_pipeline_stage(void) { = int CompileSplatsStage::run(pipeline_step *step) { PipelineErrors::reset_errors(); + PipelineErrors::set_kit_error_location(NULL, 0); compile_splats_state css; @; inter_tree *I = step->ephemera.tree; InterTree::traverse(I, CompileSplatsStage::visitor1, &css, NULL, SPLAT_IST); InterTree::traverse(I, CompileSplatsStage::visitor2, &css, NULL, 0); + PipelineErrors::set_kit_error_location(NULL, 0); int errors_found = CompileSplatsStage::function_bodies(step, &css, I); if (errors_found) return FALSE; InterTree::traverse(I, CompileSplatsStage::visitor3, &css, NULL, SPLAT_IST); + PipelineErrors::set_kit_error_location(NULL, 0); if (PipelineErrors::errors_occurred()) return FALSE; return TRUE; } @@ -134,6 +137,11 @@ void CompileSplatsStage::visitor3(inter_tree *I, inter_tree_node *P, void *state @h How definitions are assimilated. @ = + if (SplatInstruction::line_provenance(P) > 0) + PipelineErrors::set_kit_error_location( + SplatInstruction::file_provenance(P), SplatInstruction::line_provenance(P)); + else + PipelineErrors::set_kit_error_location(NULL, 0); match_results mr = Regexp::create_mr(); text_stream *raw_identifier = NULL, *value = NULL; int proceed = TRUE; @@ -702,6 +710,11 @@ We are concerned more with the surround than with the contents of the function in this section. @ = + if (SplatInstruction::line_provenance(P) > 0) + PipelineErrors::set_kit_error_location( + SplatInstruction::file_provenance(P), SplatInstruction::line_provenance(P)); + else + PipelineErrors::set_kit_error_location(NULL, 0); text_stream *raw_identifier = NULL, *local_var_names = NULL, *body = NULL; match_results mr = Regexp::create_mr(); if (SplatInstruction::plm(P) == ROUTINE_PLM) @; diff --git a/inter/pipeline-module/Chapter 3/Parsing Stages.w b/inter/pipeline-module/Chapter 3/Parsing Stages.w index f1426c9ad..4d0d54a3a 100644 --- a/inter/pipeline-module/Chapter 3/Parsing Stages.w +++ b/inter/pipeline-module/Chapter 3/Parsing Stages.w @@ -94,6 +94,8 @@ void ParsingStages::visit_insertions(inter_tree *I, inter_tree_node *P, void *st inter_bookmark here = InterBookmark::after_this_node(P); rpi_docket_state *docket_state = (rpi_docket_state *) docket->state; docket_state->assimilation_point = &here; + docket_state->file_provenance = InsertInstruction::file_provenance(P); + docket_state->line_provenance = InsertInstruction::line_provenance(P); SimpleTangler::tangle_text(docket, insertion); text_stream *replacing = InsertInstruction::replacing(P); if (Str::len(replacing) > 0) { @@ -119,6 +121,8 @@ in |K/Sections|. typedef struct rpi_docket_state { struct inter_bookmark *assimilation_point; struct text_stream *namespace; + struct text_stream *file_provenance; + inter_ti line_provenance; } rpi_docket_state; @ = @@ -130,10 +134,13 @@ typedef struct rpi_docket_state { rpi_docket_state state; state.assimilation_point = &assimilation_point; state.namespace = namespacename; + state.file_provenance = NULL; + state.line_provenance = 0; docket = SimpleTangler::new_docket( &(ParsingStages::receive_raw), &(ParsingStages::receive_command), &(ParsingStages::receive_bplus), + &(ParsingStages::line_marker), &(PipelineErrors::kit_error), step->ephemera.the_kit, &state); @@ -191,6 +198,13 @@ void ParsingStages::receive_bplus(text_stream *material, simple_tangle_docket *d "use of (+ ... +) in kit source has been withdrawn: '%S'", material); } +@ This is used to place I6 comments showing the provenance of the tangled text: + += +void ParsingStages::line_marker(text_stream *material, simple_tangle_docket *docket) { + WRITE_TO(material, "! LINEMARKER %d %f\n", docket->current_start_line, docket->current_filename); +} + @ We very much do not ignore the raw I6 code read in, though. When the reader gives us a chunk of this, we parse through it with a simple finite-state machine. This can be summarised as "divide the code up at |;| boundaries, sending each @@ -227,9 +241,29 @@ and void ParsingStages::receive_raw(text_stream *S, simple_tangle_docket *docket) { text_stream *R = Str::new(); int mode = IGNORE_WS_I6TBIT; - LOOP_THROUGH_TEXT(pos, S) { - wchar_t c = Str::get(pos); - if ((c == 10) || (c == 13)) c = '\n'; + rpi_docket_state *state = (rpi_docket_state *) docket->state; + inter_ti lc = state->line_provenance; + for (int pos = 0; pos < Str::len(S); pos++) { + wchar_t c = Str::get_at(S, pos); + if ((c == 10) || (c == 13)) { c = '\n'; lc++; } + if ((c == '!') && (Str::includes_at(S, pos, I"! LINEMARKER "))) { + text_stream *file_text = Str::new(); + TEMPORARY_TEXT(number_text) + int in_number = TRUE; + for (pos = pos + 13; pos < Str::len(S); pos++) { + wchar_t c = Str::get_at(S, pos); + if ((c == 10) || (c == 13)) break; + if ((c == ' ') && (in_number)) { in_number = FALSE; continue; } + if (in_number) PUT_TO(number_text, c); + else PUT_TO(file_text, c); + } + state->line_provenance = (inter_ti) Str::atoi(number_text, 0); + lc = state->line_provenance; + state->file_provenance = file_text; + LOG("Spotted %d and <%S>\n", state->line_provenance, state->file_provenance); + DISCARD_TEXT(number_text) + continue; + } if (mode & IGNORE_WS_I6TBIT) { if ((c == '\n') || (Characters::is_whitespace(c))) continue; mode -= IGNORE_WS_I6TBIT; @@ -269,10 +303,12 @@ void ParsingStages::receive_raw(text_stream *S, simple_tangle_docket *docket) { PUT_TO(R, c); if ((c == ';') && (!(mode & SUBORDINATE_I6TBITS))) { ParsingStages::splat(R, docket); + state->line_provenance = lc; mode = IGNORE_WS_I6TBIT; } } ParsingStages::splat(R, docket); + state->line_provenance = lc; Str::clear(S); } @@ -294,8 +330,17 @@ void ParsingStages::splat(text_stream *R, simple_tangle_docket *docket) { rpi_docket_state *state = (rpi_docket_state *) docket->state; inter_bookmark *IBM = state->assimilation_point; PUT_TO(R, '\n'); + filename *F = NULL; + inter_ti lc = 0; + if (Str::len(state->file_provenance) > 0) { + F = Filenames::from_text(state->file_provenance); + lc = state->line_provenance + 1; + } else if (docket->current_filename) { + F = docket->current_filename; + lc = 25; + } Produce::guard(SplatInstruction::new(IBM, R, I6_dir, A, state->namespace, - (inter_ti) (InterBookmark::baseline(IBM) + 1), NULL)); + F, lc, (inter_ti) (InterBookmark::baseline(IBM) + 1), NULL)); } else if (A) { I6_annotation *IA = I6Annotations::parse(A); if ((IA) && (Str::eq_insensitive(IA->identifier, I"namespace"))) { diff --git a/services/problems-module/Chapter 2/Problems, Level 1.w b/services/problems-module/Chapter 2/Problems, Level 1.w index 8624295fa..bb5338a4b 100644 --- a/services/problems-module/Chapter 2/Problems, Level 1.w +++ b/services/problems-module/Chapter 2/Problems, Level 1.w @@ -94,6 +94,31 @@ void ProblemBuffer::copy_source_reference(wording W) { DISCARD_TEXT(file) } +void ProblemBuffer::copy_file_reference(text_stream *file_ref, int line) { + TEMPORARY_TEXT(file) + WRITE_TO(file, "%S", file_ref); + pathname *proj = HTML::get_link_abbreviation_path(); + if (proj) { + TEMPORARY_TEXT(project_prefix) + WRITE_TO(project_prefix, "%p", proj); + if (Str::prefix_eq(file, project_prefix, Str::len(project_prefix))) + Str::delete_n_characters(file, Str::len(project_prefix)); + DISCARD_TEXT(project_prefix) + } else { + WRITE_TO(file, "(no file)"); + } + text_stream *paraphrase = file; + #ifdef DESCRIBE_SOURCE_FILE_PROBLEMS_CALLBACK + paraphrase = DESCRIBE_SOURCE_FILE_PROBLEMS_CALLBACK(paraphrase, NULL, file); + #endif + WRITE_TO(PBUFF, " %c%S%c%S%c%d%c", + SOURCE_REF_CHAR, paraphrase, + SOURCE_REF_CHAR, file, + SOURCE_REF_CHAR, line, + SOURCE_REF_CHAR); + DISCARD_TEXT(file) +} + @ Once the error message is fully constructed, we will want to output it to a file: in fact, by default it will go in three directions, to |stderr|, to the debugging log and of course to the problems file. The main diff --git a/services/problems-module/Chapter 2/Problems, Level 2.w b/services/problems-module/Chapter 2/Problems, Level 2.w index 5294ebf95..98ed9d742 100644 --- a/services/problems-module/Chapter 2/Problems, Level 2.w +++ b/services/problems-module/Chapter 2/Problems, Level 2.w @@ -82,7 +82,7 @@ void Problems::show_problem_location(parse_node_tree *T) { #endif for (i=0; i 10)) internal_error("problem quotation number out of range"); + problem_quotations[t].structure_quoted = NULL; + problem_quotations[t].quotation_type = 'F'; + problem_quotations[t].wording_based = FALSE; + problem_quotations[t].text_quoted = EMPTY_WORDING; + problem_quotations[t].file = Str::duplicate(file); + problem_quotations[t].line = line; } @ Here are the three public routines for quoting from text: either via a node @@ -317,7 +335,7 @@ void Problems::issue_problem_begin(parse_node_tree *T, char *message) { } else if (strcmp(message, "**") == 0) { this_is_a_subsequent_use_of_problem = FALSE; } else { - if (T) Problems::show_problem_location(T); + Problems::show_problem_location(T); problem_count++; WRITE_TO(PBUFF, ">--> "); this_is_a_subsequent_use_of_problem = @@ -402,7 +420,9 @@ on when the shortened form is the one being issued). if (Characters::isdigit((wchar_t) message[i+1])) { int t = ((int) (message[i+1]))-((int) '0'); i++; if ((t>=1) && (t<=9)) { - if (problem_quotations[t].wording_based) + if (problem_quotations[t].quotation_type == 'F') + @ + else if (problem_quotations[t].wording_based) @ else @ @@ -412,6 +432,11 @@ on when the shortened form is the one being issued). } PUT_TO(PBUFF, message[i]); +@ This is where there is an explicit reference to a filename and line number. + +@ = + ProblemBuffer::copy_file_reference(problem_quotations[t].file, problem_quotations[t].line); + @ This is where a quotation escape, such as |%2|, is expanded: by looking up its type, stored internally as a single character. diff --git a/services/words-module/Chapter 3/Lexer.w b/services/words-module/Chapter 3/Lexer.w index 2356b556c..090213517 100644 --- a/services/words-module/Chapter 3/Lexer.w +++ b/services/words-module/Chapter 3/Lexer.w @@ -421,6 +421,10 @@ source_file *Lexer::file_of_origin(int wn) { return lw_array[wn].lw_source.file_of_origin; } +int Lexer::line_of_origin(int wn) { + return lw_array[wn].lw_source.line_number; +} + source_location Lexer::word_location(int wn) { if (wn < 0) { source_location nowhere; From 8aa902ce50a13daa1927fcd712b580552406070f Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Wed, 26 Apr 2023 23:11:43 +0100 Subject: [PATCH 014/113] More on schema error reporting --- README.md | 2 +- build.txt | 4 +- docs/building-module/2-is.html | 77 +- docs/building-module/2-pis.html | 16 +- docs/building-module/2-rmf.html | 87 +- docs/building-module/2-tkn.html | 18 +- docs/building-module/P-wtmd.html | 2 +- docs/building-test/1-ut.html | 3 +- docs/bytecode-module/3-ic.html | 2 +- docs/bytecode-module/3-idt.html | 2 +- docs/bytecode-module/3-ie.html | 2 +- docs/bytecode-module/3-iibf.html | 2 +- docs/bytecode-module/3-iitf.html | 4 +- docs/bytecode-module/3-ivp.html | 2 +- docs/bytecode-module/3-mtd.html | 2 +- docs/bytecode-module/3-tp.html | 151 + docs/bytecode-module/3-vi.html | 2 +- docs/bytecode-module/4-tcc.html | 2 +- docs/bytecode-module/4-tic.html | 19 +- docs/bytecode-module/5-tsc.html | 16 +- docs/bytecode-module/index.html | 5 + docs/core-module/2-pwst.html | 31 +- docs/imperative-module/3-cid.html | 3 +- docs/pipeline-module/2-pe.html | 41 +- docs/pipeline-module/3-css.html | 32 +- docs/pipeline-module/3-ps.html | 39 +- inform7/Figures/memory-diagnostics.txt | 34 +- inform7/Figures/timings-diagnostics.txt | 62 +- .../BasicInformExtrasKit/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 +- .../Chapter 2/Problems With Source Text.w | 31 +- .../Compile Imperative Definitions.w | 3 +- inter/Tests/Kits/_Results_Ideal/BadKit.txt | 42 +- .../building-module/Chapter 2/Inter Schemas.w | 41 +- .../Chapter 2/Parsing Inter Schemas.w | 16 +- .../building-module/Chapter 2/Ramification.w | 87 +- .../building-module/Chapter 2/Tokenisation.w | 18 +- .../Preliminaries/What This Module Does.w | 2 +- inter/building-test/Chapter 1/Unit Tests.w | 3 +- .../Tests/Test Cases/_Results_Ideal/exp.txt | 806 ++-- .../Test Cases/_Results_Ideal/schemas.txt | 3508 ++++++++--------- .../Chapter 3/Text Provenance.w | 77 + .../Chapter 4/The Insert Construct.w | 19 +- .../Chapter 5/The Splat Construct.w | 16 +- inter/bytecode-module/Contents.w | 1 + .../Chapter 2/Pipeline Errors.w | 35 +- .../Chapter 3/Compile Splats Stage.w | 32 +- .../Chapter 3/Parsing Stages.w | 39 +- 51 files changed, 2885 insertions(+), 2563 deletions(-) create mode 100644 docs/bytecode-module/3-tp.html create mode 100644 inter/bytecode-module/Chapter 3/Text Provenance.w diff --git a/README.md b/README.md index 1cbd09bb8..8b77771e3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inform 7 -[Version](notes/versioning.md): 10.2.0-beta+6W37 'Krypton' (25 April 2023) +[Version](notes/versioning.md): 10.2.0-beta+6W38 'Krypton' (26 April 2023) ## About Inform diff --git a/build.txt b/build.txt index 69d40f175..e6af5567c 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: beta -Build Date: 25 April 2023 -Build Number: 6W37 +Build Date: 26 April 2023 +Build Number: 6W38 diff --git a/docs/building-module/2-is.html b/docs/building-module/2-is.html index 50a075944..a44b5b6be 100644 --- a/docs/building-module/2-is.html +++ b/docs/building-module/2-is.html @@ -77,6 +77,7 @@ few hundred — so they do not need to be stored compactly or compiled quick int mid_case; does this seem to be used inside a switch case? int dereference_mode; emit from this in dereference-pointers mode struct linked_list *parsing_errors; of schema_parsing_error + struct text_provenance provenance; CLASS_DEFINITION } inter_schema; @@ -84,13 +85,14 @@ few hundred — so they do not need to be stored compactly or compiled quick

§2.

-inter_schema *InterSchemas::new(text_stream *source) {
+inter_schema *InterSchemas::new(text_stream *source, text_provenance provenance) {
     inter_schema *sch = CREATE(inter_schema);
     sch->converted_from = Str::duplicate(source);
     sch->node_tree = NULL;
     sch->mid_case = FALSE;
     sch->dereference_mode = FALSE;
     sch->parsing_errors = NULL;
+    sch->provenance = provenance;
     return sch;
 }
 
@@ -132,6 +134,7 @@ we now more efficiently remove them.) int blocked_by_conditional; used in code generation + struct text_provenance provenance; used for error reporting CLASS_DEFINITION } inter_schema_node; @@ -139,7 +142,8 @@ we now more efficiently remove them.)

§4.

-inter_schema_node *InterSchemas::new_node(inter_schema *sch, int isnt) {
+inter_schema_node *InterSchemas::new_node(inter_schema *sch, int isnt,
+    inter_schema_token *near_here) {
     inter_schema_node *isn = CREATE(inter_schema_node);
     isn->parent_schema = sch;
 
@@ -159,6 +163,17 @@ we now more efficiently remove them.)
     isn->unopened = FALSE;
     isn->blocked_by_conditional = FALSE;
 
+    isn->provenance = (sch)?(sch->provenance):(Provenance::nowhere());
+    if ((near_here) && (Provenance::is_somewhere(isn->provenance)))
+        Provenance::set_line(&(isn->provenance),
+            Provenance::get_line(isn->provenance) + near_here->line_offset);
+    return isn;
+}
+
+inter_schema_node *InterSchemas::new_node_near_node(inter_schema *sch, int isnt,
+    inter_schema_node *near_here) {
+    inter_schema_node *isn = InterSchemas::new_node(sch, isnt, NULL);
+    if (near_here) isn->provenance = near_here->provenance;
     return isn;
 }
 
@@ -194,7 +209,7 @@ upwards.

-void InterSchemas::mark_unclosed(inter_schema_node *isn) {
+void InterSchemas::mark_unclosed(inter_schema_node *isn) {
     while (isn) {
         if (isn->isn_type == CODE_ISNT) isn->unclosed = TRUE;
         isn = isn->parent_node;
@@ -207,7 +222,7 @@ at the top of the tree to serve that role.
 

-void InterSchemas::mark_unopened(inter_schema_node *isn) {
+void InterSchemas::mark_unopened(inter_schema_node *isn) {
     while (isn) {
         if (isn->isn_type == CODE_ISNT) {
             isn->unopened = TRUE;
@@ -217,7 +232,7 @@ at the top of the tree to serve that role.
             inter_schema *sch = isn->parent_schema;
             inter_schema_node *top = sch->node_tree;
             inter_schema_node *code_isn =
-                InterSchemas::new_node(isn->parent_schema, CODE_ISNT);
+                InterSchemas::new_node(isn->parent_schema, CODE_ISNT, NULL);
             code_isn->child_node = top;
             sch->node_tree = code_isn;
             for (inter_schema_node *n = top; n; n = n->next_node)
@@ -243,7 +258,7 @@ associate this with any single node, so we mark the schema as a whole.
 

-void InterSchemas::mark_case_closed(inter_schema_node *isn) {
+void InterSchemas::mark_case_closed(inter_schema_node *isn) {
     if (isn) isn->parent_schema->mid_case = TRUE;
 }
 
@@ -313,7 +328,7 @@ compilation process, and never survive into the final schema: int preinsert; fleeting markers only int postinsert; - + int line_offset; counting lines for error message use CLASS_DEFINITION } inter_schema_token;
@@ -321,8 +336,8 @@ compilation process, and never survive into the final schema:

§10.

-inter_schema_token *InterSchemas::new_token(int type, text_stream *material,
-    inter_ti operation_primitive, int reserved_word, int n) {
+inter_schema_token *InterSchemas::new_token(int type, text_stream *material,
+    inter_ti operation_primitive, int reserved_word, int n, int offset) {
     inter_schema_token *t = CREATE(inter_schema_token);
     t->ist_type = type;
     t->material = Str::duplicate(material);
@@ -344,6 +359,7 @@ compilation process, and never survive into the final schema:
     t->constant_number = n;
     t->preinsert = FALSE;
     t->postinsert = FALSE;
+    t->line_offset = offset;
     return t;
 }
 
@@ -459,13 +475,13 @@ compilation process, and never survive into the final schema:

§14. Token insertion.

-void InterSchemas::add_token(inter_schema *sch, inter_schema_token *t) {
+void InterSchemas::add_token(inter_schema *sch, inter_schema_token *t) {
     if (sch->node_tree == NULL)
-        sch->node_tree = InterSchemas::new_node(sch, EXPRESSION_ISNT);
+        sch->node_tree = InterSchemas::new_node(sch, EXPRESSION_ISNT, t);
     InterSchemas::add_token_to_node(sch->node_tree, t);
 }
 
-void InterSchemas::add_token_to_node(inter_schema_node *isn, inter_schema_token *t) {
+void InterSchemas::add_token_to_node(inter_schema_node *isn, inter_schema_token *t) {
     if (isn->expression_tokens == NULL) isn->expression_tokens = t;
     else {
         inter_schema_token *p = isn->expression_tokens;
@@ -475,7 +491,7 @@ compilation process, and never survive into the final schema:
     t->owner = isn;
 }
 
-void InterSchemas::add_token_after(inter_schema_token *t, inter_schema_token *existing) {
+void InterSchemas::add_token_after(inter_schema_token *t, inter_schema_token *existing) {
     if (existing == NULL) internal_error("can't add after null element");
     inter_schema_token *was = existing->next;
     existing->next = t;
@@ -487,7 +503,7 @@ compilation process, and never survive into the final schema:
 

-void InterSchemas::changed_tokens_on(inter_schema_node *isn) {
+void InterSchemas::changed_tokens_on(inter_schema_node *isn) {
     if (isn)
         for (inter_schema_token *l = isn->expression_tokens; l; l=l->next)
             l->owner = isn;
@@ -497,33 +513,33 @@ compilation process, and never survive into the final schema:
 

-int InterSchemas::opening_reserved_word(inter_schema_node *node) {
+int InterSchemas::opening_reserved_word(inter_schema_node *node) {
     inter_schema_token *f = InterSchemas::first_dark_token(node);
     if ((f) && (f->ist_type == RESERVED_ISTT)) return f->reserved_word;
     return 0;
 }
 
-int InterSchemas::opening_directive_word(inter_schema_node *node) {
+int InterSchemas::opening_directive_word(inter_schema_node *node) {
     inter_schema_token *f = InterSchemas::first_dark_token(node);
     if ((f) && (f->ist_type == DIRECTIVE_ISTT)) return f->reserved_word;
     return 0;
 }
 
-inter_schema_token *InterSchemas::first_dark_token(inter_schema_node *node) {
+inter_schema_token *InterSchemas::first_dark_token(inter_schema_node *node) {
     if (node == NULL) return NULL;
     inter_schema_token *n = node->expression_tokens;
     while ((n) && (n->ist_type == WHITE_SPACE_ISTT)) n = n->next;
     return n;
 }
 
-inter_schema_token *InterSchemas::next_dark_token(inter_schema_token *t) {
+inter_schema_token *InterSchemas::next_dark_token(inter_schema_token *t) {
     if (t == NULL) return NULL;
     inter_schema_token *n = t->next;
     while ((n) && (n->ist_type == WHITE_SPACE_ISTT)) n = n->next;
     return n;
 }
 
-inter_schema_token *InterSchemas::second_dark_token(inter_schema_node *node) {
+inter_schema_token *InterSchemas::second_dark_token(inter_schema_node *node) {
     return InterSchemas::next_dark_token(InterSchemas::first_dark_token(node));
 }
 
@@ -532,7 +548,7 @@ we go to some trouble here.

-void InterSchemas::log(OUTPUT_STREAM, void *vis) {
+void InterSchemas::log(OUTPUT_STREAM, void *vis) {
     inter_schema *sch = (inter_schema *) vis;
     if (sch == NULL) LOG("<null schema>\n");
     else if (sch->node_tree == NULL) LOG("<schema without nodes>\n");
@@ -543,7 +559,12 @@ we go to some trouble here.
     for (; isn; isn=isn->next_node)
         InterSchemas::log_just(isn, depth);
 }
-void InterSchemas::log_just(inter_schema_node *isn, int depth) {
+void InterSchemas::log_just(inter_schema_node *isn, int depth) {
+    if (Provenance::is_somewhere(isn->provenance)) {
+        LOG("%04d ", Provenance::get_line(isn->provenance));
+    } else {
+        LOG(".... ");
+    }
     if (isn->blocked_by_conditional) LOG("XX"); else LOG("  ");
     for (int d = 0; d < depth; d++) LOG("    ");
     switch (isn->isn_type) {
@@ -659,7 +680,7 @@ where the check is done:
 

-void InterSchemas::lint(inter_schema *sch) {
+void InterSchemas::lint(inter_schema *sch) {
     if ((sch) && (sch->parsing_errors == NULL)) {
         text_stream *err = InterSchemas::lint_isn(sch->node_tree, 0);
         if (err) {
@@ -727,6 +748,7 @@ which, of course, it usually isn't.
 
 typedef struct schema_parsing_error {
     struct text_stream *message;
+    struct text_provenance provenance;
     CLASS_DEFINITION
 } schema_parsing_error;
 
@@ -734,11 +756,18 @@ which, of course, it usually isn't.

§20.

-void InterSchemas::throw_error(inter_schema_node *at, text_stream *message) {
+void InterSchemas::throw_error(inter_schema_node *at, text_stream *message) {
     if (at->parent_schema->parsing_errors == NULL)
         at->parent_schema->parsing_errors = NEW_LINKED_LIST(schema_parsing_error);
     schema_parsing_error *err = CREATE(schema_parsing_error);
     err->message = Str::duplicate(message);
+    if (at) {
+        if (Provenance::is_somewhere(at->provenance)) err->provenance = at->provenance;
+        else if (at->parent_schema) err->provenance = at->parent_schema->provenance;
+        else err->provenance = Provenance::nowhere();
+    } else {
+        err->provenance = Provenance::nowhere();
+    }
     ADD_TO_LINKED_LIST(err, schema_parsing_error, at->parent_schema->parsing_errors);
     LOG("Schema error: %S\n", message);
     LOG("$1\n", at->parent_schema);
@@ -748,7 +777,7 @@ which, of course, it usually isn't.
 

-void InterSchemas::internal_error_on_schema_errors(inter_schema *sch) {
+void InterSchemas::internal_error_on_schema_errors(inter_schema *sch) {
     if (LinkedLists::len(sch->parsing_errors) > 0) {
         #ifdef CORE_MODULE
         SourceProblems::inter_schema_errors(sch);
diff --git a/docs/building-module/2-pis.html b/docs/building-module/2-pis.html
index 6d8aba7d5..9dfd68559 100644
--- a/docs/building-module/2-pis.html
+++ b/docs/building-module/2-pis.html
@@ -74,8 +74,8 @@ samples produce the correct schemas.
 

-inter_schema *ParsingSchemas::from_text(text_stream *from) {
-    return ParsingSchemas::back_end(from, FALSE, 0, NULL);
+inter_schema *ParsingSchemas::from_text(text_stream *from, text_provenance provenance) {
+    return ParsingSchemas::back_end(from, FALSE, 0, NULL, provenance);
 }
 

§2. Abbreviated I6S notation. This is a slicker notation used inside the calculus module for purposes @@ -107,7 +107,7 @@ I6S code can only come from within the compiler itself, and means a bug. if (de) return (inter_schema *) Dictionaries::value_for_entry(de); inter_schema *result = ParsingSchemas::back_end(from, TRUE, - no_quoted_inames, quoted_inames); + no_quoted_inames, quoted_inames, Provenance::nowhere()); Dictionaries::create(i6s_inter_schema_cache, from); Dictionaries::write_value(i6s_inter_schema_cache, from, (void *) result); @@ -153,16 +153,16 @@ so it's the caller's responsibility to check for those and act accordingly.

 void ParsingSchemas::from_inline_phrase_definition(wchar_t *from, inter_schema **head,
-    inter_schema **tail) {
+    inter_schema **tail, text_provenance provenance) {
     *head = NULL; *tail = NULL;
 
     text_stream *head_defn = Str::new();
     text_stream *tail_defn = Str::new();
     Fetch the head and tail definitions4.1;
 
-    *head = ParsingSchemas::from_text(head_defn);
+    *head = ParsingSchemas::from_text(head_defn, provenance);
     if (Str::len(tail_defn) > 0)
-        *tail = ParsingSchemas::from_text(tail_defn);
+        *tail = ParsingSchemas::from_text(tail_defn, provenance);
 }
 

§4.1. A tail will only be present if the definition contains {-block}. If it @@ -231,8 +231,8 @@ such operations are nested, they will work. We might then write:

 inter_schema *ParsingSchemas::back_end(text_stream *from, int abbreviated,
-    int no_quoted_inames, void **quoted_inames) {
-    inter_schema *sch = InterSchemas::new(from);
+    int no_quoted_inames, void **quoted_inames, text_provenance provenance) {
+    inter_schema *sch = InterSchemas::new(from, provenance);
     if ((Log::aspect_switched_on(SCHEMA_COMPILATION_DA)) ||
         (Log::aspect_switched_on(SCHEMA_COMPILATION_DETAILS_DA)))
         LOG("\n\n------------\nCompiling inter schema from: <%S>\n", from);
diff --git a/docs/building-module/2-rmf.html b/docs/building-module/2-rmf.html
index 9e74435ad..ca65419fd 100644
--- a/docs/building-module/2-rmf.html
+++ b/docs/building-module/2-rmf.html
@@ -196,14 +196,14 @@ and inserts them around the single statements in question.
                 if ((prev) && (t->preinsert > 0)) {
                     t->preinsert--;
                     inter_schema_token *open_b =
-                        InterSchemas::new_token(OPEN_BRACE_ISTT, I"{", 0, 0, -1);
+                        InterSchemas::new_token(OPEN_BRACE_ISTT, I"{", 0, 0, -1, t->line_offset);
                     InterSchemas::add_token_after(open_b, prev);
                     changed = TRUE;
                 }
                 if (t->postinsert > 0) {
                     t->postinsert--;
                     inter_schema_token *close_b =
-                        InterSchemas::new_token(CLOSE_BRACE_ISTT, I"}", 0, 0, -1);
+                        InterSchemas::new_token(CLOSE_BRACE_ISTT, I"}", 0, 0, -1, t->line_offset);
                     InterSchemas::add_token_after(close_b, t);
                     changed = TRUE;
                 }
@@ -284,12 +284,12 @@ are removed.
             if ((prev) && (t->ist_type == OPEN_BRACE_ISTT)) {
                 prev->next = NULL;
                 inter_schema_node *code_isn =
-                    InterSchemas::new_node(isn->parent_schema, CODE_ISNT);
+                    InterSchemas::new_node(isn->parent_schema, CODE_ISNT, t);
                 isn->child_node = code_isn;
                 code_isn->parent_node = isn;
 
                 inter_schema_node *new_isn =
-                    InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+                    InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, t);
                 code_isn->child_node = new_isn;
                 new_isn->parent_node = code_isn;
 
@@ -319,7 +319,7 @@ are removed.
                         resumed = resumed->next;
                     if (resumed) {
                         inter_schema_node *new_isn =
-                            InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+                            InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, t);
                         new_isn->expression_tokens = resumed;
                         new_isn->parent_node = isn->parent_node;
                         InterSchemas::changed_tokens_on(new_isn);
@@ -374,7 +374,7 @@ We want to represent them, however, by independent subtrees. So:
             if (t->ist_type == CLOSE_ROUND_ISTT) bl--;
             if ((bl == 0) && (t->ist_type == DIVIDER_ISTT) && (t->next)) {
                 inter_schema_node *new_isn =
-                    InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+                    InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, t);
                 new_isn->expression_tokens = t->next;
                 new_isn->parent_node = isn->parent_node;
                 if (isn->child_node) {
@@ -482,7 +482,8 @@ of statements (or expressions), hierarchically arranged in code blocks.
             t->ist_type = WHITE_SPACE_ISTT;
             t->material = I" ";
             if (t->next) {
-                inter_schema_node *new_isn = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+                inter_schema_node *new_isn =
+                    InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, t);
                 new_isn->expression_tokens = t->next;
                 new_isn->parent_node = isn->parent_node;
                 if (isn->child_node) {
@@ -544,7 +545,7 @@ early commands off from the subsequent matter. Thus:
             }
             if ((m) && (n) && (n->ist_type == RESERVED_ISTT)) {
                 inter_schema_node *new_isn =
-                    InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+                    InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, n);
                 new_isn->expression_tokens = n;
                 new_isn->parent_node = isn->parent_node;
                 if (isn->child_node) {
@@ -643,12 +644,12 @@ We break this up as three code blocks:
                     inter_schema_node *sw_val = NULL;
                     inter_schema_node *sw_code = NULL;
                     if (defaulter) {
-                        sw_code = InterSchemas::new_node(isn->parent_schema, CODE_ISNT);
+                        sw_code = InterSchemas::new_node(isn->parent_schema, CODE_ISNT, n);
                         isn->child_node = sw_code;
                         sw_code->parent_node = isn;
                     } else {
-                        sw_val = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
-                        sw_code = InterSchemas::new_node(isn->parent_schema, CODE_ISNT);
+                        sw_val = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, n);
+                        sw_code = InterSchemas::new_node(isn->parent_schema, CODE_ISNT, n);
                         sw_val->next_node = sw_code;
                         sw_val->parent_node = isn; isn->child_node = sw_val;
                         sw_code->parent_node = isn;
@@ -683,7 +684,7 @@ We break this up as three code blocks:
                         isn->isn_clarifier = CASE_BIP;
 
                     inter_schema_node *sw_code_exp =
-                        InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+                        InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, n);
                     sw_code_exp->expression_tokens = n->next;
 
                     sw_code->child_node = sw_code_exp;
@@ -802,7 +803,7 @@ our work simpler to take one of those meanings out of the picture.
                         if (n->reserved_word == PRINT_I6RW) n->material = I"print";
                         else n->material = I"print_ret";
                         inter_schema_node *new_isn =
-                            InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+                            InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, n);
                         new_isn->expression_tokens = n;
                         new_isn->parent_node = isn->parent_node;
                         InterSchemas::changed_tokens_on(new_isn);
@@ -1136,13 +1137,13 @@ turned into function calls too, leaving:
 
     cons->expression_tokens = printing_rule;
     inter_schema_token *open_b =
-        InterSchemas::new_token(OPEN_ROUND_ISTT, I"(", 0, 0, -1);
+        InterSchemas::new_token(OPEN_ROUND_ISTT, I"(", 0, 0, -1, printing_rule->line_offset);
     InterSchemas::add_token_after(open_b, cons->expression_tokens);
     open_b->next = n;
     n = open_b;
     while ((n) && (n->next)) n = n->next;
     inter_schema_token *close_b =
-        InterSchemas::new_token(CLOSE_ROUND_ISTT, I")", 0, 0, -1);
+        InterSchemas::new_token(CLOSE_ROUND_ISTT, I")", 0, 0, -1, printing_rule->line_offset);
     InterSchemas::add_token_after(close_b, n);
     which_statement = 0;
     operand1 = NULL;
@@ -1160,17 +1161,17 @@ character, and one to return 
     inter_schema_node *save_next = cons->next_node;
 
     cons->next_node =
-        InterSchemas::new_node(cons->parent_schema, STATEMENT_ISNT);
+        InterSchemas::new_node(cons->parent_schema, STATEMENT_ISNT, n);
     cons->next_node->parent_node = cons->parent_node;
     cons->next_node->isn_clarifier = PRINT_BIP;
     cons->next_node->child_node =
-        InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT);
+        InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT, n);
     cons->next_node->child_node->parent_node = cons->next_node;
     InterSchemas::add_token_to_node(cons->next_node->child_node,
-        InterSchemas::new_token(DQUOTED_ISTT, I"\n", 0, 0, -1));
+        InterSchemas::new_token(DQUOTED_ISTT, I"\n", 0, 0, -1, 0));
 
     cons->next_node->next_node =
-        InterSchemas::new_node(cons->parent_schema, STATEMENT_ISNT);
+        InterSchemas::new_node(cons->parent_schema, STATEMENT_ISNT, n);
     cons->next_node->next_node->parent_node = cons->parent_node;
     cons->next_node->next_node->isn_clarifier = RETURN_BIP;
 
@@ -1218,7 +1219,7 @@ to know about the difference.
     cons->dir_clarifier = InterSchemas::opening_directive_word(cons);
     if (InterSchemas::second_dark_token(cons)) {
         inter_schema_node *new_isn =
-            InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT);
+            InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT, first);
         cons->child_node = new_isn;
         new_isn->parent_node = cons;
         new_isn->expression_tokens = InterSchemas::second_dark_token(cons);
@@ -1251,7 +1252,7 @@ to be recognised for what they are.
             if ((n) && (Str::eq(l->material, I")"))) continue;
             if (l->ist_type != WHITE_SPACE_ISTT) {
                 inter_schema_node *new_isn =
-                    InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT);
+                    InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT, n);
                 new_isn->expression_tokens = l; l->next = NULL; l->owner = new_isn;
                 if (l->operation_primitive) {
                     l->ist_type = IDENTIFIER_ISTT;
@@ -1308,7 +1309,7 @@ assembly instructions @push
 
 
-    first_child = InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT);
+    first_child = InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT, first);
     if (operand1 == NULL) operand1 = InterSchemas::second_dark_token(cons);
     first_child->expression_tokens = operand1;
     InterSchemas::changed_tokens_on(first_child);
@@ -1330,11 +1331,13 @@ they cannot both apply.)
     if (dangle_number >= 0) {
         text_stream *T = Str::new();
         WRITE_TO(T, "%d", dangle_number);
-        first_child->expression_tokens = InterSchemas::new_token(NUMBER_ISTT, T, 0, 0, -1);
+        first_child->expression_tokens =
+            InterSchemas::new_token(NUMBER_ISTT, T, 0, 0, -1, 0);
         first_child->expression_tokens->owner = first_child;
     }
     if (Str::len(dangle_text) > 0) {
-        first_child->expression_tokens = InterSchemas::new_token(DQUOTED_ISTT, dangle_text, 0, 0, -1);
+        first_child->expression_tokens =
+            InterSchemas::new_token(DQUOTED_ISTT, dangle_text, 0, 0, -1, 0);
         first_child->expression_tokens->owner = first_child;
     }
 
@@ -1348,7 +1351,7 @@ they cannot both apply.)
     if (operand2) {
         inter_schema_node *second_child =
-            InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT);
+            InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT, first);
         if (which_statement == IFELSE_BIP) {
             second_child->semicolon_terminated = TRUE;
             second_child->next_node = first_child->next_node->next_node;
@@ -1390,14 +1393,14 @@ But it is legal to do so in this schema, and that is what our expression node do
     cons->child_node = NULL;
     cons->expression_tokens = A->expression_tokens;
     cons->expression_tokens->next =
-        InterSchemas::new_token(OPERATOR_ISTT, I".", PROPERTYVALUE_BIP, 0, -1);
+        InterSchemas::new_token(OPERATOR_ISTT, I".", PROPERTYVALUE_BIP, 0, -1, 0);
     cons->expression_tokens->next->next = B->expression_tokens;
     cons->expression_tokens->next->next->next =
-        InterSchemas::new_token(OPERATOR_ISTT, I"=", STORE_BIP, 0, -1);
+        InterSchemas::new_token(OPERATOR_ISTT, I"=", STORE_BIP, 0, -1, 0);
     text_stream *T = Str::new();
     WRITE_TO(T, "%d", dangle_number);
     cons->expression_tokens->next->next->next->next =
-        InterSchemas::new_token(NUMBER_ISTT, T, 0, 0, -1);
+        InterSchemas::new_token(NUMBER_ISTT, T, 0, 0, -1, 0);
     InterSchemas::changed_tokens_on(cons);
 
@@ -1444,6 +1447,7 @@ removing the colon and bracket tokens. Thus: return FALSE; } inter_schema_token *n = predicates->expression_tokens; + inter_schema_token *near = n; inter_schema_node *code_node = predicates->next_node; int bl = 0, cw = 0; inter_schema_token *from[3], *to[3]; @@ -1471,7 +1475,8 @@ removing the colon and bracket tokens. Thus: return FALSE; } for (int i=0; i<3; i++) { - inter_schema_node *eval_isn = InterSchemas::new_node(isn->parent_schema, EVAL_ISNT); + inter_schema_node *eval_isn = + InterSchemas::new_node(isn->parent_schema, EVAL_ISNT, near); if (i == 0) isn->child_node = eval_isn; if (i == 1) isn->child_node->next_node = eval_isn; if (i == 2) { @@ -1480,7 +1485,8 @@ removing the colon and bracket tokens. Thus: } eval_isn->parent_node = isn; - inter_schema_node *expr_isn = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); + inter_schema_node *expr_isn = + InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, near); eval_isn->child_node = expr_isn; expr_isn->parent_node = eval_isn; @@ -1542,7 +1548,8 @@ from failing its lint test. return FALSE; } if (actual == req-1) { - inter_schema_node *code_isn = InterSchemas::new_node(isn->parent_schema, CODE_ISNT); + inter_schema_node *code_isn = + InterSchemas::new_node_near_node(isn->parent_schema, CODE_ISNT, isn); code_isn->parent_node = isn; inter_schema_node *ch = isn->child_node; @@ -1627,7 +1634,7 @@ that (x+1) woul

-    inter_schema_node *sub_node = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+    inter_schema_node *sub_node = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, from);
     sub_node->expression_tokens = from;
     for (inter_schema_token *l = sub_node->expression_tokens; l; l=l->next)
         if (l->next == to)
@@ -1690,7 +1697,7 @@ evaluation — evaluate a
                     prev = n; n = n->next;
                     while ((n) && (n->ist_type == WHITE_SPACE_ISTT)) { prev = n; n = n->next; }
                     inter_schema_node *new_isn =
-                        InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+                        InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, n);
                     new_isn->expression_tokens = n;
                     new_isn->parent_node = isn->parent_node;
                     InterSchemas::changed_tokens_on(new_isn);
@@ -1721,7 +1728,8 @@ We correct those to uses of the special             inter_schema_node *A = isn->child_node;
             inter_schema_node *B = isn->child_node->next_node;
             if ((A) && (B) && (B->next_node)) {
-                inter_schema_node *C = InterSchemas::new_node(isn->parent_schema, OPERATION_ISNT);
+                inter_schema_node *C =
+                    InterSchemas::new_node_near_node(isn->parent_schema, OPERATION_ISNT, A);
                 C->isn_clarifier = ALTERNATIVECASE_BIP;
                 C->child_node = A;
                 A->parent_node = C; B->parent_node = C;
@@ -1891,7 +1899,7 @@ level, as in the case of x -
 
 
     inter_schema_node *left_operand_node =
-        InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+        InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, from);
     left_operand_node->expression_tokens = from;
     for (inter_schema_token *l = left_operand_node->expression_tokens; l; l=l->next)
         if (l->next == to)
@@ -1907,7 +1915,7 @@ level, as in the case of x -
 
 
     inter_schema_node *right_operand_node =
-        InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+        InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, from);
     right_operand_node->expression_tokens = from;
     InterSchemas::changed_tokens_on(right_operand_node);
     if (isn->child_node == NULL) {
@@ -2066,7 +2074,7 @@ array lookup is performed to find the address of the function to call.
 
     if ((from) && (to) && (from != to)) {
         inter_schema_node *new_isn =
-            InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+            InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, from);
         new_isn->expression_tokens = from;
         for (inter_schema_token *l = new_isn->expression_tokens; l; l=l->next)
             if (l->next == to)
@@ -2091,8 +2099,9 @@ array lookup is performed to find the address of the function to call.
     for (inter_schema_node *prev = NULL; isn; prev = isn, isn = isn->next_node) {
         if ((isn->isn_type == STATEMENT_ISNT) &&
             (isn->isn_clarifier == RETURN_BIP) && (isn->child_node == FALSE)) {
-            inter_schema_node *one = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
-            one->expression_tokens = InterSchemas::new_token(NUMBER_ISTT, I"1", 0, 0, -1);
+            inter_schema_node *one =
+                InterSchemas::new_node_near_node(isn->parent_schema, EXPRESSION_ISNT, isn);
+            one->expression_tokens = InterSchemas::new_token(NUMBER_ISTT, I"1", 0, 0, -1, 0);
             one->expression_tokens->owner = one;
             isn->child_node = one;
             one->parent_node = isn;
diff --git a/docs/building-module/2-tkn.html b/docs/building-module/2-tkn.html
index 794edce0b..6f8f869bf 100644
--- a/docs/building-module/2-tkn.html
+++ b/docs/building-module/2-tkn.html
@@ -95,11 +95,13 @@ states:
     inter_schema_token *preceding_token = NULL;
 
     int definition_length = Str::len(from);
+    int line_offset = 0;
     text_stream *current_raw = Str::new();
     int tokeniser_state = NO_TOKSTATE;
     for (; pos<definition_length; pos++) {
         int c = Str::get_at(from, pos);
         if (Characters::is_whitespace(c)) {
+            if (c == '\n') line_offset++;
             if ((tokeniser_state == TOK_TOKSTATE) || (tokeniser_state == NO_TOKSTATE)) {
                 Absorb raw material, if any1.2;
                 tokeniser_state = WHITE_TOKSTATE;
@@ -189,17 +191,17 @@ states:
     switch (tokeniser_state) {
         case WHITE_TOKSTATE:
             InterSchemas::add_token(sch,
-                InterSchemas::new_token(WHITE_SPACE_ISTT, I" ", 0, 0, -1));
+                InterSchemas::new_token(WHITE_SPACE_ISTT, I" ", 0, 0, -1, line_offset));
             break;
         case DQUOTED_TOKSTATE:
             Tokenisation::de_escape_text(current_raw);
             InterSchemas::add_token(sch,
-                InterSchemas::new_token(DQUOTED_ISTT, current_raw, 0, 0, -1));
+                InterSchemas::new_token(DQUOTED_ISTT, current_raw, 0, 0, -1, line_offset));
             break;
         case SQUOTED_TOKSTATE:
             Tokenisation::de_escape_sq_text(current_raw);
             InterSchemas::add_token(sch,
-                InterSchemas::new_token(SQUOTED_ISTT, current_raw, 0, 0, -1));
+                InterSchemas::new_token(SQUOTED_ISTT, current_raw, 0, 0, -1, line_offset));
             break;
         default:
             Look for individual tokens1.3.1;
@@ -262,7 +264,7 @@ states:
 
     if (Str::len(source_text_fragment) > 0) {
         InterSchemas::add_token(sch,
-            InterSchemas::new_token(I7_ISTT, source_text_fragment, 0, 0, -1));
+            InterSchemas::new_token(I7_ISTT, source_text_fragment, 0, 0, -1, line_offset));
     }
 
  • This code is used in §1.6.
@@ -302,7 +304,7 @@ a bracing.

-    inter_schema_token *t = InterSchemas::new_token(INLINE_ISTT, bracing, 0, 0, -1);
+    inter_schema_token *t = InterSchemas::new_token(INLINE_ISTT, bracing, 0, 0, -1, line_offset);
     t->bracing = Str::duplicate(bracing);
     t->command = Str::new();
     t->operand = Str::new();
@@ -546,7 +548,7 @@ of modifiers are allowed. See         Absorb raw material, if any1.2;
         TEMPORARY_TEXT(T)
         for (int i=pos; i<=at; i++) PUT_TO(T, Str::get_at(from, i));
-        inter_schema_token *t = InterSchemas::new_token(INLINE_ISTT, T, 0, 0, -1);
+        inter_schema_token *t = InterSchemas::new_token(INLINE_ISTT, T, 0, 0, -1, line_offset);
         t->bracing = Str::duplicate(T);
         t->inline_command = substitute_ISINC;
         t->inline_modifiers = iss_bitmap;
@@ -556,7 +558,7 @@ of modifiers are allowed. See         DISCARD_TEXT(T)
         pos = at;
     } else if (c == '&') {
-        inter_schema_token *t = InterSchemas::new_token(INLINE_ISTT, I"*&", 0, 0, -1);
+        inter_schema_token *t = InterSchemas::new_token(INLINE_ISTT, I"*&", 0, 0, -1, line_offset);
         t->bracing = I"*&";
         t->inline_command = combine_ISINC;
         t->inline_modifiers = iss_bitmap;
@@ -803,7 +805,7 @@ inclusive; we ignore an empty token.
         int which_rw = 0, which_number = -1, which_quote = -1;
         Identify this new token1.3.1.4.1;
 
-        inter_schema_token *n = InterSchemas::new_token(is, T, which, which_rw, which_number);
+        inter_schema_token *n = InterSchemas::new_token(is, T, which, which_rw, which_number, line_offset);
         #ifdef CORE_MODULE
         if (which_quote >= 0) n->as_quoted = quoted_inames[which_quote];
         #endif
diff --git a/docs/building-module/P-wtmd.html b/docs/building-module/P-wtmd.html
index 282ca5e22..5f2300818 100644
--- a/docs/building-module/P-wtmd.html
+++ b/docs/building-module/P-wtmd.html
@@ -233,7 +233,7 @@ notation. For example, this:
 

-    inter_schema *sch = ParsingSchemas::from_text(I"return true;");
+    inter_schema *sch = ParsingSchemas::from_text(I"return true;", where);
     EmitInterSchemas::emit(I, ..., sch, ...);
 

generates Inter code equivalent to the example above.4 But the real power of diff --git a/docs/building-test/1-ut.html b/docs/building-test/1-ut.html index b67601f66..7ebecf234 100644 --- a/docs/building-test/1-ut.html +++ b/docs/building-test/1-ut.html @@ -135,7 +135,8 @@ function togglePopup(material_id) {

     LOG("Test: parse schema from:\n%S\n", iut->test_input);
     Str::trim_white_space(iut->test_input);
-    inter_schema *sch = ParsingSchemas::from_text(iut->test_input);
+    inter_schema *sch = ParsingSchemas::from_text(iut->test_input,
+        Provenance::at_file_and_line(I"hypothetical.txt", 1));
     if (sch == NULL) LOG("<null schema>\n");
     else if (sch->node_tree == NULL) LOG("<nodeless scheme\n");
     else InterSchemas::log(DL, sch);
diff --git a/docs/bytecode-module/3-ic.html b/docs/bytecode-module/3-ic.html
index 986ba5283..d9abc2d36 100644
--- a/docs/bytecode-module/3-ic.html
+++ b/docs/bytecode-module/3-ic.html
@@ -687,7 +687,7 @@ not the place to explain it. See Inter in
 }
 
diff --git a/docs/bytecode-module/3-idt.html b/docs/bytecode-module/3-idt.html index 4667c150c..f1d944c42 100644 --- a/docs/bytecode-module/3-idt.html +++ b/docs/bytecode-module/3-idt.html @@ -1077,7 +1077,7 @@ function arguments are contravariant. }
diff --git a/docs/bytecode-module/3-ie.html b/docs/bytecode-module/3-ie.html index 03dbe057c..7eda2274c 100644 --- a/docs/bytecode-module/3-ie.html +++ b/docs/bytecode-module/3-ie.html @@ -208,7 +208,7 @@ exist. See InterInstruction::tree_lint< }
diff --git a/docs/bytecode-module/3-iibf.html b/docs/bytecode-module/3-iibf.html index be36659fa..41e575dd7 100644 --- a/docs/bytecode-module/3-iibf.html +++ b/docs/bytecode-module/3-iibf.html @@ -1051,7 +1051,7 @@ the definition of any symbol created in the instruction to }
diff --git a/docs/bytecode-module/3-iitf.html b/docs/bytecode-module/3-iitf.html index fe1352820..162ed3cea 100644 --- a/docs/bytecode-module/3-iitf.html +++ b/docs/bytecode-module/3-iitf.html @@ -481,7 +481,7 @@ the filter test.

§11. Notation for text literals.

-void TextualInter::write_text(OUTPUT_STREAM, text_stream *S) {
+void TextualInter::write_text(OUTPUT_STREAM, text_stream *S) {
     WRITE("\"");
     LOOP_THROUGH_TEXT(P, S) {
         wchar_t c = Str::get(P);
@@ -853,7 +853,7 @@ therefore used typelessly.
 }
 
diff --git a/docs/bytecode-module/3-ivp.html b/docs/bytecode-module/3-ivp.html index c9adac232..322c82446 100644 --- a/docs/bytecode-module/3-ivp.html +++ b/docs/bytecode-module/3-ivp.html @@ -553,7 +553,7 @@ garbage, and doesn't take much time.
  • This code is used in §22.
diff --git a/docs/bytecode-module/3-mtd.html b/docs/bytecode-module/3-mtd.html index 47b25b3d3..25faf1dc5 100644 --- a/docs/bytecode-module/3-mtd.html +++ b/docs/bytecode-module/3-mtd.html @@ -215,7 +215,7 @@ must then be extracted): }
diff --git a/docs/bytecode-module/3-tp.html b/docs/bytecode-module/3-tp.html new file mode 100644 index 000000000..14a113cc8 --- /dev/null +++ b/docs/bytecode-module/3-tp.html @@ -0,0 +1,151 @@ + + + + Text Provenance + + + + + + + + + + + + + + + + + + +
+ + +

Recording where fragments of text originally came from.

+ +

§1. Inter code sometimes needs to contain fragments of not-yet-parsed Inform 6 +syntax code, in the form of SPLAT_IST and INSERT_IST instructions. In order +for it to be possible to relate errors in those fragments to the original text +files they came from, we need to record their "provenance". +

+ +

This is only a wrapper for saying something like "line 17 in whatever.txt". +Line numbers count from 1 at the top of a text file. +

+ +
+typedef struct text_provenance {
+    struct text_stream *textual_filename;
+    int line_number;
+} text_provenance;
+
+
  • The structure text_provenance is private to this section.
+

§2. This provides a "don't know, or, it didn't come from a text file, I made it up" +value: +

+ +
+text_provenance Provenance::nowhere(void) {
+    text_provenance nowhere;
+    nowhere.textual_filename = NULL;
+    nowhere.line_number = 0;
+    return nowhere;
+}
+
+int Provenance::is_somewhere(text_provenance where) {
+    if (Str::len(where.textual_filename) > 0) return TRUE;
+    return FALSE;
+}
+
+

§3. Composing: +

+ +
+text_provenance Provenance::at_file_and_line(text_stream *file, int line) {
+    text_provenance somewhere;
+    somewhere.textual_filename = Str::duplicate(file);
+    somewhere.line_number = line;
+    return somewhere;
+}
+
+

§4. Decomposing: +

+ +
+int Provenance::get_line(text_provenance where) {
+    if (Provenance::is_somewhere(where)) return where.line_number;
+    return 0;
+}
+
+filename *Provenance::get_filename(text_provenance where) {
+    if (Provenance::is_somewhere(where))
+        return Filenames::from_text(where.textual_filename);
+    return NULL;
+}
+
+

§5. Altering in place: +

+ +
+void Provenance::set_line(text_provenance *where, int lc) {
+    if ((where) && (Provenance::is_somewhere(*where)))
+        where->line_number = lc;
+}
+
+

§6. Writing to text: +

+ +
+void Provenance::write(OUTPUT_STREAM, text_provenance at) {
+    if (Provenance::is_somewhere(at)) {
+        TextualInter::write_text(OUT, at.textual_filename);
+        WRITE(" %d", at.line_number);
+    } else {
+        WRITE("<nowhere>");
+    }
+}
+
+ + +
+ + + diff --git a/docs/bytecode-module/3-vi.html b/docs/bytecode-module/3-vi.html index 0d6bea548..0878157db 100644 --- a/docs/bytecode-module/3-vi.html +++ b/docs/bytecode-module/3-vi.html @@ -349,7 +349,7 @@ the context of the current package: }
diff --git a/docs/bytecode-module/4-tcc.html b/docs/bytecode-module/4-tcc.html index 0174a6980..ca138d21e 100644 --- a/docs/bytecode-module/4-tcc.html +++ b/docs/bytecode-module/4-tcc.html @@ -133,7 +133,7 @@ compulsory words — see Inter Nodes}
diff --git a/docs/bytecode-module/4-tic.html b/docs/bytecode-module/4-tic.html index 2a1df780d..c0498b2c1 100644 --- a/docs/bytecode-module/4-tic.html +++ b/docs/bytecode-module/4-tic.html @@ -172,8 +172,7 @@ compulsory words — see Inter Nodes WRITE(" "); TextualInter::write_text(OUT, replacing); WRITE(" "); - TextualInter::write_text(OUT, InsertInstruction::file_provenance(P)); - WRITE(" %d", InsertInstruction::line_provenance(P)); + Provenance::write(OUT, InsertInstruction::provenance(P)); }

§6. Access functions.

@@ -191,16 +190,12 @@ compulsory words — see Inter Nodes return Inode::ID_to_text(P, P->W.instruction[REPLACING_INSERT_IFLD]); } -text_stream *InsertInstruction::file_provenance(inter_tree_node *P) { - if (P == NULL) return NULL; - if (Inode::isnt(P, INSERT_IST)) return NULL; - return Inode::ID_to_text(P, P->W.instruction[PROVENANCEFILE_INSERT_IFLD]); -} - -inter_ti InsertInstruction::line_provenance(inter_tree_node *P) { - if (P == NULL) return 0; - if (Inode::isnt(P, INSERT_IST)) return 0; - return P->W.instruction[PROVENANCELINE_INSERT_IFLD]; +text_provenance InsertInstruction::provenance(inter_tree_node *P) { + if (P == NULL) return Provenance::nowhere(); + if (Inode::isnt(P, INSERT_IST)) return Provenance::nowhere(); + return Provenance::at_file_and_line( + Inode::ID_to_text(P, P->W.instruction[PROVENANCEFILE_INSERT_IFLD]), + (int) P->W.instruction[PROVENANCELINE_INSERT_IFLD]); }

§7. PLMs. At some point PLM stood for something, but what it was is now forgotten — diff --git a/docs/bytecode-module/index.html b/docs/bytecode-module/index.html index e6e3fe052..ec94aca4f 100644 --- a/docs/bytecode-module/index.html +++ b/docs/bytecode-module/index.html @@ -186,6 +186,11 @@ Inter Errors - To issue error messages arising from loading incorrect Inter code from files.

+
  • +

    + Text Provenance - + Recording where fragments of text originally came from.

    +
  • diff --git a/docs/core-module/2-pwst.html b/docs/core-module/2-pwst.html index 21497114c..6a187c3b2 100644 --- a/docs/core-module/2-pwst.html +++ b/docs/core-module/2-pwst.html @@ -693,24 +693,27 @@ in Include (- ... -)} void SourceProblems::I6_level_error(char *message, text_stream *quote, - text_stream *file_ref, int line) { + text_provenance at) { + filename *F = Provenance::get_filename(at); + int line = Provenance::get_line(at); TEMPORARY_TEXT(file) - WRITE_TO(file, "%S", file_ref); + if (F) WRITE_TO(file, "%f", F); TEMPORARY_TEXT(kit) TEMPORARY_TEXT(M) WRITE_TO(M, message, quote); - filename *F = Filenames::from_text(file); - TEMPORARY_TEXT(EX) - Filenames::write_extension(EX, F); - if (Str::eq_insensitive(EX, I".i6t")) { - pathname *P = Filenames::up(F); - if (Str::eq_insensitive(Pathnames::directory_name(P), I"Sections")) - P = Pathnames::up(P); - WRITE_TO(kit, "%S", Pathnames::directory_name(P)); - Str::clear(file); - WRITE_TO(file, "%S", Filenames::get_leafname(F)); + if (Provenance::is_somewhere(at)) { + TEMPORARY_TEXT(EX) + Filenames::write_extension(EX, F); + if (Str::eq_insensitive(EX, I".i6t")) { + pathname *P = Filenames::up(F); + if (Str::eq_insensitive(Pathnames::directory_name(P), I"Sections")) + P = Pathnames::up(P); + WRITE_TO(kit, "%S", Pathnames::directory_name(P)); + Str::clear(file); + WRITE_TO(file, "%S", Filenames::get_leafname(F)); + } + DISCARD_TEXT(EX) } - DISCARD_TEXT(EX) if (trigger_kit_notice) { if (general_kit_notice_issued == FALSE) { StandardProblems::handmade_problem(Task::syntax_tree(), _p_(...)); @@ -737,7 +740,7 @@ in Include (- ... -) Problems::quote_stream(4, kit); if (general_kit_notice_issued) Problems::issue_problem_segment("%2, near line %3: %1."); else Problems::issue_problem_segment("Near line %3 of file %2 in %4: %1."); - } else if (Str::len(file) > 0) { + } else if (Provenance::is_somewhere(at)) { LOG("%S, line %d:\n", file, line); Problems::problem_quote_file(2, file, line); Problems::issue_problem_segment( diff --git a/docs/imperative-module/3-cid.html b/docs/imperative-module/3-cid.html index 5b119f2c9..e58855cde 100644 --- a/docs/imperative-module/3-cid.html +++ b/docs/imperative-module/3-cid.html @@ -301,7 +301,8 @@ never run through CompileImperativeDef ParsingSchemas::from_inline_phrase_definition( CompileImperativeDefn::get_inline_definition(idb), &(idb->compilation_data.inline_front_schema), - &(idb->compilation_data.inline_back_schema)); + &(idb->compilation_data.inline_back_schema), + Provenance::nowhere()); CompileImperativeDefn::issue_schema_errors(current_sentence, idb->compilation_data.inline_front_schema, idb->compilation_data.inline_back_schema); diff --git a/docs/pipeline-module/2-pe.html b/docs/pipeline-module/2-pe.html index ad64bb6a6..c94f4e7b0 100644 --- a/docs/pipeline-module/2-pe.html +++ b/docs/pipeline-module/2-pe.html @@ -214,26 +214,40 @@ what the red button marked "danger" does.

    +text_provenance kit_error_location;
    +int kit_error_location_set = FALSE;
     int kit_error_count = 0;
    -text_stream *kit_error_filename = NULL;
    -int kit_error_line_number = 0;
     
    -void PipelineErrors::set_kit_error_location(text_stream *file, inter_ti line) {
    -    kit_error_filename = file;
    -    kit_error_line_number = (int) line;
    +text_provenance PipelineErrors::get_kit_error_location(void) {
    +    if (kit_error_location_set == FALSE)
    +        PipelineErrors::clear_kit_error_location();
    +    return kit_error_location;
    +}
    +void PipelineErrors::clear_kit_error_location(void) {
    +    PipelineErrors::set_kit_error_location(Provenance::nowhere());
    +}
    +void PipelineErrors::set_kit_error_location(text_provenance where) {
    +    kit_error_location_set = TRUE;
    +    kit_error_location = where;
     }
     
    -void PipelineErrors::kit_error(char *message, text_stream *quote) {
    +void PipelineErrors::set_kit_error_location_near_splat(inter_tree_node *P) {
    +    PipelineErrors::clear_kit_error_location();
    +    if ((P) && (Inode::is(P, SPLAT_IST)))
    +        PipelineErrors::set_kit_error_location(SplatInstruction::provenance(P));
    +}
    +
    +void PipelineErrors::kit_error(char *message, text_stream *quote) {
    +    text_provenance at = PipelineErrors::get_kit_error_location();
         #ifdef CORE_MODULE
    -    SourceProblems::I6_level_error(message, quote, kit_error_filename,
    -        kit_error_line_number);
    +    SourceProblems::I6_level_error(message, quote, at);
         #endif
         #ifndef CORE_MODULE
    -    if (Str::len(kit_error_filename) > 0) {
    -        filename *F = Filenames::from_text(kit_error_filename);
    +    if (Provenance::is_somewhere(at)) {
    +        filename *F = Provenance::get_filename(at);
             TEMPORARY_TEXT(M)
             WRITE_TO(M, message, quote);
    -        Errors::at_position_S(M, F, kit_error_line_number);
    +        Errors::at_position_S(M, F, Provenance::get_line(at));
             DISCARD_TEXT(M)
         } else {
             Errors::with_text(message, quote);
    @@ -242,11 +256,12 @@ what the red button marked "danger" does.
         kit_error_count++;
     }
     
    -void PipelineErrors::reset_errors(void) {
    +void PipelineErrors::reset_errors(void) {
    +    PipelineErrors::clear_kit_error_location();
         kit_error_count = 0;
     }
     
    -int PipelineErrors::errors_occurred(void) {
    +int PipelineErrors::errors_occurred(void) {
         if (kit_error_count != 0) return TRUE;
         return FALSE;
     }
    diff --git a/docs/pipeline-module/3-css.html b/docs/pipeline-module/3-css.html
    index ff49d384c..92fa91b3b 100644
    --- a/docs/pipeline-module/3-css.html
    +++ b/docs/pipeline-module/3-css.html
    @@ -106,17 +106,16 @@ function definition, that is quite a lot of work.
     
     int CompileSplatsStage::run(pipeline_step *step) {
         PipelineErrors::reset_errors();
    -    PipelineErrors::set_kit_error_location(NULL, 0);
         compile_splats_state css;
         Initialise the CS state2.2;
         inter_tree *I = step->ephemera.tree;
         InterTree::traverse(I, CompileSplatsStage::visitor1, &css, NULL, SPLAT_IST);
         InterTree::traverse(I, CompileSplatsStage::visitor2, &css, NULL, 0);
    -    PipelineErrors::set_kit_error_location(NULL, 0);
    +    PipelineErrors::clear_kit_error_location();
         int errors_found = CompileSplatsStage::function_bodies(step, &css, I);
         if (errors_found) return FALSE;
         InterTree::traverse(I, CompileSplatsStage::visitor3, &css, NULL, SPLAT_IST);
    -    PipelineErrors::set_kit_error_location(NULL, 0);
    +    PipelineErrors::clear_kit_error_location();
         if (PipelineErrors::errors_occurred()) return FALSE;
         return TRUE;
     }
    @@ -220,11 +219,7 @@ is being compiled.
     

    -    if (SplatInstruction::line_provenance(P) > 0)
    -        PipelineErrors::set_kit_error_location(
    -            SplatInstruction::file_provenance(P), SplatInstruction::line_provenance(P));
    -    else
    -        PipelineErrors::set_kit_error_location(NULL, 0);
    +    PipelineErrors::set_kit_error_location_near_splat(P);
         match_results mr = Regexp::create_mr();
         text_stream *raw_identifier = NULL, *value = NULL;
         int proceed = TRUE;
    @@ -951,11 +946,7 @@ in this section.
     

    -    if (SplatInstruction::line_provenance(P) > 0)
    -        PipelineErrors::set_kit_error_location(
    -            SplatInstruction::file_provenance(P), SplatInstruction::line_provenance(P));
    -    else
    -        PipelineErrors::set_kit_error_location(NULL, 0);
    +    PipelineErrors::set_kit_error_location_near_splat(P);
         text_stream *raw_identifier = NULL, *local_var_names = NULL, *body = NULL;
         match_results mr = Regexp::create_mr();
         if (SplatInstruction::plm(P) == ROUTINE_PLM) Parse the routine header3.2.1;
    @@ -1131,7 +1122,7 @@ which contains the actual code.
         Str::truncate(body, L);
         inter_ti B = (inter_ti) InterBookmark::baseline(IBM) + 1;
         CompileSplatsStage::function_body(css, IBM, IP, B, body, block_bookmark, identifier,
    -        SplatInstruction::namespace(P));
    +        SplatInstruction::namespace(P), PipelineErrors::get_kit_error_location());
     

    §4. Inform 6 annotations.

    @@ -1509,7 +1500,8 @@ before they are needed.

    -    inter_schema *sch = ParsingSchemas::from_text(S);
    +    inter_schema *sch =
    +        ParsingSchemas::from_text(S, PipelineErrors::get_kit_error_location());
         int excess_tokens = FALSE;
         inter_symbol *result_s =
             CompileSplatsStage::compute_r(step, IBM, sch->node_tree, &excess_tokens);
    @@ -1705,12 +1697,13 @@ by storing up a list of requests to do the work:
         struct text_stream *body;
         struct text_stream *identifier;
         struct text_stream *namespace;
    +    struct text_provenance provenance;
         CLASS_DEFINITION
     } function_body_request;
     
     int CompileSplatsStage::function_body(compile_splats_state *css, inter_bookmark *IBM,
         inter_package *block_package, inter_ti offset, text_stream *body, inter_bookmark bb,
    -    text_stream *identifier, text_stream *namespace) {
    +    text_stream *identifier, text_stream *namespace, text_provenance provenance) {
         if (Str::is_whitespace(body)) return FALSE;
         function_body_request *req = CREATE(function_body_request);
         req->block_bookmark = bb;
    @@ -1721,6 +1714,7 @@ by storing up a list of requests to do the work:
         req->body = Str::duplicate(body);
         req->identifier = Str::duplicate(identifier);
         req->namespace = Str::duplicate(namespace);
    +    req->provenance = provenance;
         ADD_TO_LINKED_LIST(req, function_body_request, css->function_bodies_to_compile);
         return TRUE;
     }
    @@ -1739,7 +1733,7 @@ kit CommandParserKit    LOOP_OVER_LINKED_LIST(req, function_body_request, css->function_bodies_to_compile) {
             LOGIF(SCHEMA_COMPILATION, "=======\n\nFunction (%S) len %d: '%S'\n\n",
                 InterPackage::name(req->block_package), Str::len(req->body), req->body);
    -        inter_schema *sch = ParsingSchemas::from_text(req->body);
    +        inter_schema *sch = ParsingSchemas::from_text(req->body, req->provenance);
             if (LinkedLists::len(sch->parsing_errors) > 0) {
                 CompileSplatsStage::report_kit_errors(sch, req);
             } else {
    @@ -1784,11 +1778,13 @@ kit CommandParserKit    if (LinkedLists::len(sch->parsing_errors) > 0) {
             schema_parsing_error *err;
             LOOP_OVER_LINKED_LIST(err, schema_parsing_error, sch->parsing_errors) {
    +            PipelineErrors::set_kit_error_location(err->provenance);
                 TEMPORARY_TEXT(msg)
                 WRITE_TO(msg, "in function '%S': %S", req->identifier, err->message);
    -            PipelineErrors::kit_error("inform 6 syntax error %S", msg);
    +            PipelineErrors::kit_error("Inform 6 syntax error %S", msg);
                 DISCARD_TEXT(msg)
             }
    +        PipelineErrors::clear_kit_error_location();
         }
     }
     
    diff --git a/docs/pipeline-module/3-ps.html b/docs/pipeline-module/3-ps.html index 7d05370ad..90eeb82d6 100644 --- a/docs/pipeline-module/3-ps.html +++ b/docs/pipeline-module/3-ps.html @@ -161,8 +161,7 @@ it from there. inter_bookmark here = InterBookmark::after_this_node(P); rpi_docket_state *docket_state = (rpi_docket_state *) docket->state; docket_state->assimilation_point = &here; - docket_state->file_provenance = InsertInstruction::file_provenance(P); - docket_state->line_provenance = InsertInstruction::line_provenance(P); + docket_state->provenance = InsertInstruction::provenance(P); SimpleTangler::tangle_text(docket, insertion); text_stream *replacing = InsertInstruction::replacing(P); if (Str::len(replacing) > 0) { @@ -193,8 +192,7 @@ in K/Sections. typedef struct rpi_docket_state { struct inter_bookmark *assimilation_point; struct text_stream *namespace; - struct text_stream *file_provenance; - inter_ti line_provenance; + struct text_provenance provenance; } rpi_docket_state;
    • The structure rpi_docket_state is accessed in 3/css and here.
    @@ -210,8 +208,7 @@ in K/Sections. rpi_docket_state state; state.assimilation_point = &assimilation_point; state.namespace = namespacename; - state.file_provenance = NULL; - state.line_provenance = 0; + state.provenance = Provenance::nowhere(); docket = SimpleTangler::new_docket( &(ParsingStages::receive_raw), &(ParsingStages::receive_command), @@ -321,15 +318,16 @@ functions). So for example define COMMENTED_I6TBIT 8 define ROUTINED_I6TBIT 16 define CONTENT_ON_LINE_I6TBIT 32 +define NOTE_LINES_I6TBIT 64 define SUBORDINATE_I6TBITS (COMMENTED_I6TBIT + SQUOTED_I6TBIT + DQUOTED_I6TBIT + ROUTINED_I6TBIT)
     void ParsingStages::receive_raw(text_stream *S, simple_tangle_docket *docket) {
         text_stream *R = Str::new();
    -    int mode = IGNORE_WS_I6TBIT;
    +    int mode = IGNORE_WS_I6TBIT + NOTE_LINES_I6TBIT;
         rpi_docket_state *state = (rpi_docket_state *) docket->state;
    -    inter_ti lc = state->line_provenance;
    +    int lc = Provenance::get_line(state->provenance);
         for (int pos = 0; pos < Str::len(S); pos++) {
             wchar_t c = Str::get_at(S, pos);
             if ((c == 10) || (c == 13)) { c = '\n'; lc++; }
    @@ -344,16 +342,18 @@ functions). So for example
                     if (in_number) PUT_TO(number_text, c);
                     else PUT_TO(file_text, c);
                 }
    -            state->line_provenance = (inter_ti) Str::atoi(number_text, 0);
    -            lc = state->line_provenance;
    -            state->file_provenance = file_text;
    -            LOG("Spotted %d and <%S>\n", state->line_provenance, state->file_provenance);
    +            lc = Str::atoi(number_text, 0);
    +            state->provenance = Provenance::at_file_and_line(file_text, lc);
                 DISCARD_TEXT(number_text)
                 continue;
             }
             if (mode & IGNORE_WS_I6TBIT) {
                 if ((c == '\n') || (Characters::is_whitespace(c))) continue;
                 mode -= IGNORE_WS_I6TBIT;
    +            if (mode & NOTE_LINES_I6TBIT) {
    +                mode -= NOTE_LINES_I6TBIT;
    +                Provenance::set_line(&(state->provenance), lc);
    +            }
             }
             if ((c == '!') && (!(mode & (DQUOTED_I6TBIT + SQUOTED_I6TBIT)))) {
                 mode = mode | COMMENTED_I6TBIT;
    @@ -390,12 +390,12 @@ functions). So for example
             PUT_TO(R, c);
             if ((c == ';') && (!(mode & SUBORDINATE_I6TBITS))) {
                 ParsingStages::splat(R, docket);
    -            state->line_provenance = lc;
    -            mode = IGNORE_WS_I6TBIT;
    +            Provenance::set_line(&(state->provenance), lc);
    +            mode = IGNORE_WS_I6TBIT + NOTE_LINES_I6TBIT;
             }
         }
         ParsingStages::splat(R, docket);
    -    state->line_provenance = lc;
    +    Provenance::set_line(&(state->provenance), lc);
         Str::clear(S);
     }
     
    @@ -421,12 +421,9 @@ state being carried in the docket. PUT_TO(R, '\n'); filename *F = NULL; inter_ti lc = 0; - if (Str::len(state->file_provenance) > 0) { - F = Filenames::from_text(state->file_provenance); - lc = state->line_provenance + 1; - } else if (docket->current_filename) { - F = docket->current_filename; - lc = 25; + if (Provenance::is_somewhere(state->provenance)) { + F = Provenance::get_filename(state->provenance); + lc = (inter_ti) Provenance::get_line(state->provenance); } Produce::guard(SplatInstruction::new(IBM, R, I6_dir, A, state->namespace, F, lc, (inter_ti) (InterBookmark::baseline(IBM) + 1), NULL)); diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt index 39c22887a..f75c7ac62 100644 --- a/inform7/Figures/memory-diagnostics.txt +++ b/inform7/Figures/memory-diagnostics.txt @@ -1,4 +1,4 @@ -Total memory consumption was 121595K = 119 MB +Total memory consumption was 121599K = 119 MB ---- was used for 2059550 objects, in 367490 frames in 0 x 800K = 0K = 0 MB: @@ -14,8 +14,8 @@ Total memory consumption was 121595K = 119 MB 2.7% pcalc_prop_array 25 x 1000 = 25000 objects, 3400800 bytes 2.5% inter_name_array 67 x 1000 = 67000 objects, 3218144 bytes 2.1% kind_array 67 x 1000 = 67000 objects, 2682144 bytes + 1.7% inter_schema_token 14043 objects, 2134536 bytes 1.6% inter_name_generator_array 51 x 1000 = 51000 objects, 2041632 bytes - 1.6% inter_schema_token 14043 objects, 2022192 bytes 1.4% package_request 21186 objects, 1864368 bytes 1.4% vocabulary_entry_array 164 x 100 = 16400 objects, 1842048 bytes 1.2% dict_entry_array 477 x 100 = 47700 objects, 1541664 bytes @@ -25,13 +25,13 @@ Total memory consumption was 121595K = 119 MB 1.0% inter_package 26632 objects, 1278336 bytes 0.9% map_data 672 objects, 1128960 bytes 0.8% id_body 947 objects, 1083368 bytes + 0.8% inter_schema_node 8968 objects, 1004416 bytes 0.8% adjective_meaning 202 objects, 1000304 bytes 0.7% excerpt_meaning 3117 objects, 972504 bytes 0.7% production 3957 objects, 918024 bytes 0.7% ptoken 8588 objects, 893152 bytes 0.7% grammatical_usage 3636 objects, 872640 bytes 0.6% individual_form 2566 objects, 862176 bytes - 0.6% inter_schema_node 8968 objects, 860928 bytes 0.5% unary_predicate_array 16 x 1000 = 16000 objects, 640512 bytes 0.3% local_variable_array 47 x 100 = 4700 objects, 452704 bytes 0.3% verb_usage 1148 objects, 394912 bytes @@ -51,11 +51,11 @@ Total memory consumption was 121595K = 119 MB 0.1% nascent_array 2125 objects, 136000 bytes ---- inference 1703 objects, 122616 bytes ---- documentation_ref 1270 objects, 111760 bytes + ---- inter_schema 1524 objects, 109728 bytes ---- imperative_defn 1384 objects, 99648 bytes ---- noun_usage 2407 objects, 96280 bytes ---- anl_entry_array 2 x 1000 = 2000 objects, 96064 bytes ---- preposition 274 objects, 87680 bytes - ---- inter_schema 1524 objects, 85344 bytes ---- inter_tree 6 objects, 81744 bytes ---- lexical_cluster 2521 objects, 80672 bytes ---- pcalc_term_array 2 x 1000 = 2000 objects, 80064 bytes @@ -86,8 +86,8 @@ Total memory consumption was 121595K = 119 MB ---- shared_variable_access_list_array 12 x 100 = 1200 objects, 38784 bytes ---- parsing_data 672 objects, 37632 bytes ---- production_list 630 objects, 35280 bytes - ---- counting_data 672 objects, 32256 bytes ---- regions_data 672 objects, 32256 bytes + ---- counting_data 672 objects, 32256 bytes ---- property_permission 96 objects, 31488 bytes ---- verb_sense 407 objects, 29304 bytes ---- stack_frame_box 305 objects, 29280 bytes @@ -149,37 +149,37 @@ Total memory consumption was 121595K = 119 MB ---- definition 44 objects, 3168 bytes ---- target_vm 20 objects, 2880 bytes ---- use_option 29 objects, 2552 bytes - ---- part_of_inference_data 79 objects, 2528 bytes ---- parentage_inference_data 79 objects, 2528 bytes - ---- kind_constructor_casting_rule_array 1 x 100 objects, 2432 bytes + ---- part_of_inference_data 79 objects, 2528 bytes ---- kind_constructor_instance_array 1 x 100 objects, 2432 bytes + ---- kind_constructor_casting_rule_array 1 x 100 objects, 2432 bytes ---- equation_symbol 30 objects, 2400 bytes ---- JSON_type 33 objects, 2376 bytes ---- scene 1 object, 2352 bytes ---- JSON_single_requirement 49 objects, 2352 bytes ---- build_step 28 objects, 2016 bytes - ---- pronoun_usage 42 objects, 1680 bytes ---- compiler_feature 30 objects, 1680 bytes + ---- pronoun_usage 42 objects, 1680 bytes ---- table_contribution_array 1 x 100 objects, 1632 bytes ---- inform_pipeline 24 objects, 1536 bytes ---- noun_filter_token 22 objects, 1408 bytes - ---- special_meaning_holder 35 objects, 1400 bytes - ---- inter_node_array 35 objects, 1400 bytes ---- inbuild_requirement 35 objects, 1400 bytes + ---- inter_node_array 35 objects, 1400 bytes + ---- special_meaning_holder 35 objects, 1400 bytes ---- constant_phrase 20 objects, 1280 bytes ---- table_column 16 objects, 1280 bytes ---- invocation_options_array 1 x 100 objects, 1224 bytes ---- JSON_requirement 38 objects, 1216 bytes ---- direction_inference_data 30 objects, 1200 bytes - ---- tree_inventory_item 28 objects, 1120 bytes ---- inbuild_search_result 28 objects, 1120 bytes + ---- tree_inventory_item 28 objects, 1120 bytes ---- submodule_identity 33 objects, 1056 bytes ---- runtime_kind_structure 13 objects, 1040 bytes ---- quantifier 16 objects, 1024 bytes - ---- named_rulebook_outcome 15 objects, 960 bytes ---- pipeline_stage 20 objects, 960 bytes - ---- web_md 6 objects, 864 bytes + ---- named_rulebook_outcome 15 objects, 960 bytes ---- JSON_pair_requirement 27 objects, 864 bytes + ---- web_md 6 objects, 864 bytes ---- control_structure_phrase 12 objects, 864 bytes ---- cached_understanding 21 objects, 840 bytes ---- phrase_option_array 1 x 100 objects, 824 bytes @@ -195,10 +195,10 @@ Total memory consumption was 121595K = 119 MB ---- rulebook_outcome 17 objects, 544 bytes ---- small_word_set 11 objects, 528 bytes ---- chapter_md 6 objects, 528 bytes - ---- equation 4 objects, 480 bytes ---- module 6 objects, 480 bytes - ---- i6_memory_setting 14 objects, 448 bytes + ---- equation 4 objects, 480 bytes ---- bp_family 14 objects, 448 bytes + ---- i6_memory_setting 14 objects, 448 bytes ---- inference_family 11 objects, 440 bytes ---- inbuild_genre 8 objects, 384 bytes ---- article_usage 8 objects, 384 bytes @@ -248,7 +248,7 @@ Total memory consumption was 121595K = 119 MB 100.0% was used for memory not allocated for objects: - 57.0% text stream storage 70976924 bytes in 482872 claims + 57.0% text stream storage 70981292 bytes in 482888 claims 4.2% dictionary storage 5315584 bytes in 7623 claims ---- sorting 2720 bytes in 387 claims 5.7% source text 7200000 bytes in 3 claims @@ -266,5 +266,5 @@ Total memory consumption was 121595K = 119 MB ---- code generation workspace for objects 3480 bytes in 19 claims 0.2% emitter array storage 280544 bytes in 2001 claims --151.-4% was overhead - -188610272 bytes = -184189K = -179 MB +-151.-6% was overhead - -188890488 bytes = -184463K = -180 MB diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt index 134acd738..3bcd85c13 100644 --- a/inform7/Figures/timings-diagnostics.txt +++ b/inform7/Figures/timings-diagnostics.txt @@ -1,33 +1,33 @@ 100.0% in inform7 run - 69.8% in compilation to Inter - 49.2% in //Sequence::undertake_queued_tasks// - 4.8% in //MajorNodes::pre_pass// - 3.4% in //MajorNodes::pass_1// - 1.8% in //ImperativeDefinitions::assess_all// - 1.6% in //RTPhrasebook::compile_entries// - 1.4% in //RTKindConstructors::compile// - 1.0% in //Sequence::lint_inter// - 0.6% in //MajorNodes::pass_2// - 0.6% in //Sequence::undertake_queued_tasks// - 0.6% in //Sequence::undertake_queued_tasks// - 0.6% in //World::stage_V// - 0.4% in //ImperativeDefinitions::compile_first_block// - 0.2% in //CompletionModule::compile// - 0.2% in //InferenceSubjects::emit_all// - 0.2% in //RTKindConstructors::compile_permissions// - 0.2% in //Task::make_built_in_kind_constructors// - 2.8% not specifically accounted for - 26.7% in running Inter pipeline + 70.5% in compilation to Inter + 49.8% in //Sequence::undertake_queued_tasks// + 4.9% in //MajorNodes::pre_pass// + 3.5% in //MajorNodes::pass_1// + 1.7% in //ImperativeDefinitions::assess_all// + 1.5% in //RTKindConstructors::compile// + 1.5% in //RTPhrasebook::compile_entries// + 1.1% in //Sequence::lint_inter// + 0.5% in //MajorNodes::pass_2// + 0.5% in //Sequence::undertake_queued_tasks// + 0.5% in //Sequence::undertake_queued_tasks// + 0.5% in //World::stage_V// + 0.3% in //ImperativeDefinitions::compile_first_block// + 0.1% in //CompletionModule::compile// + 0.1% in //InferenceSubjects::emit_all// + 0.1% in //RTKindConstructors::compile_permissions// + 0.1% in //Task::make_built_in_kind_constructors// + 0.1% in //World::stages_II_and_III// + 2.5% not specifically accounted for + 25.8% in running Inter pipeline 10.0% in step 14/15: generate inform6 -> auto.inf - 6.0% in step 5/15: load-binary-kits - 5.4% in step 6/15: make-synoptic-module - 1.8% in step 9/15: make-identifiers-unique - 0.4% in step 12/15: eliminate-redundant-operations - 0.4% in step 4/15: compile-splats - 0.4% in step 7/15: shorten-wiring - 0.4% in step 8/15: detect-indirect-calls - 0.2% in step 10/15: reconcile-verbs - 0.2% in step 11/15: eliminate-redundant-labels - 1.4% not specifically accounted for - 3.0% in supervisor - 0.5% not specifically accounted for + 5.6% in step 5/15: load-binary-kits + 5.2% in step 6/15: make-synoptic-module + 1.7% in step 9/15: make-identifiers-unique + 0.3% in step 12/15: eliminate-redundant-operations + 0.3% in step 4/15: compile-splats + 0.3% in step 7/15: shorten-wiring + 0.3% in step 8/15: detect-indirect-calls + 0.1% in step 11/15: eliminate-redundant-labels + 1.3% not specifically accounted for + 3.1% in supervisor + 0.4% not specifically accounted for diff --git a/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json index aaf86b61b..018ce8ae0 100644 --- a/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json +++ b/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "BasicInformExtrasKit", - "version": "10.2.0-beta+6W37" + "version": "10.2.0-beta+6W38" }, "kit-details": { "has-priority": 1 diff --git a/inform7/Internal/Inter/BasicInformKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformKit/kit_metadata.json index 33b6ef69b..f1f49b135 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+6W37" + "version": "10.2.0-beta+6W38" }, "needs": [ { "unless": { diff --git a/inform7/Internal/Inter/CommandParserKit/kit_metadata.json b/inform7/Internal/Inter/CommandParserKit/kit_metadata.json index 254faeeca..fd1614c67 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+6W37" + "version": "10.2.0-beta+6W38" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json b/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json index 3555483d5..ead2265e1 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+6W37" + "version": "10.2.0-beta+6W38" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/WorldModelKit/kit_metadata.json b/inform7/Internal/Inter/WorldModelKit/kit_metadata.json index 3b8a0ef58..77cc27245 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+6W37" + "version": "10.2.0-beta+6W38" }, "needs": [ { "need": { diff --git a/inform7/core-module/Chapter 2/Problems With Source Text.w b/inform7/core-module/Chapter 2/Problems With Source Text.w index 831fa1a4e..ad5a07c01 100644 --- a/inform7/core-module/Chapter 2/Problems With Source Text.w +++ b/inform7/core-module/Chapter 2/Problems With Source Text.w @@ -635,24 +635,27 @@ void SourceProblems::kit_notification(text_stream *kit_name, text_stream *archit } void SourceProblems::I6_level_error(char *message, text_stream *quote, - text_stream *file_ref, int line) { + text_provenance at) { + filename *F = Provenance::get_filename(at); + int line = Provenance::get_line(at); TEMPORARY_TEXT(file) - WRITE_TO(file, "%S", file_ref); + if (F) WRITE_TO(file, "%f", F); TEMPORARY_TEXT(kit) TEMPORARY_TEXT(M) WRITE_TO(M, message, quote); - filename *F = Filenames::from_text(file); - TEMPORARY_TEXT(EX) - Filenames::write_extension(EX, F); - if (Str::eq_insensitive(EX, I".i6t")) { - pathname *P = Filenames::up(F); - if (Str::eq_insensitive(Pathnames::directory_name(P), I"Sections")) - P = Pathnames::up(P); - WRITE_TO(kit, "%S", Pathnames::directory_name(P)); - Str::clear(file); - WRITE_TO(file, "%S", Filenames::get_leafname(F)); + if (Provenance::is_somewhere(at)) { + TEMPORARY_TEXT(EX) + Filenames::write_extension(EX, F); + if (Str::eq_insensitive(EX, I".i6t")) { + pathname *P = Filenames::up(F); + if (Str::eq_insensitive(Pathnames::directory_name(P), I"Sections")) + P = Pathnames::up(P); + WRITE_TO(kit, "%S", Pathnames::directory_name(P)); + Str::clear(file); + WRITE_TO(file, "%S", Filenames::get_leafname(F)); + } + DISCARD_TEXT(EX) } - DISCARD_TEXT(EX) if (trigger_kit_notice) { if (general_kit_notice_issued == FALSE) { StandardProblems::handmade_problem(Task::syntax_tree(), _p_(...)); @@ -679,7 +682,7 @@ void SourceProblems::I6_level_error(char *message, text_stream *quote, Problems::quote_stream(4, kit); if (general_kit_notice_issued) Problems::issue_problem_segment("%2, near line %3: %1."); else Problems::issue_problem_segment("Near line %3 of file %2 in %4: %1."); - } else if (Str::len(file) > 0) { + } else if (Provenance::is_somewhere(at)) { LOG("%S, line %d:\n", file, line); Problems::problem_quote_file(2, file, line); Problems::issue_problem_segment( diff --git a/inform7/imperative-module/Chapter 3/Compile Imperative Definitions.w b/inform7/imperative-module/Chapter 3/Compile Imperative Definitions.w index 178d73400..b94289578 100644 --- a/inform7/imperative-module/Chapter 3/Compile Imperative Definitions.w +++ b/inform7/imperative-module/Chapter 3/Compile Imperative Definitions.w @@ -215,7 +215,8 @@ inter_schema *CompileImperativeDefn::get_back_schema(id_body *idb) { ParsingSchemas::from_inline_phrase_definition( CompileImperativeDefn::get_inline_definition(idb), &(idb->compilation_data.inline_front_schema), - &(idb->compilation_data.inline_back_schema)); + &(idb->compilation_data.inline_back_schema), + Provenance::nowhere()); CompileImperativeDefn::issue_schema_errors(current_sentence, idb->compilation_data.inline_front_schema, idb->compilation_data.inline_back_schema); diff --git a/inter/Tests/Kits/_Results_Ideal/BadKit.txt b/inter/Tests/Kits/_Results_Ideal/BadKit.txt index 2bb3194eb..4d9e87d57 100644 --- a/inter/Tests/Kits/_Results_Ideal/BadKit.txt +++ b/inter/Tests/Kits/_Results_Ideal/BadKit.txt @@ -1,21 +1,21 @@ -inter: inform 6 syntax error in function 'E1': operator '+' used with 1 not 2 operand(s) -inter: inform 6 syntax error in function 'E2': do without until -inter: inform 6 syntax error in function 'E3': expected 'on' or 'off' after 'font', not 'whatever' -inter: inform 6 syntax error in function 'E4': move without to -inter: inform 6 syntax error in function 'E5': 'for' header with too few clauses -inter: inform 6 syntax error in function 'E6': 'for' header with too many clauses -inter: inform 6 syntax error in function 'E7': unexpected '{ ... }' code block -inter: inform 6 syntax error in function 'E8': unexpected '{' -inter: inform 6 syntax error in function 'E8': unexpected use of reserved word 'print' -inter: inform 6 syntax error in function 'E8': unexpected '}' -inter: inform 6 syntax error in function 'E9': no matching '#endif' -inter: inform 6 syntax error in function 'E9': misplaced directive -inter: inform 6 syntax error in function 'E10': unexpected ',' -inter: inform 6 syntax error in function 'E11': malformed '#if...' -inter: inform 6 syntax error in function 'E11': misplaced directive -inter: inform 6 syntax error in function 'E11': misplaced directive -inter: inform 6 syntax error in function 'E12': '@something' was unexpected in expression context -inter: inform 6 syntax error in function 'E13': too many arguments for call-message -inter: inform 6 syntax error in function 'E14': malformed literal number '$ffa0z' -inter: inform 6 syntax error in function 'E15': unexpected use of reserved word 'return' -inter: inform 6 syntax error in function 'E16': 'objectloop' without visible variable +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 11: Inform 6 syntax error in function 'E1': operator '+' used with 1 not 2 operand(s) +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 13: Inform 6 syntax error in function 'E2': do without until +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 19: Inform 6 syntax error in function 'E3': expected 'on' or 'off' after 'font', not 'whatever' +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 21: Inform 6 syntax error in function 'E4': move without to +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 23: Inform 6 syntax error in function 'E5': 'for' header with too few clauses +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 25: Inform 6 syntax error in function 'E6': 'for' header with too many clauses +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 27: Inform 6 syntax error in function 'E7': unexpected '{ ... }' code block +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 29: Inform 6 syntax error in function 'E8': unexpected '{' +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 29: Inform 6 syntax error in function 'E8': unexpected use of reserved word 'print' +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 29: Inform 6 syntax error in function 'E8': unexpected '}' +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 31: Inform 6 syntax error in function 'E9': no matching '#endif' +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 31: Inform 6 syntax error in function 'E9': misplaced directive +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 33: Inform 6 syntax error in function 'E10': unexpected ',' +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 35: Inform 6 syntax error in function 'E11': malformed '#if...' +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 35: Inform 6 syntax error in function 'E11': misplaced directive +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 35: Inform 6 syntax error in function 'E11': misplaced directive +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 37: Inform 6 syntax error in function 'E12': '@something' was unexpected in expression context +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 39: Inform 6 syntax error in function 'E13': too many arguments for call-message +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 41: Inform 6 syntax error in function 'E14': malformed literal number '$ffa0z' +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 43: Inform 6 syntax error in function 'E15': unexpected use of reserved word 'return' +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 45: Inform 6 syntax error in function 'E16': 'objectloop' without visible variable diff --git a/inter/building-module/Chapter 2/Inter Schemas.w b/inter/building-module/Chapter 2/Inter Schemas.w index 1715b03d6..c170888df 100644 --- a/inter/building-module/Chapter 2/Inter Schemas.w +++ b/inter/building-module/Chapter 2/Inter Schemas.w @@ -17,17 +17,19 @@ typedef struct inter_schema { int mid_case; /* does this seem to be used inside a switch case? */ int dereference_mode; /* emit from this in dereference-pointers mode */ struct linked_list *parsing_errors; /* of |schema_parsing_error| */ + struct text_provenance provenance; CLASS_DEFINITION } inter_schema; @ = -inter_schema *InterSchemas::new(text_stream *source) { +inter_schema *InterSchemas::new(text_stream *source, text_provenance provenance) { inter_schema *sch = CREATE(inter_schema); sch->converted_from = Str::duplicate(source); sch->node_tree = NULL; sch->mid_case = FALSE; sch->dereference_mode = FALSE; sch->parsing_errors = NULL; + sch->provenance = provenance; return sch; } @@ -68,11 +70,13 @@ typedef struct inter_schema_node { int blocked_by_conditional; /* used in code generation */ + struct text_provenance provenance; /* used for error reporting */ CLASS_DEFINITION } inter_schema_node; @ = -inter_schema_node *InterSchemas::new_node(inter_schema *sch, int isnt) { +inter_schema_node *InterSchemas::new_node(inter_schema *sch, int isnt, + inter_schema_token *near_here) { inter_schema_node *isn = CREATE(inter_schema_node); isn->parent_schema = sch; @@ -92,6 +96,17 @@ inter_schema_node *InterSchemas::new_node(inter_schema *sch, int isnt) { isn->unopened = FALSE; isn->blocked_by_conditional = FALSE; + isn->provenance = (sch)?(sch->provenance):(Provenance::nowhere()); + if ((near_here) && (Provenance::is_somewhere(isn->provenance))) + Provenance::set_line(&(isn->provenance), + Provenance::get_line(isn->provenance) + near_here->line_offset); + return isn; +} + +inter_schema_node *InterSchemas::new_node_near_node(inter_schema *sch, int isnt, + inter_schema_node *near_here) { + inter_schema_node *isn = InterSchemas::new_node(sch, isnt, NULL); + if (near_here) isn->provenance = near_here->provenance; return isn; } @@ -141,7 +156,7 @@ void InterSchemas::mark_unopened(inter_schema_node *isn) { inter_schema *sch = isn->parent_schema; inter_schema_node *top = sch->node_tree; inter_schema_node *code_isn = - InterSchemas::new_node(isn->parent_schema, CODE_ISNT); + InterSchemas::new_node(isn->parent_schema, CODE_ISNT, NULL); code_isn->child_node = top; sch->node_tree = code_isn; for (inter_schema_node *n = top; n; n = n->next_node) @@ -232,13 +247,13 @@ typedef struct inter_schema_token { int preinsert; /* fleeting markers only */ int postinsert; - + int line_offset; /* counting lines for error message use */ CLASS_DEFINITION } inter_schema_token; @ = inter_schema_token *InterSchemas::new_token(int type, text_stream *material, - inter_ti operation_primitive, int reserved_word, int n) { + inter_ti operation_primitive, int reserved_word, int n, int offset) { inter_schema_token *t = CREATE(inter_schema_token); t->ist_type = type; t->material = Str::duplicate(material); @@ -260,6 +275,7 @@ inter_schema_token *InterSchemas::new_token(int type, text_stream *material, t->constant_number = n; t->preinsert = FALSE; t->postinsert = FALSE; + t->line_offset = offset; return t; } @@ -376,7 +392,7 @@ inter_schema_token *InterSchemas::new_token(int type, text_stream *material, = void InterSchemas::add_token(inter_schema *sch, inter_schema_token *t) { if (sch->node_tree == NULL) - sch->node_tree = InterSchemas::new_node(sch, EXPRESSION_ISNT); + sch->node_tree = InterSchemas::new_node(sch, EXPRESSION_ISNT, t); InterSchemas::add_token_to_node(sch->node_tree, t); } @@ -457,6 +473,11 @@ void InterSchemas::log_depth(inter_schema_node *isn, int depth) { InterSchemas::log_just(isn, depth); } void InterSchemas::log_just(inter_schema_node *isn, int depth) { + if (Provenance::is_somewhere(isn->provenance)) { + LOG("%04d ", Provenance::get_line(isn->provenance)); + } else { + LOG(".... "); + } if (isn->blocked_by_conditional) LOG("XX"); else LOG(" "); for (int d = 0; d < depth; d++) LOG(" "); switch (isn->isn_type) { @@ -639,6 +660,7 @@ which, of course, it usually isn't. = typedef struct schema_parsing_error { struct text_stream *message; + struct text_provenance provenance; CLASS_DEFINITION } schema_parsing_error; @@ -648,6 +670,13 @@ void InterSchemas::throw_error(inter_schema_node *at, text_stream *message) { at->parent_schema->parsing_errors = NEW_LINKED_LIST(schema_parsing_error); schema_parsing_error *err = CREATE(schema_parsing_error); err->message = Str::duplicate(message); + if (at) { + if (Provenance::is_somewhere(at->provenance)) err->provenance = at->provenance; + else if (at->parent_schema) err->provenance = at->parent_schema->provenance; + else err->provenance = Provenance::nowhere(); + } else { + err->provenance = Provenance::nowhere(); + } ADD_TO_LINKED_LIST(err, schema_parsing_error, at->parent_schema->parsing_errors); LOG("Schema error: %S\n", message); LOG("$1\n", at->parent_schema); diff --git a/inter/building-module/Chapter 2/Parsing Inter Schemas.w b/inter/building-module/Chapter 2/Parsing Inter Schemas.w index 6ade46d3f..7aa715508 100644 --- a/inter/building-module/Chapter 2/Parsing Inter Schemas.w +++ b/inter/building-module/Chapter 2/Parsing Inter Schemas.w @@ -14,8 +14,8 @@ Note that the results can be tested independently of //inform7// using the samples produce the correct schemas. = -inter_schema *ParsingSchemas::from_text(text_stream *from) { - return ParsingSchemas::back_end(from, FALSE, 0, NULL); +inter_schema *ParsingSchemas::from_text(text_stream *from, text_provenance provenance) { + return ParsingSchemas::back_end(from, FALSE, 0, NULL, provenance); } @h Abbreviated I6S notation. @@ -45,7 +45,7 @@ inter_schema *ParsingSchemas::from_i6s(text_stream *from, if (de) return (inter_schema *) Dictionaries::value_for_entry(de); inter_schema *result = ParsingSchemas::back_end(from, TRUE, - no_quoted_inames, quoted_inames); + no_quoted_inames, quoted_inames, Provenance::nowhere()); Dictionaries::create(i6s_inter_schema_cache, from); Dictionaries::write_value(i6s_inter_schema_cache, from, (void *) result); @@ -84,16 +84,16 @@ so it's the caller's responsibility to check for those and act accordingly. = void ParsingSchemas::from_inline_phrase_definition(wchar_t *from, inter_schema **head, - inter_schema **tail) { + inter_schema **tail, text_provenance provenance) { *head = NULL; *tail = NULL; text_stream *head_defn = Str::new(); text_stream *tail_defn = Str::new(); @; - *head = ParsingSchemas::from_text(head_defn); + *head = ParsingSchemas::from_text(head_defn, provenance); if (Str::len(tail_defn) > 0) - *tail = ParsingSchemas::from_text(tail_defn); + *tail = ParsingSchemas::from_text(tail_defn, provenance); } @ A tail will only be present if the definition contains |{-block}|. If it @@ -148,8 +148,8 @@ and then this will work as might be hoped: = inter_schema *ParsingSchemas::back_end(text_stream *from, int abbreviated, - int no_quoted_inames, void **quoted_inames) { - inter_schema *sch = InterSchemas::new(from); + int no_quoted_inames, void **quoted_inames, text_provenance provenance) { + inter_schema *sch = InterSchemas::new(from, provenance); if ((Log::aspect_switched_on(SCHEMA_COMPILATION_DA)) || (Log::aspect_switched_on(SCHEMA_COMPILATION_DETAILS_DA))) LOG("\n\n------------\nCompiling inter schema from: <%S>\n", from); diff --git a/inter/building-module/Chapter 2/Ramification.w b/inter/building-module/Chapter 2/Ramification.w index 5b37965e6..8565a0470 100644 --- a/inter/building-module/Chapter 2/Ramification.w +++ b/inter/building-module/Chapter 2/Ramification.w @@ -130,14 +130,14 @@ int Ramification::implied_braces(inter_schema_node *par, inter_schema_node *at) if ((prev) && (t->preinsert > 0)) { t->preinsert--; inter_schema_token *open_b = - InterSchemas::new_token(OPEN_BRACE_ISTT, I"{", 0, 0, -1); + InterSchemas::new_token(OPEN_BRACE_ISTT, I"{", 0, 0, -1, t->line_offset); InterSchemas::add_token_after(open_b, prev); changed = TRUE; } if (t->postinsert > 0) { t->postinsert--; inter_schema_token *close_b = - InterSchemas::new_token(CLOSE_BRACE_ISTT, I"}", 0, 0, -1); + InterSchemas::new_token(CLOSE_BRACE_ISTT, I"}", 0, 0, -1, t->line_offset); InterSchemas::add_token_after(close_b, t); changed = TRUE; } @@ -210,12 +210,12 @@ int Ramification::unbrace_schema(inter_schema_node *par, inter_schema_node *isn) if ((prev) && (t->ist_type == OPEN_BRACE_ISTT)) { prev->next = NULL; inter_schema_node *code_isn = - InterSchemas::new_node(isn->parent_schema, CODE_ISNT); + InterSchemas::new_node(isn->parent_schema, CODE_ISNT, t); isn->child_node = code_isn; code_isn->parent_node = isn; inter_schema_node *new_isn = - InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); + InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, t); code_isn->child_node = new_isn; new_isn->parent_node = code_isn; @@ -245,7 +245,7 @@ int Ramification::unbrace_schema(inter_schema_node *par, inter_schema_node *isn) resumed = resumed->next; if (resumed) { inter_schema_node *new_isn = - InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); + InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, t); new_isn->expression_tokens = resumed; new_isn->parent_node = isn->parent_node; InterSchemas::changed_tokens_on(new_isn); @@ -296,7 +296,7 @@ int Ramification::divide_schema(inter_schema_node *par, inter_schema_node *isn) if (t->ist_type == CLOSE_ROUND_ISTT) bl--; if ((bl == 0) && (t->ist_type == DIVIDER_ISTT) && (t->next)) { inter_schema_node *new_isn = - InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); + InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, t); new_isn->expression_tokens = t->next; new_isn->parent_node = isn->parent_node; if (isn->child_node) { @@ -398,7 +398,8 @@ int Ramification::resolve_halfopen_blocks(inter_schema_node *par, inter_schema_n t->ist_type = WHITE_SPACE_ISTT; t->material = I" "; if (t->next) { - inter_schema_node *new_isn = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); + inter_schema_node *new_isn = + InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, t); new_isn->expression_tokens = t->next; new_isn->parent_node = isn->parent_node; if (isn->child_node) { @@ -458,7 +459,7 @@ int Ramification::break_early_bracings(inter_schema_node *par, inter_schema_node } if ((m) && (n) && (n->ist_type == RESERVED_ISTT)) { inter_schema_node *new_isn = - InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); + InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, n); new_isn->expression_tokens = n; new_isn->parent_node = isn->parent_node; if (isn->child_node) { @@ -555,12 +556,12 @@ int Ramification::split_switches_into_cases(inter_schema_node *par, inter_schema inter_schema_node *sw_val = NULL; inter_schema_node *sw_code = NULL; if (defaulter) { - sw_code = InterSchemas::new_node(isn->parent_schema, CODE_ISNT); + sw_code = InterSchemas::new_node(isn->parent_schema, CODE_ISNT, n); isn->child_node = sw_code; sw_code->parent_node = isn; } else { - sw_val = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); - sw_code = InterSchemas::new_node(isn->parent_schema, CODE_ISNT); + sw_val = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, n); + sw_code = InterSchemas::new_node(isn->parent_schema, CODE_ISNT, n); sw_val->next_node = sw_code; sw_val->parent_node = isn; isn->child_node = sw_val; sw_code->parent_node = isn; @@ -595,7 +596,7 @@ int Ramification::split_switches_into_cases(inter_schema_node *par, inter_schema isn->isn_clarifier = CASE_BIP; inter_schema_node *sw_code_exp = - InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); + InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, n); sw_code_exp->expression_tokens = n->next; sw_code->child_node = sw_code_exp; @@ -705,7 +706,7 @@ int Ramification::split_print_statements(inter_schema_node *par, inter_schema_no if (n->reserved_word == PRINT_I6RW) n->material = I"print"; else n->material = I"print_ret"; inter_schema_node *new_isn = - InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); + InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, n); new_isn->expression_tokens = n; new_isn->parent_node = isn->parent_node; InterSchemas::changed_tokens_on(new_isn); @@ -983,13 +984,13 @@ turned into function calls too, leaving: cons->expression_tokens = printing_rule; inter_schema_token *open_b = - InterSchemas::new_token(OPEN_ROUND_ISTT, I"(", 0, 0, -1); + InterSchemas::new_token(OPEN_ROUND_ISTT, I"(", 0, 0, -1, printing_rule->line_offset); InterSchemas::add_token_after(open_b, cons->expression_tokens); open_b->next = n; n = open_b; while ((n) && (n->next)) n = n->next; inter_schema_token *close_b = - InterSchemas::new_token(CLOSE_ROUND_ISTT, I")", 0, 0, -1); + InterSchemas::new_token(CLOSE_ROUND_ISTT, I")", 0, 0, -1, printing_rule->line_offset); InterSchemas::add_token_after(close_b, n); which_statement = 0; operand1 = NULL; @@ -1002,17 +1003,17 @@ character, and one to return |true|. inter_schema_node *save_next = cons->next_node; cons->next_node = - InterSchemas::new_node(cons->parent_schema, STATEMENT_ISNT); + InterSchemas::new_node(cons->parent_schema, STATEMENT_ISNT, n); cons->next_node->parent_node = cons->parent_node; cons->next_node->isn_clarifier = PRINT_BIP; cons->next_node->child_node = - InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT); + InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT, n); cons->next_node->child_node->parent_node = cons->next_node; InterSchemas::add_token_to_node(cons->next_node->child_node, - InterSchemas::new_token(DQUOTED_ISTT, I"\n", 0, 0, -1)); + InterSchemas::new_token(DQUOTED_ISTT, I"\n", 0, 0, -1, 0)); cons->next_node->next_node = - InterSchemas::new_node(cons->parent_schema, STATEMENT_ISNT); + InterSchemas::new_node(cons->parent_schema, STATEMENT_ISNT, n); cons->next_node->next_node->parent_node = cons->parent_node; cons->next_node->next_node->isn_clarifier = RETURN_BIP; @@ -1048,7 +1049,7 @@ becomes cons->dir_clarifier = InterSchemas::opening_directive_word(cons); if (InterSchemas::second_dark_token(cons)) { inter_schema_node *new_isn = - InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT); + InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT, first); cons->child_node = new_isn; new_isn->parent_node = cons; new_isn->expression_tokens = InterSchemas::second_dark_token(cons); @@ -1075,7 +1076,7 @@ to be recognised for what they are. if ((n) && (Str::eq(l->material, I")"))) continue; if (l->ist_type != WHITE_SPACE_ISTT) { inter_schema_node *new_isn = - InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT); + InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT, n); new_isn->expression_tokens = l; l->next = NULL; l->owner = new_isn; if (l->operation_primitive) { l->ist_type = IDENTIFIER_ISTT; @@ -1123,7 +1124,7 @@ assembly instructions |@push| or |@pull| -- we do the following. if (which_statement == STORE_BIP) @; @ = - first_child = InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT); + first_child = InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT, first); if (operand1 == NULL) operand1 = InterSchemas::second_dark_token(cons); first_child->expression_tokens = operand1; InterSchemas::changed_tokens_on(first_child); @@ -1140,11 +1141,13 @@ they cannot both apply.) if (dangle_number >= 0) { text_stream *T = Str::new(); WRITE_TO(T, "%d", dangle_number); - first_child->expression_tokens = InterSchemas::new_token(NUMBER_ISTT, T, 0, 0, -1); + first_child->expression_tokens = + InterSchemas::new_token(NUMBER_ISTT, T, 0, 0, -1, 0); first_child->expression_tokens->owner = first_child; } if (Str::len(dangle_text) > 0) { - first_child->expression_tokens = InterSchemas::new_token(DQUOTED_ISTT, dangle_text, 0, 0, -1); + first_child->expression_tokens = + InterSchemas::new_token(DQUOTED_ISTT, dangle_text, 0, 0, -1, 0); first_child->expression_tokens->owner = first_child; } @@ -1153,7 +1156,7 @@ they cannot both apply.) @ = if (operand2) { inter_schema_node *second_child = - InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT); + InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT, first); if (which_statement == IFELSE_BIP) { second_child->semicolon_terminated = TRUE; second_child->next_node = first_child->next_node->next_node; @@ -1189,14 +1192,14 @@ But it is legal to do so in this schema, and that is what our expression node do cons->child_node = NULL; cons->expression_tokens = A->expression_tokens; cons->expression_tokens->next = - InterSchemas::new_token(OPERATOR_ISTT, I".", PROPERTYVALUE_BIP, 0, -1); + InterSchemas::new_token(OPERATOR_ISTT, I".", PROPERTYVALUE_BIP, 0, -1, 0); cons->expression_tokens->next->next = B->expression_tokens; cons->expression_tokens->next->next->next = - InterSchemas::new_token(OPERATOR_ISTT, I"=", STORE_BIP, 0, -1); + InterSchemas::new_token(OPERATOR_ISTT, I"=", STORE_BIP, 0, -1, 0); text_stream *T = Str::new(); WRITE_TO(T, "%d", dangle_number); cons->expression_tokens->next->next->next->next = - InterSchemas::new_token(NUMBER_ISTT, T, 0, 0, -1); + InterSchemas::new_token(NUMBER_ISTT, T, 0, 0, -1, 0); InterSchemas::changed_tokens_on(cons); @h The break for statements ramification. @@ -1240,6 +1243,7 @@ int Ramification::break_for_statements(inter_schema_node *par, inter_schema_node return FALSE; } inter_schema_token *n = predicates->expression_tokens; + inter_schema_token *near = n; inter_schema_node *code_node = predicates->next_node; int bl = 0, cw = 0; inter_schema_token *from[3], *to[3]; @@ -1267,7 +1271,8 @@ int Ramification::break_for_statements(inter_schema_node *par, inter_schema_node return FALSE; } for (int i=0; i<3; i++) { - inter_schema_node *eval_isn = InterSchemas::new_node(isn->parent_schema, EVAL_ISNT); + inter_schema_node *eval_isn = + InterSchemas::new_node(isn->parent_schema, EVAL_ISNT, near); if (i == 0) isn->child_node = eval_isn; if (i == 1) isn->child_node->next_node = eval_isn; if (i == 2) { @@ -1276,7 +1281,8 @@ int Ramification::break_for_statements(inter_schema_node *par, inter_schema_node } eval_isn->parent_node = isn; - inter_schema_node *expr_isn = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); + inter_schema_node *expr_isn = + InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, near); eval_isn->child_node = expr_isn; expr_isn->parent_node = eval_isn; @@ -1334,7 +1340,8 @@ int Ramification::add_missing_bodies(inter_schema_node *par, inter_schema_node * return FALSE; } if (actual == req-1) { - inter_schema_node *code_isn = InterSchemas::new_node(isn->parent_schema, CODE_ISNT); + inter_schema_node *code_isn = + InterSchemas::new_node_near_node(isn->parent_schema, CODE_ISNT, isn); code_isn->parent_node = isn; inter_schema_node *ch = isn->child_node; @@ -1415,7 +1422,7 @@ that |(x+1)| would now become: = @ = - inter_schema_node *sub_node = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); + inter_schema_node *sub_node = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, from); sub_node->expression_tokens = from; for (inter_schema_token *l = sub_node->expression_tokens; l; l=l->next) if (l->next == to) @@ -1472,7 +1479,7 @@ int Ramification::top_level_commas(inter_schema_node *par, inter_schema_node *is prev = n; n = n->next; while ((n) && (n->ist_type == WHITE_SPACE_ISTT)) { prev = n; n = n->next; } inter_schema_node *new_isn = - InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); + InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, n); new_isn->expression_tokens = n; new_isn->parent_node = isn->parent_node; InterSchemas::changed_tokens_on(new_isn); @@ -1503,7 +1510,8 @@ int Ramification::multiple_case_values(inter_schema_node *par, inter_schema_node inter_schema_node *A = isn->child_node; inter_schema_node *B = isn->child_node->next_node; if ((A) && (B) && (B->next_node)) { - inter_schema_node *C = InterSchemas::new_node(isn->parent_schema, OPERATION_ISNT); + inter_schema_node *C = + InterSchemas::new_node_near_node(isn->parent_schema, OPERATION_ISNT, A); C->isn_clarifier = ALTERNATIVECASE_BIP; C->child_node = A; A->parent_node = C; B->parent_node = C; @@ -1657,7 +1665,7 @@ Here the final operator is the |+|, and there are both left and right operands. @ = inter_schema_node *left_operand_node = - InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); + InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, from); left_operand_node->expression_tokens = from; for (inter_schema_token *l = left_operand_node->expression_tokens; l; l=l->next) if (l->next == to) @@ -1669,7 +1677,7 @@ Here the final operator is the |+|, and there are both left and right operands. @ = inter_schema_node *right_operand_node = - InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); + InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, from); right_operand_node->expression_tokens = from; InterSchemas::changed_tokens_on(right_operand_node); if (isn->child_node == NULL) { @@ -1803,7 +1811,7 @@ array lookup is performed to find the address of the function to call. @ = if ((from) && (to) && (from != to)) { inter_schema_node *new_isn = - InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); + InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, from); new_isn->expression_tokens = from; for (inter_schema_token *l = new_isn->expression_tokens; l; l=l->next) if (l->next == to) @@ -1827,8 +1835,9 @@ int Ramification::implied_return_values(inter_schema_node *par, inter_schema_nod for (inter_schema_node *prev = NULL; isn; prev = isn, isn = isn->next_node) { if ((isn->isn_type == STATEMENT_ISNT) && (isn->isn_clarifier == RETURN_BIP) && (isn->child_node == FALSE)) { - inter_schema_node *one = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT); - one->expression_tokens = InterSchemas::new_token(NUMBER_ISTT, I"1", 0, 0, -1); + inter_schema_node *one = + InterSchemas::new_node_near_node(isn->parent_schema, EXPRESSION_ISNT, isn); + one->expression_tokens = InterSchemas::new_token(NUMBER_ISTT, I"1", 0, 0, -1, 0); one->expression_tokens->owner = one; isn->child_node = one; one->parent_node = isn; diff --git a/inter/building-module/Chapter 2/Tokenisation.w b/inter/building-module/Chapter 2/Tokenisation.w index 58e5d056e..b0b0a547e 100644 --- a/inter/building-module/Chapter 2/Tokenisation.w +++ b/inter/building-module/Chapter 2/Tokenisation.w @@ -34,11 +34,13 @@ void Tokenisation::go(inter_schema *sch, text_stream *from, int pos, int abbrevi inter_schema_token *preceding_token = NULL; int definition_length = Str::len(from); + int line_offset = 0; text_stream *current_raw = Str::new(); int tokeniser_state = NO_TOKSTATE; for (; pos; tokeniser_state = WHITE_TOKSTATE; @@ -117,17 +119,17 @@ void Tokenisation::go(inter_schema *sch, text_stream *from, int pos, int abbrevi switch (tokeniser_state) { case WHITE_TOKSTATE: InterSchemas::add_token(sch, - InterSchemas::new_token(WHITE_SPACE_ISTT, I" ", 0, 0, -1)); + InterSchemas::new_token(WHITE_SPACE_ISTT, I" ", 0, 0, -1, line_offset)); break; case DQUOTED_TOKSTATE: Tokenisation::de_escape_text(current_raw); InterSchemas::add_token(sch, - InterSchemas::new_token(DQUOTED_ISTT, current_raw, 0, 0, -1)); + InterSchemas::new_token(DQUOTED_ISTT, current_raw, 0, 0, -1, line_offset)); break; case SQUOTED_TOKSTATE: Tokenisation::de_escape_sq_text(current_raw); InterSchemas::add_token(sch, - InterSchemas::new_token(SQUOTED_ISTT, current_raw, 0, 0, -1)); + InterSchemas::new_token(SQUOTED_ISTT, current_raw, 0, 0, -1, line_offset)); break; default: @; @@ -172,7 +174,7 @@ void Tokenisation::go(inter_schema *sch, text_stream *from, int pos, int abbrevi @ = if (Str::len(source_text_fragment) > 0) { InterSchemas::add_token(sch, - InterSchemas::new_token(I7_ISTT, source_text_fragment, 0, 0, -1)); + InterSchemas::new_token(I7_ISTT, source_text_fragment, 0, 0, -1, line_offset)); } @ Material in braces sometimes indicates an inline command, but not always, @@ -202,7 +204,7 @@ a "bracing". a bracing. @ = - inter_schema_token *t = InterSchemas::new_token(INLINE_ISTT, bracing, 0, 0, -1); + inter_schema_token *t = InterSchemas::new_token(INLINE_ISTT, bracing, 0, 0, -1, line_offset); t->bracing = Str::duplicate(bracing); t->command = Str::new(); t->operand = Str::new(); @@ -434,7 +436,7 @@ of modifiers are allowed. See //calculus: Compilation Schemas//. @; TEMPORARY_TEXT(T) for (int i=pos; i<=at; i++) PUT_TO(T, Str::get_at(from, i)); - inter_schema_token *t = InterSchemas::new_token(INLINE_ISTT, T, 0, 0, -1); + inter_schema_token *t = InterSchemas::new_token(INLINE_ISTT, T, 0, 0, -1, line_offset); t->bracing = Str::duplicate(T); t->inline_command = substitute_ISINC; t->inline_modifiers = iss_bitmap; @@ -444,7 +446,7 @@ of modifiers are allowed. See //calculus: Compilation Schemas//. DISCARD_TEXT(T) pos = at; } else if (c == '&') { - inter_schema_token *t = InterSchemas::new_token(INLINE_ISTT, I"*&", 0, 0, -1); + inter_schema_token *t = InterSchemas::new_token(INLINE_ISTT, I"*&", 0, 0, -1, line_offset); t->bracing = I"*&"; t->inline_command = combine_ISINC; t->inline_modifiers = iss_bitmap; @@ -657,7 +659,7 @@ inclusive; we ignore an empty token. int which_rw = 0, which_number = -1, which_quote = -1; @; - inter_schema_token *n = InterSchemas::new_token(is, T, which, which_rw, which_number); + inter_schema_token *n = InterSchemas::new_token(is, T, which, which_rw, which_number, line_offset); #ifdef CORE_MODULE if (which_quote >= 0) n->as_quoted = quoted_inames[which_quote]; #endif diff --git a/inter/building-module/Preliminaries/What This Module Does.w b/inter/building-module/Preliminaries/What This Module Does.w index 940e6d916..4ec0b943b 100644 --- a/inter/building-module/Preliminaries/What This Module Does.w +++ b/inter/building-module/Preliminaries/What This Module Does.w @@ -165,7 +165,7 @@ and we do that in this module, using a data structure called an //inter_schema// in effect, an annotated syntax tree -- to represent the results of parsing Inform 6 notation. For example, this: = (text as InC) - inter_schema *sch = ParsingSchemas::from_text(I"return true;"); + inter_schema *sch = ParsingSchemas::from_text(I"return true;", where); EmitInterSchemas::emit(I, ..., sch, ...); = generates Inter code equivalent to the example above.[3] But the real power of diff --git a/inter/building-test/Chapter 1/Unit Tests.w b/inter/building-test/Chapter 1/Unit Tests.w index 0c3f90312..a23cbc4e6 100644 --- a/inter/building-test/Chapter 1/Unit Tests.w +++ b/inter/building-test/Chapter 1/Unit Tests.w @@ -74,7 +74,8 @@ void Unit::test_harvester(text_stream *text, text_file_position *tfp, void *v_iu @ = LOG("Test: parse schema from:\n%S\n", iut->test_input); Str::trim_white_space(iut->test_input); - inter_schema *sch = ParsingSchemas::from_text(iut->test_input); + inter_schema *sch = ParsingSchemas::from_text(iut->test_input, + Provenance::at_file_and_line(I"hypothetical.txt", 1)); if (sch == NULL) LOG("\n"); else if (sch->node_tree == NULL) LOG("10) && (n<10)): n++) print n; - * (statement) !for - * (eval) - * (operation) !store - * (expr) +0001 * (statement) !for +0001 * (eval) +0001 * (operation) !store +0001 * (expr) IDENTIFIER n - * (expr) +0001 * (expr) NUMBER 0 - * (eval) - * (subexpression) - * (operation) !and - * (subexpression) - * (operation) !lt - * (expr) +0001 * (eval) +0001 * (subexpression) +0001 * (operation) !and +0001 * (subexpression) +0001 * (operation) !lt +0001 * (expr) IDENTIFIER n - * (operation) !lookup - * (expr) +0001 * (operation) !lookup +0001 * (expr) IDENTIFIER RE_Subexpressions - * (expr) +0001 * (expr) NUMBER 10 - * (subexpression) - * (operation) !lt - * (expr) +0001 * (subexpression) +0001 * (operation) !lt +0001 * (expr) IDENTIFIER n - * (expr) +0001 * (expr) NUMBER 10 - * (eval) - * (operation) !postincrement - * (expr) +0001 * (eval) +0001 * (operation) !postincrement +0002 * (expr) IDENTIFIER n - * (code) - * (statement) !printnumber - * (expr) +0002 * (code) +0002 * (statement) !printnumber +0002 * (expr) IDENTIFIER n ========= Test: parse schema from: spaces j; print (I7_string) str; - * (statement) !spaces - * (expr) +0001 * (statement) !spaces +0001 * (expr) IDENTIFIER j - * (call) - * (expr) +0002 * (call) +0002 * (expr) IDENTIFIER I7_String - * (expr) +0002 * (expr) IDENTIFIER str ========= Test: parse schema from: if (i == 1) print "Okay"; else "*** Arrcpy doesn't support this ***"; - * (statement) !ifelse - * (subexpression) - * (operation) !eq - * (expr) +0001 * (statement) !ifelse +0001 * (subexpression) +0001 * (operation) !eq +0001 * (expr) IDENTIFIER i - * (expr) +0001 * (expr) NUMBER 1 - * (code) - * (statement) !print - * (expr) +0001 * (code) +0001 * (statement) !print +0001 * (expr) DQUOTED Okay - * (code) - * (expr) ; +0002 * (code) +0002 * (expr) ; DQUOTED *** Arrcpy doesn't support this *** ========= Test: parse schema from: a-1 - * (operation) !minus - * (expr) +0002 * (operation) !minus +0002 * (expr) IDENTIFIER a - * (expr) +0002 * (expr) NUMBER 1 ========= Test: parse schema from: @@ -171,13 +171,13 @@ Test: parse schema from: print "Hi!"; } until (x); - * (statement) !do - * (subexpression) - * (expr) +0001 * (statement) !do +0001 * (subexpression) +0004 * (expr) IDENTIFIER x - * (code) - * (statement) !print - * (expr) +0002 * (code) +0002 * (statement) !print +0002 * (expr) DQUOTED Hi! ========= Test: parse schema from: @@ -185,18 +185,18 @@ Test: parse schema from: if (a) return wd; } until (a); - * (statement) !do - * (subexpression) - * (expr) +0001 * (statement) !do +0001 * (subexpression) +0004 * (expr) IDENTIFIER a - * (code) - * (statement) !if - * (subexpression) - * (expr) +0002 * (code) +0002 * (statement) !if +0002 * (subexpression) +0002 * (expr) IDENTIFIER a - * (code) - * (statement) !return - * (expr) +0002 * (code) +0002 * (statement) !return +0002 * (expr) IDENTIFIER wd ========= Test: parse schema from: @@ -205,65 +205,65 @@ Test: parse schema from: index++; } until ((line_token-->index == ENDIT_TOKEN) || (((line_token-->index)->0 & $10) == 0)); - * (statement) !do - * (subexpression) - * (operation) !or - * (subexpression) - * (operation) !eq - * (operation) !lookup - * (expr) +0001 * (statement) !do +0001 * (subexpression) +0004 * (operation) !or +0004 * (subexpression) +0004 * (operation) !eq +0004 * (operation) !lookup +0004 * (expr) IDENTIFIER line_token - * (expr) +0004 * (expr) IDENTIFIER index - * (expr) +0004 * (expr) IDENTIFIER ENDIT_TOKEN - * (subexpression) - * (operation) !eq - * (subexpression) - * (operation) !bitwiseand - * (operation) !lookupbyte - * (subexpression) - * (operation) !lookup - * (expr) +0004 * (subexpression) +0004 * (operation) !eq +0004 * (subexpression) +0004 * (operation) !bitwiseand +0004 * (operation) !lookupbyte +0004 * (subexpression) +0004 * (operation) !lookup +0004 * (expr) IDENTIFIER line_token - * (expr) +0004 * (expr) IDENTIFIER index - * (expr) +0004 * (expr) NUMBER 0 - * (expr) +0004 * (expr) HEX_NUMBER $10 - * (expr) +0005 * (expr) NUMBER 0 - * (code) - * (statement) !if - * (subexpression) - * (operation) !eq - * (operation) !lookup - * (expr) +0002 * (code) +0002 * (statement) !if +0002 * (subexpression) +0002 * (operation) !eq +0002 * (operation) !lookup +0002 * (expr) IDENTIFIER line_tdata - * (expr) +0002 * (expr) IDENTIFIER index - * (expr) +0002 * (expr) IDENTIFIER wd - * (code) - * (statement) !return - * (expr) +0002 * (code) +0002 * (statement) !return +0002 * (expr) IDENTIFIER wd - * (operation) !postincrement - * (expr) +0002 * (operation) !postincrement +0004 * (expr) IDENTIFIER index ========= Test: parse schema from: print ""; - * (statement) !print - * (expr) +0001 * (statement) !print +0001 * (expr) DQUOTED ========= Test: parse schema from: @@ -271,20 +271,20 @@ Test: parse schema from: X: print "A ", (string) o; } - * (statement) !switch - * (subexpression) - * (expr) +0001 * (statement) !switch +0001 * (subexpression) +0001 * (expr) IDENTIFIER Y - * (code) - * (statement) !case - * (expr) +0002 * (code) +0002 * (statement) !case +0002 * (expr) IDENTIFIER X - * (code) - * (statement) !print - * (expr) +0002 * (code) +0002 * (statement) !print +0002 * (expr) DQUOTED A - * (statement) !printstring - * (expr) +0002 * (statement) !printstring +0002 * (expr) IDENTIFIER o ========= Test: parse schema from: @@ -300,78 +300,78 @@ Test: parse schema from: #endif; ".";' - * (directive) #ifdef - * (expr) +0001 * (directive) #ifdef +0001 * (expr) IDENTIFIER RANKING_TABLE - * (call) - * (expr) +0002 * (call) +0002 * (expr) IDENTIFIER ANNOUNCE_SCORE_RM - * (expr) +0002 * (expr) SQUOTED B - * (operation) !store - * (expr) +0003 * (operation) !store +0003 * (expr) IDENTIFIER j - * (call) - * (expr) +0004 * (call) +0004 * (expr) IDENTIFIER TableRows - * (expr) +0004 * (expr) IDENTIFIER RANKING_TABLE - * (statement) !for - * (eval) - * (operation) !store - * (expr) +0004 * (statement) !for +0005 * (eval) +0005 * (operation) !store +0005 * (expr) IDENTIFIER i - * (expr) +0005 * (expr) IDENTIFIER j - * (eval) - * (operation) !ge - * (expr) +0005 * (eval) +0005 * (operation) !ge +0005 * (expr) IDENTIFIER i - * (expr) +0005 * (expr) NUMBER 1 - * (eval) - * (operation) !postdecrement - * (expr) +0005 * (eval) +0005 * (operation) !postdecrement +0005 * (expr) IDENTIFIER i - * (code) - * (statement) !if - * (subexpression) - * (operation) !ge - * (expr) +0005 * (code) +0005 * (statement) !if +0005 * (subexpression) +0005 * (operation) !ge +0005 * (expr) IDENTIFIER score - * (call) - * (expr) +0005 * (call) +0005 * (expr) IDENTIFIER TableLookUpEntry - * (expr) +0005 * (expr) IDENTIFIER RANKING_TABLE - * (expr) +0005 * (expr) NUMBER 1 - * (expr) +0005 * (expr) IDENTIFIER i - * (code) - * (operation) !store - * (expr) +0006 * (code) +0006 * (operation) !store +0006 * (expr) IDENTIFIER v - * (call) - * (expr) +0006 * (call) +0006 * (expr) IDENTIFIER TableLookUpEntry - * (expr) +0006 * (expr) IDENTIFIER RANKING_TABLE - * (expr) +0006 * (expr) NUMBER 2 - * (expr) +0007 * (expr) IDENTIFIER i - * (call) - * (expr) +0007 * (call) +0008 * (expr) IDENTIFIER TEXT_TY_Say - * (expr) +0008 * (expr) IDENTIFIER v - * (expr) ; +0008 * (expr) ; DQUOTED . - * (directive) #endif - * (expr) ; +0005 * (directive) #endif +0011 * (expr) ; DQUOTED . - * (expr) +0011 * (expr) SQUOTED ========= @@ -379,21 +379,21 @@ Test: parse schema from: if (B) if (A) { print "Yes"; } print "No"; - * (statement) !if - * (subexpression) - * (expr) +0001 * (statement) !if +0001 * (subexpression) +0001 * (expr) IDENTIFIER B - * (code) - * (statement) !if - * (subexpression) - * (expr) +0001 * (code) +0001 * (statement) !if +0001 * (subexpression) +0001 * (expr) IDENTIFIER A - * (code) - * (statement) !print - * (expr) +0001 * (code) +0001 * (statement) !print +0001 * (expr) DQUOTED Yes - * (statement) !print - * (expr) +0001 * (statement) !print +0002 * (expr) DQUOTED No ========= Test: parse schema from: @@ -402,26 +402,26 @@ Test: parse schema from: PlaceInScope(obj, true); } - * (statement) !switch - * (subexpression) - * (expr) +0001 * (statement) !switch +0001 * (subexpression) +0001 * (expr) IDENTIFIER scope_stage - * (code) < - * (statement) !case - * (expr) +0002 * (code) < +0002 * (statement) !case +0002 * (expr) NUMBER 2 - * (code) < - * (statement) !objectloop - * (subexpression) - * (expr) +0002 * (code) < +0002 * (statement) !objectloop +0002 * (subexpression) +0003 * (expr) IDENTIFIER obj - * (code) - * (call) - * (expr) +0003 * (code) +0003 * (call) +0003 * (expr) IDENTIFIER PlaceInScope - * (expr) +0003 * (expr) IDENTIFIER obj - * (expr) +0004 * (expr) NUMBER true ========= Test: parse schema from: @@ -434,125 +434,125 @@ Test: parse schema from: token = token-->RE_NEXT; } - * (statement) !while - * (subexpression) - * (operation) !ne - * (expr) +0001 * (statement) !while +0001 * (subexpression) +0001 * (operation) !ne +0001 * (expr) IDENTIFIER token - * (expr) +0001 * (expr) IDENTIFIER NULL - * (code) - * (statement) !switch - * (subexpression) - * (operation) !lookup - * (expr) +0002 * (code) +0002 * (statement) !switch +0002 * (subexpression) +0002 * (operation) !lookup +0002 * (expr) IDENTIFIER token - * (expr) +0002 * (expr) IDENTIFIER RE_CCLASS - * (code) - * (statement) !case - * (expr) +0003 * (code) +0003 * (statement) !case +0003 * (expr) IDENTIFIER DISJUNCTION_RE_CC - * (code) - * (operation) !store - * (operation) !lookup - * (expr) +0003 * (code) +0003 * (operation) !store +0003 * (operation) !lookup +0003 * (expr) IDENTIFIER token - * (expr) +0003 * (expr) IDENTIFIER RE_CONSTRAINT - * (expr) +0004 * (expr) NUMBER -1 - * (statement) !case - * (expr) +0004 * (statement) !case +0004 * (expr) IDENTIFIER QUANTIFIER_RE_CC - * (code) - * (operation) !store - * (operation) !lookup - * (expr) +0004 * (code) +0004 * (operation) !store +0004 * (operation) !lookup +0004 * (expr) IDENTIFIER token - * (expr) +0004 * (expr) IDENTIFIER RE_CONSTRAINT - * (expr) +0005 * (expr) NUMBER -1 - * (statement) !if - * (subexpression) - * (operation) !lookup - * (expr) +0003 * (statement) !if +0006 * (subexpression) +0006 * (operation) !lookup +0006 * (expr) IDENTIFIER token - * (expr) +0006 * (expr) IDENTIFIER RE_DOWN - * (code) - * (call) - * (expr) +0007 * (code) +0007 * (call) +0007 * (expr) IDENTIFIER TEXT_TY_RE_EraseConstraints - * (operation) !lookup - * (expr) +0007 * (operation) !lookup +0007 * (expr) IDENTIFIER token - * (expr) +0007 * (expr) IDENTIFIER RE_DOWN - * (operation) !store - * (expr) +0007 * (operation) !store +0007 * (expr) IDENTIFIER token - * (operation) !lookup - * (expr) +0008 * (operation) !lookup +0008 * (expr) IDENTIFIER token - * (expr) +0008 * (expr) IDENTIFIER RE_NEXT ========= Test: parse schema from: if (b) print 1; else print 2; - * (statement) !ifelse - * (subexpression) - * (expr) +0001 * (statement) !ifelse +0001 * (subexpression) +0001 * (expr) IDENTIFIER b - * (code) - * (statement) !printnumber - * (expr) +0001 * (code) +0001 * (statement) !printnumber +0001 * (expr) NUMBER 1 - * (code) - * (statement) !printnumber - * (expr) +0001 * (code) +0001 * (statement) !printnumber +0001 * (expr) NUMBER 2 ========= Test: parse schema from: a: if (b) print 1; else print 2; - * (statement) !case - * (expr) +0001 * (statement) !case +0001 * (expr) IDENTIFIER a - * (code) < - * (statement) !ifelse - * (subexpression) - * (expr) +0001 * (code) < +0001 * (statement) !ifelse +0001 * (subexpression) +0001 * (expr) IDENTIFIER b - * (code) - * (statement) !printnumber - * (expr) +0001 * (code) +0001 * (statement) !printnumber +0001 * (expr) NUMBER 1 - * (code) - * (statement) !printnumber - * (expr) +0001 * (code) +0001 * (statement) !printnumber +0001 * (expr) NUMBER 2 ========= Test: parse schema from: print_ret "This is ", (char) X, "."; - * (statement) !print - * (expr) +0001 * (statement) !print +0001 * (expr) DQUOTED This is - * (statement) !printchar - * (expr) +0001 * (statement) !printchar +0001 * (expr) IDENTIFIER X - * (statement) !print - * (expr) +0001 * (statement) !print +0001 * (expr) DQUOTED . - * (statement) !print - * (expr) +0001 * (statement) !print +0001 * (expr) DQUOTED - * (statement) !return - * (expr) +0001 * (statement) !return +0001 * (expr) NUMBER 1 ========= Test: parse schema from: @@ -563,59 +563,59 @@ Test: parse schema from: @jl y 0 ?~rtrue; @jl y 0 ?~rfalse; - * (assembly) - * (expr) +0001 * (assembly) +0001 * (expr) OPCODE @jl - * (expr) +0001 * (expr) IDENTIFIER y - * (expr) +0001 * (expr) NUMBER 0 - * (expr) +0002 * (expr) ASM_LABEL X - * (assembly) - * (expr) +0002 * (assembly) +0002 * (expr) OPCODE @jl - * (expr) +0002 * (expr) IDENTIFIER y - * (expr) +0002 * (expr) NUMBER 0 - * (expr) +0003 * (expr) NEGASM_LABEL X - * (assembly) - * (expr) +0003 * (assembly) +0003 * (expr) OPCODE @jl - * (expr) +0003 * (expr) IDENTIFIER y - * (expr) +0003 * (expr) NUMBER 0 - * (expr) +0004 * (expr) ASM_LABEL rtrue - * (assembly) - * (expr) +0004 * (assembly) +0004 * (expr) OPCODE @jl - * (expr) +0004 * (expr) IDENTIFIER y - * (expr) +0004 * (expr) NUMBER 0 - * (expr) +0005 * (expr) ASM_LABEL rfalse - * (assembly) - * (expr) +0005 * (assembly) +0005 * (expr) OPCODE @jl - * (expr) +0005 * (expr) IDENTIFIER y - * (expr) +0005 * (expr) NUMBER 0 - * (expr) +0006 * (expr) NEGASM_LABEL rtrue - * (assembly) - * (expr) +0006 * (assembly) +0006 * (expr) OPCODE @jl - * (expr) +0006 * (expr) IDENTIFIER y - * (expr) +0006 * (expr) NUMBER 0 - * (expr) +0007 * (expr) NEGASM_LABEL rfalse ========= Test: parse schema from: @@ -645,127 +645,127 @@ Test: parse schema from: outcome = true; } - * (statement) !switch - * (subexpression) - * (operation) !lookup - * (expr) +0001 * (statement) !switch +0001 * (subexpression) +0001 * (operation) !lookup +0001 * (expr) IDENTIFIER token - * (expr) +0001 * (expr) IDENTIFIER RE_CCLASS - * (code) - * (statement) !case - * (expr) +0002 * (code) +0002 * (statement) !case +0005 * (expr) IDENTIFIER CHOICE_RE_CC - * (code) - * (statement) !return - * (expr) +0005 * (code) +0005 * (statement) !return +0005 * (expr) DQUOTED internal error - * (statement) !case - * (expr) +0006 * (statement) !case +0010 * (expr) IDENTIFIER SENSITIVITY_RE_CC - * (code) - * (statement) !ifelse - * (subexpression) - * (operation) !lookup - * (expr) +0010 * (code) +0010 * (statement) !ifelse +0010 * (subexpression) +0010 * (operation) !lookup +0010 * (expr) IDENTIFIER token - * (expr) +0010 * (expr) IDENTIFIER RE_PAR1 - * (code) - * (operation) !store - * (expr) +0010 * (code) +0010 * (operation) !store +0010 * (expr) IDENTIFIER mode_flags - * (operation) !bitwiseor - * (expr) +0010 * (operation) !bitwiseor +0010 * (expr) IDENTIFIER mode_flags - * (expr) +0011 * (expr) IDENTIFIER CIS_MFLAG - * (code) - * (operation) !store - * (expr) +0011 * (code) +0011 * (operation) !store +0011 * (expr) IDENTIFIER mode_flags - * (operation) !bitwiseand - * (expr) +0011 * (operation) !bitwiseand +0011 * (expr) IDENTIFIER mode_flags - * (subexpression) - * (operation) !bitwisenot - * (expr) +0012 * (subexpression) +0012 * (operation) !bitwisenot +0012 * (expr) IDENTIFIER CIS_MFLAG - * (operation) !store - * (expr) +0011 * (operation) !store +0012 * (expr) IDENTIFIER outcome - * (expr) +0013 * (expr) NUMBER true - * (statement) !case - * (expr) +0013 * (statement) !case +0017 * (expr) IDENTIFIER ALWAYS_RE_CC - * (code) - * (operation) !store - * (expr) +0017 * (code) +0017 * (operation) !store +0017 * (expr) IDENTIFIER outcome - * (expr) +0018 * (expr) NUMBER true - * (statement) !case - * (expr) +0018 * (statement) !case +0019 * (expr) IDENTIFIER NEVER_RE_CC - * (code) - * (statement) !case - * (expr) +0019 * (code) +0019 * (statement) !case +0020 * (expr) IDENTIFIER START_RE_CC - * (code) - * (statement) !if - * (subexpression) - * (operation) !eq - * (expr) +0020 * (code) +0020 * (statement) !if +0020 * (subexpression) +0020 * (operation) !eq +0020 * (expr) IDENTIFIER ipos - * (expr) +0020 * (expr) NUMBER 0 - * (code) - * (operation) !store - * (expr) +0020 * (code) +0020 * (operation) !store +0020 * (expr) IDENTIFIER outcome - * (expr) +0021 * (expr) NUMBER true - * (statement) !case - * (expr) +0020 * (statement) !case +0022 * (expr) IDENTIFIER END_RE_CC - * (code) - * (statement) !if - * (subexpression) - * (operation) !eq - * (call) - * (expr) +0022 * (code) +0022 * (statement) !if +0022 * (subexpression) +0022 * (operation) !eq +0022 * (call) +0022 * (expr) IDENTIFIER BlkValueRead - * (expr) +0022 * (expr) IDENTIFIER txt - * (expr) +0022 * (expr) IDENTIFIER ipos - * (expr) +0022 * (expr) NUMBER 0 - * (code) - * (operation) !store - * (expr) +0022 * (code) +0022 * (operation) !store +0022 * (expr) IDENTIFIER outcome - * (expr) +0023 * (expr) NUMBER true - * (statement) !case - * (expr) +0022 * (statement) !case +0024 * (expr) IDENTIFIER SOMETIMES_RE_CC - * (code) - * (operation) !store - * (expr) +0024 * (code) +0024 * (operation) !store +0024 * (expr) IDENTIFIER outcome - * (expr) +0025 * (expr) NUMBER true ========= Test: parse schema from: print (char) 'a'; print (char) '''; - * (statement) !printchar - * (expr) +0001 * (statement) !printchar +0001 * (expr) SQUOTED a - * (statement) !printchar - * (expr) +0002 * (statement) !printchar +0002 * (expr) SQUOTED ' ========= diff --git a/inter/building-test/Tests/Test Cases/_Results_Ideal/schemas.txt b/inter/building-test/Tests/Test Cases/_Results_Ideal/schemas.txt index aee626a75..6393be40b 100644 --- a/inter/building-test/Tests/Test Cases/_Results_Ideal/schemas.txt +++ b/inter/building-test/Tests/Test Cases/_Results_Ideal/schemas.txt @@ -1,2491 +1,2491 @@ Test: parse schema from: {-say:val:K} - * (expr) +0001 * (expr) INLINE -say:val:K ========= Test: parse schema from: print (number) say__n=({something}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LanguageNumber - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) IDENTIFIER say__n - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE something ========= Test: parse schema from: STextSubstitution(); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER STextSubstitution ========= Test: parse schema from: print (PrintTimeOfDayEnglish) {something}; - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER PrintTimeOfDayEnglish - * (expr) +0001 * (expr) INLINE something ========= Test: parse schema from: print (a) {something}; - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER IndefArt - * (expr) +0001 * (expr) INLINE something ========= Test: parse schema from: print (a) {something}; - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER IndefArt - * (expr) +0001 * (expr) INLINE something ========= Test: parse schema from: CIndefArt({something}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER CIndefArt - * (expr) +0001 * (expr) INLINE something ========= Test: parse schema from: CIndefArt({something}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER CIndefArt - * (expr) +0001 * (expr) INLINE something ========= Test: parse schema from: print (the) {something}; - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER DefArt - * (expr) +0001 * (expr) INLINE something ========= Test: parse schema from: print (The) {something}; - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER CDefArt - * (expr) +0001 * (expr) INLINE something ========= Test: parse schema from: @nop; {-segment-count}: - * (assembly) - * (expr) +0001 * (assembly) +0001 * (expr) OPCODE @nop - * (statement) !case - * (expr) +0001 * (statement) !case +0001 * (expr) INLINE -segment-count - * (code) < +0001 * (code) < ========= Test: parse schema from: {-close-brace} - * (code) > +0001 * (code) > ========= Test: parse schema from: {-close-brace} - * (code) > +0001 * (code) > ========= Test: parse schema from: {-close-brace} - * (code) > +0001 * (code) > ========= Test: parse schema from: {-close-brace} - * (code) > +0001 * (code) > ========= Test: parse schema from: {-close-brace} - * (code) > +0001 * (code) > ========= Test: parse schema from: {-close-brace} - * (code) > +0001 * (code) > ========= Test: parse schema from: {-close-brace} - * (code) > +0001 * (code) > ========= Test: parse schema from: {-close-brace} - * (code) > +0001 * (code) > ========= Test: parse schema from: {-close-brace} - * (code) > +0001 * (code) > ========= Test: parse schema from: {-close-brace} - * (code) > +0001 * (code) > ========= Test: parse schema from: new_line; - * (statement) !print - * (expr) +0001 * (statement) !print +0001 * (expr) DQUOTED ========= Test: parse schema from: DivideParagraphPoint(); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER DivideParagraphPoint ========= Test: parse schema from: CommandClarificationBreak(); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER CommandClarificationBreak ========= Test: parse schema from: DivideParagraphPoint(); new_line; - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER DivideParagraphPoint - * (statement) !print - * (expr) +0001 * (statement) !print +0001 * (expr) DQUOTED ========= Test: parse schema from: RunParagraphOn(); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RunParagraphOn ========= Test: parse schema from: SpecialLookSpacingBreak(); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER SpecialLookSpacingBreak ========= Test: parse schema from: (say__p) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) IDENTIFIER say__p ========= Test: parse schema from: print "["; - * (statement) !print - * (expr) +0001 * (statement) !print +0001 * (expr) DQUOTED [ ========= Test: parse schema from: print "]"; - * (statement) !print - * (expr) +0001 * (statement) !print +0001 * (expr) DQUOTED ] ========= Test: parse schema from: print "'"; - * (statement) !print - * (expr) +0001 * (statement) !print +0001 * (expr) DQUOTED ' ========= Test: parse schema from: print "~"; - * (statement) !print - * (expr) +0001 * (statement) !print +0001 * (expr) DQUOTED " ========= Test: parse schema from: style bold; - * (statement) !style - * (expr) +0001 * (statement) !style +0001 * (expr) NUMBER 1 ========= Test: parse schema from: style underline; - * (statement) !style - * (expr) +0001 * (statement) !style +0001 * (expr) NUMBER 2 ========= Test: parse schema from: style roman; - * (statement) !style - * (expr) +0001 * (statement) !style +0001 * (expr) NUMBER 0 ========= Test: parse schema from: font off; - * (statement) !font - * (expr) +0001 * (statement) !font +0001 * (expr) NUMBER 0 ========= Test: parse schema from: font on; - * (statement) !font - * (expr) +0001 * (statement) !font +0001 * (expr) NUMBER 1 ========= Test: parse schema from: DisplayBoxedQuotation({-box-quotation-text:Q}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER DisplayBoxedQuotation - * (expr) +0001 * (expr) INLINE -box-quotation-text:Q ========= Test: parse schema from: Banner(); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER Banner ========= Test: parse schema from: ShowExtensionVersions(); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER ShowExtensionVersions ========= Test: parse schema from: ShowFullExtensionVersions(); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER ShowFullExtensionVersions ========= Test: parse schema from: SL_Location(true); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER SL_Location - * (expr) +0001 * (expr) NUMBER true ========= Test: parse schema from: WriteListFrom(child({O}), {phrase options}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER WriteListFrom - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER child - * (expr) +0001 * (expr) INLINE O - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: c_style = c_style &~ (RECURSE_BIT+FULLINV_BIT+PARTINV_BIT); - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) IDENTIFIER c_style - * (operation) !bitwiseand - * (expr) +0001 * (operation) !bitwiseand +0001 * (expr) IDENTIFIER c_style - * (operation) !bitwisenot - * (subexpression) - * (operation) !plus - * (operation) !plus - * (expr) +0001 * (operation) !bitwisenot +0001 * (subexpression) +0001 * (operation) !plus +0001 * (operation) !plus +0001 * (expr) IDENTIFIER RECURSE_BIT - * (expr) +0001 * (expr) IDENTIFIER FULLINV_BIT - * (expr) +0001 * (expr) IDENTIFIER PARTINV_BIT ========= Test: parse schema from: LIST_OF_TY_Say({-by-reference:L}, 1); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_Say - * (expr) +0001 * (expr) INLINE -by-reference:L - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_Say({-by-reference:L}, 2); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_Say - * (expr) +0001 * (expr) INLINE -by-reference:L - * (expr) +0001 * (expr) NUMBER 2 ========= Test: parse schema from: LIST_OF_TY_Say({-by-reference:L}, 3); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_Say - * (expr) +0001 * (expr) INLINE -by-reference:L - * (expr) +0001 * (expr) NUMBER 3 ========= Test: parse schema from: list_filter_routine = {D}; - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) IDENTIFIER list_filter_routine - * (expr) +0001 * (expr) INLINE D ========= Test: parse schema from: list_filter_routine = 0; - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) IDENTIFIER list_filter_routine - * (expr) +0001 * (expr) NUMBER 0 ========= Test: parse schema from: {cn} - * (expr) +0001 * (expr) INLINE cn ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X}) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE -arithmetic-operation:X ========= Test: parse schema from: ({-arithmetic-operation:X}) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE -arithmetic-operation:X ========= Test: parse schema from: {-primitive-definition:total-of} - * (expr) +0001 * (expr) INLINE -primitive-definition:total-of ========= Test: parse schema from: Float({R}, {N}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER Float - * (expr) +0001 * (expr) INLINE R - * (expr) +0001 * (expr) INLINE N ========= Test: parse schema from: FloatDec({R}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FloatDec - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: FloatDec({R}, {N}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FloatDec - * (expr) +0001 * (expr) INLINE R - * (expr) +0001 * (expr) INLINE N ========= Test: parse schema from: FloatExp({R}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FloatExp - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: FloatExp({R}, {N}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FloatExp - * (expr) +0001 * (expr) INLINE R - * (expr) +0001 * (expr) INLINE N ========= Test: parse schema from: REAL_NUMBER_TY_Reciprocal({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Reciprocal - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Abs({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Abs - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Root({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Root - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Ceiling({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Ceiling - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Floor({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Floor - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_to_NUMBER_TY({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_to_NUMBER_TY - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Log({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Log - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_BLog({R}, {N}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_BLog - * (expr) +0001 * (expr) INLINE R - * (expr) +0001 * (expr) INLINE N ========= Test: parse schema from: REAL_NUMBER_TY_Exp({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Exp - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Pow({R}, {P}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Pow - * (expr) +0001 * (expr) INLINE R - * (expr) +0001 * (expr) INLINE P ========= Test: parse schema from: REAL_NUMBER_TY_Times({R}, $+0.0174532925) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Times - * (expr) +0001 * (expr) INLINE R - * (expr) +0001 * (expr) REAL_NUMBER $+0.0174532925 ========= Test: parse schema from: REAL_NUMBER_TY_Sin({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Sin - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Cos({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Cos - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Tan({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Tan - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Arcsin({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Arcsin - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Arccos({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Arccos - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Arctan({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Arctan - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Sinh({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Sinh - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Cosh({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Cosh - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Tanh({R}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER REAL_NUMBER_TY_Tanh - * (expr) +0001 * (expr) INLINE R ========= Test: parse schema from: {-primitive-definition:number-of} - * (expr) +0001 * (expr) INLINE -primitive-definition:number-of ========= Test: parse schema from: {-next-routine:K}({X}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE -next-routine:K - * (expr) +0001 * (expr) INLINE X ========= Test: parse schema from: {-previous-routine:K}({X}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE -previous-routine:K - * (expr) +0001 * (expr) INLINE X ========= Test: parse schema from: ({C}) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE C ========= Test: parse schema from: {-primitive-definition:random-of} - * (expr) +0001 * (expr) INLINE -primitive-definition:random-of ========= Test: parse schema from: {-ranger-routine:K}({first value}, {second value}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE -ranger-routine:K - * (expr) +0001 * (expr) INLINE first value - * (expr) +0001 * (expr) INLINE second value ========= Test: parse schema from: {-ranger-routine:K}({first value}, {second value}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE -ranger-routine:K - * (expr) +0001 * (expr) INLINE first value - * (expr) +0001 * (expr) INLINE second value ========= Test: parse schema from: {-ranger-routine:K}({first value}, {second value}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE -ranger-routine:K - * (expr) +0001 * (expr) INLINE first value - * (expr) +0001 * (expr) INLINE second value ========= Test: parse schema from: {-ranger-routine:K}({first value}, {second value}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE -ranger-routine:K - * (expr) +0001 * (expr) INLINE first value - * (expr) +0001 * (expr) INLINE second value ========= Test: parse schema from: (GenerateRandomNumber(1, {M}) <= {N}) - * (subexpression) - * (operation) !le - * (call) - * (expr) +0001 * (subexpression) +0001 * (operation) !le +0001 * (call) +0001 * (expr) IDENTIFIER GenerateRandomNumber - * (expr) +0001 * (expr) NUMBER 1 - * (expr) +0001 * (expr) INLINE M - * (expr) +0001 * (expr) INLINE N ========= Test: parse schema from: VM_Seed_RNG({N}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER VM_Seed_RNG - * (expr) +0001 * (expr) INLINE N ========= Test: parse schema from: {-my:ct_0} = {T}; {-my:ct_1} = {N}; - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) INLINE -my:ct_0 - * (expr) +0001 * (expr) INLINE T - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) INLINE -my:ct_1 - * (expr) +0001 * (expr) INLINE N ========= Test: parse schema from: {-my:ct_0} = {T}; {-my:ct_1} = TableRowCorr(ct_0, {TC}, {w}); - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) INLINE -my:ct_0 - * (expr) +0001 * (expr) INLINE T - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) INLINE -my:ct_1 - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableRowCorr - * (expr) +0001 * (expr) IDENTIFIER ct_0 - * (expr) +0001 * (expr) INLINE TC - * (expr) +0001 * (expr) INLINE w ========= Test: parse schema from: {-my:ct_0} = {T}; {-my:ct_1} = TableBlankRow(ct_0); - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) INLINE -my:ct_0 - * (expr) +0001 * (expr) INLINE T - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) INLINE -my:ct_1 - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableBlankRow - * (expr) +0001 * (expr) IDENTIFIER ct_0 ========= Test: parse schema from: {-my:ct_0} = {T}; {-my:ct_1} = TableRandomRow(ct_0); - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) INLINE -my:ct_0 - * (expr) +0001 * (expr) INLINE T - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) INLINE -my:ct_1 - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableRandomRow - * (expr) +0001 * (expr) IDENTIFIER ct_0 ========= Test: parse schema from: TableRows({T}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableRows - * (expr) +0001 * (expr) INLINE T ========= Test: parse schema from: TableBlankRows({T}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableBlankRows - * (expr) +0001 * (expr) INLINE T ========= Test: parse schema from: TableFilledRows({T}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableFilledRows - * (expr) +0001 * (expr) INLINE T ========= Test: parse schema from: ({-reference-exists:TR}) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) INLINE -reference-exists:TR ========= Test: parse schema from: ({-reference-exists:TR} == false) - * (subexpression) - * (operation) !eq - * (expr) +0001 * (subexpression) +0001 * (operation) !eq +0001 * (expr) INLINE -reference-exists:TR - * (expr) +0001 * (expr) NUMBER false ========= Test: parse schema from: {-by-reference-blank-out:tr}; - * (expr) ; +0001 * (expr) ; INLINE -by-reference-blank-out:tr ========= Test: parse schema from: TableBlankOutRow({-my:ct_0}, {-my:ct_1}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableBlankOutRow - * (expr) +0001 * (expr) INLINE -my:ct_0 - * (expr) +0001 * (expr) INLINE -my:ct_1 ========= Test: parse schema from: TableBlankOutColumn({T}, {TC}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableBlankOutColumn - * (expr) +0001 * (expr) INLINE T - * (expr) +0001 * (expr) INLINE TC ========= Test: parse schema from: TableBlankOutAll({T}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableBlankOutAll - * (expr) +0001 * (expr) INLINE T ========= Test: parse schema from: TableDebug({T}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableDebug - * (expr) +0001 * (expr) INLINE T ========= Test: parse schema from: TableRowDebug({-my:ct_0}, {-my:ct_1}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableRowDebug - * (expr) +0001 * (expr) INLINE -my:ct_0 - * (expr) +0001 * (expr) INLINE -my:ct_1 ========= Test: parse schema from: TableRowDebug({T}, {N}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableRowDebug - * (expr) +0001 * (expr) INLINE T - * (expr) +0001 * (expr) INLINE N ========= Test: parse schema from: TableColumnDebug({T}, {TC}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableColumnDebug - * (expr) +0001 * (expr) INLINE T - * (expr) +0001 * (expr) INLINE TC ========= Test: parse schema from: TableShuffle({T}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableShuffle - * (expr) +0001 * (expr) INLINE T ========= Test: parse schema from: TableSort({T}, {TC}, 1); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableSort - * (expr) +0001 * (expr) INLINE T - * (expr) +0001 * (expr) INLINE TC - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: TableSort({T}, {TC}, -1); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TableSort - * (expr) +0001 * (expr) INLINE T - * (expr) +0001 * (expr) INLINE TC - * (operation) !unaryminus - * (expr) +0001 * (operation) !unaryminus +0001 * (expr) NUMBER 1 ========= Test: parse schema from: TEXT_TY_BlobAccess({-by-reference:T}, CHR_BLOB) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_BlobAccess - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) IDENTIFIER CHR_BLOB ========= Test: parse schema from: TEXT_TY_BlobAccess({-by-reference:T}, WORD_BLOB) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_BlobAccess - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) IDENTIFIER WORD_BLOB ========= Test: parse schema from: TEXT_TY_BlobAccess({-by-reference:T}, PWORD_BLOB) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_BlobAccess - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) IDENTIFIER PWORD_BLOB ========= Test: parse schema from: TEXT_TY_BlobAccess({-by-reference:T}, UWORD_BLOB) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_BlobAccess - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) IDENTIFIER UWORD_BLOB ========= Test: parse schema from: TEXT_TY_BlobAccess({-by-reference:T}, LINE_BLOB) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_BlobAccess - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) IDENTIFIER LINE_BLOB ========= Test: parse schema from: TEXT_TY_BlobAccess({-by-reference:T}, PARA_BLOB) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_BlobAccess - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) IDENTIFIER PARA_BLOB ========= Test: parse schema from: TEXT_TY_GetBlob({-new:text}, {-by-reference:T}, {N}, CHR_BLOB) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_GetBlob - * (expr) +0001 * (expr) INLINE -new:text - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) IDENTIFIER CHR_BLOB ========= Test: parse schema from: TEXT_TY_GetBlob({-new:text}, {-by-reference:T}, {N}, WORD_BLOB) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_GetBlob - * (expr) +0001 * (expr) INLINE -new:text - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) IDENTIFIER WORD_BLOB ========= Test: parse schema from: TEXT_TY_GetBlob({-new:text}, {-by-reference:T}, {N}, PWORD_BLOB) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_GetBlob - * (expr) +0001 * (expr) INLINE -new:text - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) IDENTIFIER PWORD_BLOB ========= Test: parse schema from: TEXT_TY_GetBlob({-new:text}, {-by-reference:T}, {N}, UWORD_BLOB) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_GetBlob - * (expr) +0001 * (expr) INLINE -new:text - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) IDENTIFIER UWORD_BLOB ========= Test: parse schema from: TEXT_TY_GetBlob({-new:text}, {-by-reference:T}, {N}, LINE_BLOB) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_GetBlob - * (expr) +0001 * (expr) INLINE -new:text - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) IDENTIFIER LINE_BLOB ========= Test: parse schema from: TEXT_TY_GetBlob({-new:text}, {-by-reference:T}, {N}, PARA_BLOB) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_GetBlob - * (expr) +0001 * (expr) INLINE -new:text - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) IDENTIFIER PARA_BLOB ========= Test: parse schema from: TEXT_TY_SubstitutedForm({-new:text}, {-by-reference:T}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_SubstitutedForm - * (expr) +0001 * (expr) INLINE -new:text - * (expr) +0001 * (expr) INLINE -by-reference:T ========= Test: parse schema from: TEXT_TY_Replace_RE(CHR_BLOB,{-by-reference:T},{-by-reference:find},0,{phrase options},1) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_Replace_RE - * (expr) +0001 * (expr) IDENTIFIER CHR_BLOB - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) INLINE -by-reference:find - * (expr) +0001 * (expr) NUMBER 0 - * (expr) +0001 * (expr) INLINE phrase options - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: TEXT_TY_Replace_RE(CHR_BLOB,{-by-reference:T},{-by-reference:find},0,{phrase options}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_Replace_RE - * (expr) +0001 * (expr) IDENTIFIER CHR_BLOB - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) INLINE -by-reference:find - * (expr) +0001 * (expr) NUMBER 0 - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: TEXT_TY_Replace_RE(CHR_BLOB,{-by-reference:T},{-by-reference:find},1,{phrase options}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_Replace_RE - * (expr) +0001 * (expr) IDENTIFIER CHR_BLOB - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) INLINE -by-reference:find - * (expr) +0001 * (expr) NUMBER 1 - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: TEXT_TY_Replace_RE(REGEXP_BLOB,{-by-reference:T},{-by-reference:find},0,{phrase options},1) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_Replace_RE - * (expr) +0001 * (expr) IDENTIFIER REGEXP_BLOB - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) INLINE -by-reference:find - * (expr) +0001 * (expr) NUMBER 0 - * (expr) +0001 * (expr) INLINE phrase options - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: TEXT_TY_Replace_RE(REGEXP_BLOB,{-by-reference:T},{-by-reference:find},0,{phrase options}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_Replace_RE - * (expr) +0001 * (expr) IDENTIFIER REGEXP_BLOB - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) INLINE -by-reference:find - * (expr) +0001 * (expr) NUMBER 0 - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: TEXT_TY_RE_GetMatchVar(0) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_RE_GetMatchVar - * (expr) +0001 * (expr) NUMBER 0 ========= Test: parse schema from: TEXT_TY_RE_GetMatchVar({N}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_RE_GetMatchVar - * (expr) +0001 * (expr) INLINE N ========= Test: parse schema from: TEXT_TY_Replace_RE(REGEXP_BLOB,{-by-reference:T},{-by-reference:find},1,{phrase options}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_Replace_RE - * (expr) +0001 * (expr) IDENTIFIER REGEXP_BLOB - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) INLINE -by-reference:find - * (expr) +0001 * (expr) NUMBER 1 - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: TEXT_TY_ReplaceText(WORD_BLOB, {-lvalue-by-reference:T}, {-by-reference:find}, {-by-reference:replace}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_ReplaceText - * (expr) +0001 * (expr) IDENTIFIER WORD_BLOB - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:T - * (expr) +0001 * (expr) INLINE -by-reference:find - * (expr) +0001 * (expr) INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_ReplaceText(PWORD_BLOB, {-lvalue-by-reference:T}, {-by-reference:find}, {-by-reference:replace}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_ReplaceText - * (expr) +0001 * (expr) IDENTIFIER PWORD_BLOB - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:T - * (expr) +0001 * (expr) INLINE -by-reference:find - * (expr) +0001 * (expr) INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_ReplaceBlob(CHR_BLOB, {-lvalue-by-reference:T}, {N}, {-by-reference:replace}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_ReplaceBlob - * (expr) +0001 * (expr) IDENTIFIER CHR_BLOB - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:T - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_ReplaceBlob(WORD_BLOB, {-lvalue-by-reference:T}, {N}, {-by-reference:replace}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_ReplaceBlob - * (expr) +0001 * (expr) IDENTIFIER WORD_BLOB - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:T - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_ReplaceBlob(PWORD_BLOB, {-lvalue-by-reference:T}, {N}, {-by-reference:replace}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_ReplaceBlob - * (expr) +0001 * (expr) IDENTIFIER PWORD_BLOB - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:T - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_ReplaceBlob(UWORD_BLOB, {-lvalue-by-reference:T}, {N}, {-by-reference:replace}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_ReplaceBlob - * (expr) +0001 * (expr) IDENTIFIER UWORD_BLOB - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:T - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_ReplaceBlob(LINE_BLOB, {-lvalue-by-reference:T}, {N}, {-by-reference:replace}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_ReplaceBlob - * (expr) +0001 * (expr) IDENTIFIER LINE_BLOB - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:T - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_ReplaceBlob(PARA_BLOB, {-lvalue-by-reference:T}, {N}, {-by-reference:replace}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_ReplaceBlob - * (expr) +0001 * (expr) IDENTIFIER PARA_BLOB - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:T - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_CharactersToCase({-new:text}, {-by-reference:T}, 0) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_CharactersToCase - * (expr) +0001 * (expr) INLINE -new:text - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) NUMBER 0 ========= Test: parse schema from: TEXT_TY_CharactersToCase({-new:text}, {-by-reference:T}, 1) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_CharactersToCase - * (expr) +0001 * (expr) INLINE -new:text - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: TEXT_TY_CharactersToCase({-new:text}, {-by-reference:T}, 2) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_CharactersToCase - * (expr) +0001 * (expr) INLINE -new:text - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) NUMBER 2 ========= Test: parse schema from: TEXT_TY_CharactersToCase({-new:text}, {-by-reference:T}, 3) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_CharactersToCase - * (expr) +0001 * (expr) INLINE -new:text - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) NUMBER 3 ========= Test: parse schema from: TEXT_TY_CharactersOfCase({-by-reference:T}, 0) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_CharactersOfCase - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) NUMBER 0 ========= Test: parse schema from: TEXT_TY_CharactersOfCase({-by-reference:T}, 1) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TEXT_TY_CharactersOfCase - * (expr) +0001 * (expr) INLINE -by-reference:T - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: {V}(1); - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE V - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: {V}(2); - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE V - * (expr) +0001 * (expr) NUMBER 2 ========= Test: parse schema from: {V}(3); - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE V - * (expr) +0001 * (expr) NUMBER 3 ========= Test: parse schema from: {V}(CV_POS, PNToVP(), story_tense); - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE V - * (expr) +0001 * (expr) IDENTIFIER CV_POS - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER PNToVP - * (expr) +0001 * (expr) IDENTIFIER story_tense ========= Test: parse schema from: {V}(CV_POS, PNToVP(), {T}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE V - * (expr) +0001 * (expr) IDENTIFIER CV_POS - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER PNToVP - * (expr) +0001 * (expr) INLINE T ========= Test: parse schema from: {V}(CV_POS, {P}, story_tense); - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE V - * (expr) +0001 * (expr) IDENTIFIER CV_POS - * (expr) +0001 * (expr) INLINE P - * (expr) +0001 * (expr) IDENTIFIER story_tense ========= Test: parse schema from: {V}(CV_POS, {P}, {T}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE V - * (expr) +0001 * (expr) IDENTIFIER CV_POS - * (expr) +0001 * (expr) INLINE P - * (expr) +0001 * (expr) INLINE T ========= Test: parse schema from: {V}(CV_NEG, PNToVP(), story_tense); - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE V - * (expr) +0001 * (expr) IDENTIFIER CV_NEG - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER PNToVP - * (expr) +0001 * (expr) IDENTIFIER story_tense ========= Test: parse schema from: {V}(CV_NEG, PNToVP(), {T}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE V - * (expr) +0001 * (expr) IDENTIFIER CV_NEG - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER PNToVP - * (expr) +0001 * (expr) INLINE T ========= Test: parse schema from: {V}(CV_NEG, {P}, story_tense); - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE V - * (expr) +0001 * (expr) IDENTIFIER CV_NEG - * (expr) +0001 * (expr) INLINE P - * (expr) +0001 * (expr) IDENTIFIER story_tense ========= Test: parse schema from: {V}(CV_NEG, {P}, {T}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE V - * (expr) +0001 * (expr) IDENTIFIER CV_NEG - * (expr) +0001 * (expr) INLINE P - * (expr) +0001 * (expr) INLINE T ========= Test: parse schema from: {V}(CV_MEANING) - * (call) - * (expr) +0001 * (call) +0001 * (expr) INLINE V - * (expr) +0001 * (expr) IDENTIFIER CV_MEANING ========= Test: parse schema from: LIST_OF_TY_InsertItem({-lvalue-by-reference:L}, {new entry}, 0, 0, {phrase options}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_InsertItem - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) INLINE new entry - * (expr) +0001 * (expr) NUMBER 0 - * (expr) +0001 * (expr) NUMBER 0 - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: LIST_OF_TY_InsertItem({-lvalue-by-reference:L}, {new entry}, 1, {E}, {phrase options}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_InsertItem - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) INLINE new entry - * (expr) +0001 * (expr) NUMBER 1 - * (expr) +0001 * (expr) INLINE E - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: LIST_OF_TY_AppendList({-lvalue-by-reference:L}, {-by-reference:LX}, 0, 0, {phrase options}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_AppendList - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) INLINE -by-reference:LX - * (expr) +0001 * (expr) NUMBER 0 - * (expr) +0001 * (expr) NUMBER 0 - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: LIST_OF_TY_AppendList({-lvalue-by-reference:L}, {-by-reference:LX}, 1, {E}, 0); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_AppendList - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) INLINE -by-reference:LX - * (expr) +0001 * (expr) NUMBER 1 - * (expr) +0001 * (expr) INLINE E - * (expr) +0001 * (expr) NUMBER 0 ========= Test: parse schema from: LIST_OF_TY_RemoveValue({-lvalue-by-reference:L}, {existing entry}, {phrase options}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_RemoveValue - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) INLINE existing entry - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: LIST_OF_TY_Remove_List({-lvalue-by-reference:L}, {-by-reference:N}, {phrase options}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_Remove_List - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) INLINE -by-reference:N - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: LIST_OF_TY_RemoveItemRange({-lvalue-by-reference:L}, {N}, {N}, {phrase options}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_RemoveItemRange - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: LIST_OF_TY_RemoveItemRange({-lvalue-by-reference:L}, {N}, {N2}, {phrase options}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_RemoveItemRange - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) INLINE N2 - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: (LIST_OF_TY_FindItem({-by-reference:L}, {N})) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_FindItem - * (expr) +0001 * (expr) INLINE -by-reference:L - * (expr) +0001 * (expr) INLINE N ========= Test: parse schema from: (LIST_OF_TY_FindItem({-by-reference:L}, {N}) == false) - * (subexpression) - * (operation) !eq - * (call) - * (expr) +0001 * (subexpression) +0001 * (operation) !eq +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_FindItem - * (expr) +0001 * (expr) INLINE -by-reference:L - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) NUMBER false ========= Test: parse schema from: {-new-list-of:list of K} - * (expr) +0001 * (expr) INLINE -new-list-of:list of K ========= Test: parse schema from: LIST_OF_TY_Mol({-new:list of objects}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_Mol - * (expr) +0001 * (expr) INLINE -new:list of objects ========= Test: parse schema from: LIST_OF_TY_Set_Mol({-by-reference:L}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_Set_Mol - * (expr) +0001 * (expr) INLINE -by-reference:L ========= Test: parse schema from: LIST_OF_TY_GetLength({-by-reference:L}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_GetLength - * (expr) +0001 * (expr) INLINE -by-reference:L ========= Test: parse schema from: LIST_OF_TY_SetLength({-lvalue-by-reference:L}, {N}, -1, 1); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_SetLength - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) INLINE N - * (operation) !unaryminus - * (expr) +0001 * (operation) !unaryminus +0001 * (expr) NUMBER 1 - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_SetLength({-lvalue-by-reference:L}, {N}, -1, 1); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_SetLength - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) INLINE N - * (operation) !unaryminus - * (expr) +0001 * (operation) !unaryminus +0001 * (expr) NUMBER 1 - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_SetLength({-lvalue-by-reference:L}, {N}, -1, -1); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_SetLength - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) INLINE N - * (operation) !unaryminus - * (expr) +0001 * (operation) !unaryminus +0001 * (expr) NUMBER 1 - * (operation) !unaryminus - * (expr) +0001 * (operation) !unaryminus +0001 * (expr) NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_SetLength({-lvalue-by-reference:L}, {N}, 1); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_SetLength - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_SetLength({-lvalue-by-reference:L}, {N}, 0); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_SetLength - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) INLINE N - * (expr) +0001 * (expr) NUMBER 0 ========= Test: parse schema from: LIST_OF_TY_Reverse({-lvalue-by-reference:L}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_Reverse - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L ========= Test: parse schema from: LIST_OF_TY_Rotate({-lvalue-by-reference:L}, 0); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_Rotate - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) NUMBER 0 ========= Test: parse schema from: LIST_OF_TY_Rotate({-lvalue-by-reference:L}, 1); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_Rotate - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_Sort({-lvalue-by-reference:L}, 1); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_Sort - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_Sort({-lvalue-by-reference:L}, -1); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_Sort - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (operation) !unaryminus - * (expr) +0001 * (operation) !unaryminus +0001 * (expr) NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_Sort({-lvalue-by-reference:L}, 2); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_Sort - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) NUMBER 2 ========= Test: parse schema from: LIST_OF_TY_Sort({-lvalue-by-reference:L}, 1, {P}, {-property-holds-block-value:P}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_Sort - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (expr) +0001 * (expr) NUMBER 1 - * (expr) +0001 * (expr) INLINE P - * (expr) +0001 * (expr) INLINE -property-holds-block-value:P ========= Test: parse schema from: LIST_OF_TY_Sort({-lvalue-by-reference:L}, -1, {P}, {-property-holds-block-value:P}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LIST_OF_TY_Sort - * (expr) +0001 * (expr) INLINE -lvalue-by-reference:L - * (operation) !unaryminus - * (expr) +0001 * (operation) !unaryminus +0001 * (expr) NUMBER 1 - * (expr) +0001 * (expr) INLINE P - * (expr) +0001 * (expr) INLINE -property-holds-block-value:P ========= Test: parse schema from: {-show-me:R}; RelationTest({-by-reference:R}, RELS_SHOW); - * (expr) ; +0001 * (expr) ; INLINE -show-me:R - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RelationTest - * (expr) +0001 * (expr) INLINE -by-reference:R - * (expr) +0001 * (expr) IDENTIFIER RELS_SHOW ========= Test: parse schema from: RelationRouteTo({-by-reference:R},{O1},{O2},false) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RelationRouteTo - * (expr) +0001 * (expr) INLINE -by-reference:R - * (expr) +0001 * (expr) INLINE O1 - * (expr) +0001 * (expr) INLINE O2 - * (expr) +0001 * (expr) NUMBER false ========= Test: parse schema from: RelationRouteTo({-by-reference:R},{O1},{O2},true) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RelationRouteTo - * (expr) +0001 * (expr) INLINE -by-reference:R - * (expr) +0001 * (expr) INLINE O1 - * (expr) +0001 * (expr) INLINE O2 - * (expr) +0001 * (expr) NUMBER true ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LIST, {-new:list of K}, RLIST_ALL_X) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RelationTest - * (expr) +0001 * (expr) INLINE -by-reference:R - * (expr) +0001 * (expr) IDENTIFIER RELS_LIST - * (expr) +0001 * (expr) INLINE -new:list of K - * (expr) +0001 * (expr) IDENTIFIER RLIST_ALL_X ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LIST, {-new:list of L}, RLIST_ALL_Y) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RelationTest - * (expr) +0001 * (expr) INLINE -by-reference:R - * (expr) +0001 * (expr) IDENTIFIER RELS_LIST - * (expr) +0001 * (expr) INLINE -new:list of L - * (expr) +0001 * (expr) IDENTIFIER RLIST_ALL_Y ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LIST, {-new:list of L}, RLIST_ALL_Y) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RelationTest - * (expr) +0001 * (expr) INLINE -by-reference:R - * (expr) +0001 * (expr) IDENTIFIER RELS_LIST - * (expr) +0001 * (expr) INLINE -new:list of L - * (expr) +0001 * (expr) IDENTIFIER RLIST_ALL_Y ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ALL_X, {Y}, {-new:list of K}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RelationTest - * (expr) +0001 * (expr) INLINE -by-reference:R - * (expr) +0001 * (expr) IDENTIFIER RELS_LOOKUP_ALL_X - * (expr) +0001 * (expr) INLINE Y - * (expr) +0001 * (expr) INLINE -new:list of K ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ALL_Y, {X}, {-new:list of L}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RelationTest - * (expr) +0001 * (expr) INLINE -by-reference:R - * (expr) +0001 * (expr) IDENTIFIER RELS_LOOKUP_ALL_Y - * (expr) +0001 * (expr) INLINE X - * (expr) +0001 * (expr) INLINE -new:list of L ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ALL_Y, {X}, {-new:list of L}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RelationTest - * (expr) +0001 * (expr) INLINE -by-reference:R - * (expr) +0001 * (expr) IDENTIFIER RELS_LOOKUP_ALL_Y - * (expr) +0001 * (expr) INLINE X - * (expr) +0001 * (expr) INLINE -new:list of L ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ANY, {Y}, RLANY_CAN_GET_X) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RelationTest - * (expr) +0001 * (expr) INLINE -by-reference:R - * (expr) +0001 * (expr) IDENTIFIER RELS_LOOKUP_ANY - * (expr) +0001 * (expr) INLINE Y - * (expr) +0001 * (expr) IDENTIFIER RLANY_CAN_GET_X ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ANY, {X}, RLANY_CAN_GET_Y) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RelationTest - * (expr) +0001 * (expr) INLINE -by-reference:R - * (expr) +0001 * (expr) IDENTIFIER RELS_LOOKUP_ANY - * (expr) +0001 * (expr) INLINE X - * (expr) +0001 * (expr) IDENTIFIER RLANY_CAN_GET_Y ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ANY, {Y}, RLANY_GET_X) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RelationTest - * (expr) +0001 * (expr) INLINE -by-reference:R - * (expr) +0001 * (expr) IDENTIFIER RELS_LOOKUP_ANY - * (expr) +0001 * (expr) INLINE Y - * (expr) +0001 * (expr) IDENTIFIER RLANY_GET_X ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ANY, {X}, RLANY_GET_Y) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RelationTest - * (expr) +0001 * (expr) INLINE -by-reference:R - * (expr) +0001 * (expr) IDENTIFIER RELS_LOOKUP_ANY - * (expr) +0001 * (expr) INLINE X - * (expr) +0001 * (expr) IDENTIFIER RLANY_GET_Y ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ANY, {X}, RLANY_GET_Y) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RelationTest - * (expr) +0001 * (expr) INLINE -by-reference:R - * (expr) +0001 * (expr) IDENTIFIER RELS_LOOKUP_ANY - * (expr) +0001 * (expr) INLINE X - * (expr) +0001 * (expr) IDENTIFIER RLANY_GET_Y ========= Test: parse schema from: {-primitive-definition:description-application} - * (expr) +0001 * (expr) INLINE -primitive-definition:description-application ========= Test: parse schema from: {-primitive-definition:function-application} - * (expr) +0001 * (expr) INLINE -primitive-definition:function-application ========= Test: parse schema from: {-primitive-definition:function-application} - * (expr) +0001 * (expr) INLINE -primitive-definition:function-application ========= Test: parse schema from: {-primitive-definition:function-application} - * (expr) +0001 * (expr) INLINE -primitive-definition:function-application ========= Test: parse schema from: {-primitive-definition:function-application} - * (expr) +0001 * (expr) INLINE -primitive-definition:function-application ========= Test: parse schema from: {-primitive-definition:function-application}; - * (expr) ; +0001 * (expr) ; INLINE -primitive-definition:function-application ========= Test: parse schema from: {-primitive-definition:function-application}; - * (expr) ; +0001 * (expr) ; INLINE -primitive-definition:function-application ========= Test: parse schema from: {-primitive-definition:function-application}; - * (expr) ; +0001 * (expr) ; INLINE -primitive-definition:function-application ========= Test: parse schema from: {-primitive-definition:function-application}; - * (expr) ; +0001 * (expr) ; INLINE -primitive-definition:function-application ========= Test: parse schema from: {-show-me:V} - * (expr) +0001 * (expr) INLINE -show-me:V ========= Test: parse schema from: {-new:K} - * (expr) +0001 * (expr) INLINE -new:K ========= Test: parse schema from: FileIO_GetTable({filename}, {T}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FileIO_GetTable - * (expr) +0001 * (expr) INLINE filename - * (expr) +0001 * (expr) INLINE T ========= Test: parse schema from: FileIO_PutTable({filename}, {T}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FileIO_PutTable - * (expr) +0001 * (expr) INLINE filename - * (expr) +0001 * (expr) INLINE T ========= Test: parse schema from: (FileIO_Exists({filename}, false)) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER FileIO_Exists - * (expr) +0001 * (expr) INLINE filename - * (expr) +0001 * (expr) NUMBER false ========= Test: parse schema from: (FileIO_Ready({filename}, false)) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER FileIO_Ready - * (expr) +0001 * (expr) INLINE filename - * (expr) +0001 * (expr) NUMBER false ========= Test: parse schema from: FileIO_MarkReady({filename}, true); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FileIO_MarkReady - * (expr) +0001 * (expr) INLINE filename - * (expr) +0001 * (expr) NUMBER true ========= Test: parse schema from: FileIO_MarkReady({filename}, false); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FileIO_MarkReady - * (expr) +0001 * (expr) INLINE filename - * (expr) +0001 * (expr) NUMBER false ========= Test: parse schema from: FileIO_PutContents({FN}, {T}, false); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FileIO_PutContents - * (expr) +0001 * (expr) INLINE FN - * (expr) +0001 * (expr) INLINE T - * (expr) +0001 * (expr) NUMBER false ========= Test: parse schema from: FileIO_PutContents({FN}, {T}, true); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FileIO_PutContents - * (expr) +0001 * (expr) INLINE FN - * (expr) +0001 * (expr) INLINE T - * (expr) +0001 * (expr) NUMBER true ========= Test: parse schema from: FileIO_PrintContents({FN}); say__p = 1; - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FileIO_PrintContents - * (expr) +0001 * (expr) INLINE FN - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) IDENTIFIER say__p - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: DisplayFigure(ResourceIDsOfFigures-->{F}, {phrase options}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER DisplayFigure - * (operation) !lookup - * (expr) +0001 * (operation) !lookup +0001 * (expr) IDENTIFIER ResourceIDsOfFigures - * (expr) +0001 * (expr) INLINE F - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: ResourceIDsOfFigures-->{F} - * (operation) !lookup - * (expr) +0001 * (operation) !lookup +0001 * (expr) IDENTIFIER ResourceIDsOfFigures - * (expr) +0001 * (expr) INLINE F ========= Test: parse schema from: PlaySound(ResourceIDsOfSounds-->{SFX}, {phrase options}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER PlaySound - * (operation) !lookup - * (expr) +0001 * (operation) !lookup +0001 * (expr) IDENTIFIER ResourceIDsOfSounds - * (expr) +0001 * (expr) INLINE SFX - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: ResourceIDsOfSounds-->{SFX} - * (operation) !lookup - * (expr) +0001 * (operation) !lookup +0001 * (expr) IDENTIFIER ResourceIDsOfSounds - * (expr) +0001 * (expr) INLINE SFX ========= Test: parse schema from: {c} - * (expr) +0001 * (expr) INLINE c ========= Test: parse schema from: (~~{c}) - * (subexpression) - * (operation) !not - * (expr) +0001 * (subexpression) +0001 * (operation) !not +0001 * (expr) INLINE c ========= Test: parse schema from: @@ -2493,7 +2493,7 @@ Test: parse schema from: schemawhile {c} - * (expr) +0002 * (expr) IDENTIFIER end IDENTIFIER schemawhile INLINE c @@ -2501,103 +2501,103 @@ schemawhile {c} Test: parse schema from: for ({loopvar}={v}: {loopvar}<={w}: {loopvar}++) - * (statement) !for - * (eval) - * (operation) !store - * (expr) +0001 * (statement) !for +0001 * (eval) +0001 * (operation) !store +0001 * (expr) INLINE loopvar - * (expr) +0001 * (expr) INLINE v - * (eval) - * (operation) !le - * (expr) +0001 * (eval) +0001 * (operation) !le +0001 * (expr) INLINE loopvar - * (expr) +0001 * (expr) INLINE w - * (eval) - * (operation) !postincrement - * (expr) +0001 * (eval) +0001 * (operation) !postincrement +0001 * (expr) INLINE loopvar - * (code) < +0001 * (code) < ========= Test: parse schema from: for ({loopvar}={v}: {loopvar}<={w}: {loopvar}++) - * (statement) !for - * (eval) - * (operation) !store - * (expr) +0001 * (statement) !for +0001 * (eval) +0001 * (operation) !store +0001 * (expr) INLINE loopvar - * (expr) +0001 * (expr) INLINE v - * (eval) - * (operation) !le - * (expr) +0001 * (eval) +0001 * (operation) !le +0001 * (expr) INLINE loopvar - * (expr) +0001 * (expr) INLINE w - * (eval) - * (operation) !postincrement - * (expr) +0001 * (eval) +0001 * (operation) !postincrement +0001 * (expr) INLINE loopvar - * (code) < +0001 * (code) < ========= Test: parse schema from: {-primitive-definition:repeat-through} - * (expr) +0001 * (expr) INLINE -primitive-definition:repeat-through ========= Test: parse schema from: {-primitive-definition:repeat-through-list} - * (expr) +0001 * (expr) INLINE -primitive-definition:repeat-through-list ========= Test: parse schema from: {-primitive-definition:break} - * (expr) +0001 * (expr) INLINE -primitive-definition:break ========= Test: parse schema from: continue; - * (statement) !continue +0001 * (statement) !continue ========= Test: parse schema from: rtrue; - * (statement) !return - * (expr) +0001 * (statement) !return +0001 * (expr) NUMBER 1 ========= Test: parse schema from: rtrue; - * (statement) !return - * (expr) +0001 * (statement) !return +0001 * (expr) NUMBER 1 ========= Test: parse schema from: rfalse; - * (statement) !return - * (expr) +0001 * (statement) !return +0001 * (expr) NUMBER 0 ========= Test: parse schema from: rfalse; - * (statement) !return - * (expr) +0001 * (statement) !return +0001 * (expr) NUMBER 0 ========= Test: parse schema from: return {-return-value:something}; - * (statement) !return - * (expr) +0001 * (statement) !return +0001 * (expr) INLINE -return-value:something ========= Test: parse schema from: @@ -2608,1550 +2608,1550 @@ Test: parse schema from: Test: parse schema from: rtrue; - * (statement) !return - * (expr) +0001 * (statement) !return +0001 * (expr) NUMBER 1 ========= Test: parse schema from: {-try-action:S} - * (expr) +0001 * (expr) INLINE -try-action:S ========= Test: parse schema from: {-try-action-silently:S} - * (expr) +0001 * (expr) INLINE -try-action-silently:S ========= Test: parse schema from: {-try-action-silently:S} - * (expr) +0001 * (expr) INLINE -try-action-silently:S ========= Test: parse schema from: (keep_silent == false) - * (subexpression) - * (operation) !eq - * (expr) +0001 * (subexpression) +0001 * (operation) !eq +0001 * (expr) IDENTIFIER keep_silent - * (expr) +0001 * (expr) NUMBER false ========= Test: parse schema from: (NeedToTouchNoun()) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER NeedToTouchNoun ========= Test: parse schema from: (NeedToTouchSecondNoun()) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER NeedToTouchSecondNoun ========= Test: parse schema from: (NeedToCarryNoun()) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER NeedToCarryNoun ========= Test: parse schema from: (NeedToCarrySecondNoun()) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER NeedToCarrySecondNoun ========= Test: parse schema from: (NeedLightForAction()) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER NeedLightForAction ========= Test: parse schema from: rtrue; - * (statement) !return - * (expr) +0001 * (statement) !return +0001 * (expr) NUMBER 1 ========= Test: parse schema from: rfalse; - * (statement) !return - * (expr) +0001 * (statement) !return +0001 * (expr) NUMBER 0 ========= Test: parse schema from: STORED_ACTION_TY_Current({-new:action}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER STORED_ACTION_TY_Current - * (expr) +0001 * (expr) INLINE -new:action ========= Test: parse schema from: {A} - * (expr) +0001 * (expr) INLINE A ========= Test: parse schema from: (STORED_ACTION_TY_Involves({-by-reference:act}, {X})) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER STORED_ACTION_TY_Involves - * (expr) +0001 * (expr) INLINE -by-reference:act - * (expr) +0001 * (expr) INLINE X ========= Test: parse schema from: (STORED_ACTION_TY_Part({-by-reference:act}, STORA_ACTION_F)) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER STORED_ACTION_TY_Part - * (expr) +0001 * (expr) INLINE -by-reference:act - * (expr) +0001 * (expr) IDENTIFIER STORA_ACTION_F ========= Test: parse schema from: (STORED_ACTION_TY_Part({-by-reference:act}, STORA_NOUN_F)) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER STORED_ACTION_TY_Part - * (expr) +0001 * (expr) INLINE -by-reference:act - * (expr) +0001 * (expr) IDENTIFIER STORA_NOUN_F ========= Test: parse schema from: (STORED_ACTION_TY_Part({-by-reference:act}, STORA_SECOND_F)) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER STORED_ACTION_TY_Part - * (expr) +0001 * (expr) INLINE -by-reference:act - * (expr) +0001 * (expr) IDENTIFIER STORA_SECOND_F ========= Test: parse schema from: (STORED_ACTION_TY_Part({-by-reference:act}, STORA_ACTOR_F)) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER STORED_ACTION_TY_Part - * (expr) +0001 * (expr) INLINE -by-reference:act - * (expr) +0001 * (expr) IDENTIFIER STORA_ACTOR_F ========= Test: parse schema from: CarryOutActivity({A}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER CarryOutActivity - * (expr) +0001 * (expr) INLINE A ========= Test: parse schema from: CarryOutActivity({A}, {val}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER CarryOutActivity - * (expr) +0001 * (expr) INLINE A - * (expr) +0001 * (expr) INLINE val ========= Test: parse schema from: rfalse; - * (statement) !return - * (expr) +0001 * (statement) !return +0001 * (expr) NUMBER 0 ========= Test: parse schema from: BeginActivity({A}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER BeginActivity - * (expr) +0001 * (expr) INLINE A ========= Test: parse schema from: BeginActivity({A}, {val}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER BeginActivity - * (expr) +0001 * (expr) INLINE A - * (expr) +0001 * (expr) INLINE val ========= Test: parse schema from: (~~(ForActivity({A}))) - * (subexpression) - * (operation) !not - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (operation) !not +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER ForActivity - * (expr) +0001 * (expr) INLINE A ========= Test: parse schema from: (~~(ForActivity({A}, {val}))) - * (subexpression) - * (operation) !not - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (operation) !not +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER ForActivity - * (expr) +0001 * (expr) INLINE A - * (expr) +0001 * (expr) INLINE val ========= Test: parse schema from: EndActivity({A}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER EndActivity - * (expr) +0001 * (expr) INLINE A ========= Test: parse schema from: EndActivity({A}, {val}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER EndActivity - * (expr) +0001 * (expr) INLINE A - * (expr) +0001 * (expr) INLINE val ========= Test: parse schema from: AbandonActivity({A}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER AbandonActivity - * (expr) +0001 * (expr) INLINE A ========= Test: parse schema from: AbandonActivity({A}, {val}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER AbandonActivity - * (expr) +0001 * (expr) INLINE A - * (expr) +0001 * (expr) INLINE val ========= Test: parse schema from: FollowRulebook({RL}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FollowRulebook - * (expr) +0001 * (expr) INLINE RL ========= Test: parse schema from: FollowRulebook({RL}, {V}, true); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FollowRulebook - * (expr) +0001 * (expr) INLINE RL - * (expr) +0001 * (expr) INLINE V - * (expr) +0001 * (expr) NUMBER true ========= Test: parse schema from: FollowRulebook({RL}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FollowRulebook - * (expr) +0001 * (expr) INLINE RL ========= Test: parse schema from: ResultOfRule({RL}, 0, true, {-strong-kind:K}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER ResultOfRule - * (expr) +0001 * (expr) INLINE RL - * (expr) +0001 * (expr) NUMBER 0 - * (expr) +0001 * (expr) NUMBER true - * (expr) +0001 * (expr) INLINE -strong-kind:K ========= Test: parse schema from: ResultOfRule({RL}, {V}, true, {-strong-kind:L}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER ResultOfRule - * (expr) +0001 * (expr) INLINE RL - * (expr) +0001 * (expr) INLINE V - * (expr) +0001 * (expr) NUMBER true - * (expr) +0001 * (expr) INLINE -strong-kind:L ========= Test: parse schema from: ResultOfRule({RL}, 0, true, {-strong-kind:K}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER ResultOfRule - * (expr) +0001 * (expr) INLINE RL - * (expr) +0001 * (expr) NUMBER 0 - * (expr) +0001 * (expr) NUMBER true - * (expr) +0001 * (expr) INLINE -strong-kind:K ========= Test: parse schema from: if (FollowRulebook({RL})) rtrue; - * (statement) !if - * (subexpression) - * (call) - * (expr) +0001 * (statement) !if +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER FollowRulebook - * (expr) +0001 * (expr) INLINE RL - * (code) - * (statement) !return - * (expr) +0001 * (code) +0001 * (statement) !return +0001 * (expr) NUMBER 1 ========= Test: parse schema from: if (FollowRulebook({RL}, {V}, true)) rtrue; - * (statement) !if - * (subexpression) - * (call) - * (expr) +0001 * (statement) !if +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER FollowRulebook - * (expr) +0001 * (expr) INLINE RL - * (expr) +0001 * (expr) INLINE V - * (expr) +0001 * (expr) NUMBER true - * (code) - * (statement) !return - * (expr) +0001 * (code) +0001 * (statement) !return +0001 * (expr) NUMBER 1 ========= Test: parse schema from: if (FollowRulebook({RL})) rtrue; - * (statement) !if - * (subexpression) - * (call) - * (expr) +0001 * (statement) !if +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER FollowRulebook - * (expr) +0001 * (expr) INLINE RL - * (code) - * (statement) !return - * (expr) +0001 * (code) +0001 * (statement) !return +0001 * (expr) NUMBER 1 ========= Test: parse schema from: rfalse; - * (statement) !return - * (expr) +0001 * (statement) !return +0001 * (expr) NUMBER 0 ========= Test: parse schema from: RulebookSucceeds(); rtrue; - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RulebookSucceeds - * (statement) !return - * (expr) +0001 * (statement) !return +0001 * (expr) NUMBER 1 ========= Test: parse schema from: RulebookFails(); rtrue; - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RulebookFails - * (statement) !return - * (expr) +0001 * (statement) !return +0001 * (expr) NUMBER 1 ========= Test: parse schema from: RulebookSucceeds({-weak-kind:rule-return-kind},{-return-value-from-rule:val}); rtrue; - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RulebookSucceeds - * (expr) +0001 * (expr) INLINE -weak-kind:rule-return-kind - * (expr) +0001 * (expr) INLINE -return-value-from-rule:val - * (statement) !return - * (expr) +0001 * (statement) !return +0001 * (expr) NUMBER 1 ========= Test: parse schema from: (RulebookSucceeded()) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER RulebookSucceeded ========= Test: parse schema from: (RulebookFailed()) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER RulebookFailed ========= Test: parse schema from: (ResultOfRule()) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER ResultOfRule ========= Test: parse schema from: deadflag=3; story_complete=false; - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) IDENTIFIER deadflag - * (expr) +0001 * (expr) NUMBER 3 - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) IDENTIFIER story_complete - * (expr) +0001 * (expr) NUMBER false ========= Test: parse schema from: deadflag=3; story_complete=true; - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) IDENTIFIER deadflag - * (expr) +0001 * (expr) NUMBER 3 - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) IDENTIFIER story_complete - * (expr) +0001 * (expr) NUMBER true ========= Test: parse schema from: deadflag={-by-reference:finale}; story_complete=false; - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) IDENTIFIER deadflag - * (expr) +0001 * (expr) INLINE -by-reference:finale - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) IDENTIFIER story_complete - * (expr) +0001 * (expr) NUMBER false ========= Test: parse schema from: deadflag={-by-reference:finale}; story_complete=true; - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) IDENTIFIER deadflag - * (expr) +0001 * (expr) INLINE -by-reference:finale - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) IDENTIFIER story_complete - * (expr) +0001 * (expr) NUMBER true ========= Test: parse schema from: (deadflag~=0) - * (subexpression) - * (operation) !ne - * (expr) +0001 * (subexpression) +0001 * (operation) !ne +0001 * (expr) IDENTIFIER deadflag - * (expr) +0001 * (expr) NUMBER 0 ========= Test: parse schema from: (story_complete) - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) IDENTIFIER story_complete ========= Test: parse schema from: (deadflag==0) - * (subexpression) - * (operation) !eq - * (expr) +0001 * (subexpression) +0001 * (operation) !eq +0001 * (expr) IDENTIFIER deadflag - * (expr) +0001 * (expr) NUMBER 0 ========= Test: parse schema from: (story_complete==false) - * (subexpression) - * (operation) !eq - * (expr) +0001 * (subexpression) +0001 * (operation) !eq +0001 * (expr) IDENTIFIER story_complete - * (expr) +0001 * (expr) NUMBER false ========= Test: parse schema from: resurrect_please = true; - * (operation) !store - * (expr) +0001 * (operation) !store +0001 * (expr) IDENTIFIER resurrect_please - * (expr) +0001 * (expr) NUMBER true ========= Test: parse schema from: ({t}%ONE_HOUR) - * (subexpression) - * (operation) !modulo - * (expr) +0001 * (subexpression) +0001 * (operation) !modulo +0001 * (expr) INLINE t - * (expr) +0001 * (expr) IDENTIFIER ONE_HOUR ========= Test: parse schema from: ({t}/ONE_HOUR) - * (subexpression) - * (operation) !divide - * (expr) +0001 * (subexpression) +0001 * (operation) !divide +0001 * (expr) INLINE t - * (expr) +0001 * (expr) IDENTIFIER ONE_HOUR ========= Test: parse schema from: ((({t}+20*ONE_HOUR)%(TWENTY_FOUR_HOURS))<(({t2}+20*ONE_HOUR)%(TWENTY_FOUR_HOURS))) - * (subexpression) - * (operation) !lt - * (subexpression) - * (operation) !modulo - * (subexpression) - * (operation) !plus - * (expr) +0001 * (subexpression) +0001 * (operation) !lt +0001 * (subexpression) +0001 * (operation) !modulo +0001 * (subexpression) +0001 * (operation) !plus +0001 * (expr) INLINE t - * (operation) !times - * (expr) +0001 * (operation) !times +0001 * (expr) NUMBER 20 - * (expr) +0001 * (expr) IDENTIFIER ONE_HOUR - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) IDENTIFIER TWENTY_FOUR_HOURS - * (subexpression) - * (operation) !modulo - * (subexpression) - * (operation) !plus - * (expr) +0001 * (subexpression) +0001 * (operation) !modulo +0001 * (subexpression) +0001 * (operation) !plus +0001 * (expr) INLINE t2 - * (operation) !times - * (expr) +0001 * (operation) !times +0001 * (expr) NUMBER 20 - * (expr) +0001 * (expr) IDENTIFIER ONE_HOUR - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) IDENTIFIER TWENTY_FOUR_HOURS ========= Test: parse schema from: ((({t}+20*ONE_HOUR)%(TWENTY_FOUR_HOURS))>(({t2}+20*ONE_HOUR)%(TWENTY_FOUR_HOURS))) - * (subexpression) - * (operation) !gt - * (subexpression) - * (operation) !modulo - * (subexpression) - * (operation) !plus - * (expr) +0001 * (subexpression) +0001 * (operation) !gt +0001 * (subexpression) +0001 * (operation) !modulo +0001 * (subexpression) +0001 * (operation) !plus +0001 * (expr) INLINE t - * (operation) !times - * (expr) +0001 * (operation) !times +0001 * (expr) NUMBER 20 - * (expr) +0001 * (expr) IDENTIFIER ONE_HOUR - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) IDENTIFIER TWENTY_FOUR_HOURS - * (subexpression) - * (operation) !modulo - * (subexpression) - * (operation) !plus - * (expr) +0001 * (subexpression) +0001 * (operation) !modulo +0001 * (subexpression) +0001 * (operation) !plus +0001 * (expr) INLINE t2 - * (operation) !times - * (expr) +0001 * (operation) !times +0001 * (expr) NUMBER 20 - * (expr) +0001 * (expr) IDENTIFIER ONE_HOUR - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) IDENTIFIER TWENTY_FOUR_HOURS ========= Test: parse schema from: (({t2}-{t}+TWENTY_FOUR_HOURS)%(TWENTY_FOUR_HOURS)) - * (subexpression) - * (operation) !modulo - * (subexpression) - * (operation) !plus - * (operation) !minus - * (expr) +0001 * (subexpression) +0001 * (operation) !modulo +0001 * (subexpression) +0001 * (operation) !plus +0001 * (operation) !minus +0001 * (expr) INLINE t2 - * (expr) +0001 * (expr) INLINE t - * (expr) +0001 * (expr) IDENTIFIER TWENTY_FOUR_HOURS - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) IDENTIFIER TWENTY_FOUR_HOURS ========= Test: parse schema from: (({t2}+{t}+TWENTY_FOUR_HOURS)%(TWENTY_FOUR_HOURS)) - * (subexpression) - * (operation) !modulo - * (subexpression) - * (operation) !plus - * (operation) !plus - * (expr) +0001 * (subexpression) +0001 * (operation) !modulo +0001 * (subexpression) +0001 * (operation) !plus +0001 * (operation) !plus +0001 * (expr) INLINE t2 - * (expr) +0001 * (expr) INLINE t - * (expr) +0001 * (expr) IDENTIFIER TWENTY_FOUR_HOURS - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) IDENTIFIER TWENTY_FOUR_HOURS ========= Test: parse schema from: (({n})%(TWENTY_FOUR_HOURS)) - * (subexpression) - * (operation) !modulo - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (operation) !modulo +0001 * (subexpression) +0001 * (expr) INLINE n - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) IDENTIFIER TWENTY_FOUR_HOURS ========= Test: parse schema from: (({n}*ONE_HOUR)%(TWENTY_FOUR_HOURS)) - * (subexpression) - * (operation) !modulo - * (subexpression) - * (operation) !times - * (expr) +0001 * (subexpression) +0001 * (operation) !modulo +0001 * (subexpression) +0001 * (operation) !times +0001 * (expr) INLINE n - * (expr) +0001 * (expr) IDENTIFIER ONE_HOUR - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) IDENTIFIER TWENTY_FOUR_HOURS ========= Test: parse schema from: SetTimedEvent({-mark-event-used:R}, {t}+1, 0); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER SetTimedEvent - * (expr) +0001 * (expr) INLINE -mark-event-used:R - * (operation) !plus - * (expr) +0001 * (operation) !plus +0001 * (expr) INLINE t - * (expr) +0001 * (expr) NUMBER 1 - * (expr) +0001 * (expr) NUMBER 0 ========= Test: parse schema from: SetTimedEvent({-mark-event-used:R}, {t}, 1); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER SetTimedEvent - * (expr) +0001 * (expr) INLINE -mark-event-used:R - * (expr) +0001 * (expr) INLINE t - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: SetTimedEvent({-mark-event-used:R}, (the_time+{t})%(TWENTY_FOUR_HOURS), 1); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER SetTimedEvent - * (expr) +0001 * (expr) INLINE -mark-event-used:R - * (operation) !modulo - * (subexpression) - * (operation) !plus - * (expr) +0001 * (operation) !modulo +0001 * (subexpression) +0001 * (operation) !plus +0001 * (expr) IDENTIFIER the_time - * (expr) +0001 * (expr) INLINE t - * (subexpression) - * (expr) +0001 * (subexpression) +0001 * (expr) IDENTIFIER TWENTY_FOUR_HOURS - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: (scene_endings-->({sc}-1)) - * (subexpression) - * (operation) !lookup - * (expr) +0001 * (subexpression) +0001 * (operation) !lookup +0001 * (expr) IDENTIFIER scene_endings - * (subexpression) - * (operation) !minus - * (expr) +0001 * (subexpression) +0001 * (operation) !minus +0001 * (expr) INLINE sc - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: (scene_endings-->({sc}-1) == 0) - * (subexpression) - * (operation) !eq - * (operation) !lookup - * (expr) +0001 * (subexpression) +0001 * (operation) !eq +0001 * (operation) !lookup +0001 * (expr) IDENTIFIER scene_endings - * (subexpression) - * (operation) !minus - * (expr) +0001 * (subexpression) +0001 * (operation) !minus +0001 * (expr) INLINE sc - * (expr) +0001 * (expr) NUMBER 1 - * (expr) +0001 * (expr) NUMBER 0 ========= Test: parse schema from: (scene_endings-->({sc}-1) > 1) - * (subexpression) - * (operation) !gt - * (operation) !lookup - * (expr) +0001 * (subexpression) +0001 * (operation) !gt +0001 * (operation) !lookup +0001 * (expr) IDENTIFIER scene_endings - * (subexpression) - * (operation) !minus - * (expr) +0001 * (subexpression) +0001 * (operation) !minus +0001 * (expr) INLINE sc - * (expr) +0001 * (expr) NUMBER 1 - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: (scene_endings-->({sc}-1) <= 1) - * (subexpression) - * (operation) !le - * (operation) !lookup - * (expr) +0001 * (subexpression) +0001 * (operation) !le +0001 * (operation) !lookup +0001 * (expr) IDENTIFIER scene_endings - * (subexpression) - * (operation) !minus - * (expr) +0001 * (subexpression) +0001 * (operation) !minus +0001 * (expr) INLINE sc - * (expr) +0001 * (expr) NUMBER 1 - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: (SceneUtility({sc}, 1)) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER SceneUtility - * (expr) +0001 * (expr) INLINE sc - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: (SceneUtility({sc}, 2)) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER SceneUtility - * (expr) +0001 * (expr) INLINE sc - * (expr) +0001 * (expr) NUMBER 2 ========= Test: parse schema from: (SceneUtility({sc}, 3)) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER SceneUtility - * (expr) +0001 * (expr) INLINE sc - * (expr) +0001 * (expr) NUMBER 3 ========= Test: parse schema from: (SceneUtility({sc}, 4)) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER SceneUtility - * (expr) +0001 * (expr) INLINE sc - * (expr) +0001 * (expr) NUMBER 4 ========= Test: parse schema from: (location==thedark) - * (subexpression) - * (operation) !eq - * (expr) +0001 * (subexpression) +0001 * (operation) !eq +0001 * (expr) IDENTIFIER location - * (expr) +0001 * (expr) IDENTIFIER thedark ========= Test: parse schema from: MoveObject({something}, {something else}, {phrase options}, false); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER MoveObject - * (expr) +0001 * (expr) INLINE something - * (expr) +0001 * (expr) INLINE something else - * (expr) +0001 * (expr) INLINE phrase options - * (expr) +0001 * (expr) NUMBER false ========= Test: parse schema from: RemoveFromPlay({something}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RemoveFromPlay - * (expr) +0001 * (expr) INLINE something ========= Test: parse schema from: MoveBackdrop({O}, {D}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER MoveBackdrop - * (expr) +0001 * (expr) INLINE O - * (expr) +0001 * (expr) INLINE D ========= Test: parse schema from: MoveFloatingObjects(); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER MoveFloatingObjects ========= Test: parse schema from: LocationOf({O}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LocationOf - * (expr) +0001 * (expr) INLINE O ========= Test: parse schema from: MapConnection({R1},{D}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER MapConnection - * (expr) +0001 * (expr) INLINE R1 - * (expr) +0001 * (expr) INLINE D ========= Test: parse schema from: DoorFrom({R1},{D}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER DoorFrom - * (expr) +0001 * (expr) INLINE R1 - * (expr) +0001 * (expr) INLINE D ========= Test: parse schema from: OtherSideOfDoor({D},{R1}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER OtherSideOfDoor - * (expr) +0001 * (expr) INLINE D - * (expr) +0001 * (expr) INLINE R1 ========= Test: parse schema from: DirectionDoorLeadsIn({D},{R1}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER DirectionDoorLeadsIn - * (expr) +0001 * (expr) INLINE D - * (expr) +0001 * (expr) INLINE R1 ========= Test: parse schema from: RoomOrDoorFrom({R1},{D}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RoomOrDoorFrom - * (expr) +0001 * (expr) INLINE R1 - * (expr) +0001 * (expr) INLINE D ========= Test: parse schema from: AssertMapConnection({R1},{D},{R2}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER AssertMapConnection - * (expr) +0001 * (expr) INLINE R1 - * (expr) +0001 * (expr) INLINE D - * (expr) +0001 * (expr) INLINE R2 ========= Test: parse schema from: AssertMapConnection({R1},{D},nothing); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER AssertMapConnection - * (expr) +0001 * (expr) INLINE R1 - * (expr) +0001 * (expr) INLINE D - * (expr) +0001 * (expr) NUMBER nothing ========= Test: parse schema from: FrontSideOfDoor({D}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FrontSideOfDoor - * (expr) +0001 * (expr) INLINE D ========= Test: parse schema from: BackSideOfDoor({D}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER BackSideOfDoor - * (expr) +0001 * (expr) INLINE D ========= Test: parse schema from: MapRouteTo({R1},{R2},0,{phrase options}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER MapRouteTo - * (expr) +0001 * (expr) INLINE R1 - * (expr) +0001 * (expr) INLINE R2 - * (expr) +0001 * (expr) NUMBER 0 - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: MapRouteTo({R1},{R2},0,{phrase options},true) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER MapRouteTo - * (expr) +0001 * (expr) INLINE R1 - * (expr) +0001 * (expr) INLINE R2 - * (expr) +0001 * (expr) NUMBER 0 - * (expr) +0001 * (expr) INLINE phrase options - * (expr) +0001 * (expr) NUMBER true ========= Test: parse schema from: MapRouteTo({R1},{R2},{RS},{phrase options}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER MapRouteTo - * (expr) +0001 * (expr) INLINE R1 - * (expr) +0001 * (expr) INLINE R2 - * (expr) +0001 * (expr) INLINE RS - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: MapRouteTo({R1},{R2},{RS},{phrase options},true) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER MapRouteTo - * (expr) +0001 * (expr) INLINE R1 - * (expr) +0001 * (expr) INLINE R2 - * (expr) +0001 * (expr) INLINE RS - * (expr) +0001 * (expr) INLINE phrase options - * (expr) +0001 * (expr) NUMBER true ========= Test: parse schema from: (HolderOf({something})) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER HolderOf - * (expr) +0001 * (expr) INLINE something ========= Test: parse schema from: (sibling({something})) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER sibling - * (expr) +0001 * (expr) INLINE something ========= Test: parse schema from: (child({something})) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER child - * (expr) +0001 * (expr) INLINE something ========= Test: parse schema from: YesOrNo() - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER YesOrNo ========= Test: parse schema from: (SnippetMatches({S}, {T})) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER SnippetMatches - * (expr) +0001 * (expr) INLINE S - * (expr) +0001 * (expr) INLINE T ========= Test: parse schema from: (SnippetMatches({S}, {T}) == false) - * (subexpression) - * (operation) !eq - * (call) - * (expr) +0001 * (subexpression) +0001 * (operation) !eq +0001 * (call) +0001 * (expr) IDENTIFIER SnippetMatches - * (expr) +0001 * (expr) INLINE S - * (expr) +0001 * (expr) INLINE T - * (expr) +0001 * (expr) NUMBER false ========= Test: parse schema from: (matched_text=SnippetIncludes({T},{S})) - * (subexpression) - * (operation) !store - * (expr) +0001 * (subexpression) +0001 * (operation) !store +0001 * (expr) IDENTIFIER matched_text - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER SnippetIncludes - * (expr) +0001 * (expr) INLINE T - * (expr) +0001 * (expr) INLINE S ========= Test: parse schema from: (SnippetIncludes({T},{S})==0) - * (subexpression) - * (operation) !eq - * (call) - * (expr) +0001 * (subexpression) +0001 * (operation) !eq +0001 * (call) +0001 * (expr) IDENTIFIER SnippetIncludes - * (expr) +0001 * (expr) INLINE T - * (expr) +0001 * (expr) INLINE S - * (expr) +0001 * (expr) NUMBER 0 ========= Test: parse schema from: SetPlayersCommand({-by-reference:T}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER SetPlayersCommand - * (expr) +0001 * (expr) INLINE -by-reference:T ========= Test: parse schema from: SpliceSnippet({S}, {-by-reference:T}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER SpliceSnippet - * (expr) +0001 * (expr) INLINE S - * (expr) +0001 * (expr) INLINE -by-reference:T ========= Test: parse schema from: SpliceSnippet({S}, 0); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER SpliceSnippet - * (expr) +0001 * (expr) INLINE S - * (expr) +0001 * (expr) NUMBER 0 ========= Test: parse schema from: RulebookFails(); rtrue; - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER RulebookFails - * (statement) !return - * (expr) +0001 * (statement) !return +0001 * (expr) NUMBER 1 ========= Test: parse schema from: PlaceInScope({O}, {phrase options}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER PlaceInScope - * (expr) +0001 * (expr) INLINE O - * (expr) +0001 * (expr) INLINE phrase options ========= Test: parse schema from: ScopeWithin({O}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER ScopeWithin - * (expr) +0001 * (expr) INLINE O ========= Test: parse schema from: PronounNotice({O}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER PronounNotice - * (expr) +0001 * (expr) INLINE O ========= Test: parse schema from: NotifyTheScore(); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER NotifyTheScore ========= Test: parse schema from: print (address) pronoun_word; - * (statement) !printdword - * (expr) +0001 * (statement) !printdword +0001 * (expr) IDENTIFIER pronoun_word ========= Test: parse schema from: PrintCommand(); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER PrintCommand ========= Test: parse schema from: print (address) pronoun_word; - * (statement) !printdword - * (expr) +0001 * (statement) !printdword +0001 * (expr) IDENTIFIER pronoun_word ========= Test: parse schema from: PrintCommand(); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER PrintCommand ========= Test: parse schema from: CoreOf({X}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER CoreOf - * (expr) +0001 * (expr) INLINE X ========= Test: parse schema from: (CommonAncestor({O}, {P})) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER CommonAncestor - * (expr) +0001 * (expr) INLINE O - * (expr) +0001 * (expr) INLINE P ========= Test: parse schema from: (CoreOfParentOfCoreOf({O})) - * (subexpression) - * (call) - * (expr) +0001 * (subexpression) +0001 * (call) +0001 * (expr) IDENTIFIER CoreOfParentOfCoreOf - * (expr) +0001 * (expr) INLINE O ========= Test: parse schema from: VisibilityParent({O}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER VisibilityParent - * (expr) +0001 * (expr) INLINE O ========= Test: parse schema from: FindVisibilityLevels(); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER FindVisibilityLevels ========= Test: parse schema from: TouchabilityCeiling({O}) - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER TouchabilityCeiling - * (expr) +0001 * (expr) INLINE O ========= Test: parse schema from: visibility_levels - * (expr) +0001 * (expr) IDENTIFIER visibility_levels ========= Test: parse schema from: visibility_ceiling - * (expr) +0001 * (expr) IDENTIFIER visibility_ceiling ========= Test: parse schema from: LookAfterGoing(); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER LookAfterGoing ========= Test: parse schema from: PrintOrRun(location, description); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER PrintOrRun - * (expr) +0001 * (expr) IDENTIFIER location - * (expr) +0001 * (expr) IDENTIFIER description ========= Test: parse schema from: say__comp - * (expr) +0001 * (expr) IDENTIFIER say__comp ========= Test: parse schema from: (multiflag==1) - * (subexpression) - * (operation) !eq - * (expr) +0001 * (subexpression) +0001 * (operation) !eq +0001 * (expr) IDENTIFIER multiflag - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: (lookmode == 1) - * (subexpression) - * (operation) !eq - * (expr) +0001 * (subexpression) +0001 * (operation) !eq +0001 * (expr) IDENTIFIER lookmode - * (expr) +0001 * (expr) NUMBER 1 ========= Test: parse schema from: (lookmode == 2) - * (subexpression) - * (operation) !eq - * (expr) +0001 * (subexpression) +0001 * (operation) !eq +0001 * (expr) IDENTIFIER lookmode - * (expr) +0001 * (expr) NUMBER 2 ========= Test: parse schema from: (lookmode == 3) - * (subexpression) - * (operation) !eq - * (expr) +0001 * (subexpression) +0001 * (operation) !eq +0001 * (expr) IDENTIFIER lookmode - * (expr) +0001 * (expr) NUMBER 3 ========= Test: parse schema from: return GVS_Convert({AN},{O},0); - * (statement) !return - * (call) - * (expr) +0001 * (statement) !return +0001 * (call) +0001 * (expr) IDENTIFIER GVS_Convert - * (expr) +0001 * (expr) INLINE AN - * (expr) +0001 * (expr) INLINE O - * (expr) +0001 * (expr) NUMBER 0 ========= Test: parse schema from: return ConvertToRequest({X}, {AN}, {Y}, {Z}); - * (statement) !return - * (call) - * (expr) +0001 * (statement) !return +0001 * (call) +0001 * (expr) IDENTIFIER ConvertToRequest - * (expr) +0001 * (expr) INLINE X - * (expr) +0001 * (expr) INLINE AN - * (expr) +0001 * (expr) INLINE Y - * (expr) +0001 * (expr) INLINE Z ========= Test: parse schema from: return ConvertToGoingWithPush(); - * (statement) !return - * (call) - * (expr) +0001 * (statement) !return +0001 * (call) +0001 * (expr) IDENTIFIER ConvertToGoingWithPush ========= Test: parse schema from: move {something} to {something else}; - * (statement) !move - * (expr) +0001 * (statement) !move +0001 * (expr) INLINE something - * (expr) +0001 * (expr) INLINE something else ========= Test: parse schema from: MoveDuringGoing({something}, {something else}); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER MoveDuringGoing - * (expr) +0001 * (expr) INLINE something - * (expr) +0001 * (expr) INLINE something else ========= Test: parse schema from: SilentlyConsiderLight(); - * (call) - * (expr) +0001 * (call) +0001 * (expr) IDENTIFIER SilentlyConsiderLight ========= Test: parse schema from: {-primitive-definition:verbose-checking} - * (expr) +0001 * (expr) INLINE -primitive-definition:verbose-checking ========= Test: parse schema from: {-primitive-definition:verbose-checking} - * (expr) +0001 * (expr) INLINE -primitive-definition:verbose-checking ========= Test: parse schema from: @log_shift xorshift_seed -3 -> temp; @log_shift xorshift_seed (-3) -> temp; - * (assembly) - * (expr) +0001 * (assembly) +0001 * (expr) OPCODE @log_shift - * (expr) +0001 * (expr) IDENTIFIER xorshift_seed - * (expr) +0001 * (expr) NUMBER -3 - * (expr) +0001 * (expr) ASM_ARROW -> - * (expr) +0001 * (expr) IDENTIFIER temp - * (assembly) - * (expr) +0002 * (assembly) +0002 * (expr) OPCODE @log_shift - * (expr) +0002 * (expr) IDENTIFIER xorshift_seed - * (expr) +0002 * (expr) NUMBER -3 - * (expr) +0002 * (expr) ASM_ARROW -> - * (expr) +0001 * (expr) IDENTIFIER temp ========= Test: parse schema from: print ""; - * (statement) !print - * (expr) +0001 * (statement) !print +0001 * (expr) DQUOTED ========= Test: parse schema from: @@ -4162,38 +4162,38 @@ Test: parse schema from: print (char) '@{0041}', " might be an A, who knows.^"; print (address) 'x@{0041}', " might be an xA, who knows.^"; - * (statement) !printnumber - * (expr) +0001 * (statement) !printnumber +0001 * (expr) SQUOTED ^ - * (statement) !printnumber - * (expr) +0002 * (statement) !printnumber +0002 * (expr) SQUOTED helen's// - * (statement) !printchar - * (expr) +0003 * (statement) !printchar +0003 * (expr) SQUOTED ß - * (statement) !print - * (expr) +0003 * (statement) !print +0003 * (expr) DQUOTED might be an ß, who knows. - * (statement) !printdword - * (expr) +0004 * (statement) !printdword +0004 * (expr) SQUOTED xß - * (statement) !print - * (expr) +0004 * (statement) !print +0004 * (expr) DQUOTED might be an xß, who knows. - * (statement) !printchar - * (expr) +0005 * (statement) !printchar +0005 * (expr) SQUOTED A - * (statement) !print - * (expr) +0005 * (statement) !print +0005 * (expr) DQUOTED might be an A, who knows. - * (statement) !printdword - * (expr) +0006 * (statement) !printdword +0006 * (expr) SQUOTED xA - * (statement) !print - * (expr) +0006 * (statement) !print +0006 * (expr) DQUOTED might be an xA, who knows. ========= @@ -4276,249 +4276,249 @@ Test: parse schema from: print "inverted ?: @@223."; print "[unicode 169] is a copyright sign. [unicode 1060] is a capital Cyrillic ef, and [unicode 9650] is a triangle."; - * (statement) !print - * (expr) +0001 * (statement) !print +0001 * (expr) DQUOTED Les œuvres d'Æsop en français, mon élève! - * (statement) !print - * (expr) +0002 * (statement) !print +0002 * (expr) DQUOTED Naïve readers of the New Yorker reëlected Mr Clinton. - * (statement) !print - * (expr) +0003 * (statement) !print +0003 * (expr) DQUOTED Gauß first proved the Fundamental Theorem of Algebra. - * (statement) !print - * (expr) +0004 * (statement) !print +0004 * (expr) DQUOTED áéíóúýÁÉÍÓÚÝàèìòùÀÈÌÒÙâêîôûÂÊÎÔÛäëïöüÿÄËÏÖÜŸ - * (statement) !print - * (expr) +0005 * (statement) !print +0005 * (expr) DQUOTED ãñõÃÑÕçÇøØæÆðÐþΣ¡¿«»ßåÅœŒ - * (statement) !print - * (expr) +0006 * (statement) !print +0006 * (expr) DQUOTED So © is a copyright sign, and Ф is a capital Cyrillic ef, and ▲ is a triangle - * (statement) !print - * (expr) +0007 * (statement) !print +0007 * (expr) DQUOTED Backslash: \ At sign: @ Caret: ^ Tilde: ~ - * (statement) !print - * (expr) +0008 * (statement) !print +0008 * (expr) DQUOTED a-diarhesis: ä. - * (statement) !print - * (expr) +0009 * (statement) !print +0009 * (expr) DQUOTED o-diarhesis: ö. - * (statement) !print - * (expr) +0010 * (statement) !print +0010 * (expr) DQUOTED u-diarhesis: ü. - * (statement) !print - * (expr) +0011 * (statement) !print +0011 * (expr) DQUOTED A-diarhesis: Ä. - * (statement) !print - * (expr) +0012 * (statement) !print +0012 * (expr) DQUOTED O-diarhesis: Ö. - * (statement) !print - * (expr) +0013 * (statement) !print +0013 * (expr) DQUOTED U-diarhesis: Ü. - * (statement) !print - * (expr) +0014 * (statement) !print +0014 * (expr) DQUOTED sharp s: ß. - * (statement) !print - * (expr) +0015 * (statement) !print +0015 * (expr) DQUOTED close double-angle quotation mark: ». - * (statement) !print - * (expr) +0016 * (statement) !print +0016 * (expr) DQUOTED open double-angle quotation mark: «. - * (statement) !print - * (expr) +0017 * (statement) !print +0017 * (expr) DQUOTED e-diarhesis: ë. - * (statement) !print - * (expr) +0018 * (statement) !print +0018 * (expr) DQUOTED i-diarhesis: ï. - * (statement) !print - * (expr) +0019 * (statement) !print +0019 * (expr) DQUOTED y-diarhesis: ÿ. - * (statement) !print - * (expr) +0020 * (statement) !print +0020 * (expr) DQUOTED E-diarhesis: Ë. - * (statement) !print - * (expr) +0021 * (statement) !print +0021 * (expr) DQUOTED I-diarhesis: Ï. - * (statement) !print - * (expr) +0022 * (statement) !print +0022 * (expr) DQUOTED a-acute: á. - * (statement) !print - * (expr) +0023 * (statement) !print +0023 * (expr) DQUOTED e-acute: é. - * (statement) !print - * (expr) +0024 * (statement) !print +0024 * (expr) DQUOTED i-acute: í. - * (statement) !print - * (expr) +0025 * (statement) !print +0025 * (expr) DQUOTED o-acute: ó. - * (statement) !print - * (expr) +0026 * (statement) !print +0026 * (expr) DQUOTED u-acute: ú. - * (statement) !print - * (expr) +0027 * (statement) !print +0027 * (expr) DQUOTED y-acute: ý. - * (statement) !print - * (expr) +0028 * (statement) !print +0028 * (expr) DQUOTED A-acute: Á. - * (statement) !print - * (expr) +0029 * (statement) !print +0029 * (expr) DQUOTED E-acute: É. - * (statement) !print - * (expr) +0030 * (statement) !print +0030 * (expr) DQUOTED I-acute: Í. - * (statement) !print - * (expr) +0031 * (statement) !print +0031 * (expr) DQUOTED O-acute: Ó. - * (statement) !print - * (expr) +0032 * (statement) !print +0032 * (expr) DQUOTED U-acute: Ú. - * (statement) !print - * (expr) +0033 * (statement) !print +0033 * (expr) DQUOTED Y-acute: Ý. - * (statement) !print - * (expr) +0034 * (statement) !print +0034 * (expr) DQUOTED a-grave: à. - * (statement) !print - * (expr) +0035 * (statement) !print +0035 * (expr) DQUOTED e-grave: è. - * (statement) !print - * (expr) +0036 * (statement) !print +0036 * (expr) DQUOTED i-grave: ì. - * (statement) !print - * (expr) +0037 * (statement) !print +0037 * (expr) DQUOTED o-grave: ò. - * (statement) !print - * (expr) +0038 * (statement) !print +0038 * (expr) DQUOTED u-grave: ù. - * (statement) !print - * (expr) +0039 * (statement) !print +0039 * (expr) DQUOTED A-grave: À. - * (statement) !print - * (expr) +0040 * (statement) !print +0040 * (expr) DQUOTED E-grave: È. - * (statement) !print - * (expr) +0041 * (statement) !print +0041 * (expr) DQUOTED I-grave: Ì. - * (statement) !print - * (expr) +0042 * (statement) !print +0042 * (expr) DQUOTED O-grave: Ò. - * (statement) !print - * (expr) +0043 * (statement) !print +0043 * (expr) DQUOTED U-grave: Ù. - * (statement) !print - * (expr) +0044 * (statement) !print +0044 * (expr) DQUOTED a-circumflex: â. - * (statement) !print - * (expr) +0045 * (statement) !print +0045 * (expr) DQUOTED e-circumflex: ê. - * (statement) !print - * (expr) +0046 * (statement) !print +0046 * (expr) DQUOTED i-circumflex: î. - * (statement) !print - * (expr) +0047 * (statement) !print +0047 * (expr) DQUOTED o-circumflex: ô. - * (statement) !print - * (expr) +0048 * (statement) !print +0048 * (expr) DQUOTED u-circumflex: û. - * (statement) !print - * (expr) +0049 * (statement) !print +0049 * (expr) DQUOTED A-circumflex: Â. - * (statement) !print - * (expr) +0050 * (statement) !print +0050 * (expr) DQUOTED E-circumflex: Ê. - * (statement) !print - * (expr) +0051 * (statement) !print +0051 * (expr) DQUOTED I-circumflex: Î. - * (statement) !print - * (expr) +0052 * (statement) !print +0052 * (expr) DQUOTED O-circumflex: Ô. - * (statement) !print - * (expr) +0053 * (statement) !print +0053 * (expr) DQUOTED U-circumflex: Û. - * (statement) !print - * (expr) +0054 * (statement) !print +0054 * (expr) DQUOTED a-ring: æ. - * (statement) !print - * (expr) +0055 * (statement) !print +0055 * (expr) DQUOTED A-ring: Æ. - * (statement) !print - * (expr) +0056 * (statement) !print +0056 * (expr) DQUOTED o-stroke: ø. - * (statement) !print - * (expr) +0057 * (statement) !print +0057 * (expr) DQUOTED O-stroke: Ø. - * (statement) !print - * (expr) +0058 * (statement) !print +0058 * (expr) DQUOTED a-tilde: ã. - * (statement) !print - * (expr) +0059 * (statement) !print +0059 * (expr) DQUOTED n-tilde: ñ. - * (statement) !print - * (expr) +0060 * (statement) !print +0060 * (expr) DQUOTED o-tilde: õ. - * (statement) !print - * (expr) +0061 * (statement) !print +0061 * (expr) DQUOTED A-tilde: Ã. - * (statement) !print - * (expr) +0062 * (statement) !print +0062 * (expr) DQUOTED N-tilde: Ñ. - * (statement) !print - * (expr) +0063 * (statement) !print +0063 * (expr) DQUOTED O-tilde: Õ. - * (statement) !print - * (expr) +0064 * (statement) !print +0064 * (expr) DQUOTED ae: æ. - * (statement) !print - * (expr) +0065 * (statement) !print +0065 * (expr) DQUOTED AE: Æ. - * (statement) !print - * (expr) +0066 * (statement) !print +0066 * (expr) DQUOTED c-cedilla: ç. - * (statement) !print - * (expr) +0067 * (statement) !print +0067 * (expr) DQUOTED C-cedilla: Ç. - * (statement) !print - * (expr) +0068 * (statement) !print +0068 * (expr) DQUOTED thorn: þ. - * (statement) !print - * (expr) +0069 * (statement) !print +0069 * (expr) DQUOTED eth: ð. - * (statement) !print - * (expr) +0070 * (statement) !print +0070 * (expr) DQUOTED Thorn: Þ. - * (statement) !print - * (expr) +0071 * (statement) !print +0071 * (expr) DQUOTED Eth: Ð. - * (statement) !print - * (expr) +0072 * (statement) !print +0072 * (expr) DQUOTED pound sterling sign: £. - * (statement) !print - * (expr) +0073 * (statement) !print +0073 * (expr) DQUOTED oe: œ. - * (statement) !print - * (expr) +0074 * (statement) !print +0074 * (expr) DQUOTED OE: Œ. - * (statement) !print - * (expr) +0075 * (statement) !print +0075 * (expr) DQUOTED inverted !: ¡. - * (statement) !print - * (expr) +0076 * (statement) !print +0076 * (expr) DQUOTED inverted ?: ¿. - * (statement) !print - * (expr) +0077 * (statement) !print +0077 * (expr) DQUOTED © is a copyright sign. Ф is a capital Cyrillic ef, and ▲ is a triangle. ========= Test: parse schema from: print BasicInformKit`stuff(); DialogueKit`temp = 1; - * (statement) !printnumber - * (call) - * (expr) +0001 * (statement) !printnumber +0001 * (call) +0002 * (expr) IDENTIFIER BasicInformKit`stuff - * (operation) !store - * (expr) +0002 * (operation) !store +0002 * (expr) IDENTIFIER DialogueKit`temp - * (expr) +0003 * (expr) NUMBER 1 ========= diff --git a/inter/bytecode-module/Chapter 3/Text Provenance.w b/inter/bytecode-module/Chapter 3/Text Provenance.w new file mode 100644 index 000000000..4a62a6977 --- /dev/null +++ b/inter/bytecode-module/Chapter 3/Text Provenance.w @@ -0,0 +1,77 @@ +[Provenance::] Text Provenance. + +Recording where fragments of text originally came from. + +@ Inter code sometimes needs to contain fragments of not-yet-parsed Inform 6 +syntax code, in the form of |SPLAT_IST| and |INSERT_IST| instructions. In order +for it to be possible to relate errors in those fragments to the original text +files they came from, we need to record their "provenance". + +This is only a wrapper for saying something like "line 17 in |whatever.txt|". +Line numbers count from 1 at the top of a text file. + += +typedef struct text_provenance { + struct text_stream *textual_filename; + int line_number; +} text_provenance; + +@ This provides a "don't know, or, it didn't come from a text file, I made it up" +value: + += +text_provenance Provenance::nowhere(void) { + text_provenance nowhere; + nowhere.textual_filename = NULL; + nowhere.line_number = 0; + return nowhere; +} + +int Provenance::is_somewhere(text_provenance where) { + if (Str::len(where.textual_filename) > 0) return TRUE; + return FALSE; +} + +@ Composing: + += +text_provenance Provenance::at_file_and_line(text_stream *file, int line) { + text_provenance somewhere; + somewhere.textual_filename = Str::duplicate(file); + somewhere.line_number = line; + return somewhere; +} + +@ Decomposing: + += +int Provenance::get_line(text_provenance where) { + if (Provenance::is_somewhere(where)) return where.line_number; + return 0; +} + +filename *Provenance::get_filename(text_provenance where) { + if (Provenance::is_somewhere(where)) + return Filenames::from_text(where.textual_filename); + return NULL; +} + +@ Altering in place: + += +void Provenance::set_line(text_provenance *where, int lc) { + if ((where) && (Provenance::is_somewhere(*where))) + where->line_number = lc; +} + +@ Writing to text: + += +void Provenance::write(OUTPUT_STREAM, text_provenance at) { + if (Provenance::is_somewhere(at)) { + TextualInter::write_text(OUT, at.textual_filename); + WRITE(" %d", at.line_number); + } else { + WRITE(""); + } +} diff --git a/inter/bytecode-module/Chapter 4/The Insert Construct.w b/inter/bytecode-module/Chapter 4/The Insert Construct.w index d571375cf..fc0745107 100644 --- a/inter/bytecode-module/Chapter 4/The Insert Construct.w +++ b/inter/bytecode-module/Chapter 4/The Insert Construct.w @@ -112,8 +112,7 @@ void InsertInstruction::write(inter_construct *IC, OUTPUT_STREAM, inter_tree_nod WRITE(" "); TextualInter::write_text(OUT, replacing); WRITE(" "); - TextualInter::write_text(OUT, InsertInstruction::file_provenance(P)); - WRITE(" %d", InsertInstruction::line_provenance(P)); + Provenance::write(OUT, InsertInstruction::provenance(P)); } @h Access functions. @@ -131,14 +130,10 @@ text_stream *InsertInstruction::replacing(inter_tree_node *P) { return Inode::ID_to_text(P, P->W.instruction[REPLACING_INSERT_IFLD]); } -text_stream *InsertInstruction::file_provenance(inter_tree_node *P) { - if (P == NULL) return NULL; - if (Inode::isnt(P, INSERT_IST)) return NULL; - return Inode::ID_to_text(P, P->W.instruction[PROVENANCEFILE_INSERT_IFLD]); -} - -inter_ti InsertInstruction::line_provenance(inter_tree_node *P) { - if (P == NULL) return 0; - if (Inode::isnt(P, INSERT_IST)) return 0; - return P->W.instruction[PROVENANCELINE_INSERT_IFLD]; +text_provenance InsertInstruction::provenance(inter_tree_node *P) { + if (P == NULL) return Provenance::nowhere(); + if (Inode::isnt(P, INSERT_IST)) return Provenance::nowhere(); + return Provenance::at_file_and_line( + Inode::ID_to_text(P, P->W.instruction[PROVENANCEFILE_INSERT_IFLD]), + (int) P->W.instruction[PROVENANCELINE_INSERT_IFLD]); } diff --git a/inter/bytecode-module/Chapter 5/The Splat Construct.w b/inter/bytecode-module/Chapter 5/The Splat Construct.w index 4858af037..b82c1b542 100644 --- a/inter/bytecode-module/Chapter 5/The Splat Construct.w +++ b/inter/bytecode-module/Chapter 5/The Splat Construct.w @@ -157,16 +157,12 @@ text_stream *SplatInstruction::namespace(inter_tree_node *P) { return Inode::ID_to_text(P, P->W.instruction[NAMESPACE_SPLAT_IFLD]); } -text_stream *SplatInstruction::file_provenance(inter_tree_node *P) { - if (P == NULL) return NULL; - if (Inode::isnt(P, SPLAT_IST)) return NULL; - return Inode::ID_to_text(P, P->W.instruction[PROVENANCEFILE_SPLAT_IFLD]); -} - -inter_ti SplatInstruction::line_provenance(inter_tree_node *P) { - if (P == NULL) return 0; - if (Inode::isnt(P, SPLAT_IST)) return 0; - return P->W.instruction[PROVENANCELINE_SPLAT_IFLD]; +text_provenance SplatInstruction::provenance(inter_tree_node *P) { + if (P == NULL) return Provenance::nowhere(); + if (Inode::isnt(P, SPLAT_IST)) return Provenance::nowhere(); + return Provenance::at_file_and_line( + Inode::ID_to_text(P, P->W.instruction[PROVENANCEFILE_SPLAT_IFLD]), + (int) P->W.instruction[PROVENANCELINE_SPLAT_IFLD]); } @h PLMs. diff --git a/inter/bytecode-module/Contents.w b/inter/bytecode-module/Contents.w index af80bcbdc..3009e0f88 100644 --- a/inter/bytecode-module/Contents.w +++ b/inter/bytecode-module/Contents.w @@ -34,6 +34,7 @@ Chapter 3: Their Instructions Inter Data Types Metadata Inter Errors + Text Provenance Chapter 4: Void Constructs The Comment Construct diff --git a/inter/pipeline-module/Chapter 2/Pipeline Errors.w b/inter/pipeline-module/Chapter 2/Pipeline Errors.w index 2094dd602..97cd1002d 100644 --- a/inter/pipeline-module/Chapter 2/Pipeline Errors.w +++ b/inter/pipeline-module/Chapter 2/Pipeline Errors.w @@ -139,26 +139,40 @@ power tools just lying around, people will eventually pick them up and wonder what the red button marked "danger" does. = +text_provenance kit_error_location; +int kit_error_location_set = FALSE; int kit_error_count = 0; -text_stream *kit_error_filename = NULL; -int kit_error_line_number = 0; -void PipelineErrors::set_kit_error_location(text_stream *file, inter_ti line) { - kit_error_filename = file; - kit_error_line_number = (int) line; +text_provenance PipelineErrors::get_kit_error_location(void) { + if (kit_error_location_set == FALSE) + PipelineErrors::clear_kit_error_location(); + return kit_error_location; +} +void PipelineErrors::clear_kit_error_location(void) { + PipelineErrors::set_kit_error_location(Provenance::nowhere()); +} +void PipelineErrors::set_kit_error_location(text_provenance where) { + kit_error_location_set = TRUE; + kit_error_location = where; +} + +void PipelineErrors::set_kit_error_location_near_splat(inter_tree_node *P) { + PipelineErrors::clear_kit_error_location(); + if ((P) && (Inode::is(P, SPLAT_IST))) + PipelineErrors::set_kit_error_location(SplatInstruction::provenance(P)); } void PipelineErrors::kit_error(char *message, text_stream *quote) { + text_provenance at = PipelineErrors::get_kit_error_location(); #ifdef CORE_MODULE - SourceProblems::I6_level_error(message, quote, kit_error_filename, - kit_error_line_number); + SourceProblems::I6_level_error(message, quote, at); #endif #ifndef CORE_MODULE - if (Str::len(kit_error_filename) > 0) { - filename *F = Filenames::from_text(kit_error_filename); + if (Provenance::is_somewhere(at)) { + filename *F = Provenance::get_filename(at); TEMPORARY_TEXT(M) WRITE_TO(M, message, quote); - Errors::at_position_S(M, F, kit_error_line_number); + Errors::at_position_S(M, F, Provenance::get_line(at)); DISCARD_TEXT(M) } else { Errors::with_text(message, quote); @@ -168,6 +182,7 @@ void PipelineErrors::kit_error(char *message, text_stream *quote) { } void PipelineErrors::reset_errors(void) { + PipelineErrors::clear_kit_error_location(); kit_error_count = 0; } diff --git a/inter/pipeline-module/Chapter 3/Compile Splats Stage.w b/inter/pipeline-module/Chapter 3/Compile Splats Stage.w index 54c3fe6bc..c1caa0de7 100644 --- a/inter/pipeline-module/Chapter 3/Compile Splats Stage.w +++ b/inter/pipeline-module/Chapter 3/Compile Splats Stage.w @@ -31,17 +31,16 @@ void CompileSplatsStage::create_pipeline_stage(void) { = int CompileSplatsStage::run(pipeline_step *step) { PipelineErrors::reset_errors(); - PipelineErrors::set_kit_error_location(NULL, 0); compile_splats_state css; @; inter_tree *I = step->ephemera.tree; InterTree::traverse(I, CompileSplatsStage::visitor1, &css, NULL, SPLAT_IST); InterTree::traverse(I, CompileSplatsStage::visitor2, &css, NULL, 0); - PipelineErrors::set_kit_error_location(NULL, 0); + PipelineErrors::clear_kit_error_location(); int errors_found = CompileSplatsStage::function_bodies(step, &css, I); if (errors_found) return FALSE; InterTree::traverse(I, CompileSplatsStage::visitor3, &css, NULL, SPLAT_IST); - PipelineErrors::set_kit_error_location(NULL, 0); + PipelineErrors::clear_kit_error_location(); if (PipelineErrors::errors_occurred()) return FALSE; return TRUE; } @@ -137,11 +136,7 @@ void CompileSplatsStage::visitor3(inter_tree *I, inter_tree_node *P, void *state @h How definitions are assimilated. @ = - if (SplatInstruction::line_provenance(P) > 0) - PipelineErrors::set_kit_error_location( - SplatInstruction::file_provenance(P), SplatInstruction::line_provenance(P)); - else - PipelineErrors::set_kit_error_location(NULL, 0); + PipelineErrors::set_kit_error_location_near_splat(P); match_results mr = Regexp::create_mr(); text_stream *raw_identifier = NULL, *value = NULL; int proceed = TRUE; @@ -710,11 +705,7 @@ We are concerned more with the surround than with the contents of the function in this section. @ = - if (SplatInstruction::line_provenance(P) > 0) - PipelineErrors::set_kit_error_location( - SplatInstruction::file_provenance(P), SplatInstruction::line_provenance(P)); - else - PipelineErrors::set_kit_error_location(NULL, 0); + PipelineErrors::set_kit_error_location_near_splat(P); text_stream *raw_identifier = NULL, *local_var_names = NULL, *body = NULL; match_results mr = Regexp::create_mr(); if (SplatInstruction::plm(P) == ROUTINE_PLM) @; @@ -852,7 +843,7 @@ These have package types |_function| and |_code| respectively. Str::truncate(body, L); inter_ti B = (inter_ti) InterBookmark::baseline(IBM) + 1; CompileSplatsStage::function_body(css, IBM, IP, B, body, block_bookmark, identifier, - SplatInstruction::namespace(P)); + SplatInstruction::namespace(P), PipelineErrors::get_kit_error_location()); @h Inform 6 annotations. @@ -1180,7 +1171,8 @@ answer. Since we recurse depth-first, the subsidiary results are always made before they are needed. @ = - inter_schema *sch = ParsingSchemas::from_text(S); + inter_schema *sch = + ParsingSchemas::from_text(S, PipelineErrors::get_kit_error_location()); int excess_tokens = FALSE; inter_symbol *result_s = CompileSplatsStage::compute_r(step, IBM, sch->node_tree, &excess_tokens); @@ -1352,12 +1344,13 @@ typedef struct function_body_request { struct text_stream *body; struct text_stream *identifier; struct text_stream *namespace; + struct text_provenance provenance; CLASS_DEFINITION } function_body_request; int CompileSplatsStage::function_body(compile_splats_state *css, inter_bookmark *IBM, inter_package *block_package, inter_ti offset, text_stream *body, inter_bookmark bb, - text_stream *identifier, text_stream *namespace) { + text_stream *identifier, text_stream *namespace, text_provenance provenance) { if (Str::is_whitespace(body)) return FALSE; function_body_request *req = CREATE(function_body_request); req->block_bookmark = bb; @@ -1368,6 +1361,7 @@ int CompileSplatsStage::function_body(compile_splats_state *css, inter_bookmark req->body = Str::duplicate(body); req->identifier = Str::duplicate(identifier); req->namespace = Str::duplicate(namespace); + req->provenance = provenance; ADD_TO_LINKED_LIST(req, function_body_request, css->function_bodies_to_compile); return TRUE; } @@ -1384,7 +1378,7 @@ int CompileSplatsStage::function_bodies(pipeline_step *step, compile_splats_stat LOOP_OVER_LINKED_LIST(req, function_body_request, css->function_bodies_to_compile) { LOGIF(SCHEMA_COMPILATION, "=======\n\nFunction (%S) len %d: '%S'\n\n", InterPackage::name(req->block_package), Str::len(req->body), req->body); - inter_schema *sch = ParsingSchemas::from_text(req->body); + inter_schema *sch = ParsingSchemas::from_text(req->body, req->provenance); if (LinkedLists::len(sch->parsing_errors) > 0) { CompileSplatsStage::report_kit_errors(sch, req); } else { @@ -1423,10 +1417,12 @@ void CompileSplatsStage::report_kit_errors(inter_schema *sch, function_body_requ if (LinkedLists::len(sch->parsing_errors) > 0) { schema_parsing_error *err; LOOP_OVER_LINKED_LIST(err, schema_parsing_error, sch->parsing_errors) { + PipelineErrors::set_kit_error_location(err->provenance); TEMPORARY_TEXT(msg) WRITE_TO(msg, "in function '%S': %S", req->identifier, err->message); - PipelineErrors::kit_error("inform 6 syntax error %S", msg); + PipelineErrors::kit_error("Inform 6 syntax error %S", msg); DISCARD_TEXT(msg) } + PipelineErrors::clear_kit_error_location(); } } diff --git a/inter/pipeline-module/Chapter 3/Parsing Stages.w b/inter/pipeline-module/Chapter 3/Parsing Stages.w index 4d0d54a3a..41a6f6136 100644 --- a/inter/pipeline-module/Chapter 3/Parsing Stages.w +++ b/inter/pipeline-module/Chapter 3/Parsing Stages.w @@ -94,8 +94,7 @@ void ParsingStages::visit_insertions(inter_tree *I, inter_tree_node *P, void *st inter_bookmark here = InterBookmark::after_this_node(P); rpi_docket_state *docket_state = (rpi_docket_state *) docket->state; docket_state->assimilation_point = &here; - docket_state->file_provenance = InsertInstruction::file_provenance(P); - docket_state->line_provenance = InsertInstruction::line_provenance(P); + docket_state->provenance = InsertInstruction::provenance(P); SimpleTangler::tangle_text(docket, insertion); text_stream *replacing = InsertInstruction::replacing(P); if (Str::len(replacing) > 0) { @@ -121,8 +120,7 @@ in |K/Sections|. typedef struct rpi_docket_state { struct inter_bookmark *assimilation_point; struct text_stream *namespace; - struct text_stream *file_provenance; - inter_ti line_provenance; + struct text_provenance provenance; } rpi_docket_state; @ = @@ -134,8 +132,7 @@ typedef struct rpi_docket_state { rpi_docket_state state; state.assimilation_point = &assimilation_point; state.namespace = namespacename; - state.file_provenance = NULL; - state.line_provenance = 0; + state.provenance = Provenance::nowhere(); docket = SimpleTangler::new_docket( &(ParsingStages::receive_raw), &(ParsingStages::receive_command), @@ -233,6 +230,7 @@ and @d COMMENTED_I6TBIT 8 @d ROUTINED_I6TBIT 16 @d CONTENT_ON_LINE_I6TBIT 32 +@d NOTE_LINES_I6TBIT 64 @d SUBORDINATE_I6TBITS (COMMENTED_I6TBIT + SQUOTED_I6TBIT + DQUOTED_I6TBIT + ROUTINED_I6TBIT) @@ -240,9 +238,9 @@ and = void ParsingStages::receive_raw(text_stream *S, simple_tangle_docket *docket) { text_stream *R = Str::new(); - int mode = IGNORE_WS_I6TBIT; + int mode = IGNORE_WS_I6TBIT + NOTE_LINES_I6TBIT; rpi_docket_state *state = (rpi_docket_state *) docket->state; - inter_ti lc = state->line_provenance; + int lc = Provenance::get_line(state->provenance); for (int pos = 0; pos < Str::len(S); pos++) { wchar_t c = Str::get_at(S, pos); if ((c == 10) || (c == 13)) { c = '\n'; lc++; } @@ -257,16 +255,18 @@ void ParsingStages::receive_raw(text_stream *S, simple_tangle_docket *docket) { if (in_number) PUT_TO(number_text, c); else PUT_TO(file_text, c); } - state->line_provenance = (inter_ti) Str::atoi(number_text, 0); - lc = state->line_provenance; - state->file_provenance = file_text; - LOG("Spotted %d and <%S>\n", state->line_provenance, state->file_provenance); + lc = Str::atoi(number_text, 0); + state->provenance = Provenance::at_file_and_line(file_text, lc); DISCARD_TEXT(number_text) continue; } if (mode & IGNORE_WS_I6TBIT) { if ((c == '\n') || (Characters::is_whitespace(c))) continue; mode -= IGNORE_WS_I6TBIT; + if (mode & NOTE_LINES_I6TBIT) { + mode -= NOTE_LINES_I6TBIT; + Provenance::set_line(&(state->provenance), lc); + } } if ((c == '!') && (!(mode & (DQUOTED_I6TBIT + SQUOTED_I6TBIT)))) { mode = mode | COMMENTED_I6TBIT; @@ -303,12 +303,12 @@ void ParsingStages::receive_raw(text_stream *S, simple_tangle_docket *docket) { PUT_TO(R, c); if ((c == ';') && (!(mode & SUBORDINATE_I6TBITS))) { ParsingStages::splat(R, docket); - state->line_provenance = lc; - mode = IGNORE_WS_I6TBIT; + Provenance::set_line(&(state->provenance), lc); + mode = IGNORE_WS_I6TBIT + NOTE_LINES_I6TBIT; } } ParsingStages::splat(R, docket); - state->line_provenance = lc; + Provenance::set_line(&(state->provenance), lc); Str::clear(S); } @@ -332,12 +332,9 @@ void ParsingStages::splat(text_stream *R, simple_tangle_docket *docket) { PUT_TO(R, '\n'); filename *F = NULL; inter_ti lc = 0; - if (Str::len(state->file_provenance) > 0) { - F = Filenames::from_text(state->file_provenance); - lc = state->line_provenance + 1; - } else if (docket->current_filename) { - F = docket->current_filename; - lc = 25; + if (Provenance::is_somewhere(state->provenance)) { + F = Provenance::get_filename(state->provenance); + lc = (inter_ti) Provenance::get_line(state->provenance); } Produce::guard(SplatInstruction::new(IBM, R, I6_dir, A, state->namespace, F, lc, (inter_ti) (InterBookmark::baseline(IBM) + 1), NULL)); From 568429d61c6b3fa20ee5d372dc7a86b50a37c387 Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Fri, 28 Apr 2023 11:18:56 +0100 Subject: [PATCH 015/113] More accurate I6 error location --- README.md | 2 +- build.txt | 4 +- docs/building-module/2-is.html | 8 ++-- docs/building-module/2-pis.html | 4 ++ docs/bytecode-module/3-tp.html | 5 +++ docs/pipeline-module/3-css.html | 17 +++++-- docs/pipeline-module/3-ps.html | 5 +-- inform7/Figures/memory-diagnostics.txt | 42 +++++++++--------- inform7/Figures/timings-diagnostics.txt | 21 ++++----- .../BasicInformExtrasKit/kit_metadata.json | 2 +- .../Inter/BasicInformKit/kit_metadata.json | 2 +- .../Inter/CommandParserKit/kit_metadata.json | 2 +- .../Internal/Inter/DialogueKit/arch-16.interb | Bin 112240 -> 119657 bytes .../Inter/DialogueKit/arch-16d.interb | Bin 112261 -> 119678 bytes .../Internal/Inter/DialogueKit/arch-32.interb | Bin 112404 -> 119821 bytes .../Inter/DialogueKit/arch-32d.interb | Bin 112425 -> 119842 bytes .../Inter/EnglishLanguageKit/arch-16.interb | Bin 20753 -> 25585 bytes .../Inter/EnglishLanguageKit/arch-16d.interb | Bin 20774 -> 25606 bytes .../Inter/EnglishLanguageKit/arch-32.interb | Bin 20759 -> 25591 bytes .../Inter/EnglishLanguageKit/arch-32d.interb | Bin 20780 -> 25612 bytes .../EnglishLanguageKit/kit_metadata.json | 2 +- .../Inter/WorldModelKit/kit_metadata.json | 2 +- inter/Tests/Kits/_Results_Ideal/BadKit.txt | 2 +- .../building-module/Chapter 2/Inter Schemas.w | 8 ++-- .../Chapter 2/Parsing Inter Schemas.w | 4 ++ .../Test Cases/_Results_Ideal/schemas.txt | 19 ++++++++ .../Tests/Test Cases/schemas.txt | 10 +++++ .../Chapter 3/Text Provenance.w | 5 +++ .../Chapter 3/Compile Splats Stage.w | 17 +++++-- .../Chapter 3/Parsing Stages.w | 5 +-- 30 files changed, 128 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index 8b77771e3..76c260cd7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inform 7 -[Version](notes/versioning.md): 10.2.0-beta+6W38 'Krypton' (26 April 2023) +[Version](notes/versioning.md): 10.2.0-beta+6W39 'Krypton' (28 April 2023) ## About Inform diff --git a/build.txt b/build.txt index e6af5567c..64e2b5f06 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: beta -Build Date: 26 April 2023 -Build Number: 6W38 +Build Date: 28 April 2023 +Build Number: 6W39 diff --git a/docs/building-module/2-is.html b/docs/building-module/2-is.html index a44b5b6be..2a034ebc3 100644 --- a/docs/building-module/2-is.html +++ b/docs/building-module/2-is.html @@ -164,9 +164,7 @@ we now more efficiently remove them.) isn->blocked_by_conditional = FALSE; isn->provenance = (sch)?(sch->provenance):(Provenance::nowhere()); - if ((near_here) && (Provenance::is_somewhere(isn->provenance))) - Provenance::set_line(&(isn->provenance), - Provenance::get_line(isn->provenance) + near_here->line_offset); + if (near_here) Provenance::advance_line(&(isn->provenance), near_here->line_offset); return isn; } @@ -770,6 +768,10 @@ which, of course, it usually isn't. } ADD_TO_LINKED_LIST(err, schema_parsing_error, at->parent_schema->parsing_errors); LOG("Schema error: %S\n", message); + if ((at->parent_schema) && (Provenance::is_somewhere(at->parent_schema->provenance))) + LOG("Schema provenance %f, line %d\n", + Provenance::get_filename(at->parent_schema->provenance), + Provenance::get_line(at->parent_schema->provenance)); LOG("$1\n", at->parent_schema); }
    diff --git a/docs/building-module/2-pis.html b/docs/building-module/2-pis.html index 9dfd68559..959631dc5 100644 --- a/docs/building-module/2-pis.html +++ b/docs/building-module/2-pis.html @@ -242,6 +242,10 @@ such operations are nested, they will work. We might then write: sch->dereference_mode = TRUE; pos = 3; } Tokenisation::go(sch, from, pos, abbreviated, no_quoted_inames, quoted_inames); + if ((Log::aspect_switched_on(SCHEMA_COMPILATION_DA)) || + (Log::aspect_switched_on(SCHEMA_COMPILATION_DETAILS_DA))) + LOG("Tokenised inter schema:\n$1", sch); + Ramification::go(sch); InterSchemas::lint(sch); diff --git a/docs/bytecode-module/3-tp.html b/docs/bytecode-module/3-tp.html index 14a113cc8..dfde7004b 100644 --- a/docs/bytecode-module/3-tp.html +++ b/docs/bytecode-module/3-tp.html @@ -127,6 +127,11 @@ value: if ((where) && (Provenance::is_somewhere(*where))) where->line_number = lc; } + +void Provenance::advance_line(text_provenance *where, int by) { + if ((where) && (Provenance::is_somewhere(*where))) + where->line_number += by; +}
  • §6. Writing to text:

    diff --git a/docs/pipeline-module/3-css.html b/docs/pipeline-module/3-css.html index 92fa91b3b..520fce5ec 100644 --- a/docs/pipeline-module/3-css.html +++ b/docs/pipeline-module/3-css.html @@ -949,6 +949,7 @@ in this section. PipelineErrors::set_kit_error_location_near_splat(P); text_stream *raw_identifier = NULL, *local_var_names = NULL, *body = NULL; match_results mr = Regexp::create_mr(); + int line_offset = 0; if (SplatInstruction::plm(P) == ROUTINE_PLM) Parse the routine header3.2.1; if (SplatInstruction::plm(P) == STUB_PLM) Parse the stub directive3.2.2; if (raw_identifier) { @@ -967,13 +968,17 @@ in this section.
         text_stream *S = SplatInstruction::splatter(P);
    +    int pos = 0;
         if (Regexp::match(&mr, S, L" *%[ *([A-Za-z0-9_`]+) *; *(%c*)")) {
    -        raw_identifier = mr.exp[0]; body = mr.exp[1];
    +        raw_identifier = mr.exp[0]; body = mr.exp[1]; pos = mr.exp_at[1];
         } else if (Regexp::match(&mr, S, L" *%[ *([A-Za-z0-9_`]+) *(%c*?); *(%c*)")) {
    -        raw_identifier = mr.exp[0]; local_var_names = mr.exp[1]; body = mr.exp[2];
    +        raw_identifier = mr.exp[0]; local_var_names = mr.exp[1]; body = mr.exp[2]; pos = mr.exp_at[2];
         } else {
             PipelineErrors::kit_error("invalid Inform 6 routine declaration", NULL);
         }
    +    for (int i=0; i<pos; i++)
    +        if (Str::get_at(S, i) == '\n')
    +            line_offset++;
     
    • This code is used in §3.2.

    §3.2.2. Another of Inform 6's shabby notations for conditional compilation in disguise @@ -1121,8 +1126,10 @@ which contains the actual code. while ((L>0) && (Characters::is_whitespace(Str::get_at(body, L-1)))) L--; Str::truncate(body, L); inter_ti B = (inter_ti) InterBookmark::baseline(IBM) + 1; + text_provenance prov = PipelineErrors::get_kit_error_location(); + Provenance::advance_line(&prov, line_offset); CompileSplatsStage::function_body(css, IBM, IP, B, body, block_bookmark, identifier, - SplatInstruction::namespace(P), PipelineErrors::get_kit_error_location()); + SplatInstruction::namespace(P), prov);

    §4. Inform 6 annotations.

    @@ -1733,6 +1740,10 @@ kit CommandParserKit LOOP_OVER_LINKED_LIST(req, function_body_request, css->function_bodies_to_compile) { LOGIF(SCHEMA_COMPILATION, "=======\n\nFunction (%S) len %d: '%S'\n\n", InterPackage::name(req->block_package), Str::len(req->body), req->body); + if (Provenance::is_somewhere(req->provenance)) + LOGIF(SCHEMA_COMPILATION, "Function provenance %f, line %d\n\n", + Provenance::get_filename(req->provenance), + Provenance::get_line(req->provenance)); inter_schema *sch = ParsingSchemas::from_text(req->body, req->provenance); if (LinkedLists::len(sch->parsing_errors) > 0) { CompileSplatsStage::report_kit_errors(sch, req); diff --git a/docs/pipeline-module/3-ps.html b/docs/pipeline-module/3-ps.html index 90eeb82d6..b784435b5 100644 --- a/docs/pipeline-module/3-ps.html +++ b/docs/pipeline-module/3-ps.html @@ -359,10 +359,7 @@ functions). So for example mode = mode | COMMENTED_I6TBIT; } if (mode & COMMENTED_I6TBIT) { - if (c == '\n') { - mode -= COMMENTED_I6TBIT; - if (!(mode & CONTENT_ON_LINE_I6TBIT)) continue; - } + if (c == '\n') mode -= COMMENTED_I6TBIT; else continue; } if ((c == '[') && (!(mode & SUBORDINATE_I6TBITS))) { diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt index f75c7ac62..d94207546 100644 --- a/inform7/Figures/memory-diagnostics.txt +++ b/inform7/Figures/memory-diagnostics.txt @@ -1,36 +1,36 @@ -Total memory consumption was 121599K = 119 MB +Total memory consumption was 123104K = 120 MB - ---- was used for 2059550 objects, in 367490 frames in 0 x 800K = 0K = 0 MB: + ---- was used for 2061850 objects, in 367513 frames in 0 x 800K = 0K = 0 MB: - 33.5% inter_tree_node_array 58 x 8192 = 475136 objects, 41813824 bytes - 21.0% text_stream_array 4655 x 100 = 465500 objects, 26216960 bytes - 19.9% linked_list 44435 objects, 24883600 bytes - 11.3% inter_symbol_array 133 x 1024 = 136192 objects, 14168224 bytes - 10.7% inter_error_stash_array 102 x 1024 = 104448 objects, 13372608 bytes - 8.3% parse_node 130356 objects, 10428480 bytes - 6.1% verb_conjugation 164 objects, 7610912 bytes + 33.1% inter_tree_node_array 58 x 8192 = 475136 objects, 41813824 bytes + 20.9% text_stream_array 4678 x 100 = 467800 objects, 26346496 bytes + 19.7% linked_list 44435 objects, 24883600 bytes + 11.2% inter_symbol_array 133 x 1024 = 136192 objects, 14168224 bytes + 10.6% inter_error_stash_array 102 x 1024 = 104448 objects, 13372608 bytes + 8.2% parse_node 130356 objects, 10428480 bytes + 6.0% verb_conjugation 164 objects, 7610912 bytes 4.4% parse_node_annotation_array 348 x 500 = 174000 objects, 5579136 bytes 2.8% scan_directory 866 objects, 3574848 bytes - 2.7% pcalc_prop_array 25 x 1000 = 25000 objects, 3400800 bytes + 2.6% pcalc_prop_array 25 x 1000 = 25000 objects, 3400800 bytes 2.5% inter_name_array 67 x 1000 = 67000 objects, 3218144 bytes 2.1% kind_array 67 x 1000 = 67000 objects, 2682144 bytes - 1.7% inter_schema_token 14043 objects, 2134536 bytes + 1.6% inter_schema_token 14043 objects, 2134536 bytes 1.6% inter_name_generator_array 51 x 1000 = 51000 objects, 2041632 bytes 1.4% package_request 21186 objects, 1864368 bytes 1.4% vocabulary_entry_array 164 x 100 = 16400 objects, 1842048 bytes 1.2% dict_entry_array 477 x 100 = 47700 objects, 1541664 bytes - 1.2% match_trie_array 11 x 1000 = 11000 objects, 1496352 bytes + 1.1% match_trie_array 11 x 1000 = 11000 objects, 1496352 bytes 1.1% inter_symbols_table 26632 objects, 1491392 bytes - 1.1% i6_schema_array 23 x 100 = 2300 objects, 1380736 bytes + 1.0% i6_schema_array 23 x 100 = 2300 objects, 1380736 bytes 1.0% inter_package 26632 objects, 1278336 bytes - 0.9% map_data 672 objects, 1128960 bytes + 0.8% map_data 672 objects, 1128960 bytes 0.8% id_body 947 objects, 1083368 bytes - 0.8% inter_schema_node 8968 objects, 1004416 bytes - 0.8% adjective_meaning 202 objects, 1000304 bytes + 0.7% inter_schema_node 8968 objects, 1004416 bytes + 0.7% adjective_meaning 202 objects, 1000304 bytes 0.7% excerpt_meaning 3117 objects, 972504 bytes 0.7% production 3957 objects, 918024 bytes 0.7% ptoken 8588 objects, 893152 bytes - 0.7% grammatical_usage 3636 objects, 872640 bytes + 0.6% grammatical_usage 3636 objects, 872640 bytes 0.6% individual_form 2566 objects, 862176 bytes 0.5% unary_predicate_array 16 x 1000 = 16000 objects, 640512 bytes 0.3% local_variable_array 47 x 100 = 4700 objects, 452704 bytes @@ -248,16 +248,16 @@ Total memory consumption was 121599K = 119 MB 100.0% was used for memory not allocated for objects: - 57.0% text stream storage 70981292 bytes in 482888 claims + 57.5% text stream storage 72515996 bytes in 487440 claims 4.2% dictionary storage 5315584 bytes in 7623 claims ---- sorting 2720 bytes in 387 claims 5.7% source text 7200000 bytes in 3 claims - 8.6% source text details 10800000 bytes in 2 claims + 8.5% source text details 10800000 bytes in 2 claims 0.2% documentation fragments 262144 bytes in 1 claim ---- linguistic stock array 81920 bytes in 2 claims ---- small word set array 105600 bytes in 22 claims 3.6% inter symbols storage 4559120 bytes in 27994 claims - 13.4% inter bytecode storage 16768036 bytes in 14 claims + 13.3% inter bytecode storage 16773980 bytes in 14 claims 4.9% inter links storage 6222976 bytes in 11 claims 0.1% inter tree location list storage 191232 bytes in 32 claims 1.3% instance-of-kind counting 1705636 bytes in 1 claim @@ -266,5 +266,5 @@ Total memory consumption was 121599K = 119 MB ---- code generation workspace for objects 3480 bytes in 19 claims 0.2% emitter array storage 280544 bytes in 2001 claims --151.-6% was overhead - -188890488 bytes = -184463K = -180 MB +-149.-9% was overhead - -189020024 bytes = -184589K = -180 MB diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt index 3bcd85c13..81623043f 100644 --- a/inform7/Figures/timings-diagnostics.txt +++ b/inform7/Figures/timings-diagnostics.txt @@ -1,9 +1,9 @@ 100.0% in inform7 run - 70.5% in compilation to Inter - 49.8% in //Sequence::undertake_queued_tasks// - 4.9% in //MajorNodes::pre_pass// - 3.5% in //MajorNodes::pass_1// - 1.7% in //ImperativeDefinitions::assess_all// + 70.8% in compilation to Inter + 50.1% in //Sequence::undertake_queued_tasks// + 4.8% in //MajorNodes::pre_pass// + 3.4% in //MajorNodes::pass_1// + 1.9% in //ImperativeDefinitions::assess_all// 1.5% in //RTKindConstructors::compile// 1.5% in //RTPhrasebook::compile_entries// 1.1% in //Sequence::lint_inter// @@ -12,15 +12,16 @@ 0.5% in //Sequence::undertake_queued_tasks// 0.5% in //World::stage_V// 0.3% in //ImperativeDefinitions::compile_first_block// + 0.1% in //Closures::compile_closures// 0.1% in //CompletionModule::compile// 0.1% in //InferenceSubjects::emit_all// 0.1% in //RTKindConstructors::compile_permissions// 0.1% in //Task::make_built_in_kind_constructors// 0.1% in //World::stages_II_and_III// - 2.5% not specifically accounted for + 2.3% not specifically accounted for 25.8% in running Inter pipeline - 10.0% in step 14/15: generate inform6 -> auto.inf - 5.6% in step 5/15: load-binary-kits + 9.8% in step 14/15: generate inform6 -> auto.inf + 5.7% in step 5/15: load-binary-kits 5.2% in step 6/15: make-synoptic-module 1.7% in step 9/15: make-identifiers-unique 0.3% in step 12/15: eliminate-redundant-operations @@ -28,6 +29,6 @@ 0.3% in step 7/15: shorten-wiring 0.3% in step 8/15: detect-indirect-calls 0.1% in step 11/15: eliminate-redundant-labels - 1.3% not specifically accounted for - 3.1% in supervisor + 1.5% not specifically accounted for + 2.8% in supervisor 0.4% not specifically accounted for diff --git a/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json index 018ce8ae0..bc78e140b 100644 --- a/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json +++ b/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "BasicInformExtrasKit", - "version": "10.2.0-beta+6W38" + "version": "10.2.0-beta+6W39" }, "kit-details": { "has-priority": 1 diff --git a/inform7/Internal/Inter/BasicInformKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformKit/kit_metadata.json index f1f49b135..eb43216d3 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+6W38" + "version": "10.2.0-beta+6W39" }, "needs": [ { "unless": { diff --git a/inform7/Internal/Inter/CommandParserKit/kit_metadata.json b/inform7/Internal/Inter/CommandParserKit/kit_metadata.json index fd1614c67..c29ae59af 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+6W38" + "version": "10.2.0-beta+6W39" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/DialogueKit/arch-16.interb b/inform7/Internal/Inter/DialogueKit/arch-16.interb index cb76ee7b91e9cb95468925bc927341b9e617cffc..7145bffa51250fd0c242d8625cec9c8f1ae392d1 100644 GIT binary patch literal 119657 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 literal 112240 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

    *+|>_6m;2H=YOa^L zR9kB4n0afaR{LMO$YHO>SVw`K4qvs-HHC8(O;5)!z7}xq&UlSU}a26wTsg0YW;i?L&5*R## zR@#Vh+KgXB9$D>yy_Aj_T^c=RMAvF5Z$t996k`_@Hy!|@&`zL0SZGrh9Yew`Y8v`@ zuBeXyEy6d7#|Q-xsN&K{cKs}y$?g+_6WZi!D;%fTtg5wZh}3X(KSNQM9I3?+p*&ZA zh8rNZ57%3$+o6@AHqlhs#4*(BP)uXt93q58i@Mk(PuV8`@&^(>6V`PB+ZK z)R0|k!}eJBxl~I^tKE84n8>03b?U|H++KKdkxswJ5Qd38oTba;==wqpOaaQL{j0wb z_Cq>4Nn@E+@J{G{DALv4M6+jLBB^AHo^{0j1`=s0pGnf@QB;foTx{I69Mi>9u(Pj& zmhab6h@cLT=gr8{lwnS2g>~zWo%m$1i26ifxp;=CKyvx3S)nWah@7k{L<%wZ+ym)~MF&M!-N7Mos&)cuc zd2OWc346oydb4;@pmC9o?h-_7F-~=^MHlo8BOA z9^S2w9Fe947aXGQ=vlF{4~8iqj7v-pE_9&AK*Z=6qbopJGk<8>8R3|!!MWO%jQy4V zwa#c1=hKa=BV*qNlh_oCx%A*oPieJdO94J`5>A5W$rNhEAZm1ARp2U={j*bA<-|(` zq!(vUFub2w57_jsaJ8t#B|f_QEnpryV?&5Wnx{!%!$fj6_L2aT$l9UZP#h(x1F2|b z9jN1go*>&%%VAppzV`8 znZ{^omfzfa6kd9+5C7TTQhhnDm+H>Z1Y4z6KoyyrX)nFZ$&1*w6f03lm*w;`vWupT zx;j%dT4i)Dj~k&GNlT5@?R+{hhg+8;Q$T2H3@xWN z8*rD?3PTBVIr`k$7t6 zgbbMqaEfWfGNRUHOAK9lV}3BdlAEaq&2-^)lo+dbbZrfj2cg@|hIn^Y9EI?&d7(fL zjHZG_HN(hzf#?%u89Hf&2!qew7ZX2EA%VpN1+GQf5{?@xTSCR*xg<+B&B19nzSf)C zV2%Jg(S3L%n<^q8W%`pMbufT3H5NOhaV#Ni?luc%7{}7qfV}EpdTgPPYkoj{lW9r+ z6fL~aq81=wbLfyw^8<=t=o5BV>x-0BBw9da7~vQzXk?;lj%}=%k|7IH^mK~i!ooRo zs`-}Fs_;&1y?CHHuvs&u(;e<^_wsUQt}43Yy*N&~b3};;lo1mv-OcZPmNUEHaZIb^ zK6vcGb#}t{i5A+TW?f1#i|(j1+FRe+d|6c;e>X^}5%;We?9_0t#HV`#oa^ZM68p$C z1mUF!#FgB1qm34q%gafsI8)f<&LycH5$;FDUd}OYVVtqd(oBVQ@7g`& z@gc${S~yZ)~0DH$5rnr6BPAoW5{A>9xj^j*= z`*N5Gj!s9TkQrmb9~HRvBW_&>Idc~+j6z+H#iOGr2u1q@5(!d_Yhx{NoG0&|VQo~E zB`mUQJOx`s_2>)Vs32udzDYDz)~>nJ!5Muczjd%m$E%Fx=T0?-Q9I&Blx*$}QS#PZ zg8XWf$K+kr3JL-8CT$V8AKRIk!`gL@PV98FPtBO~(ni|qmO7QId!KW-0^0-WABO+p zY8NL3@fdy^q?&*dIAiBMfR}Jy$@rl5Ez6qap$aT?o386OZiNoMQkETpi^O3`jx&jNX zR{}_cWcsK+0CCh{YAF?L7{8A3)p7()EyV{!*fUrWz2v3Nx#Fd?@#JrCsNQNstyHEF zd+|w+iQ?$t8$GR2z*BP^hk(OAP3lwFkOFxu%H?~oK2!3p zQbSjRa|30iQx(P@p;%C@fw!Y4qJs&HQ0Pv`n!y!W(QAGA{m|k?nL) zAN`O7hfM}g7@>Z=kuv))(`M#TiQzeo{hWy{6Hz#!03djqE$xAh#sd6VDJKX3B<-OE z90jsGtfVvgCR$Ndg})7nd?&2=QBtN3RkSZnjk^&F(Lr?%X$=-FX_DS&{m*uU(sN>d ztZ!Zp$8;$+1ZURZ1as>OEOg>?nNZplt=;(SZ6mDnnKK0 zG6x)3r$yMT100|`u}u?Z;N(HHQ4?l3ygZIhsxFVU3Y!Ghh3zEzSW#%~rL+Za6Q@RW z22lmo!`5z1mNpQf(I-wgk!BZ8JYGE}s>dYtn5-VBsK==%Qt5JnK24>Zt{!Ko$C>JJ z)`?>njy}zrS(NMUS{ths8irbleoZnarlILrl7z}*0#%(zVq0i#&WYio(XwibwhK@Q zXUl{#qtw6|s49!9xU-;;YW4(5#88Ef9#e~Ws-Xa6;)yEP>2_vz*G!O5x741ZynOPM z4Bsi@z*A?MbjFxWjQsNQNfXtCZ+SUXmR7+smFB~vR7Oqp5oy$v7{b#N@Fl^WW+_u> z=<{x;Og}7GaM+$1 zB4)#r!QaM^=|Lk(8LLX@PO_Fl2dS0y__R8_9`6axw(E&ftTfx+4q` zFY4hSxV;5I55{nMuzS*&ODG1WYSetpb@YYY1C2ALF(-XE7MFU_*M1K+>ES13DF@%p zJ=WwTef5f9@Il?94NT!ZF$95+1Kat%#4n8!5Iz=sgh3PgIwWP|o57Znq%TMk489+1 z+rhhY_>+c|gAWNGYPW1UUv8s3d|3EUQ?ZWi`2Kpz+v9nM$MWjc;soVB?|DbMx$cLQ zD1UD(-~BcY1nCF`~`U63TlihSuaYc2MriF{0f2_$mJt z&pRkmEq$DUGG6t(LrjKV$su-8)@zOmP+IibdxCh~^Nvd>9Jy+q;NAf3=4@y5T6oHR z(;2>j!u(2 z86S8z$-KkOWSrvQq5WJY{Zt1JMt&ywG=~Mwa=6Jp-C?56Hmjrt;jTcso*| z6OTm?-cG0Xq|m|JdoC) z!P^_lbOQx%Ukqs&C3r8S!hnbBv!=~^F-D?^0lb%D*i1%ahxc-f3O6$FUP*cTyKUxg zHhHh6!ids|3B1=Fc@kmKfWUh_6$XS(u}C!Fy#Y#-Ljmtir&=ct@ZNG-?FIqf+YX~5 z5rFqjEGJ~)yN*i5e82ae!^NoM_uhB1qF&$oz#-dl`O4or9CO{X^7jmqNrfS>1L8V+ zh8yX~(Sc)6&j6#Gx(eMqgB+I%17BreVcX5MVGMD60fgh=8R7(|TPYmm-8pNtOJdBm zGr)W+njoe zQ=EJ@C!XpQhr{Ny)0}oX-kS4HcX$+Y)trBZQ`Yg*oOhnGiOhCusdFv^JWls;}7U0Pi@VT>ZXRp{E?0Z205FpWVWqi zMNh7=qqDV{zI?|y=YU&P$zNpV{3>uH>EnBxITM;t_&HzBngwPhew~_BkN_H+Kl>Rdy+Z51<;WjmpC;?k~J57s*9F5 zeK`dziT5jU_6oGz-MGbxD-oNPIuyu2txoJ^m*P0*QX*VOqMTDdi_#8~El7PF|0uSsQTc$A|+An*4v#5p8+=tE_@eeV!8JhI2>aF}U+YkP~gUp$52 zdwg#{1s`r{@+!i2f?4f*N5o;8>|RChpb$DtrE+U*+Z_n~wQlc#!Za##x$hkirGF6? zExnn&x=J7_Iq9ke~LwgB(cyQq|0=hH7s(gWBH&yUzCx zRj>tLweF6;x8C>mS9w;>`A%<$^MjzS^t}-Z%IIKJI%E@Ub%fG zh^sAx-CgIE+gF0P#>#{T8}?Hl-tg#eg8hu|9jW+}_*q!*;KXDqd9AG_dfLSs9{o+Q zpS86_cJ2@_Xy1-^aAGo*yw27V-K^makNzgu&sqIafu8fpSqxO;U!kQEpSQA)e^%7n zFP=j1U+}$y6}MvF9Q8)T5(xTwOOLDEIKEcVj`nrteOM z{hEFe+!w7JoNf|+v(7s>F_}uAl3iF-voPy?E%)-aeUNxfn)u23c=rL`H-}mo#wz+x3=W! zBVXsBa$onoV^o{0iZw?+^WYs;EQiY9<$K2!Dc|aRCB-|s0EwGTm^N7dUjWKS0lY(! z)2Zy;zIV8yLI=_A_X@lN6B4P^H^TnleyRZd!Tm{)_gLTJ9MtfJI6nyLUMt_|u?%l` z^f$rYXE8cwG!Wc}2Q~=mo3>r9rBXq0gLhy;B9*$|ax&)4Or&>6aypgWX#0iLJG*xr z;i&PuHjTwRC1H=9j$dB zc^9g8XauEV2Dv#Z{g9>6u_HKZqT?lHk?@;fziq9$dmP#u>i#0QhkY-jC@OyT#yg^T z9^u$*^~5;<;|+0s5Y!_!9#cnKyg}+odEc?pFmzmFkG0f1|57|jnrVF8pfG=yXe2BbC{@vA4km@ZF?8!MVS@J$xFEG#c>qBR>k zM03_qJnbc2oaR@W9Xe4efz1ZW4Thii7DRFZGZgDG>wQIVGD>RAll(?;AMdB+|-0lQPSPb&SSDBKpl-_kBzLx4udjs&vTW@RH z^IN@bX)o0=nYOExn#IFjl|GPFzt6+Cd42}`u7mkX*$wDY#)G+=@R3?e(=56 za2h->969eu6a=;bl^Q@}2asOxbS$nJCwt=FwD?9!+*7QD;y!A>RnNq=LQi~?nQ))& z2T5SWiTnSGoJbnTgB6M6cJQE-f@3RGf`VfcRPxZ?6C2awn<;UBNw$awh;!Do@Z1e= zzJiVW7W3-?Yqr8n;?jezmJim3nfodh!kYFh&e&7Xoq0tUMEc z6FCVE7fk11%bm6&Hf%H#IM{8c8}3Zc&>lOhxk(-i^4gph-%g2#6U8DPQ4(|L#^8-7 z8&L8)EU`zdJ)vfqY*Ow=t;Et^*)n9(rE51i9iFEnM zRtisipWE`iQadxn52!WPOHrSKlVWEDlLKe9-Idplv}X+y^u4I;p!&r;9CW|X!$I#$ z$r|d96~TnHJM@84J`nw&_{tQzL$trrE>op&i5_!HT6{kxeo&O(;)ey|h*)4x{D{Tz z!-zOs5b7sCc9hGq`Y-Dy$*kK^iZ=ze%o9(g#g9_r$C2i{#EYj3`jz8jJn<85{L_(s z6#`Jxf9f{9yQ68%%8pf}jG?)(8fiI$Ruol2G@`(0hKgBWG@+Op+|E0bJ=SS{3IoQ8nFr?C&kZ54n-V~C;oxO@Uw^*?T!(W!p|Kk zq!4&S1yF+BFvz9&LXs-B>JLekoQ?OyKc>Y$q{PpYnrp-NPu${PL_Cwp zrUw7gHaO-M3=sB%Q6!NxjQi)b_@|WkWn$IhS434rN)AR({0r0dt4N0k0f@3+TgqUe zJ8Am_gh4VvKL|TTAK^+VnSk%fJ1so%uW9iwDe>zf+agL7*&^qOf8*BuCSvPc z5Nh9Vo%V(8F>U;dR4ut#Xm6qz|2-}KEhTxmsq z_4eXtZp2Q9R;{k_)l!m3k)={}@ggnQl@>cvVrLQ3#BQS77Nt3Peb@($e~yXXZ9BP> zOX{*mQQSroP-*%)D!X%5N)zCWe<@$-)+HYV*YNY4Kc2 z>`7{c*h}rR-ILIp6H92|K5pP%>%HAatu3)l z&J!=D#lDnyA+ZtSC2F6IT(|+|)D;@|GB@xgYiT0+)WTQ(?^;-No1Z6MO^cUP;+5oP zh}R05Xk$t=@pW$EYmp|}d}`tw$xYP3P6=7|t)#J-Gu*xDi8s^Y^^|xc(j-fkc#E23 z)h@p4-4kzfqu#OxGX_D;dWV`dV0D(e-|##in#1k)yzziKVmZFggd6Rb0RR!59n)aM z&EszjwlV(RiJrR*>)GC}v{ykdP5EZr=j83i&+e627E(W-1MubE9s|SI4w82(KK_M! zi;jQc(grU=6o3v$CoZ*zbyjJd9TP8FPi{6h=zS45aalOLe;M{m`F#Vec1GZUr8bs4 z;^tjbY9GX_*6Z7i4s^6qcU)(D9_|=>9jB~RC1&db9ih~%a7sA)9^OpCh}b~g#zY4x z3nv7SP1o(wNlI&VW9J?`@orkYof7X9Qy=jjDOd60@3U^bXNLw+{G?hRkZM_tfpzaw zyXlldV+||Mk&dA6cL{#gdX8w+HTvR!L&6C7MIx&>4^{1 z;{BBPpa`d=7hz+JZtO)PHp=kyMic;Slqq6kdO0pKBoCSD#z-&PEv=eU*>DR9MY=_X z=W;+=`YD;RG)HTdX`~A(2(l~cIztKCt%M}Oc<63+(!l%_gzm691v4rzJf%D`Y*A4w z4m(unt?ATv@h$5xMoC-tVT+1&*T{MAs5r?eMSBO#P|pBCTf5`DQxKU3diHeXI1b;TsNcmpGSjtmh3{sK&k@o`VsD zQ**+aHi3+EJdq~{r{%zu9F){&WEu4)+mKmmYZdh-YeQr?cd9bWu0kN{TNQ+;udQ01 z9FmshDOpjXMmdx)*(Fh@HeT(+){q|TZa`-r#&iws$DwsOoKW^_ADAacq~)-b9NrfJ zazDap)y^SP9gg$l{!HI~b_OR7LR>q5km%Jk8z?lJ4Q_Ov9t}M(E%#5!1B%uq4T$%C1ggRBq>fry+#90O_1A1r#*{2|sFgo|t2b6sS{`;z&NesUgevNR*$HcM=x zgV{A9lDj*OS6o$8MeA-$#TiqaoL(}r$lsu#aljUI~1sigx?OX0i zM^7HkLO9GWA{M}q431DTXeNg`NPQ8V2F1GR30vxDJA~$3Y@yHWr-PIV&JRH>k)t|b zf6_4>Fg@{z4%l7lc#bEJOv}Sl@`&R6kVhr(%RTq$$)lNHN5%N%z!1NVarkA2=!S7% zO$o+PE5-aQgU=r zl4T{eD8_MfI@ptAxH*-v;^D0za%@stXr_n`C;#QTSI}wENfVFgp_jU+`OrC?gLw!# zqi6SE{32Z+HZQ5`BhpOl`V?)JIGN|kacMawCC4VSRgNc?+elFDnkFC%1{a|ZF5*d`Xa!0MZF7|m>ZYlQEp9;VV&})9c#fVz z->lJb&ZtA(>{mzR-VR!Wugd3I=7gs~*K*DgDur|;FQbL}ZUWZylPUJ!>N_cwcNbIaG)Wc2_kTBdm zO!ADhJS`p?dDH|qaX%Cc9Iq2G8{W&MPa<6DBp?D=1MxlMy-B6=KheDCQ8K+Z@ z*&#rYzHJK^31{q}chNZsD4VvG;k*qLF0SyVFF@N0Oe^%QVBQ9%NDnsLZHBNw5yBkJ zgeB_hJ`hiyotD#6az>IELi7tp3Dk`wkNF9!%h@jasUfatiO?Sib&46#{fpcZbMN z*p6gnfdSFV;;hBc2{2F2Ps^H=JlC=*l!dG%3EKFH@AvWK0+wB^<%GVoPu4j$e84I+ zClpyl-hPgnCVdj*1nHH&egc9_kO*1*Vl0LXtrcSy>uVy4NU=~Hke_7=BfuZ%4n$`o zE{oSpctV7Bmds{GrXC@|WD$|Gjl)!o>Q__%@ z=cVK#w_4dq*kj`fPcCLs8m%Un>m}uqzY;O9fmp%{=#8lFzZAK2nBU$h(K_^_;(j+sdkfL@nK;9N{8ep6rM&OJ5VF zE0Zl>srR6>Cz?2P^VODxl%cJh;?o|bJcHJ;3}ntswU&&j2( zvrM@--ce#z6mHIHaAdSnsFLW@3A#w3nX#ePXF%F;Zk7|UMi@8+^rrwE|ir8xU>I)6f6fo@x&yS4?Y9UC!|PODxJ z&Qd_9i-(NR=z@6)C~(0%1(ervJvJTB-vCgRI=bg<5%c6_Y1x{Rm)b@+yq9exGiwSW z*LQky6$`D+R_$h!)Y_@AwOMNac@^*AQAAQ`6uIEflO1WfDka+!Ym}XY&kktOhVT=O zP`^(xHJw&NBl$#5S3k%pxSG(D`Lz60N_HjJE4vA)Wu1FTsV94wqHe3yPA<{2x*zno zS0Z|HO&r81OR`I(g;Sj8XDM-ie!YTAIBL)Xi*r?Ff!%tXciP>p*iIUSP zKN(^`LSwE?r?W|B21KmIBa{d8!32FGJAzB z>f{n{1LExfdf>PW*_Q*(K&YXIK8LV-1CEW8xX$J$9rLbH%NWo2=@5uw3I0sBsEiBLku{^ z3b^2cWqkaPKUH*Okpq>Sk0JD7N!KWICI-@n6kemuSx~*h6R%O`T++X!qu87Y{fm)g z_uF$m>0;q+$()7A`N$%-C38L^=z|LmmT(T4$oOr^oB zlx^NXjWnt7BDX4>mb8VS`1U zWZ1-ajy6ris$TKjNwm$YgqY!|zL1tUMe+G$3CinWxvE_Zz|&Hg-XTvZJjI%f0e8KN{rtY zg8BV5!jW(W0>$s(;$JJ`rRAMmdl5g4;$P?Dcb4+x@-D(rct{kbH*o2@lKs5Ao5~d& zNaq&lsgiP{rD(UPC zM2YWmiN|A+lzf69leV>@$dg>;iDHqK{2rB!Y_>z8?{lH=6@*~&2Lv7NI0Wbx2K_-a zFq1zdICqaBAb-S=Ka2-#^2Y?5u>TN6p5h`uE)vhlr>SJp7DW{O2^W33SiC2HN@YuI zV+4w47{yQf2n*%U2vg)U8Yue@T=r)L@uK`WLB}VtP~acAz|WInN%;#Z<4iOG{GS;7 z7qJji{*oZw89RXfGlTvz9(KxK5o~Pw1mOR|;J-?UM&+*=yAz87{9hUT*YOBd{)S+q z)2o2~H-`RAVcaTzOYre^FqHUrF7ex>cvk+7>xe|NDDfX$;&+8nuKYdM5sPtA;y<~> z?~|fm`3EXfWC9*V|BH+Mp+s;j|40}j^Yke9-(2pG1rf9S6G4~U27=Q6!=?Y!XIL%& zOxOyioe-{-uEX=>|8flQ=j0ez_7dXw+H8N&Ze_H+NddInMo4Wu!a*q_kN#kNma%TL z0gEZi0n2tmYo`x63xB%0`-6A~Bi>#le3v^3bu>T^1Ni>n-^KWMmKp=d-Bd}GVQLi6 zp9-Gi3U)_n3U78^rx;Dxvm%b9v8`%{NWQOWWqCm8TqpBSIAfV1H$BNdvh++u{M3i+CU$k?%CGp(ySJM#I~Wo>ISZ5?YeNRqGn2U1RZM~1(cgHQZ&@*93RFlJX^ z!+M2$(;tc-*eu_f$#zf4$hZ6vl)1b+*TtzwdYcJDZ8%G-fZp+sCd7-|QE6L_cD?6X zGR=Ihh-#>i@A~@@KwU?7CYxzl#?`*3sL^R{C$}_n^85Y>P2@6+hB@g2n?(B_IO#(_ zm8lFozdUQMZ4G>XNKbqCGv%koXMzEKSr@LPSdF1#koGHDyX>!loIl8~$l5){!C)VU zD4pMB3{&ohA883HsFqIi`IcY^Lk#u9kF*5C{9(BAVuHO(FBr}+BYgKWGQocSu%32j zM{%&fKVZz1ir@e=EE62)4Qq2vp5h;dYN;O??L$N8rh$A#aH@X@(HPG_?Wd81 zPEYKE!5Nfyrhhn9+!N_WE!{25nzQ^0;9cI))7}DHQ&czQ+g8wuV5(mMj*t{qKo_PF zw(0)iib!=Q3#fA-W)Q^LjATW2buQD>38d%n??t(M&noKLK@|bb^!*vZEPv2B*)DuQ zDwu8Gs{JvQ^=&yUEhr7lwreJUU77BcxlC8K9mGt6=rX|^|KLovy(QDxmCNTdO6yJ< zQ&ADjC9`@+i`jQ#zW~s*I?FR>M_oQ=7)5jH#D$!T6N5A$8Y+;Y^?nqAhG z%Lg^Ygaa&~Wx_dLaBe!7=LI!II26oh_9gQOrE9tL{1QwI77&Ky4=Dga9V1v!oXx>P zE^ldf8IAJwTz+A3K?LVf`NM4am?(f^5u-S-q_lzt!g6#07FS+C)ySwC`j%_3nDB*6 zw^Y$-e;``Ih!&R+eQ-Wua6kWmVoSN$`EivH*Y}DWY3jaft9s@=abvIeeD79qQ|~r$ zYwxq-E4|yroxMB6-Mu@-eZ9NH1HHS&L%q+5M|$^&$9ta_-|O8ge%QNDJl*?(_*w6Z z;upOyiC^`;EPm7biuhgctKtv6uZchPzAk!u-w@k--xRxh-x7O!-xe?Rz9U}ieOJ8I z`<{5O_kHR0ejwAmyo?~r_?eMI`8iVV$InsnAbuVv598tvNBP+(ALr*{`2;_g$nWvH~egt zzvX9({2f1Y^7s5)F8{#K74nb#Tq*y=&sOZJ`pV7=aa!gets`FkDuQU8u`ru8jqQrv=(x|Jv+hA>^~A&46m)G$9=TU1y zZP$3>=ek+zG?(NK^j?kjGoJY6Rv5)?EbCu~d}PxrccOoL;bxsb-K!{bV~x=lFvK`W3~rITl4I5dtspW!GL+<&oPwix1+y!V%t`j z?QN_PJGDl9UPFH2Sx(-gDZXCQaD%4d#+@)Yo_Ik+U$4P#*bY0h12)DJuOw$Zh^#jX zkix2Y;+^LqIIU1u?5o(V#r(w=l>l#gNj-aBR?jcJqMkRus-CyJrk<-`SI=ADP|q*F zsh+pJrJlFH4PWGm4|I#ZvIB0(sLL*x0nN?zS}(r32PVRkDNXa&bg^qZIY>iZuOYA0 z8gz%|f1ulPwbt7kUO+Qn1cP3J@qHNv{1rIHS5dnr{EF9M%-?{)eiJonV%NV7ir!I# z-}x?_<9jgh@2lU}eV~o}u@%pePtCxO({p6SZckQdQ}lID4%e@DdGY}Ly1|o&=!Se< zOY|ni<#bL7ebBYTJuAVjp6K7f|DisPQG#_%dqLy7|DX z@S|G1-+CRCy+OT7p00U&l}2}m=Iut!+jUxVuHOf@sJp>8UxaIX3E`M0r)Vl+v%6uDo`d)1 zh!fs=FFg1@5TS{^?L}0f34O?ub-K3oI}iZuMA2O+vK!8wQK0DaK)o0JXdn8|3njm6}u7MYTdj|Q+KV_&4>0P6w?;% zPEF;*n!Df70=h?Q(!IJH-1jQNU(MOuHRY?ddEWdcLV8X8BX1*Ieg`4myYi2qej>=a zRFj3UNK>tpc>NwQ<9RerEBBR}q>Y-SK$CR!OBf+&a=z@z_Fe?$Tjei-xl6tN9Iva@ z>o4&7Y29q#-(wu0QP3G{G zT4%4*!q}*r78Gq7gv0(@23iQ;(L%UFQ}n2A^<&swqPyt~PySi!+)7XOhOcn;9E%`z zd-!VnK2mpwse8iLz2WN%_SH+LeQ)4^^gz4}_Q>fpnU_zRm#ledHZLvaC8tXI-XMB0 zKL(ejE4*GG|LA3F3NM54vTcA$cs8wbwhz=VI|k{OorCqut}?t(q21-G&~p_?C`ZDc zA$Z}e=ZC7Sy~9ug!R{NL;^zw^)bqvt)bpkNQ%uRr2c&$DNP6W!yikc(4^q$94o-2# z>zFuY&^Hd%)xC)cQ&sU>hnu&zF-xk_-Z_%q2<5w&D`k}L9j%`4AESu+0Mn&Z74i1i zO!%G|8NQDk6~2$cR4O4P_~S66YJVJmg7f19Ot9LV(I+}TPONl(RE}|ej2Y|v7(34S zF>bu`WBdf?$ApudA19rRAA>Y)Cr{+&5}6YxsV39=q{-p?RYg&?P$ z9=@M`M)-clnc@4HXNB))O$pzpOjXjPYNt-~aqv&qHEnwMK79smbk*rI&i2zd_@;lI zeGZD4ALmrzM}^L*nu&IXKWEN@euY?O%}(K$Y1iy(`&vE6qMI`pAO`o`dCre{HNb5M ztvNR&^xXMj%jVZ&ceEy^c7bizg1Q0ry>4OH_=WY*J=4hg^H70p%6W_M%lC$8WQ!W; zC%&_)e>XJp@37{^#i3d)UV==6cFFk!X*hKLQZ8rEF1>(%`UdR<7pmV@Lod7t2?o_g zpP*cW>Jt|;tU-10CH&Ktyrc=gjd3y0vh*PCAIp4_eN$QafbxO9`+r&aAitM0vlT-I z3>la*|CbF(rFwnuC!Uw0*RAyGKmFl{^kbX)Aw2r=tom^d|Jbg6T=gvF?4Tds(^qks zo%CbChaY~ZO6}r2pTKtWD;IxGy&4+$sR<@Rw<$u!jpB;~#1}y;|8W4eGC=dtVP(Sx zfiP-wOE5Q>R~F10G(a`8DX0m~9UPoHJl*SqI*+qdxu#%#P&+uNjby1hn}P*F-Qb`u zlBFtW3Kj>FnfRP(W=?!we4$KyVGx>0Z1|+OUfeK1+_3*Z{24fCpt#|{ zLH=I6A2xW9xZ#L0@S?1j-Ubs_{KWjNHs50;T%BTFPTVBER3^R@R(G?wWq`Pas=I}% zyG2!Z3srZEt?m|89nb-Y(J6N4#I54XW#Y>ry4%F<1H|ow?sh_VyFz#SVT0+t%zu55 zxc!K7-3axD`-73j%>jOtV*E;GIq?aKk)LXbod7 zr=k_qq-~U1PHof)+wI#{Re-9Rs-Wog1e?FjzV#CRa)PPgMx0AILx7%yO_lbI!vh~9 zIA&AHk~~qUx$P{SXQ@_tQ?(A}T2G`z)LMEs8%h-nBe6rzHykmP-XM0$r~1+PbYhszEgzyZuU3QO=~eY|n1_3gD^ z6c4FN?XpN=0>CDp$xvpRvgnP(PFdVS&f*ptTWtH$$o4 zFE$Po8=ol2D(*O{y!mOHVC9kWq*(7-?4#{sM#WBSTh#)YwgBz6{+)c3TO<)&@f!t~q zH57zkx$z9~Tol&ujlkG0=t>zSTL^BbavucLcL8YUMr%l*6KqI!anHz!2gJ9^#J56~ zdQfZ{C^jjT!h=)_k8SGlEHrBqY1SsvtW8>GGw4+@ar7Xu$#!z}Mh;*TDat0Ta*)X; z^aIFb(_s|^&uoBU*<||(Ed0lz`jHXS%31>u-1E|!8&Hz~8v zuAbuUDRE5I;7C*nS zsti-AqOugHSyeb(VOV}+RZ)7WR7K@;0ai&?6-rd9qHHH8nz#}@l>7N^hR=zI#J9`D zx5Iw^u-H6MY^HubKy0Qiy_vf7W@Cm2iOtHP!uf6{=5E%#7hPnt?wx4tX5HORAb4f) z%p2L(!fdor0g_qROg+}Xz$|Q5A>3vP;Wn$j3Ol)(LpW+EBZ$>YMh1je*IHTnb4%b9kFrg-k5{8o)H>(Z~S#73nO{tKj zN#z7Ga+?nuVGDEX$rvc+sM;YmRmkPo--jEdY`Ou@+c#zgTd=*VmCPq)(k#$UhYS1u zddy(wwwa=c&C0DX2aWSH+R7X>iVr%A4i1m4(ErCs z{~sg$f6VAVy(*W65cx5!`(p=*$84~q-biL98v#o^yKEa_NB1!>Ak{6%?R$*c_n3{6 zsA2?(IspyVZ-^WWdFRrr3x$|KLm@0fOPB+DGzT6R-z^j04LR_Hcyge4QgHwe;=q%{ zfhUOrPlg0h0|5#IuP5PZ9?V3^?ExWDYz@9C*@lfGP$DbOJb_ z-@pMw9ykz%0tYk{IDnQg2cFj)_@4NFnfQLlfggx11H~4_0X!(k!GnSvJf2mL?dq`u z+}T3h*+Sge5^`rt$ek@AceW_*fEx8i+%ehUPCUB|{bmbs$H0I)8U~FmT^nq!0X1)K zZKJ7tIa#hPHgwnUyNgw-%CktekVv*Dksu)6Vh3zQ6wI2N58F%JfXH+K*g^faRkb2k z03uZg%l3q=JliCC%yP{XE?G`lYRtr~QdMyRhTuBuS<13AR%km5pSh%p8c1?ITgdfn z(cWveDhc1Qg$5KFA3}G+7fa<@2Blygbqin~^&1yZuDFWI^0;FQ4IDJzx!E-7qWEmb z9hz4*o96bYI9Kfycf{5wTL=RWGq%|HTE8*N`@^R)s>JY#D;z>i;m8?2K%;}T2b)qa z*jBRQ@(|bvhO$Tmo^OG6P$?U>7*?V_-E;Tqp8G@bqcZWMu;>0*JT*`}rFt$NWV@cC z-uV>u&ZolO`Bd0Dp9*{DQ`UB=HPglkIwndZ&Rw?{o`tM|g@l%2U>MQN^#T z66g;aBP8qM=6N@Cngn{Gt_GKV+fj^)vYjCgCXIYx*;eKT+rNF9i%*N6l!>2&T>Pnc zW}tXRaS;!)e|V7n!-MP}9^1j%XNa}W5Nn?aS^G@L+Gj%6K4V#{-iWm(8?23Im!VP5 z5Niz#=ywa+*?@%F{=f3RHp6A{XOI_;HDb?MYQcC$QrIb?2S1F~GQc5YMlu{~!2u=_|1QA3Sk7a2j zjis?I+p;rp)aQBjKIgpm&b>2=mw&KU*GkseKKq<~_IdWl+3$JZxxxe85o9(zj~(%( zFqbI=WAvdwtIMl=xE`Q2T$F~3I#*K%u6~4hAS59eu^dxQbezu=T%G!NOn|jxyYpp# z$ZnyJa7Fexg80--MAZ?GD)__^6tP-LVTQ~bEaV+dVC9MuoTEs>UDDJ{Q6_8NBYtgp zxZts3&tt`&$BI3VWqUeBdnPvQ*~zX@P#&W_(-?qKpD6PjqdkxL z#^9`67*QM@I4pyLJ*gh-S)YIm(>?(iBqqQXc|YuwJ%LxdLL8LsdCctzp9l)>l4MAA z*%M(6w1oL{f%)&XK3%mwT`>Rs*70WRxMPlnn4@9v94FYv3HI><_VEJt@dEbo47O7Q zJFx+FC!4`@oM5Lh(6~NP*c~U>$MccPg#mVSAb5fT*i;W-*Czn%_6hLFn1JBP`(bAS zyG@~wkfSpL2nU6uD3l~P0qgSt>mRf}Q?))*VEx0^iDv7B!-|F_%n9Oof_R>Ag-`Is z&a{HGDsFB8OK{a2LpysV{|2f7JSH)%tAF>5p3{o2`?s z6B_Dtk~*EFPA7|vPZk@WEH*xwZR`|noY=5&C!1x}N!mD#fsN}E1Jw*5|6$=ZgFNX=|q0nsN6-L-(7Z`_0h(W{UgGg!=*6nQ*@yt6MYK z{hXrx68ny&Y`WhJ-7k%KfTUhX%ZeVE7crgY9gOXHLez;bgVHL-bQFi$l-(9YSW)veVr~sB?{KWwI z$<}Punk^td)q?y?nmpMh~$Vd9C^O+L) zDKA0b-Ji=rZv}W&AA$LRAY{6%z3=cG2Z4Pfw5PaJvyLJP{`q&KwS2) zQ)vQ-%~7{G=!P^n7rK|BNHac^+rX+)^Kz(pwso#*ohxddZy^Nd-6hfR@I%AHZ=Ooe zQ|bAn1IaZKbSugHLVZ5t=M;lBv5^=%*$lRMZXu0<#xZ7=ok~gbglOI&0uEdlo)jJM zq@Zy4VFFX$d_F7M$HIOw_KXV;H%sHSNn!MIVDwDuLe;uZFuK@UXtov{BQy-#1%k6c za25(U3k95o0?tAP$0>r7*Z`-K&9Ge{IB5*PsZSI*3j}Au!2x7k7~n()oFXWI)1e+9 zpj-{s;SOgD4S;D(JKa+Qct;W_wNi-%B!u8Af#9>P=c?9o1;OWAmzu3hjvyK$c!>yJ zB7&C+f|m+{mkNTHGJ;MK!NdlFoopg_i3p}KP_;f$2wozBmokD}7@$N45DW?kcBlsg zDOZCNf}sHrjA=lyhXz0}36xq1K_DRnKOYFb(0Z|Iy;u-@sdc&8y6gy|VVt62oL(l7 zmkH$M0_5ca)Nh=r=Hnyn$Kt8<>mi-Pl;j9jIV2 ztnnN>bTcC{qMpxvD4~+T#tXSOkEFXM)!v7pyf_J^w0rFamy(N7fDE>?Rd2jlmXI5u zj)kHkQEe^8rx3Sure6I?aC$44*dNYpVdn!W81F|hrtwndOLym!rJJz2-na>awvEeK zQvsLnztT?R3(_AE)dl@H(j3|ZlN_W#gl7Ra_$qvde&tG6b>^;O%=tW~W{wB65BEvD z)ealuR1Res6JeD*QfHOfmBYZ=a*;2^)AX9Hw3*^xDDmiDFLSJ}`~+ z`qWqQRGC;4kbOd2OwA$b9)cVhd^{utg-^AT-F^Fb4Zi5F*M)d7{gq-vo|-Y$4lrItU)*eWYjZa1gF3*srI5D6sMu z%yB}<7WqVtQwzlbjy9dBUx*X+3$0hH)~n@2{bCDg=8B)FXn3Nc;facdx0zRXKwjYi zc_nI>_pWYTi9(+2HRR-%cvtW`1PSnppLi%Kt{|hLzQ3Y_j2?T1#}|8%FRt)>xZ;Nv zwsi%5gLIub61D2OB}*WK#1e?$v{`Ss?JqX@Fw}LHcBVoOf}~kBPE5#Z~>=Y z<39VlYJf8`X^<(rBzg@yY;={6lQhZi+#ymCZSwlr-N5gT%%LPh-}Hj0WavbcEnNtF13R zy@0)j9M5PUB+0)uzyQ_XPiAVi%-5(j$a@&2H|iSYf77C+r0Ew!(|&7K)-0N?HY~Wt zHAO>B(I5r0!9xujJk+qkLk$}|)UcVuX4Y^sYq*&;X)`3#6%fdD1!QZ|qh(MiLNj{+ zN_4QRvy@KN5*BHUPmD{ivf6eH#g~Uk)cH&Sj}Sj!Ud$aAGW8@`e9~>3@Koo7**xK*Pw=xJa~4|=UFf3y zJjIc^mRxZcwKdLA6z?$-cv46YkPCU~XKS!%Lu<*>s&i=~sy%JECcD5=cKKXyQBP}E zjpy0$&kL}G9_2Jy)N^TBd|Hzg@D1c;9hO^N2zzhKf)G0{(w)o88+pk3#wGGpmA;TE zjaQ#`Nfq2f))wg>Y?s;Qu-*3mV(m zq#gs8WeJodA*XsdQSNxsRPLGryi>v}S0h0NU)}gT$F@0++*TqRi(FaZSn`|pr#^QX zM_1ukRQ>`d67dz2S}4$Xl{2(8B}q|QRMdRpwgr0X#2sOK=9Gn`qbx*fRfD6|C+s|z zbsMPYE&~(DoGu?y((3M1Uo2ogMAEb9EoEwlo+DW&g1(JhkM0Kl`(|>LdLmD7CG12ras$5Ih!bFQ<1YN%K<0Lxh3RWXV+JDeUbA9+uUcHDQ7d~Y%X#( zXF1?xId2U)H`tAp-B{$j(Y7>gi`OA&Scjlt9fAgrg0_WgY~dPPum-|&3y<3^Zg)8T z7GG|*D<26f_&6-P%s-R)NK53?1n(v3Zi1sCR+>u`qh|{%lr2%A+(Qn1v)^7Uy+ehB zjeG!You=Y1D5AHLXgN1Zgd}wjNk6(!;%wQxjwQ<$cRfvz6KcY`#(BzxmtvT9pcRz^ zQEfpYKG*HBSZ_pmBz8e8Bie(X5oK0Lh)SR2?XYF`itXVQH`$vidsFd>H`~^xZFR3e zGYjCh(hs)M54MJ#0MXX46HfQ7VU9ai+t!>PouaCVJ+PFG_d<{ki>5J9w?0uAZKc<3 zjT6fk#t{}B$Y?>qAYIhMK}Fe`AVVW7hmuHqY1z9-y2(YlE$`w`85__C1(3JqYAXbt z?YRjUBI%@^$q?{jfSC<(YZ&6o>@AhOr5NJNZClf}xgpRnJkdM_du*dUw$UEjiaoX! zdu%KA*p}_#6z!4Nutz7GN5?kWBaMO9F$Pi2)sO|Y(H`5}9*Au&40xjhX(1@s0~7EX z7#%vbB%wYQRdS3ysXy~xp3D9-|w7med zy#Tbm0JJ>=M2?66!I07VBJHYfm;)WZX1`zUy6 zjCxu-$tc_&DBNndRd!oJ;dUEn+JK{ghA0dWg#n^4P*4~sC=3)71~Ljx5rxDC3Y~1C zFhCU27@$y}C=>>W!azoW3j>Ad0180?g`^%(XdeX>ViZuoPBIDufx-^kS=r8l!W}l) zv_VG!4PyokV`h+G3=)jN0>)qgW3YfRn89$0U?euc=wvfy1_?$Q12F0n1;!x37|dXB zVSo`Gh?$@O2Gv85)h8gx+9v>)n1G_Q%YJZn247RXxIhUBw4>6(87@eZVRDKw`rO zI@$DrUG#x823prA%A~vK1G};haAEjBbifCKf)7wV_&|LE4B0*bJ`fY&19?B}RPscG zwkyOz`I=%^TvL>pQdlq(s2a>W1Ln8e-Id*4V7|vtXAL>bXqa$@i0=^b9V++^6?}&Z zzC#&br-*N21K&@p%G{;aj2la$G zq5}>d6wHx!^AO4UDA*uI&2{KELXPSU6bC~r5Qie*P&y68Yu6ndv;pO7g@|!#RfEIV zbBsqKO57nuRlngG9YPxCi!7m_VpH4lI4?`jzivz8Ash-do^cH>6b)YcZeFg7l#g}a z4TrhkexNKX(zDhF5_HwYOyRa{$kWcVr1Uh7%dXeS4!BP!V7Mo(&r9RRjOLXm$+Yqj zQJ0GTHP}#~($<=w?5PQ&=A6Z<2&vcIpwf=S){eqetYoD0BnsyBNz4R6;mNYsa$hJjS6U8_XK9h0 zSu|WMbR-i!1s4YL`yk$PANw>!4E57 zCMmk(S%E>4^+P3w&sdVu*tF*v< z=v>;(b1AUHBPyV6Am*cEw(Bq)Z@YE)C7;vIiGjF+v>4){&G;?s1o# zWrtjHkGrJScb6nf-m`~EB_tw=b3wRU>PQsbt;+;$S?)$9v}HM&wk%3Z%31d}ozy8hX=1}kJJ}U#=wUi(8Ur7UiCi96Nw~Ki_8K4F zmX-%F-q~+gN-xeND8-B0VRu-hkv8F)#>1fhFyglt%NI^{OssPlhE1!-I_Ixuoxa}d z^cRU`KZl#8H`c*ZblOj*kpFtAzq&U|IJ@W6R;-q+h?nTGBFgI}YcKR(U~O;Ky0S`b zZB()ys4l-YUWE7B_lDlAjb)YE+SiueKzjMLQF`}U8}E2}v92qt)YiV{$Tl18ZKDbT$&1`&nsZ~+d4dWx|v=UC!VLqc14K5;Ma^?QRZ(#2_ ze!(#851>fqL1_m|u$}c4v<>a6K#8jWB-&h8+!=ZNE9`;F9w>SIeYUr0dp(b%;YG|| zCh5IQ(t9IGKeXERM(QLR(Z4qm^$0ntigCxXmmaV;u*0_YY7_m3H>;PIEZ&2kr|dTD zhHhekRxhzPx>z{jvSQ!ZO)QS`USjcDGwtEN6-3`uL_geH;G4jzS>mp+#Dn(!%HCfr z@sN!)ZNx2shL#wiB}Qn8k#by)#BqrVWyDV>c!^Vd#W_OrjD&em(2S&lhNMb{5%(>a z!zq4(GNQ2e`7k0!!s|zFf}f6f)Q))6YL?;z=kW;s(gE&1;(?Bs!n_7N75$90=+_i_ zr!S-`WiBmVo#k-9O~4I4wbjg2dL_lkic*E7?$KiV2s286>yLyhCW`NE0bdS+T>S3(4%27gNDTn8WuBX@Ut>DN_&jb9;2ZQ^8IMo14YTG+XEiy6!9FT zJw{`P2#QhZ*njxVrS}1n{5xJ7#ozH_gdjptkA_v8&t$PPb@D;i+012}jx^IYolC=% zqY;mAg;AJ=LZqqEg@m|iI2_g()7Vkg2b%_vIXw+?vN420(BJ~pRWfIVsa}CO5 zRAgzgFCheQazrmq4ys%xpdf3Xz}?6MzA=PEnwlv8+nCY^=q(MF29jC zrlb1tZ1nSQH!7(u3a2XZ>X-+A#5^8&?epNEAprsFYw*D9B0*C(^1!=l2}D9B_V+G3 zI;W!ci^XMg-t)P4qNL#>oG#`+I`dFj26)F8X)Qho9EgBf_;AEAhLrJPOR&AguaGZ%kCQ?*trds(!KYMVC*%abKexByP%kW=g#_6-36@- zgl6d!MuORgPk9ll`~1lW;fEC( kzCHgf*RZGUMdOk0Hsi4?+;VPykJaDMPpDBi# zhEn@WdP21xu5a9zr^?ci0?u5Ht-aIWpcrG zPbl>v`*39+E=qmG#`B$dII^fR&F$!28fFUGNk(nu`r~@<<`I3zi@<4|8fNVx=Ae*+zOQd!2ud);Y zTpWO4ZyAtx1R#IOzOJ&bD}elE8*kdUAAo3h0HWamh=z|1Xm|&ThIgQ7_yQ3PUm%VX z!Equuo)BDZ<9^*OHozJ$V2p>OBC(G*R5Fz7RIg4msbrd#~ z!P9-G6}~Fq>TrtsR=6ozK7*jyGUxVoksb*svD){5nyq~gs0@5JjM+fBhJOQZ;(FrN zv6Wd@Mtjh~fun_UwFkL)F-P}36lc&J-TLdd0E&fqP+hG;C>6p*q?!VC{HAcM0yRET z=m~X}fN&+~9b3jx0k3IXa-E9Em95ty2w_b3LrQIT1LTr$h=Rx?9JE9gJX}$Nnz|!h zy#y_;>x%GA?T)`)+@^!VX(jvNj$~;tFKfF?RC+$2%IM_O$B1k2HL5iOx3(!_QQg%|bb4MzPN*eIbzcH)KC&d?MDco^2 zkTg(auVm+1ATL=k>(>!r>9ium-1Sbbxxu%p=gx7zO^~WOueDXBL3yTbv?D{xR65&Z zmNI}I)^#SJ7@%+k11>6JP!TBI%KlN{r2X&6sOEgb0;lcVK!M}I(|`C*&h(rp5PfeF z(gC+H3%$613E}Sg598xcYRg_cvBwr?xoG$C`0_F>T2tli>g7j8C5nAu$sfv`J+ePn z*0~o+jq2b+J38?SxDA7mgh6$=rYOqrar_t#Cdq>M`V1RuyuuD{m33Cqya@PwO@LdB zqxjFTVVdrb7TK}M6TU7~WNuP^x=6M%>4paW3T(N>Uac+GVTQYlau4?&bq`0mvG9PM zNR<-uRr+78Cc0N<{h0j~`)Fk!Ej7_!wS!GN=rs`<)^1ON{Sytd?;5+pyujrBpC91^7LCqX)Vy9>f$MOBcP+Xdmg4OJvd&uvHv?SSwt zbnM{C8U)%c%A$i_48j4ala!QBQeJ1#L4UT_5;}_-t_QsY34+r|q8_Tt%JtAeagaM4xdG%|&cBPMvLq%jiDG5v?%p|L^RDWIDd#HwSkvfb!yIA8*K1Z^8oI3L1X&y}Na2Zu;|E^yQlH8Tt-wQ~iB%mL8NpvAY^SJe`4!=WpIVxr^Gi@( z+rak>6ZoYx4pS^?Mcs$vDH3Y%JB03wtxFpx7JLqk?IL5s2lyg9I^?N(x~~tL^9D{K0wq z5^ic158ltW;VB0c=Ron$78MV68?;y()Uj-DXn5LjtG%INt+7-$)DCSL)pq_)-#Hy$ zj^}vE4IErdt!3QZk#YaJeSKwLUo!6Bu*s%Pdd5Y=jEjaD7Y#Em8fIKH%(#=xxRcDd zllZ&~$#2qg9gZZYc!>cPEi%bOIvJNz?A5tG>F4^S*M~TnCjDHW^z?TJc@B0 zk^{b$mQ=wIo7Ixa+FDXdKayneFK8xtSW!(%L4F`sB#|E`Bdgy=QXlF}B3TO;B^JpR zCD|Kz3Tr#6A0|D;A;UW5Xy*ci61B?}B~pN5eV*FlNTFUbJ~B(Jg3LmJ(v5mB`lze` zEGm+!>!JO6Qr3RGP`;IOJxglq*W!22v5;~j-dO~N!YC+Y&Pl(im1l1B;d-Rda8VjA z3U^6RjhT1SOC>z4O!AmxFMdHKdW-7XoNhWMdA}N#6?po{G<75vYbW{?&4_4C@q<-r z(fUrYKW2Z^zM-;jDAD@2?9o1Zlri`yWAM==hvb?DlzKG6O#|{}>ir?^Z`(Ik_Kii{ z-?7K~>@kXajN%?E;vRExk7aQfkj1?##Qk0Srpmsli2Hl?c%MB^agS5n<3-%#F7ELx z4g<2dJt6Mz+c#JC%|+Zlu&Jg^d1^w#)P#nq2@O*d8m1;Ryy`{6t6nttDOomWk*}tx z%@nnn3T@z3QxTS^G^Si5mphlB*GwN%2aB(PYji_B%wQe`Dt4=yVz8)+lSKv5ZMAZDCmQQ5X(95JqL|KathmBcuOvI0fdlqWmn!70yGxVp%ra_8AZxep+faf}o~DhnBNX%Md; zk_^1Mm}2VdGX4yE*E4Y>CCW5;V&u2X*96aW_$`zv&q4TdZi+c*D#~$fIOo7AREpZA za-eppRE8>eiX|fWzKu;3s5=jB!-qScj-qXJA1`b;p7}XBLoJeaP_mA~-j4NNj?u$B zJ{!+?abdX}50U=E@1pp1EMCJ@c;HGf*M@0nKdtV|L!azA^xeG|drz6Lk`y7nOiT*U zt}!W9-8qGlj(ed*%EK>wrvnQV5X3^^7a!{-2w7#p3@p~CyZ}>R_@lP7P@o4(5W4OX z88r#{GFkWJ*Aa<0AyYo1{HREBCr76c=-9?r_%`r!FNg$BlpC<~3S~e2S=mfQfb>X3 zKo_Gc`BV-3Wouraq+_dGE^MW#sB;}kJ;>qtj8C%3<`6 z>`>DV`C){HhY=bcMrioq%^{vNhj`K)f?*JahvF6>Q#hWZ4|TIs3?~d{cpl=RawrZ+ z_NrPw1f+4c9Lm-5A+MGXL6A$3t#LY0BtQ?50Ntq`5>Vbyf^?SzIGSt8 zLWa82-0&-oB8mEpE0DaMq+S>uLMGKVR4Qt9QLt6$|47oKnqMM7GiA|P@^r&?$TPVF zP!un3V@t?;hj@fj4FQYuB=FL1RFYe5CNZ=Y{P+abmy&9V>!Odo+0 zjPTTUmz1dla(Wy{aFeUgsHD{D#s&FX_T2Y`=eEo$v*NjjZMtdG?zw2_xoGIQXjn#} zVHt&nWfU5gQD|63p}{ZmvpEMJpQevb)5oX7@DHrEX(>hgmr|SpOH7ADAcIfKllu?9 zuk<3fPDd2Od8X6x&9QQl^NC{C%WRTHCm?=80{n%0kOXZ{66C_ot`bma z^jfmtCotCV7bXrZ9~;xo=>F5Z;t70Es0BV!R@F_NkGvH8b*^Q{e4KI#U*~IOl5PnE z{4`R!_NJ7MXqonVLz&L&8oZ*Kjwd*get{*@e{5Uib#iBs*B9~)h1^`o8wz=2A>ZgE zRoKD|ac8D(CG|%3y`9vJq;M@Y{pK4;$xAnr8e$)R@qN`hNL^3rUQ&8pbRQ`dMY~C{ z=34bmQaZ!#rx{SQ5fH*O+Hcc0Y`n-0FI-RI+Y>hmq;s#jvnEh>*_c*kg&nKL z%ScLlmbNcrss&KEZ&hP~5jgi4@)>;J>uo z*O|Mh!}@Eq_=fC;qEN7PN#3ei93yR42cLXb=Yagj+47%uHa~-0{+Pf8l;_gwEKZOc zEA7zh>smSWeyZlZI+paDt%SE^=tEc$4?G)JH)eG(J!1dZzO}M%UESwD%sy`a#J;Vv zZ)@O(+E?M+*({!q9k=ha@2c#(5^t4wPf5(wjZwShZE0rIUBrx zV?R>ak0hS!axQrP)_%0IA5A>h<$Umd%znJGA5T2jWj=U6VLw^fPbOYddOj1pe`h~c z*-s_jYVj@v@88=`SN7A1w?@2+!TS&PGnM^J;`tsHg7+WoXDj>J#PdD)zlS_-|H*!? zvY$&lpZ8qM`_K0CmHm9;IcCoX@4whDRQ3yr=kxp@fgQL1YQI?7FD9O^_d?A3Z}v-- z{ZiujJpYF!$L+t{FIV=3cpG*83n6f<8JYxUUzP++_a-9gY53rL1e# zk$&o$^(@Bl|5@>#T-yNsl;)*$_Al)R*VzwZ2|a8x-613(H>I>cwVBFh$md+h0WYPr zCk_8S+s;cV?I}A|*{OD3N@-8q>B>&G^HNGXV{?_wwewO+J8S1EJJ-%jDeb(?S2o|y XODXLcyHMGMc3w(p7j2=kh0ObZJ!3sR diff --git a/inform7/Internal/Inter/DialogueKit/arch-16d.interb b/inform7/Internal/Inter/DialogueKit/arch-16d.interb index ab57032c96669823d502f4e388c32cb156cd9ece..1b91ed88e335734fc9398012059944b708bb6049 100644 GIT binary patch literal 119678 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%0D)F9@oTh!ZeNScIlX%yN zcPe<_Yu{Jd_a$CKyr+Zr&+Ypw`~Jl16Yq5J{)PQOWj~O3{omUZw6Y&fJlExX@P5pGys{rpJlADDct2r3 zS=mn}-hlLcCV2nOeyXycO1#zLT?pR4x1X-;rxS0Dco&2BAM9r;`h`xoQ8&ey*~gOFW{k-cvG#vrv1$L) zezme+O+3fi|7pRd{V)5q%6={J9Bcna^P2X*?bj>&^~7_m{hxzt+W)cNsO&cq&$0G@ z$E<1p*N#+nB=IWQ!T&{;rv0XUyt0oc-dgeeA2n#&Z`skxjwaqZ@%*0=XxeYvCo20y z;;k2t$M&|^|L@onl|7O88#3R2j<{)`v`)EtFv=fz`Nc3cpG*83n6f<8JYxUUzP++_a-9gY53rL1e#k$&o$^(@Bl|5@>#T-yNsl;)*$_Al)R*VzwZ2|a8x-613(H>I>c zwVBFh$md+h0WYPrCk_8S+s;cV?I}A|*{OD3N@-8q>B>&G^HNGXV{?_wwewO+J8S1E jJJ-%jDeb(?S2o|yODXLcyHMGMc3w(p7j2=kh0ObZz->WV diff --git a/inform7/Internal/Inter/DialogueKit/arch-32.interb b/inform7/Internal/Inter/DialogueKit/arch-32.interb index ed7cb0b5a2f6a67e76bf356f90b81400c1231eec..567f915b4ce05ae78dca278bd7152bba1d8cc496 100644 GIT binary patch literal 119821 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 XDWyGY=PNtk&Pyrnf-P0HlzD#y8MlAz diff --git a/inform7/Internal/Inter/DialogueKit/arch-32d.interb b/inform7/Internal/Inter/DialogueKit/arch-32d.interb index ea9d0d968d0403be5e13233c31480ae8eb687c25..afabbaa15566643d93586cda049759bf55496d88 100644 GIT binary patch literal 119842 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 delta 8756 zcmZ`;X2xka2qAz0Lk@0;+{mE>a*zlKkOT-IVG=sYKxPJJCP2Kp$`g+j zp>KUVZOX^)boe z?PUD}1r)V$s_63D=7t}n>8>spJZ6;Qu9c6>nPZn z)}k)?q=)qyj9J#;w0zRjTA!9jdRfQ8?rkmZT0qXT-t0P@cgUE%}&g^_L!J6DBk4&^4?2}I>SxJ2d zkjYjI#*3^k`ko>eZ^_AtddZY6JM*>@Qe=Hp@D`bB?dm^_OtY#6WRqg+i2*}MiIqKY z7%8=G88}EQBlO;dIo8wV8CLqB8_9HQ*PwNz+}bjD5~;984>?ROv6c-Dkr`H>VKQhsYN}G1*whwkj0M7>=q#(Uu%~afTBXdg!oxGi&GFc(;%f=FMWRZF zs;I$0D5`X-3JEAmwL04~Cw+!L)ZFH8HfjPvqpGRc-(KUfJ=W~P?pr=A+~g~+RTI^k zq{eV4WHiRYk?35Httc|6I1m9hEUYN=V9mMR-E0!5Zwk$~UKrDFT%9`4Gym+s1(+|x z4XX*4hnm8Xpb<3`Wg%o-VBJ4FtIr~ja;dt|v*=vB#n$Yxy|sGaF7AQ-%Y+q|VAX2O zSQAqezgq8El7UD`1Fn_gt~J+)G$=|V1U96d?t}QH7>_M7)JD(JGa{NSGOn-I3{g$J zt`SqtYKVAg6^sB%A4YA>j&4s5P`TH5n1yZYy(qugsNd*t6n)GDNnNjZaq1C>)+h zB5ZCn<`2c9F;h)hj}G1uW*>$ zgUqW$ViVbkRaLX9g$hc6ZKg^Ok|`r3q#83cUvC^lHwRGU&C0gz0rM zwa`JYNA7i;D}~S-MDDemURzmQ1$J^i%YqQm}*;SX_($D`L2{(kbg7h$EEy+ zIP_a3-Bq&=>9=xvT+MBQz8>j%(To|cm<`BYp8_6}ySNyOc>S%d^mdo*D!Bv6w<9?& zm;UfM-ybWzJx|ttY z9Uxc4<4E3&*zm-&k5NP4{^nRfFV1akhuPTx)C2@L?Y;NpS|=W4EQir zy11-=5fwCr=uSyTNhUn2>Bq?5$@%d{{#)=rk$hLrr%3;V)8lgfBj}$YJ)u%Q_dZAR zXUW3Bm3%=+i0*QDW|i9*8;QGs7?;pNJfSe{6dB#+cO$VAi1EeuaN=Gh>UAaZ>Aw$| zdsAEwU;Il#+Ub6mIa0iT=vPSHkJR|`UlVV;5v2!QvMb;qat|OkuHYModkDG7MKf!w z%PY&ojrT3m52c;vnzS-ihC18SOUoC`KQNN5>00MpTTZ$33jRAl2PYYsT{z#Ld*uz|!I4Xj~< zh%XB7;}9DRuW?+C4IyeM011Xd0`L!mw^J);3@2J_wb2T(g+zzOL}CWu7Z4rua(e_x zXfgv$+#X31AU`)pkwm@*zZgw)z7EEYAv!L_{bPCdP^_JeBT29hSi`W6@$w4Gxsap? z%&BSuNfy_KLW(e<0;jP3kksMYf+_QvxHf&`$ z2+?x{P%VHO7pS#vsOXz8moHdrZLY{R=Mj>_<`Xi3)e&#biXdA6lRwB7!dWdWWQ$-5 ztzwswM3`Vp!jX2im~@Hxmm4{8Pdyx1ATJ?mYdE}|`H6Q8TsDvdV~rnvjvB0ycrOFb zQlhT*!znfdv5AWa2#3u{5RbvX+l9BO9EKz2(Qo*K)E7J{FQ{#MpXd<~I+ z(ZqtzGmeEw0(^Tmz`a;w&$2t_+MNsR-HYu#4fft9d*3qq%aFZ4W`DKH{<_^haD{!) zw7;QO+lT0N_P2Dc{hdi~whz-=?eFP&`v-cveT3d=AEg`ZWAq;TIK9vQkv?euL?51O*E`lNl5K4bq%pS4d-QIzxP^L);sTlw6NzQpHTx{c3y^mRVx)9rjNpl|cJ zKYfqS<^Z~b8w2Twd>%x1@_8`*gwI3hXM7$?cky``?d0=tx|h#|bU&Xjpa=Lof*#`Y zNP3vhqv#PnkEX}@Jcgd&^H_QkXHyx+6z&+$e0;u;CG+`W){oCqSP`G6vT1xSW+i+s zVP$+SWwo|4zoQ1bQ3j9Vj-(ESB|Fy>I=Oq|?xc=A+?uqPPm}lY=^}-t7CFo!xO+Nk zwlvSY+^5&ndTV_iZ>@D`POce=>QT*W6HH$pYt!32s!fz_ibBxe;rLgr)>jL^wg&y3 zj=%jf{W8~oIr?`y{wuE3uXO!ap?{C#H!0OAbrH(+sHu7PIvBm0UZc}%BzP^x?GxB_ z^m?6MFR>dC`%++Q>5V$QQDQeCwqIa3(_3_Ui^P6|*jEC(m9EpNxlV$&A^5cb*V7F; z-5@awu>%6To!+6-J0$j7#10DVPI{M4?~>Tvh0u!I=x?F4GUCq{Q?B=#4? zjuVrgJNi6*L8mWB@UIB|C<3?A7j^og#QuiZPXc?1zO2)iCH4wpCj_>QzN*t#CH5L( zKMU-2`i4&50L;X*uF*FU{6&D<>03H|O9uWOv6BLOo4%vdcO>>MV!sOPJ^H>*-b^58q z|Ks9$0{@JDuG7yY{srJBSC}sdyQr;GTM|0l1O)=`q`P&xTjG0MyuZNr(tSGJC-E;` ze1O3B)30>;mBhd1_dm91pdcKe2X%T-625U03=;Su`mIjCmH2lqK3L#~>GwMQUgAHv z_z-~~p+|LkRN}{UQ|!@DK{!r-)aj3s@ROThn7~iapLP1P#D8(|;Q~KNf7R))5_ci@!{S8L(caIO;J>RNe~1XpZ3VmzUE zN3dj;La%2jGGQvv)}3-vD0r8#E@yetOqmM|PU?C(iC|dz=^XCqb{a=x8A$4WhAR_Y zJj5E!tN8XF7- zY@)`7fC2lbv7unV)@f`Q7|Cc1hx(Niv z2Om3$w>sVDt@dfY>I{t>^j7yw(5idupiJ)sR|47VUfRM?QaBY8PUH-<3S3sFW;)@p z)z#?ks?@S^Q4He;7f4zYUGqDc<58v{5X$` z-Q%v%Aq*wye;Bghb1*LAIZ(*}uylgiuoxYi<5YEy`p;Be_kSu{fV+S@=RA*$x%2dS za_8pP`RZ`zymhc!b+B7?8Jed2c!@w)?6Ri@klF=v!1J9jO z1qR=tTCX3@rK`Ncb;G}qMB(Vd!viN6`hk6OzW$AdM!iw?ZK>fic;5`@n*n_@M7UY1 z8Sb_iu#zEqR0fvQqv>EdEt(Egl&P_W(pm%-D%RMgUL!qGaz_e=$`;3Sf)9(*SiR)( zFS0m!$vMb=Np_B=BSK{j=ioN}AMR4gEkA=%VG5maJlvL4fQxsOV5hL7&Tl58sabE9 z9c>Bt0=%OE=x6{s8jvS3;GRS+;5?gb0NtY(kVh|oZ8h;c0?+BIA+08`oW3@L<#esZ z8-N{hQ&kARLgdou5@!Jvp>pRJow01WzFaDA4f=vyc@UJFL69Dl(t}cZ(3KvP(t}cZ zP~J4b4ELr9W{8_c3-a@=v4FIeftA8{emPi9t*u}s5%?m}SP)F7#E>@#CAv#i2tSnQ zN<^0^5tL(z&JR-~6xPGC#1$)jE3rfz;ne{nygF7wxhtXCmGaJ6**k&XWD5HK3-o1Z A)Bpeg diff --git a/inform7/Internal/Inter/EnglishLanguageKit/arch-16d.interb b/inform7/Internal/Inter/EnglishLanguageKit/arch-16d.interb index 1c387fa241e55135c088b1b87c4ac88f36676349..7d3225761a6a882f65cbe9c94ca89a8efe38142a 100644 GIT binary patch literal 25606 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 delta 8690 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 a0VDi$tcK;ThSjcCPtNL|N#Y^X(EneoTU%5B diff --git a/inform7/Internal/Inter/EnglishLanguageKit/arch-32.interb b/inform7/Internal/Inter/EnglishLanguageKit/arch-32.interb index aa34c29256741c82e31d610687f4179e1f274124..3bc0653b96cfeb24b3f45c94ddb8aa6111bb439d 100644 GIT binary patch literal 25591 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 A@&Et; diff --git a/inform7/Internal/Inter/EnglishLanguageKit/arch-32d.interb b/inform7/Internal/Inter/EnglishLanguageKit/arch-32d.interb index adc273d7d50f0b29196955f9ddf23696e853ee38..0e81a48f34644b9773bc096972b60cbe260091c0 100644 GIT binary patch literal 25612 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 diff --git a/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json b/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json index ead2265e1..a531dfefb 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+6W38" + "version": "10.2.0-beta+6W39" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/WorldModelKit/kit_metadata.json b/inform7/Internal/Inter/WorldModelKit/kit_metadata.json index 77cc27245..4a60ec88b 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+6W38" + "version": "10.2.0-beta+6W39" }, "needs": [ { "need": { diff --git a/inter/Tests/Kits/_Results_Ideal/BadKit.txt b/inter/Tests/Kits/_Results_Ideal/BadKit.txt index 4d9e87d57..588030b43 100644 --- a/inter/Tests/Kits/_Results_Ideal/BadKit.txt +++ b/inter/Tests/Kits/_Results_Ideal/BadKit.txt @@ -1,5 +1,5 @@ inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 11: Inform 6 syntax error in function 'E1': operator '+' used with 1 not 2 operand(s) -inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 13: Inform 6 syntax error in function 'E2': do without until +inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 14: Inform 6 syntax error in function 'E2': do without until inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 19: Inform 6 syntax error in function 'E3': expected 'on' or 'off' after 'font', not 'whatever' inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 21: Inform 6 syntax error in function 'E4': move without to inter: inter/Tests/Kits/_kits/BadKit/Sections/Wrong Wrong Wrong.i6t, line 23: Inform 6 syntax error in function 'E5': 'for' header with too few clauses diff --git a/inter/building-module/Chapter 2/Inter Schemas.w b/inter/building-module/Chapter 2/Inter Schemas.w index c170888df..cc8aceabc 100644 --- a/inter/building-module/Chapter 2/Inter Schemas.w +++ b/inter/building-module/Chapter 2/Inter Schemas.w @@ -97,9 +97,7 @@ inter_schema_node *InterSchemas::new_node(inter_schema *sch, int isnt, isn->blocked_by_conditional = FALSE; isn->provenance = (sch)?(sch->provenance):(Provenance::nowhere()); - if ((near_here) && (Provenance::is_somewhere(isn->provenance))) - Provenance::set_line(&(isn->provenance), - Provenance::get_line(isn->provenance) + near_here->line_offset); + if (near_here) Provenance::advance_line(&(isn->provenance), near_here->line_offset); return isn; } @@ -679,6 +677,10 @@ void InterSchemas::throw_error(inter_schema_node *at, text_stream *message) { } ADD_TO_LINKED_LIST(err, schema_parsing_error, at->parent_schema->parsing_errors); LOG("Schema error: %S\n", message); + if ((at->parent_schema) && (Provenance::is_somewhere(at->parent_schema->provenance))) + LOG("Schema provenance %f, line %d\n", + Provenance::get_filename(at->parent_schema->provenance), + Provenance::get_line(at->parent_schema->provenance)); LOG("$1\n", at->parent_schema); } diff --git a/inter/building-module/Chapter 2/Parsing Inter Schemas.w b/inter/building-module/Chapter 2/Parsing Inter Schemas.w index 7aa715508..df79b2dbb 100644 --- a/inter/building-module/Chapter 2/Parsing Inter Schemas.w +++ b/inter/building-module/Chapter 2/Parsing Inter Schemas.w @@ -159,6 +159,10 @@ inter_schema *ParsingSchemas::back_end(text_stream *from, int abbreviated, sch->dereference_mode = TRUE; pos = 3; } Tokenisation::go(sch, from, pos, abbreviated, no_quoted_inames, quoted_inames); + if ((Log::aspect_switched_on(SCHEMA_COMPILATION_DA)) || + (Log::aspect_switched_on(SCHEMA_COMPILATION_DETAILS_DA))) + LOG("Tokenised inter schema:\n$1", sch); + Ramification::go(sch); InterSchemas::lint(sch); diff --git a/inter/building-test/Tests/Test Cases/_Results_Ideal/schemas.txt b/inter/building-test/Tests/Test Cases/_Results_Ideal/schemas.txt index 6393be40b..ea487aa08 100644 --- a/inter/building-test/Tests/Test Cases/_Results_Ideal/schemas.txt +++ b/inter/building-test/Tests/Test Cases/_Results_Ideal/schemas.txt @@ -4522,3 +4522,22 @@ Test: parse schema from: 0003 * (expr) NUMBER 1 ========= +Test: parse schema from: + + + + print BasicInformKit`stuff(); + + + DialogueKit`temp = 1; + +0004 * (statement) !printnumber +0004 * (call) +0005 * (expr) + IDENTIFIER BasicInformKit`stuff +0005 * (operation) !store +0007 * (expr) + IDENTIFIER DialogueKit`temp +0008 * (expr) + NUMBER 1 +========= diff --git a/inter/building-test/Tests/Test Cases/schemas.txt b/inter/building-test/Tests/Test Cases/schemas.txt index 688c57d51..312bf203b 100644 --- a/inter/building-test/Tests/Test Cases/schemas.txt +++ b/inter/building-test/Tests/Test Cases/schemas.txt @@ -1637,3 +1637,13 @@ schema print BasicInformKit`stuff(); DialogueKit`temp = 1; end + +schema + + + + print BasicInformKit`stuff(); + + + DialogueKit`temp = 1; +end diff --git a/inter/bytecode-module/Chapter 3/Text Provenance.w b/inter/bytecode-module/Chapter 3/Text Provenance.w index 4a62a6977..c5fd17f45 100644 --- a/inter/bytecode-module/Chapter 3/Text Provenance.w +++ b/inter/bytecode-module/Chapter 3/Text Provenance.w @@ -64,6 +64,11 @@ void Provenance::set_line(text_provenance *where, int lc) { where->line_number = lc; } +void Provenance::advance_line(text_provenance *where, int by) { + if ((where) && (Provenance::is_somewhere(*where))) + where->line_number += by; +} + @ Writing to text: = diff --git a/inter/pipeline-module/Chapter 3/Compile Splats Stage.w b/inter/pipeline-module/Chapter 3/Compile Splats Stage.w index c1caa0de7..68e2faee4 100644 --- a/inter/pipeline-module/Chapter 3/Compile Splats Stage.w +++ b/inter/pipeline-module/Chapter 3/Compile Splats Stage.w @@ -708,6 +708,7 @@ in this section. PipelineErrors::set_kit_error_location_near_splat(P); text_stream *raw_identifier = NULL, *local_var_names = NULL, *body = NULL; match_results mr = Regexp::create_mr(); + int line_offset = 0; if (SplatInstruction::plm(P) == ROUTINE_PLM) @; if (SplatInstruction::plm(P) == STUB_PLM) @; if (raw_identifier) { @@ -722,13 +723,17 @@ in this section. @ = text_stream *S = SplatInstruction::splatter(P); + int pos = 0; if (Regexp::match(&mr, S, L" *%[ *([A-Za-z0-9_`]+) *; *(%c*)")) { - raw_identifier = mr.exp[0]; body = mr.exp[1]; + raw_identifier = mr.exp[0]; body = mr.exp[1]; pos = mr.exp_at[1]; } else if (Regexp::match(&mr, S, L" *%[ *([A-Za-z0-9_`]+) *(%c*?); *(%c*)")) { - raw_identifier = mr.exp[0]; local_var_names = mr.exp[1]; body = mr.exp[2]; + raw_identifier = mr.exp[0]; local_var_names = mr.exp[1]; body = mr.exp[2]; pos = mr.exp_at[2]; } else { PipelineErrors::kit_error("invalid Inform 6 routine declaration", NULL); } + for (int i=0; i0) && (Characters::is_whitespace(Str::get_at(body, L-1)))) L--; Str::truncate(body, L); inter_ti B = (inter_ti) InterBookmark::baseline(IBM) + 1; + text_provenance prov = PipelineErrors::get_kit_error_location(); + Provenance::advance_line(&prov, line_offset); CompileSplatsStage::function_body(css, IBM, IP, B, body, block_bookmark, identifier, - SplatInstruction::namespace(P), PipelineErrors::get_kit_error_location()); + SplatInstruction::namespace(P), prov); @h Inform 6 annotations. @@ -1378,6 +1385,10 @@ int CompileSplatsStage::function_bodies(pipeline_step *step, compile_splats_stat LOOP_OVER_LINKED_LIST(req, function_body_request, css->function_bodies_to_compile) { LOGIF(SCHEMA_COMPILATION, "=======\n\nFunction (%S) len %d: '%S'\n\n", InterPackage::name(req->block_package), Str::len(req->body), req->body); + if (Provenance::is_somewhere(req->provenance)) + LOGIF(SCHEMA_COMPILATION, "Function provenance %f, line %d\n\n", + Provenance::get_filename(req->provenance), + Provenance::get_line(req->provenance)); inter_schema *sch = ParsingSchemas::from_text(req->body, req->provenance); if (LinkedLists::len(sch->parsing_errors) > 0) { CompileSplatsStage::report_kit_errors(sch, req); diff --git a/inter/pipeline-module/Chapter 3/Parsing Stages.w b/inter/pipeline-module/Chapter 3/Parsing Stages.w index 41a6f6136..e4913c516 100644 --- a/inter/pipeline-module/Chapter 3/Parsing Stages.w +++ b/inter/pipeline-module/Chapter 3/Parsing Stages.w @@ -272,10 +272,7 @@ void ParsingStages::receive_raw(text_stream *S, simple_tangle_docket *docket) { mode = mode | COMMENTED_I6TBIT; } if (mode & COMMENTED_I6TBIT) { - if (c == '\n') { - mode -= COMMENTED_I6TBIT; - if (!(mode & CONTENT_ON_LINE_I6TBIT)) continue; - } + if (c == '\n') mode -= COMMENTED_I6TBIT; else continue; } if ((c == '[') && (!(mode & SUBORDINATE_I6TBITS))) { From b382906e3996987fde0876c50e0470a6958bf7ff Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Sat, 29 Apr 2023 23:36:11 +0100 Subject: [PATCH 016/113] Further improvements to I6 syntax error reporting --- README.md | 2 +- build.txt | 4 +- docs/building-module/2-eis.html | 40 ++-- docs/building-module/2-i6a.html | 2 +- docs/building-module/2-i6o.html | 2 +- docs/building-module/2-i6se.html | 203 +++++++++++++++++ docs/building-module/2-if.html | 2 +- docs/building-module/2-is.html | 69 +----- docs/building-module/2-pis.html | 4 +- docs/building-module/2-rmf.html | 46 ++-- docs/building-module/2-tkn.html | 6 +- docs/building-module/3-prd.html | 2 +- docs/building-module/index.html | 5 + docs/bytecode-module/3-ivp.html | 2 +- docs/core-module/2-pwst.html | 4 +- docs/imperative-module/4-cs.html | 2 +- docs/pipeline-module/2-pe.html | 62 +---- docs/pipeline-module/3-css.html | 132 ++++++----- docs/pipeline-module/3-ps.html | 193 ++++++++++------ docs/pipeline-module/3-rccs.html | 56 ++++- docs/supervisor-module/3-is.html | 4 +- .../supervisor-module/Chapter 3/Inter Skill.w | 4 +- inform7/Figures/memory-diagnostics.txt | 6 +- inform7/Figures/timings-diagnostics.txt | 64 +++--- .../BasicInformExtrasKit/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 +- .../Tests/Test Problems/PM_I6SyntaxError.txt | 125 +++++++++++ .../_Results_Ideal/PM_I6SyntaxError.txt | 212 ++++++++++++++++++ .../Chapter 2/Problems With Source Text.w | 4 +- .../Chapter 4/Compile Schemas.w | 2 +- .../Chapter 2/Emitting Inter Schemas.w | 38 ++-- .../Chapter 2/Inform 6 Syntax Errors.w | 128 +++++++++++ .../building-module/Chapter 2/Inter Schemas.w | 56 ----- .../Chapter 2/Parsing Inter Schemas.w | 2 +- .../building-module/Chapter 2/Ramification.w | 44 ++-- .../building-module/Chapter 2/Tokenisation.w | 4 +- inter/building-module/Contents.w | 1 + .../Chapter 3/Inter Value Pairs.w | 2 +- .../Chapter 2/Pipeline Errors.w | 60 ----- .../Chapter 3/Compile Splats Stage.w | 132 ++++++----- .../Chapter 3/Parsing Stages.w | 180 +++++++++------ .../Resolve Conditional Compilation Stage.w | 56 ++++- 45 files changed, 1316 insertions(+), 656 deletions(-) create mode 100644 docs/building-module/2-i6se.html create mode 100644 inform7/Tests/Test Problems/PM_I6SyntaxError.txt create mode 100644 inform7/Tests/Test Problems/_Results_Ideal/PM_I6SyntaxError.txt create mode 100644 inter/building-module/Chapter 2/Inform 6 Syntax Errors.w diff --git a/README.md b/README.md index 76c260cd7..462fd028c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inform 7 -[Version](notes/versioning.md): 10.2.0-beta+6W39 'Krypton' (28 April 2023) +[Version](notes/versioning.md): 10.2.0-beta+6W40 'Krypton' (29 April 2023) ## About Inform diff --git a/build.txt b/build.txt index 64e2b5f06..9382b82be 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: beta -Build Date: 28 April 2023 -Build Number: 6W39 +Build Date: 29 April 2023 +Build Number: 6W40 diff --git a/docs/building-module/2-eis.html b/docs/building-module/2-eis.html index 059b90fcc..4fefbab78 100644 --- a/docs/building-module/2-eis.html +++ b/docs/building-module/2-eis.html @@ -251,7 +251,7 @@ all conditionals are resolved. at = at->next_node; } if (endif_node == NULL) { - InterSchemas::throw_error(dir_node, I"no matching '#endif'"); + I6Errors::issue_at_node(dir_node, I"no matching '#endif'"); return FALSE; }

    @@ -269,6 +269,10 @@ all conditionals are resolved.
         if ((dir_node->dir_clarifier == IFDEF_I6RW) ||
             (dir_node->dir_clarifier == IFNDEF_I6RW)) {
    +        if (dir_node->child_node == NULL) {
    +            I6Errors::issue_at_node(dir_node, I"bare '#ifdef' or '#ifndef'");
    +            return FALSE;
    +        }
             symbol_to_check = dir_node->child_node->expression_tokens->material;
         } else {
             inter_schema_node *to_eval = dir_node->child_node;
    @@ -276,7 +280,7 @@ all conditionals are resolved.
                 to_eval = to_eval->child_node;
             if ((to_eval == NULL) || (to_eval->child_node == NULL) ||
                 (to_eval->child_node->expression_tokens == NULL)) {
    -            InterSchemas::throw_error(dir_node, I"malformed '#if...'");
    +            I6Errors::issue_at_node(dir_node, I"malformed '#if...'");
                 return FALSE;
             }
             symbol_to_check = to_eval->child_node->expression_tokens->material;
    @@ -460,8 +464,8 @@ compilation — are ever visited.
     

    -    if (prim_cat != CODE_PRIM_CAT) {
    -        InterSchemas::throw_error(node, I"assembly language unexpected here");
    +    if (prim_cat != CODE_PRIM_CAT) {  should never in fact happen
    +        I6Errors::issue_at_node(node, I"assembly language unexpected here");
             return;
         }
         inter_schema_node *at = node->child_node;
    @@ -473,7 +477,7 @@ compilation — are ever visited.
                     opcode_text = tok->material;
             }
             if (opcode_text == NULL) {  should never in fact happen
    -            InterSchemas::throw_error(node, I"assembly language malformed here");
    +            I6Errors::issue_at_node(node, I"assembly language malformed here");
                 return;
             }
             Produce::inv_assembly(I, opcode_text);
    @@ -567,7 +571,7 @@ changed back again very soon after.
         } else if (Str::eq(tok->material, I"indirect")) {
             at = at->next_node;
         } else if (Str::eq(tok->material, I"glk")) {
    -        InterSchemas::throw_error(node, I"the glk() function is now unsupported");
    +        I6Errors::issue_at_node(node, I"the glk() function is now unsupported");
             return;
         } else {
             to_call = IdentifierFinders::find_token(I, tok, finder);
    @@ -614,7 +618,7 @@ somewhere (in fact, always in a property value).
             int argc = 0;
             for (inter_schema_node *n = node->child_node; n; n=n->next_node) argc++;
             if (argc > 4) {
    -            InterSchemas::throw_error(node, I"too many arguments for call-message");
    +            I6Errors::issue_at_node(node, I"too many arguments for call-message");
                 return;
             }
             inter_ti BIP = Primitives::BIP_for_indirect_call_returning_value(argc-1);
    @@ -636,7 +640,7 @@ more natural { ... }
         if (prim_cat != CODE_PRIM_CAT) {
    -        InterSchemas::throw_error(node, I"unexpected '{ ... }' code block");
    +        I6Errors::issue_at_node(node, I"unexpected '{ ... }' code block");
             return;
         }
         if (node->unopened == FALSE) {
    @@ -660,7 +664,7 @@ only part of I6 syntax covered by schemas. Therefore:
     

    -    InterSchemas::throw_error(node, I"misplaced directive");
    +    I6Errors::issue_at_node(node, I"misplaced directive");
         return;
     
    • This code is used in §3.1.
    @@ -673,7 +677,7 @@ evaluated for their potential side-effects, but only the last produces a value.
         if ((prim_cat != CODE_PRIM_CAT) && (prim_cat != VAL_PRIM_CAT)){
    -        InterSchemas::throw_error(node, I"expression in unexpected place");
    +        I6Errors::issue_at_node(node, I"expression in unexpected place");
             return;
         }
         if (node->child_node == NULL) Produce::val(I, K_value, InterValuePairs::number(1));
    @@ -793,7 +797,7 @@ parsing the schema.)
                     if (InterValuePairs::is_undef(val)) {
                         TEMPORARY_TEXT(msg)
                         WRITE_TO(msg, "malformed literal number '%S'", t->material);
    -                    InterSchemas::throw_error(node, msg);
    +                    I6Errors::issue_at_node(node, msg);
                         DISCARD_TEXT(msg)
                         return;
                     }
    @@ -825,7 +829,7 @@ parsing the schema.)
             default: {
                 TEMPORARY_TEXT(msg)
                 WRITE_TO(msg, "'%S' was unexpected in expression context", t->material);
    -            InterSchemas::throw_error(node, msg);
    +            I6Errors::issue_at_node(node, msg);
                 DISCARD_TEXT(msg)
                 break;
             }
    @@ -860,7 +864,7 @@ For example, the schema .{-la
     
     
         if (prim_cat != CODE_PRIM_CAT) {
    -        InterSchemas::throw_error(node, I"label in unexpected place");
    +        I6Errors::issue_at_node(node, I"label in unexpected place");
             return;
         }
         TEMPORARY_TEXT(L)
    @@ -879,7 +883,7 @@ For example, the schema .{-la
                 } else {
                     TEMPORARY_TEXT(msg)
                     WRITE_TO(msg, "expected label name but found '%S'", t->material);
    -                InterSchemas::throw_error(node, msg);
    +                I6Errors::issue_at_node(node, msg);
                     DISCARD_TEXT(msg)
                     return;
                 }
    @@ -991,7 +995,7 @@ on others.
     
     
         if (prim_cat != CODE_PRIM_CAT) {
    -        InterSchemas::throw_error(node, I"statement in unexpected place");
    +        I6Errors::issue_at_node(node, I"statement in unexpected place");
             return;
         }
         if (node->isn_clarifier == CASE_BIP) Produce::set_level_to_current_code_block_plus(I, 2);
    @@ -1067,7 +1071,7 @@ these possibilities:
                 EIS_RECURSE(var_node, REF_PRIM_CAT);
                 EIS_RECURSE(cl_node, VAL_PRIM_CAT);
             } else {
    -            InterSchemas::throw_error(node, I"malformed 'objectloop' header");
    +            I6Errors::issue_at_node(node, I"malformed 'objectloop' header");
                 return;
             }
         } else {
    @@ -1080,7 +1084,7 @@ these possibilities:
                 EIS_RECURSE(var_node, REF_PRIM_CAT);
                 Produce::val_symbol(I, K_value, IdentifierFinders::find(I, I"Object", finder));
             } else {
    -            InterSchemas::throw_error(node, I"'objectloop' without visible variable");
    +            I6Errors::issue_at_node(node, I"'objectloop' without visible variable");
                 return;
             }
         }
    @@ -1113,7 +1117,7 @@ like the comma in C) to throw away the results of the non-final evaluations.
     
    • This code is used in §3.1.
    diff --git a/docs/building-module/2-i6a.html b/docs/building-module/2-i6a.html index 653929641..36f0d05ef 100644 --- a/docs/building-module/2-i6a.html +++ b/docs/building-module/2-i6a.html @@ -248,7 +248,7 @@ if a syntax error is reached.
    • This code is used in §5 (twice).
    diff --git a/docs/building-module/2-i6o.html b/docs/building-module/2-i6o.html index 940d9a91a..5031953f1 100644 --- a/docs/building-module/2-i6o.html +++ b/docs/building-module/2-i6o.html @@ -254,7 +254,7 @@ irrelevant, of course, for unary operators. }
    diff --git a/docs/building-module/2-i6se.html b/docs/building-module/2-i6se.html new file mode 100644 index 000000000..192f5d3a6 --- /dev/null +++ b/docs/building-module/2-i6se.html @@ -0,0 +1,203 @@ + + + + Inform 6 Syntax Errors + + + + + + + + + + + + + + + + + + +
    + + +

    To issue problem messages when parsing malformed I6-syntax code.

    + +

    §1. Errors like these used to be basically failed assertions, but inevitably people +reported that as a bug (Mantis 0001596). It was never intended that Inform 6-syntax +hacking should be part of the outside-facing Inform language; but if you leave +power tools just lying around, people will eventually pick them up and wonder +what the red button marked "danger" does. +

    + +

    Note that i6_syntax_error_location is initially uninitialised and thus has +undefined contents, so we take care to blank it out if it is read before being +written to for the first time. +

    + +
    +text_provenance i6_syntax_error_location;
    +int i6_syntax_error_location_set = FALSE;
    +
    +text_provenance I6Errors::get_current_location(void) {
    +    if (i6_syntax_error_location_set == FALSE)
    +        I6Errors::clear_current_location();
    +    return i6_syntax_error_location;
    +}
    +void I6Errors::clear_current_location(void) {
    +    I6Errors::set_current_location(Provenance::nowhere());
    +}
    +void I6Errors::set_current_location(text_provenance where) {
    +    i6_syntax_error_location_set = TRUE;
    +    i6_syntax_error_location = where;
    +}
    +
    +void I6Errors::set_current_location_near_splat(inter_tree_node *P) {
    +    I6Errors::clear_current_location();
    +    if ((P) && (Inode::is(P, SPLAT_IST)))
    +        I6Errors::set_current_location(SplatInstruction::provenance(P));
    +}
    +
    +

    §2. The issuing mechanism, or rather, the mechanism used if the main Inform +compiler doesn't gazump us (in order to provide something better-looking in +the GUI apps). +

    + +
    +int i6_syntax_error_count = 0;
    +
    +void I6Errors::issue(char *message, text_stream *quote) {
    +    text_provenance at = I6Errors::get_current_location();
    +    #ifdef CORE_MODULE
    +    SourceProblems::I6_level_error(message, quote, at);
    +    #endif
    +    #ifndef CORE_MODULE
    +    if (Provenance::is_somewhere(at)) {
    +        filename *F = Provenance::get_filename(at);
    +        TEMPORARY_TEXT(M)
    +        WRITE_TO(M, message, quote);
    +        Errors::at_position_S(M, F, Provenance::get_line(at));
    +        DISCARD_TEXT(M)
    +    } else {
    +        Errors::with_text(message, quote);
    +    }
    +    #endif
    +    i6_syntax_error_count++;
    +}
    +
    +void I6Errors::reset_count(void) {
    +    I6Errors::clear_current_location();
    +    i6_syntax_error_count = 0;
    +}
    +
    +int I6Errors::errors_occurred(void) {
    +    if (i6_syntax_error_count != 0) return TRUE;
    +    return FALSE;
    +}
    +
    +

    §3. The functions below are for errors detected when parsing text into schemas, or +when emitting code from them. +

    + +

    Note that the parsing_errors field of a schema is null until the first error +is detected — which, of course, it usually isn't. It holds a linked list of these: +

    + +
    +typedef struct schema_parsing_error {
    +    struct text_stream *message;
    +    struct text_provenance provenance;
    +    CLASS_DEFINITION
    +} schema_parsing_error;
    +
    +
    • The structure schema_parsing_error is accessed in 2/is and here.
    +

    §4.

    + +
    +void I6Errors::issue_at_node(inter_schema_node *at, text_stream *message) {
    +    if (at->parent_schema->parsing_errors == NULL)
    +        at->parent_schema->parsing_errors = NEW_LINKED_LIST(schema_parsing_error);
    +    schema_parsing_error *err = CREATE(schema_parsing_error);
    +    err->message = Str::duplicate(message);
    +    if (at) {
    +        if (Provenance::is_somewhere(at->provenance)) err->provenance = at->provenance;
    +        else if (at->parent_schema) err->provenance = at->parent_schema->provenance;
    +        else err->provenance = Provenance::nowhere();
    +    } else {
    +        err->provenance = Provenance::nowhere();
    +    }
    +    ADD_TO_LINKED_LIST(err, schema_parsing_error, at->parent_schema->parsing_errors);
    +    LOG("Schema error: %S\n", message);
    +    if ((at->parent_schema) && (Provenance::is_somewhere(at->parent_schema->provenance)))
    +        LOG("Schema provenance %f, line %d\n",
    +            Provenance::get_filename(at->parent_schema->provenance),
    +            Provenance::get_line(at->parent_schema->provenance));
    +    LOG("$1\n", at->parent_schema);
    +}
    +
    +

    §5. That function of course caches schema errors for playback later: well, here's +the later. Unless the main Inform compiler takes over from us, the result will +be drastic, halting what is presumably the inter tool: +

    + +
    +void I6Errors::internal_error_on_schema_errors(inter_schema *sch) {
    +    if (LinkedLists::len(sch->parsing_errors) > 0) {
    +        #ifdef CORE_MODULE
    +        SourceProblems::inter_schema_errors(sch);
    +        #endif
    +        #ifndef CORE_MODULE
    +        WRITE_TO(STDERR, "Parsing error(s) in the internal schema '%S':\n",
    +            sch->converted_from);
    +        schema_parsing_error *err;
    +        LOOP_OVER_LINKED_LIST(err, schema_parsing_error, sch->parsing_errors)
    +            WRITE_TO(STDERR, "- %S\n", err->message);
    +        exit(1);
    +        #endif
    +    }
    +}
    +
    + + +
    + + + diff --git a/docs/building-module/2-if.html b/docs/building-module/2-if.html index a48cf1f4c..ccb919873 100644 --- a/docs/building-module/2-if.html +++ b/docs/building-module/2-if.html @@ -205,7 +205,7 @@ because the symbol which that iname incarnates as must be the right one. }
    diff --git a/docs/building-module/2-is.html b/docs/building-module/2-is.html index 2a034ebc3..baa799107 100644 --- a/docs/building-module/2-is.html +++ b/docs/building-module/2-is.html @@ -59,7 +59,7 @@ function togglePopup(material_id) {

    Building an inter schema, a form of annotated syntax tree.

    -
    +

    §1. Introduction. See What This Module Does for an introduction to what an Inter schema is. For this section of code, it's sufficient to know that an inter_schema @@ -81,7 +81,7 @@ few hundred — so they do not need to be stored compactly or compiled quick CLASS_DEFINITION } inter_schema;

    -
    • The structure inter_schema is accessed in 2/pis, 2/tkn, 2/rmf, 2/eis and here.
    +
    • The structure inter_schema is accessed in 2/pis, 2/tkn, 2/rmf, 2/eis, 2/i6se and here.

    §2.

    @@ -138,7 +138,7 @@ we now more efficiently remove them.)
         CLASS_DEFINITION
     } inter_schema_node;
     
    -
    • The structure inter_schema_node is accessed in 2/rmf, 2/eis and here.
    +
    • The structure inter_schema_node is accessed in 2/rmf, 2/eis, 2/i6se and here.

    §4.

    @@ -734,69 +734,8 @@ where the check is done:
         return NULL;
     }
     
    -

    §19. Errors. Errors can be detected both when parsing text into schemas, and also when emitting -code from them. In either case, the following is used to attach error message(s) -to the schema itself. -

    - -

    Note that the parsing_errors field is null until the first error is detected — -which, of course, it usually isn't. -

    - -
    -typedef struct schema_parsing_error {
    -    struct text_stream *message;
    -    struct text_provenance provenance;
    -    CLASS_DEFINITION
    -} schema_parsing_error;
    -
    -
    • The structure schema_parsing_error is private to this section.
    -

    §20.

    - -
    -void InterSchemas::throw_error(inter_schema_node *at, text_stream *message) {
    -    if (at->parent_schema->parsing_errors == NULL)
    -        at->parent_schema->parsing_errors = NEW_LINKED_LIST(schema_parsing_error);
    -    schema_parsing_error *err = CREATE(schema_parsing_error);
    -    err->message = Str::duplicate(message);
    -    if (at) {
    -        if (Provenance::is_somewhere(at->provenance)) err->provenance = at->provenance;
    -        else if (at->parent_schema) err->provenance = at->parent_schema->provenance;
    -        else err->provenance = Provenance::nowhere();
    -    } else {
    -        err->provenance = Provenance::nowhere();
    -    }
    -    ADD_TO_LINKED_LIST(err, schema_parsing_error, at->parent_schema->parsing_errors);
    -    LOG("Schema error: %S\n", message);
    -    if ((at->parent_schema) && (Provenance::is_somewhere(at->parent_schema->provenance)))
    -        LOG("Schema provenance %f, line %d\n",
    -            Provenance::get_filename(at->parent_schema->provenance),
    -            Provenance::get_line(at->parent_schema->provenance));
    -    LOG("$1\n", at->parent_schema);
    -}
    -
    -

    §21. And this is an especially drastic way to deal with such errors: -

    - -
    -void InterSchemas::internal_error_on_schema_errors(inter_schema *sch) {
    -    if (LinkedLists::len(sch->parsing_errors) > 0) {
    -        #ifdef CORE_MODULE
    -        SourceProblems::inter_schema_errors(sch);
    -        #endif
    -        #ifndef CORE_MODULE
    -        WRITE_TO(STDERR, "Parsing error(s) in the internal schema '%S':\n",
    -            sch->converted_from);
    -        schema_parsing_error *err;
    -        LOOP_OVER_LINKED_LIST(err, schema_parsing_error, sch->parsing_errors)
    -            WRITE_TO(STDERR, "- %S\n", err->message);
    -        internal_error("malformed schema");
    -        #endif
    -    }
    -}
    -
    diff --git a/docs/building-module/2-pis.html b/docs/building-module/2-pis.html index 959631dc5..b1c47c8cc 100644 --- a/docs/building-module/2-pis.html +++ b/docs/building-module/2-pis.html @@ -112,7 +112,7 @@ I6S code can only come from within the compiler itself, and means a bug. Dictionaries::create(i6s_inter_schema_cache, from); Dictionaries::write_value(i6s_inter_schema_cache, from, (void *) result); - InterSchemas::internal_error_on_schema_errors(result); + I6Errors::internal_error_on_schema_errors(result); return result; } @@ -256,7 +256,7 @@ such operations are nested, they will work. We might then write: } diff --git a/docs/building-module/2-rmf.html b/docs/building-module/2-rmf.html index ca65419fd..2714566a9 100644 --- a/docs/building-module/2-rmf.html +++ b/docs/building-module/2-rmf.html @@ -940,7 +940,7 @@ nodes, which we want to fold into just one: operand1 = InterSchemas::second_dark_token(until_node); cons->next_node = until_node->next_node; } else { - InterSchemas::throw_error(cons, I"do without until"); + I6Errors::issue_at_node(cons, I"do without until"); return FALSE; } @@ -957,7 +957,7 @@ nodes, which we want to fold into just one: TEMPORARY_TEXT(msg) WRITE_TO(msg, "expected 'on' or 'off' after 'font', not '%S'", n->material); - InterSchemas::throw_error(cons, msg); + I6Errors::issue_at_node(cons, msg); DISCARD_TEXT(msg) return FALSE; } @@ -1023,7 +1023,7 @@ clause at all. We split these possibilities into two different statement nodes. to = InterSchemas::next_dark_token(to); } if (to == NULL) { - InterSchemas::throw_error(cons, I"move without to"); + I6Errors::issue_at_node(cons, I"move without to"); return FALSE; } operand2 = InterSchemas::next_dark_token(to); @@ -1443,7 +1443,7 @@ removing the colon and bracket tokens. Thus: (isn->node_marked == FALSE)) { inter_schema_node *predicates = isn->child_node; if ((predicates == NULL) || (predicates->isn_type != EXPRESSION_ISNT)) { - InterSchemas::throw_error(isn, I"malformed 'for' loop"); + I6Errors::issue_at_node(isn, I"malformed 'for' loop"); return FALSE; } inter_schema_token *n = predicates->expression_tokens; @@ -1471,7 +1471,7 @@ removing the colon and bracket tokens. Thus: n = n->next; } if (cw != 3) { - InterSchemas::throw_error(isn, I"'for' header with too few clauses"); + I6Errors::issue_at_node(isn, I"'for' header with too few clauses"); return FALSE; } for (int i=0; i<3; i++) { @@ -1515,7 +1515,7 @@ removing the colon and bracket tokens. Thus:
         if (cw >= 3) {
    -        InterSchemas::throw_error(isn, I"'for' header with too many clauses");
    +        I6Errors::issue_at_node(isn, I"'for' header with too many clauses");
             return FALSE;
         }
         if (from[cw] == NULL) to[cw] = NULL;
    @@ -1544,7 +1544,7 @@ from failing its lint test.
                 int actual = 0;
                 for (inter_schema_node *ch = isn->child_node; ch; ch=ch->next_node) actual++;
                 if ((actual < req-1) || (actual > req)) {
    -                InterSchemas::throw_error(isn, I"malformed statement");
    +                I6Errors::issue_at_node(isn, I"malformed statement");
                     return FALSE;
                 }
                 if (actual == req-1) {
    @@ -1962,7 +1962,7 @@ operation a.b.
                 WRITE_TO(msg, "operator '%S' used with %d not %d operand(s)",
                     I6Operators::I6_notation_for(isn->isn_clarifier),
                     a, I6Operators::arity(isn->isn_clarifier));
    -            InterSchemas::throw_error(isn, msg);
    +            I6Errors::issue_at_node(isn, msg);
                 DISCARD_TEXT(msg)
                 return FALSE;
             }
    @@ -2159,32 +2159,32 @@ to cause trouble later. If no error is thrown, the schema is unchanged.
                 for (inter_schema_token *t = isn->expression_tokens; t; t=t->next) {
                     switch (t->ist_type) {
                         case OPCODE_ISTT:       asm = TRUE; break;
    -                    case RAW_ISTT:          InterSchemas::throw_error(isn, I"malformed expression"); break;
    -                    case OPEN_BRACE_ISTT:   InterSchemas::throw_error(isn, I"unexpected '{'"); break;
    -                    case CLOSE_BRACE_ISTT:  InterSchemas::throw_error(isn, I"unexpected '}'"); break;
    -                    case OPEN_ROUND_ISTT:   InterSchemas::throw_error(isn, I"unexpected '('"); break;
    -                    case CLOSE_ROUND_ISTT:  InterSchemas::throw_error(isn, I"unexpected ')'"); break;
    -                    case COMMA_ISTT:        InterSchemas::throw_error(isn, I"unexpected ','"); break;
    -                    case DIVIDER_ISTT:      InterSchemas::throw_error(isn, I"malformed expression"); break;
    +                    case RAW_ISTT:          I6Errors::issue_at_node(isn, I"malformed expression"); break;
    +                    case OPEN_BRACE_ISTT:   I6Errors::issue_at_node(isn, I"unexpected '{'"); break;
    +                    case CLOSE_BRACE_ISTT:  I6Errors::issue_at_node(isn, I"unexpected '}'"); break;
    +                    case OPEN_ROUND_ISTT:   I6Errors::issue_at_node(isn, I"unexpected '('"); break;
    +                    case CLOSE_ROUND_ISTT:  I6Errors::issue_at_node(isn, I"unexpected ')'"); break;
    +                    case COMMA_ISTT:        I6Errors::issue_at_node(isn, I"unexpected ','"); break;
    +                    case DIVIDER_ISTT:      I6Errors::issue_at_node(isn, I"malformed expression"); break;
                         case RESERVED_ISTT: {
                             TEMPORARY_TEXT(msg)
                             WRITE_TO(msg, "unexpected use of reserved word '%S'", t->material);
    -                        InterSchemas::throw_error(isn, msg);
    +                        I6Errors::issue_at_node(isn, msg);
                             DISCARD_TEXT(msg)
                             break;
                         }
    -                    case COLON_ISTT:        InterSchemas::throw_error(isn, I"unexpected ':'"); break;
    -                    case DCOLON_ISTT:       InterSchemas::throw_error(isn,
    +                    case COLON_ISTT:        I6Errors::issue_at_node(isn, I"unexpected ':'"); break;
    +                    case DCOLON_ISTT:       I6Errors::issue_at_node(isn,
                                                     I"the Inform 6 '::' operator is unsupported"); break;
    -                    case OPERATOR_ISTT:     InterSchemas::throw_error(isn, I"unexpected operator"); break;
    +                    case OPERATOR_ISTT:     I6Errors::issue_at_node(isn, I"unexpected operator"); break;
                     }
                     if ((t->ist_type == NUMBER_ISTT) && (t->next) &&
                         (t->next->ist_type == NUMBER_ISTT) && (asm == FALSE))
    -                    InterSchemas::throw_error(isn, I"two consecutive numbers");
    +                    I6Errors::issue_at_node(isn, I"two consecutive numbers");
                 }
    -            if (isn->child_node) InterSchemas::throw_error(isn, I"malformed expression");
    +            if (isn->child_node) I6Errors::issue_at_node(isn, I"malformed expression");
             } else {
    -            if (isn->expression_tokens) InterSchemas::throw_error(isn, I"syntax error");
    +            if (isn->expression_tokens) I6Errors::issue_at_node(isn, I"syntax error");
             }
             Ramification::sanity_check(isn, isn->child_node);
         }
    @@ -2192,7 +2192,7 @@ to cause trouble later. If no error is thrown, the schema is unchanged.
     }
     
    diff --git a/docs/building-module/2-tkn.html b/docs/building-module/2-tkn.html index 6f8f869bf..8c5259958 100644 --- a/docs/building-module/2-tkn.html +++ b/docs/building-module/2-tkn.html @@ -521,7 +521,7 @@ of modifiers are allowed. See wchar_t c = Str::get_at(from, ++at); int iss_bitmap = 0; switch (c) { - case '!': InterSchemas::throw_error(sch->node_tree, + case '!': I6Errors::issue_at_node(sch->node_tree, I"the '*!' schema notation has been abolished"); break; case '%': iss_bitmap = iss_bitmap | LVALUE_CONTEXT_ISSBM; c = Str::get_at(from, ++at); break; @@ -566,7 +566,7 @@ of modifiers are allowed. See preceding_token = t; pos = at; } else if (c == '-') { - InterSchemas::throw_error(sch->node_tree, + I6Errors::issue_at_node(sch->node_tree, I"the '*-' schema notation has been abolished"); } else if (c == '*') { int c = '*'; Absorb a raw character1.1; @@ -1501,7 +1501,7 @@ single quotation mark in a dictionary literal, but not a character literal. } diff --git a/docs/building-module/3-prd.html b/docs/building-module/3-prd.html index 13e09e9db..cf0ba2add 100644 --- a/docs/building-module/3-prd.html +++ b/docs/building-module/3-prd.html @@ -736,7 +736,7 @@ doesn't add the name tp the current stack frame in } diff --git a/docs/building-module/index.html b/docs/building-module/index.html index 34e1b84e3..2466bc1e3 100644 --- a/docs/building-module/index.html +++ b/docs/building-module/index.html @@ -150,6 +150,11 @@ Inform 6 Annotations - Parsing Inform 6-syntax annotation markers.

    +
  • +

    + Inform 6 Syntax Errors - + To issue problem messages when parsing malformed I6-syntax code.

    +
  • diff --git a/docs/bytecode-module/3-ivp.html b/docs/bytecode-module/3-ivp.html index 322c82446..076539329 100644 --- a/docs/bytecode-module/3-ivp.html +++ b/docs/bytecode-module/3-ivp.html @@ -143,7 +143,7 @@ Inter program is printed to text files, not the meaning of the program. else if ((c >= 'A') && (c <= 'Z')) d = c-'A'+10; else if ((c >= '0') && (c <= '9')) d = c-'0'; else return InterValuePairs::undef(); - if (d > base) return InterValuePairs::undef(); + if (d >= base) return InterValuePairs::undef(); N = base*N + (long long int) d; if (pos.index > 34) return InterValuePairs::undef(); } diff --git a/docs/core-module/2-pwst.html b/docs/core-module/2-pwst.html index 6a187c3b2..28861f6cf 100644 --- a/docs/core-module/2-pwst.html +++ b/docs/core-module/2-pwst.html @@ -732,7 +732,7 @@ in Include (- ... -) notified_kit_name, notified_architecture_name); trigger_kit_notice = FALSE; } - StandardProblems::handmade_problem(Task::syntax_tree(), _p_(...)); + StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_I6SyntaxError)); Problems::quote_stream(1, M); if (Str::len(kit) > 0) { Problems::quote_stream(2, file); @@ -744,7 +744,7 @@ in Include (- ... -) LOG("%S, line %d:\n", file, line); Problems::problem_quote_file(2, file, line); Problems::issue_problem_segment( - "A mistake was found in the Inform 6-syntax code near here %2: %1."); + "Inform 6 syntax error near here %2: %1."); } else { Problems::issue_problem_segment( "My low-level reader of source code reported a mistake - \"%1\". " diff --git a/docs/imperative-module/4-cs.html b/docs/imperative-module/4-cs.html index d2d868af9..39bc2b575 100644 --- a/docs/imperative-module/4-cs.html +++ b/docs/imperative-module/4-cs.html @@ -156,7 +156,7 @@ as above), we fill in its kind. EmitInterSchemas::emit(Emit::tree(), &VH, sch->compiled, IdentifierFinders::common_names_only(), &CompileSchemas::from_schema_token, NULL, &ems); - InterSchemas::internal_error_on_schema_errors(sch->compiled); + I6Errors::internal_error_on_schema_errors(sch->compiled); }
    • The structure i6s_emission_state is private to this section.
    diff --git a/docs/pipeline-module/2-pe.html b/docs/pipeline-module/2-pe.html index c94f4e7b0..cb8b6fc32 100644 --- a/docs/pipeline-module/2-pe.html +++ b/docs/pipeline-module/2-pe.html @@ -59,7 +59,7 @@ function togglePopup(material_id) {

    To issue problem messages when parsing or running erroneous pipelines.

    -
    +

    §1. Syntax errors.

    @@ -206,66 +206,6 @@ function togglePopup(material_id) { TextualInter::write(DL, Emit::tree(), NULL);
    • This code is used in §2 (twice).
    -

    §3. Errors in kit source. Errors like this used to be basically failed assertions, but inevitably people -reported that as a bug (0001596). It was never intended that Inform 6-syntax -hacking should be part of the outside-facing Inform language; but if you leave -power tools just lying around, people will eventually pick them up and wonder -what the red button marked "danger" does. -

    - -
    -text_provenance kit_error_location;
    -int kit_error_location_set = FALSE;
    -int kit_error_count = 0;
    -
    -text_provenance PipelineErrors::get_kit_error_location(void) {
    -    if (kit_error_location_set == FALSE)
    -        PipelineErrors::clear_kit_error_location();
    -    return kit_error_location;
    -}
    -void PipelineErrors::clear_kit_error_location(void) {
    -    PipelineErrors::set_kit_error_location(Provenance::nowhere());
    -}
    -void PipelineErrors::set_kit_error_location(text_provenance where) {
    -    kit_error_location_set = TRUE;
    -    kit_error_location = where;
    -}
    -
    -void PipelineErrors::set_kit_error_location_near_splat(inter_tree_node *P) {
    -    PipelineErrors::clear_kit_error_location();
    -    if ((P) && (Inode::is(P, SPLAT_IST)))
    -        PipelineErrors::set_kit_error_location(SplatInstruction::provenance(P));
    -}
    -
    -void PipelineErrors::kit_error(char *message, text_stream *quote) {
    -    text_provenance at = PipelineErrors::get_kit_error_location();
    -    #ifdef CORE_MODULE
    -    SourceProblems::I6_level_error(message, quote, at);
    -    #endif
    -    #ifndef CORE_MODULE
    -    if (Provenance::is_somewhere(at)) {
    -        filename *F = Provenance::get_filename(at);
    -        TEMPORARY_TEXT(M)
    -        WRITE_TO(M, message, quote);
    -        Errors::at_position_S(M, F, Provenance::get_line(at));
    -        DISCARD_TEXT(M)
    -    } else {
    -        Errors::with_text(message, quote);
    -    }
    -    #endif
    -    kit_error_count++;
    -}
    -
    -void PipelineErrors::reset_errors(void) {
    -    PipelineErrors::clear_kit_error_location();
    -    kit_error_count = 0;
    -}
    -
    -int PipelineErrors::errors_occurred(void) {
    -    if (kit_error_count != 0) return TRUE;
    -    return FALSE;
    -}
    -
    diff --git a/docs/pipeline-module/3-css.html b/docs/pipeline-module/3-css.html index 520fce5ec..91f0d6ed5 100644 --- a/docs/pipeline-module/3-css.html +++ b/docs/pipeline-module/3-css.html @@ -105,18 +105,18 @@ function definition, that is quite a lot of work.
  •  int CompileSplatsStage::run(pipeline_step *step) {
    -    PipelineErrors::reset_errors();
    +    I6Errors::reset_count();
         compile_splats_state css;
         Initialise the CS state2.2;
         inter_tree *I = step->ephemera.tree;
         InterTree::traverse(I, CompileSplatsStage::visitor1, &css, NULL, SPLAT_IST);
         InterTree::traverse(I, CompileSplatsStage::visitor2, &css, NULL, 0);
    -    PipelineErrors::clear_kit_error_location();
    +    I6Errors::clear_current_location();
         int errors_found = CompileSplatsStage::function_bodies(step, &css, I);
         if (errors_found) return FALSE;
         InterTree::traverse(I, CompileSplatsStage::visitor3, &css, NULL, SPLAT_IST);
    -    PipelineErrors::clear_kit_error_location();
    -    if (PipelineErrors::errors_occurred()) return FALSE;
    +    I6Errors::clear_current_location();
    +    if (I6Errors::errors_occurred()) return FALSE;
         return TRUE;
     }
     
    @@ -219,7 +219,7 @@ is being compiled.

    -    PipelineErrors::set_kit_error_location_near_splat(P);
    +    I6Errors::set_current_location_near_splat(P);
         match_results mr = Regexp::create_mr();
         text_stream *raw_identifier = NULL, *value = NULL;
         int proceed = TRUE;
    @@ -600,11 +600,13 @@ first to work out which of the several array formats this is, then the contents
             } else if (Regexp::match(&mr, value, L" *buffer *(%c*?) *")) {
                 conts = mr.exp[0]; as_bytes = TRUE; bounded = TRUE;
             } else if (Regexp::match(&mr, value, L" *string *(%c*?) *")) {
    -            LOG("Identifier = <%S>, Value = <%S>", identifier, value);
    -            PipelineErrors::kit_error("Inform 6 'string' arrays are unsupported", NULL);
    +            I6Errors::issue(
    +                "cannot make array '%S': the 'string' initialiser is unsupported",
    +                identifier);
             } else {
    -            LOG("Identifier = <%S>, Value = <%S>", identifier, value);
    -            PipelineErrors::kit_error("invalid Inform 6 array declaration", NULL);
    +            I6Errors::issue(
    +                "cannot make array '%S': the initial value syntax is unrecognised",
    +                identifier);
             }
         } else {
             conts = value; grammatical = TRUE;
    @@ -670,18 +672,16 @@ see why other kits would, either.
     
     
         text_stream *full_conts = entries;
    -    if (from > to) {
    -        PipelineErrors::kit_error("Inform 6 array contains empty entry", NULL);
    -    } else {
    -        int count_before = no_assimilated_array_entries;
    -        TEMPORARY_TEXT(conts)
    -        for (int j=from; j<=to; j++) PUT_TO(conts, Str::get_at(full_conts, j));
    -        Parse the old-style I6 array entry notation3.1.3.1.4.5.2.2
    -        DISCARD_TEXT(conts)
    -        if (no_assimilated_array_entries > count_before+1)
    -            PipelineErrors::kit_error(
    -                "Multiple entries between ';' markers in a '[ ...; ...; ... ]' array", NULL);
    -    }
    +    int count_before = no_assimilated_array_entries;
    +    TEMPORARY_TEXT(conts)
    +    for (int j=from; j<=to; j++) PUT_TO(conts, Str::get_at(full_conts, j));
    +    Parse the old-style I6 array entry notation3.1.3.1.4.5.2.2
    +    DISCARD_TEXT(conts)
    +    if (no_assimilated_array_entries == count_before)
    +        I6Errors::issue("array '%S' contains empty entry", identifier);
    +    if (no_assimilated_array_entries > count_before+1)
    +        I6Errors::issue(
    +            "multiple entries between ';' markers in array '%S'", identifier);
     

    §3.1.3.1.4.5.2.2. Parse the old-style I6 array entry notation3.1.3.1.4.5.2.2 = @@ -703,17 +703,21 @@ see why other kits would, either.

         if (Str::eq(value, I"+"))
    -        PipelineErrors::kit_error("Inform 6 array declaration using operator '+' "
    -            "(use brackets '(' ... ')' around the size for a calculated array size)", NULL);
    +        I6Errors::issue("array '%S' gives its size using operator '+' "
    +            "(use brackets '(' ... ')' around the size for a calculated array size)",
    +            identifier);
         else if (Str::eq(value, I"-"))
    -        PipelineErrors::kit_error("Inform 6 array declaration using operator '-' "
    -            "(use brackets '(' ... ')' around the size for a calculated array size)", NULL);
    +        I6Errors::issue("array '%S' gives its size using operator '-' "
    +            "(use brackets '(' ... ')' around the size for a calculated array size)",
    +            identifier);
         else if (Str::eq(value, I"*"))
    -        PipelineErrors::kit_error("Inform 6 array declaration using operator '*' "
    -            "(use brackets '(' ... ')' around the size for a calculated array size)", NULL);
    +        I6Errors::issue("array '%S' gives its size using operator '*' "
    +            "(use brackets '(' ... ')' around the size for a calculated array size)",
    +            identifier);
         else if (Str::eq(value, I"/"))
    -        PipelineErrors::kit_error("Inform 6 array declaration using operator '/' "
    -            "(use brackets '(' ... ')' around the size for a calculated array size)", NULL);
    +        I6Errors::issue("array '%S' gives its size using operator '/' "
    +            "(use brackets '(' ... ')' around the size for a calculated array size)",
    +            identifier);
         else {
             inter_pair val = InterValuePairs::undef();
             Assimilate a value3.1.3.1.4.1.1;
    @@ -902,7 +906,7 @@ equating it to a function definition elsewhere.
     
     
         if (no_assimilated_array_entries >= MAX_ASSIMILATED_ARRAY_ENTRIES) {
    -        PipelineErrors::kit_error("excessively long Verb or Extend", NULL);
    +        I6Errors::issue("excessively long Verb or Extend", NULL);
             break;
         }
         val_pile[no_assimilated_array_entries] = val;
    @@ -946,7 +950,7 @@ in this section.
     

    -    PipelineErrors::set_kit_error_location_near_splat(P);
    +    I6Errors::set_current_location_near_splat(P);
         text_stream *raw_identifier = NULL, *local_var_names = NULL, *body = NULL;
         match_results mr = Regexp::create_mr();
         int line_offset = 0;
    @@ -973,8 +977,12 @@ in this section.
             raw_identifier = mr.exp[0]; body = mr.exp[1]; pos = mr.exp_at[1];
         } else if (Regexp::match(&mr, S, L" *%[ *([A-Za-z0-9_`]+) *(%c*?); *(%c*)")) {
             raw_identifier = mr.exp[0]; local_var_names = mr.exp[1]; body = mr.exp[2]; pos = mr.exp_at[2];
    +    } else if (Regexp::match(&mr, S, L" *%[ *(%c+?) *; *(%c*)")) {
    +        I6Errors::issue("invalid Inform 6 routine declaration: '%S'", mr.exp[0]);
         } else {
    -        PipelineErrors::kit_error("invalid Inform 6 routine declaration", NULL);
    +        text_stream *start = Str::duplicate(S);
    +        Str::truncate(start, 50);
    +        I6Errors::issue("invalid Inform 6 routine declaration: '%S'", start);
         }
         for (int i=0; i<pos; i++)
             if (Str::get_at(S, i) == '\n')
    @@ -1017,7 +1025,11 @@ supported only to avoid throwing errors.
             if ((N<0) || (N>15)) N = 1;
             for (int i=1; i<=N; i++) WRITE_TO(local_var_names, "x%d ", i);
             body = Str::duplicate(I"rfalse; ];");
    -    } else PipelineErrors::kit_error("invalid Inform 6 Stub declaration", NULL);
    +    } else {
    +        text_stream *start = Str::duplicate(S);
    +        Str::truncate(start, 50);
    +        I6Errors::issue("invalid #Stub declaration: '%S'", start);
    +    }
     
    • This code is used in §3.2.

    §3.2.3. Function packages have a standardised shape in Inter, and though this is a @@ -1091,14 +1103,14 @@ which contains the actual code. int invalid = FALSE; for (int i=0; i<Str::len(value); i++) { wchar_t c = Str::get_at(value, i); + if ((i == 0) && (Characters::isdigit(c))) invalid = TRUE; if ((c != '_') && (Characters::isalnum(c) == FALSE) && - ((i > 0) || (Characters::isdigit(c) == FALSE))) - invalid = TRUE; + (Characters::isdigit(c) == FALSE)) invalid = TRUE; } if (invalid) { text_stream *err = Str::new(); WRITE_TO(err, "'%S' in function '%S'", value, identifier); - PipelineErrors::kit_error("invalid Inform 6 local variable name: %S", err); + I6Errors::issue("invalid Inform 6 local variable name: %S", err); } inter_symbol *loc_name = InterSymbolsTable::create_with_unique_name(InterPackage::scope(IP), value); @@ -1126,7 +1138,7 @@ which contains the actual code. while ((L>0) && (Characters::is_whitespace(Str::get_at(body, L-1)))) L--; Str::truncate(body, L); inter_ti B = (inter_ti) InterBookmark::baseline(IBM) + 1; - text_provenance prov = PipelineErrors::get_kit_error_location(); + text_provenance prov = I6Errors::get_current_location(); Provenance::advance_line(&prov, line_offset); CompileSplatsStage::function_body(css, IBM, IP, B, body, block_bookmark, identifier, SplatInstruction::namespace(P), prov); @@ -1140,12 +1152,11 @@ which contains the actual code. if (Str::get_last_char(NS) == '+') apply_private = FALSE; if (Str::get_last_char(NS) == '-') apply_private = TRUE; if (apply_private != NOT_APPLICABLE) L--; + TEMPORARY_TEXT(N) if (L > 0) { - TEMPORARY_TEXT(N) for (int i=0; i<L; i++) PUT_TO(N, Str::get_at(NS, i)); LOGIF(INTER_CONNECTORS, "Assign namespace '%S' to $3\n", N, S); InterSymbol::set_namespace(S, N); - DISCARD_TEXT(N) } if (Str::len(A) > 0) { LOGIF(INTER_CONNECTORS, "Trying to apply '%S' to $3\n", A, S); @@ -1153,18 +1164,20 @@ which contains the actual code. if (Str::eq_insensitive(IA->identifier, I"private")) { if ((IA->terms == NULL) || (LinkedLists::len(IA->terms) == 0)) { if (apply_private == TRUE) - PipelineErrors::kit_error("the +private annotation is redundant here", NULL); + I6Errors::issue("the +private annotation is redundant in namespace '%S'", N); apply_private = TRUE; } else { - PipelineErrors::kit_error("the +private annotation does not take any terms", NULL); + I6Errors::issue( + "the +private annotation does not take any terms", NULL); } } else if (Str::eq_insensitive(IA->identifier, I"public")) { if ((IA->terms == NULL) || (LinkedLists::len(IA->terms) == 0)) { if (apply_private == FALSE) - PipelineErrors::kit_error("the +public annotation is redundant here", NULL); + I6Errors::issue("the +public annotation is redundant in namespace '%S'", N); apply_private = FALSE; } else { - PipelineErrors::kit_error("the +public annotation does not take any terms", NULL); + I6Errors::issue( + "the +public annotation does not take any terms", NULL); } } else if (Str::eq_insensitive(IA->identifier, I"replacing")) { text_stream *from = I"_"; int keeping = FALSE; @@ -1176,21 +1189,28 @@ which contains the actual code. } else if (Str::eq_insensitive(term->key, I"_")) { if (Str::eq(term->value, I"keeping")) keeping = TRUE; else { - PipelineErrors::kit_error("expected 'from K' or 'keeping', not '%S'", term->value); + I6Errors::issue( + "expected 'from K' or 'keeping' in '+replacing(...)', not '%S'", + term->value); } } else - PipelineErrors::kit_error( - "the +replacing annotation does not take the term '%S'", term->key); + I6Errors::issue( + "the +replacing annotation does not take the term '%S'", + term->key); } InterSymbol::set_replacement(S, from); if (keeping) SymbolAnnotation::set_b(S, KEEPING_IANN, TRUE); + } else if (Str::eq_insensitive(IA->identifier, I"namespace")) { + I6Errors::issue( + "the annotation '%S' must be followed by a ';'", A); } else { - PipelineErrors::kit_error( - "annotation '%S' not recognised", IA->identifier); + I6Errors::issue( + "the annotation '+%S' is not one of those allowed", IA->identifier); } } } if (apply_private == TRUE) SymbolAnnotation::set_b(S, PRIVATE_IANN, TRUE); + DISCARD_TEXT(N) }

    §5. Plumbing. Some convenient Inter utilities. @@ -1452,7 +1472,7 @@ from command parser grammar: slightly different syntax applies there. if (marker) *marker = FALSE; return InterValuePairs::symbolic(IBM, symb); } else { - PipelineErrors::kit_error("unknown scope routine", S); + I6Errors::issue("can't find any scope routine called '%S'", mr.exp[0]); return InterValuePairs::number(1); } } @@ -1462,7 +1482,7 @@ from command parser grammar: slightly different syntax applies there. if (marker) *marker = TRUE; return InterValuePairs::symbolic(IBM, symb); } else { - PipelineErrors::kit_error("unknown noun routine", S); + I6Errors::issue("can't find any noun routine called '%S'", mr.exp[0]); return InterValuePairs::number(1); } } @@ -1508,12 +1528,12 @@ before they are needed.

         inter_schema *sch =
    -        ParsingSchemas::from_text(S, PipelineErrors::get_kit_error_location());
    +        ParsingSchemas::from_text(S, I6Errors::get_current_location());
         int excess_tokens = FALSE;
         inter_symbol *result_s =
             CompileSplatsStage::compute_r(step, IBM, sch->node_tree, &excess_tokens);
    -    if (result_s == NULL) {
    -        PipelineErrors::kit_error("Inform 6 constant too complex", S);
    +    if (result_s == NULL) {  a precaution, but should no longer happen
    +        I6Errors::issue("Inform 6 constant too complex", S);
             return InterValuePairs::number(1);
         }
         return InterValuePairs::symbolic(IBM, result_s);
    @@ -1789,13 +1809,13 @@ kit CommandParserKit    if (LinkedLists::len(sch->parsing_errors) > 0) {
             schema_parsing_error *err;
             LOOP_OVER_LINKED_LIST(err, schema_parsing_error, sch->parsing_errors) {
    -            PipelineErrors::set_kit_error_location(err->provenance);
    +            I6Errors::set_current_location(err->provenance);
                 TEMPORARY_TEXT(msg)
                 WRITE_TO(msg, "in function '%S': %S", req->identifier, err->message);
    -            PipelineErrors::kit_error("Inform 6 syntax error %S", msg);
    +            I6Errors::issue("Inform 6 syntax error %S", msg);
                 DISCARD_TEXT(msg)
             }
    -        PipelineErrors::clear_kit_error_location();
    +        I6Errors::clear_current_location();
         }
     }
     
    diff --git a/docs/pipeline-module/3-ps.html b/docs/pipeline-module/3-ps.html index b784435b5..8a3e037ef 100644 --- a/docs/pipeline-module/3-ps.html +++ b/docs/pipeline-module/3-ps.html @@ -214,7 +214,7 @@ in K/Sections. &(ParsingStages::receive_command), &(ParsingStages::receive_bplus), &(ParsingStages::line_marker), - &(PipelineErrors::kit_error), + &(I6Errors::issue), step->ephemera.the_kit, &state);
    @@ -407,71 +407,25 @@ state being carried in the docket.
     void ParsingStages::splat(text_stream *R, simple_tangle_docket *docket) {
         if (Str::len(R) > 0) {
    +        rpi_docket_state *state = (rpi_docket_state *) docket->state;
    +        I6Errors::set_current_location(state->provenance);
    +
             TEMPORARY_TEXT(A)
             Find annotation, if any7.1;
             inter_ti I6_dir = 0;
     
             Find directive7.2;
    -        if (I6_dir != WHITESPACE_PLM) {
    -            rpi_docket_state *state = (rpi_docket_state *) docket->state;
    -            inter_bookmark *IBM = state->assimilation_point;
    -            PUT_TO(R, '\n');
    -            filename *F = NULL;
    -            inter_ti lc = 0;
    -            if (Provenance::is_somewhere(state->provenance)) {
    -                F = Provenance::get_filename(state->provenance);
    -                lc = (inter_ti) Provenance::get_line(state->provenance);
    -            }
    -            Produce::guard(SplatInstruction::new(IBM, R, I6_dir, A, state->namespace,
    -                F, lc, (inter_ti) (InterBookmark::baseline(IBM) + 1), NULL));
    -        } else if (A) {
    +        if (I6_dir != WHITESPACE_PLM) Splat the directive7.3
    +        else if (A) {
                 I6_annotation *IA = I6Annotations::parse(A);
                 if ((IA) && (Str::eq_insensitive(IA->identifier, I"namespace"))) {
    -                rpi_docket_state *state = (rpi_docket_state *) docket->state;
    -                Str::clear(state->namespace);
    -                int private = NOT_APPLICABLE;
    -                I6_annotation_term *term;
    -                LOOP_OVER_LINKED_LIST(term, I6_annotation_term, IA->terms) {
    -                    if (Str::eq_insensitive(term->key, I"_")) {
    -                        WRITE_TO(state->namespace, "%S", term->value);
    -                    } else if (Str::eq_insensitive(term->key, I"access")) {
    -                        if (Str::eq_insensitive(term->value, I"private")) private = TRUE;
    -                        else if (Str::eq_insensitive(term->value, I"public")) private = FALSE;
    -                        else PipelineErrors::kit_error(
    -                            "the 'access' must be 'private' or 'public', not '%S'", term->value);
    -                    } else {
    -                        PipelineErrors::kit_error(
    -                            "the +namespace annotation does not take the term '%S'", term->key);
    -                    }
    -                }
    -                int bad_name = FALSE;
    -                for (int i=0; i<Str::len(state->namespace); i++) {
    -                    wchar_t c = Str::get_at(state->namespace, i);
    -                    if (i == 0) {
    -                        if (Characters::isalpha(c) == FALSE) bad_name = TRUE;
    -                    } else {
    -                        if ((Characters::isalnum(c) == FALSE) && (c != '_')) bad_name = TRUE;
    -                    }
    -                }
    -                if (bad_name)
    -                     PipelineErrors::kit_error(
    -                        "a namespace name should begin with a letter and contain "
    -                        "only alphanumeric characters or '_'", NULL);
    -                if (Str::len(state->namespace) == 0)
    -                     PipelineErrors::kit_error(
    -                        "use '+namespace(main);' to return to the global namespace", NULL);
    -                if (Str::eq(state->namespace, I"main")) Str::clear(state->namespace);
    -                if (Str::eq(state->namespace, I"replaced")) {
    -                     PipelineErrors::kit_error(
    -                        "the namespace 'replaced' is reserved, and cannot be used directly", NULL);
    -                    Str::clear(state->namespace);
    -                }
    -                if (private == TRUE) PUT_TO(state->namespace, '-');
    -                if (private == FALSE) PUT_TO(state->namespace, '+');
    +                Respond to a change of namespace7.4;
                 } else {
    -                (*(docket->error_callback))(
    -                    "this annotation seems not to apply to any directive: '%S'", A);
    +                 I6Errors::issue(
    +                    "the annotation '%S' seems not to apply to any directive: "
    +                    "only '+namespace' can do that", A);
                 }
    +            I6Errors::clear_current_location();
             }
             Str::clear(R);
             DISCARD_TEXT(A)
    @@ -484,8 +438,7 @@ state being carried in the docket.
     
         int verdict = I6Annotations::check(R);
         if (verdict == -1) {
    -        (*(docket->error_callback))(
    -            "this Inform 6 annotation is malformed: '%S'", R);
    +        I6Errors::issue("this +annotation is malformed: '%S'", R);
         } else {
             for (int i=0; i<verdict; i++) PUT_TO(A, Str::get_at(R, i));
             Str::trim_white_space(A);
    @@ -506,13 +459,13 @@ the directive type as 0.
         match_results mr = Regexp::create_mr();
         if (Regexp::match(&mr, R, L" *(%[) *(%c*);%c*")) {
             I6_dir = ROUTINE_PLM;
    -    } else if (Regexp::match(&mr, R, L" *(%C+) *(%c*);%c*")) {
    -             if (Str::eq_insensitive(mr.exp[0], I"#ifdef"))      I6_dir = IFDEF_PLM;
    -        else if (Str::eq_insensitive(mr.exp[0], I"#ifndef"))     I6_dir = IFNDEF_PLM;
    -        else if (Str::eq_insensitive(mr.exp[0], I"#iftrue"))     I6_dir = IFTRUE_PLM;
    -        else if (Str::eq_insensitive(mr.exp[0], I"#ifnot"))      I6_dir = IFNOT_PLM;
    -        else if (Str::eq_insensitive(mr.exp[0], I"#endif"))      I6_dir = ENDIF_PLM;
    -        else if (Str::eq_insensitive(mr.exp[0], I"#stub"))       I6_dir = STUB_PLM;
    +    } else if (Regexp::match(&mr, R, L" *#*(%C+) *(%c*);%c*")) {
    +             if (Str::eq_insensitive(mr.exp[0], I"Ifdef"))      I6_dir = IFDEF_PLM;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Ifndef"))     I6_dir = IFNDEF_PLM;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Iftrue"))     I6_dir = IFTRUE_PLM;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Ifnot"))      I6_dir = IFNOT_PLM;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Endif"))      I6_dir = ENDIF_PLM;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Stub"))       I6_dir = STUB_PLM;
             else if (Str::eq_insensitive(mr.exp[0], I"Constant"))    I6_dir = CONSTANT_PLM;
             else if (Str::eq_insensitive(mr.exp[0], I"Global"))      I6_dir = GLOBAL_PLM;
             else if (Str::eq_insensitive(mr.exp[0], I"Array"))       I6_dir = ARRAY_PLM;
    @@ -531,12 +484,114 @@ the directive type as 0.
                     (Str::get(pos) != ';'))
                     I6_dir = MYSTERY_PLM;
         }
    -    if (I6_dir == MYSTERY_PLM)
    -        (*(docket->error_callback))(
    -            "this Inform 6 directive is not supported in kits or '(-' inclusions: '%S'", R);
    +    if (I6_dir == MYSTERY_PLM) {
    +        int known = FALSE;
    +             if (Str::eq_insensitive(mr.exp[0], I"Ifv3"))        known = TRUE;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Ifv5"))        known = TRUE;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Iffalse"))     known = TRUE;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Abbreviate"))  known = TRUE;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Dictionary"))  known = TRUE;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Import"))      known = TRUE;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Link"))        known = TRUE;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Lowstring"))   known = TRUE;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Origsource"))  known = TRUE;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Replace"))     known = TRUE;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Switches"))    known = TRUE;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Trace"))       known = TRUE;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Undef"))       known = TRUE;
    +        else if (Str::eq_insensitive(mr.exp[0], I"Version"))     known = TRUE;
    +        if (known)
    +            I6Errors::issue(
    +                "this Inform 6 directive is not supported in kits or '(-' inclusions: '%S' "
    +                "(only #Ifdef, #Ifndef, #Iftrue, #Ifnot, #Endif, #Stub, Constant, Global, "
    +                "Array, Attribute, Property, Verb, Fake_action, Object, Default are "
    +                "supported)", R);
    +        else
    +            I6Errors::issue("this is not an Inform 6 directive", R);
    +    }
         Regexp::dispose_of(&mr);
     
    • This code is used in §7.
    +

    §7.3. Splat the directive7.3 = +

    + +
    +    inter_bookmark *IBM = state->assimilation_point;
    +    PUT_TO(R, '\n');
    +    filename *F = NULL;
    +    inter_ti lc = 0;
    +    if (Provenance::is_somewhere(state->provenance)) {
    +        F = Provenance::get_filename(state->provenance);
    +        lc = (inter_ti) Provenance::get_line(state->provenance);
    +    }
    +    Produce::guard(SplatInstruction::new(IBM, R, I6_dir, A, state->namespace,
    +        F, lc, (inter_ti) (InterBookmark::baseline(IBM) + 1), NULL));
    +
    +
    • This code is used in §7.
    +

    §7.4. So the following picks up +namespace(Whatever) annotations, which do not +apply to any directive. +

    + +

    Respond to a change of namespace7.4 = +

    + +
    +    Str::clear(state->namespace);
    +    int private = NOT_APPLICABLE;
    +    I6_annotation_term *term;
    +    LOOP_OVER_LINKED_LIST(term, I6_annotation_term, IA->terms) {
    +        if (Str::eq_insensitive(term->key, I"_")) {
    +            WRITE_TO(state->namespace, "%S", term->value);
    +        } else if (Str::eq_insensitive(term->key, I"access")) {
    +            if (Str::eq_insensitive(term->value, I"private")) private = TRUE;
    +            else if (Str::eq_insensitive(term->value, I"public")) private = FALSE;
    +            else I6Errors::issue(
    +                "in a +namespace annotation, the 'access' must be 'private' or "
    +                "'public', not '%S'", term->value);
    +        } else {
    +            I6Errors::issue(
    +                "the +namespace annotation does not take the term '%S'", term->key);
    +        }
    +    }
    +    Vet the new namespace name7.4.1;
    +    if (private == TRUE) PUT_TO(state->namespace, '-');
    +    if (private == FALSE) PUT_TO(state->namespace, '+');
    +
    +
    • This code is used in §7.
    +

    §7.4.1. Vet the new namespace name7.4.1 = +

    + +
    +    int bad_name = FALSE;
    +    for (int i=0; i<Str::len(state->namespace); i++) {
    +        wchar_t c = Str::get_at(state->namespace, i);
    +        if (i == 0) {
    +            if (Characters::isalpha(c) == FALSE) bad_name = TRUE;
    +        } else {
    +            if ((Characters::isalnum(c) == FALSE) && (c != '_')) bad_name = TRUE;
    +        }
    +    }
    +    if (bad_name)
    +         I6Errors::issue(
    +            "the namespace '%S' is not allowed: namespace names should begin "
    +            "with a letter and contain only alphanumeric characters or '_'",
    +            state->namespace);
    +    if (Str::len(state->namespace) == 0)
    +         I6Errors::issue(
    +            "'+namespace()' is not allowed: use '+namespace(main);' to return "
    +            "to the global namespace", NULL);
    +    if (Str::eq(state->namespace, I"main")) Str::clear(state->namespace);
    +    else if (Str::eq_insensitive(state->namespace, I"main"))
    +         I6Errors::issue(
    +            "'+namespace(...)' names are case-sensitive: use 'main', not '%S', "
    +            "to return to the global namespace", state->namespace);
    +    if (Str::eq(state->namespace, I"replaced")) {
    +         I6Errors::issue(
    +            "the namespace 'replaced' is reserved, and cannot be used directly", NULL);
    +        Str::clear(state->namespace);
    +    }
    +
    +
    • This code is used in §7.4.

    §8. And that's it: the result of these stages is just to break the I6T source they found up into individual directives, and put them into the tree as SPLAT_IST nodes. No effort has been made yet to see what directives they are. Subsequent stages diff --git a/docs/pipeline-module/3-rccs.html b/docs/pipeline-module/3-rccs.html index b9ef561a4..4951453b4 100644 --- a/docs/pipeline-module/3-rccs.html +++ b/docs/pipeline-module/3-rccs.html @@ -139,8 +139,9 @@ a nesting depth of about 3, so the following maximum is plenty: state.cc_sp = 0; InterTree::traverse(I, ResolveConditionalsStage::visitor, &state, NULL, 0); if (state.cc_sp != 0) - PipelineErrors::kit_error( + I6Errors::issue( "conditional compilation wrongly structured: not enough #endif", NULL); + I6Errors::clear_current_location(); }

    • The structure rcc_state is private to this section.
    @@ -155,6 +156,7 @@ is written such that this can safely be done.) int compile_this = TRUE; for (int i=0; i<state->cc_sp; i++) if (state->cc_stack[i] == FALSE) compile_this = FALSE; if (Inode::is(P, SPLAT_IST)) { + I6Errors::set_current_location_near_splat(P); text_stream *S = SplatInstruction::splatter(P); switch (SplatInstruction::plm(P)) { case CONSTANT_PLM: @@ -268,17 +270,55 @@ Inform kits use this only to test match_results mr2 = Regexp::create_mr(); if (Regexp::match(&mr2, cond, L" *(%C+?) *== *(%d+) *")) { text_stream *identifier = mr2.exp[0]; - inter_symbol *symbol = - LargeScale::architectural_symbol(I, identifier); + inter_symbol *symbol = LargeScale::architectural_symbol(I, identifier); if (symbol) { int V = InterSymbol::evaluate_to_int(symbol); int W = Str::atoi(mr2.exp[1], 0); if ((V >= 0) && (V == W)) result = TRUE; else result = FALSE; } } + if (Regexp::match(&mr2, cond, L" *(%C+?) *>= *(%d+) *")) { + text_stream *identifier = mr2.exp[0]; + inter_symbol *symbol = LargeScale::architectural_symbol(I, identifier); + if (symbol) { + int V = InterSymbol::evaluate_to_int(symbol); + int W = Str::atoi(mr2.exp[1], 0); + if ((V >= 0) && (V >= W)) result = TRUE; else result = FALSE; + } + } + if (Regexp::match(&mr2, cond, L" *(%C+?) *> *(%d+) *")) { + text_stream *identifier = mr2.exp[0]; + inter_symbol *symbol = LargeScale::architectural_symbol(I, identifier); + if (symbol) { + int V = InterSymbol::evaluate_to_int(symbol); + int W = Str::atoi(mr2.exp[1], 0); + if ((V >= 0) && (V > W)) result = TRUE; else result = FALSE; + } + } + if (Regexp::match(&mr2, cond, L" *(%C+?) *<= *(%d+) *")) { + text_stream *identifier = mr2.exp[0]; + inter_symbol *symbol = LargeScale::architectural_symbol(I, identifier); + if (symbol) { + int V = InterSymbol::evaluate_to_int(symbol); + int W = Str::atoi(mr2.exp[1], 0); + if ((V >= 0) && (V <= W)) result = TRUE; else result = FALSE; + } + } + if (Regexp::match(&mr2, cond, L" *(%C+?) *< *(%d+) *")) { + text_stream *identifier = mr2.exp[0]; + inter_symbol *symbol = LargeScale::architectural_symbol(I, identifier); + if (symbol) { + int V = InterSymbol::evaluate_to_int(symbol); + int W = Str::atoi(mr2.exp[1], 0); + if ((V >= 0) && (V < W)) result = TRUE; else result = FALSE; + } + } if (result == NOT_APPLICABLE) { - PipelineErrors::kit_error( - "conditional compilation is too difficult: #iftrue on %S", cond); + I6Errors::issue( + "conditional compilation is too difficult: #iftrue on '%S' " + "(can only test SYMBOL == DECIMALVALUE, or >, <, >=, <=, where " + "the DECIMALVALUE is non-negative, and even then only for a few " + "symbols, of which 'WORDSIZE' is the most useful)", cond); result = FALSE; } LOGIF(RESOLVING_CONDITIONAL_COMPILATION, "Must decide if %S: ", cond); @@ -295,7 +335,7 @@ Inform kits use this only to test if (state->cc_sp >= MAX_CC_STACK_SIZE) { state->cc_sp = MAX_CC_STACK_SIZE; - PipelineErrors::kit_error( + I6Errors::issue( "conditional compilation wrongly structured: too many nested #ifdef or #iftrue", NULL); } else { state->cc_stack[state->cc_sp++] = result; @@ -308,7 +348,7 @@ Inform kits use this only to test LOGIF(RESOLVING_CONDITIONAL_COMPILATION, "ifnot\n"); if (state->cc_sp == 0) - PipelineErrors::kit_error("conditional compilation wrongly structured: #ifnot at top level", NULL); + I6Errors::issue("conditional compilation wrongly structured: #ifnot at top level", NULL); else state->cc_stack[state->cc_sp-1] = (state->cc_stack[state->cc_sp-1])?FALSE:TRUE; compile_this = FALSE; @@ -323,7 +363,7 @@ Inform kits use this only to test state->cc_sp--; if (state->cc_sp < 0) { state->cc_sp = 0; - PipelineErrors::kit_error("conditional compilation wrongly structured: too many #endif", NULL); + I6Errors::issue("conditional compilation wrongly structured: too many #endif", NULL); } compile_this = FALSE;
    diff --git a/docs/supervisor-module/3-is.html b/docs/supervisor-module/3-is.html index 74f10c4c5..cadbde06e 100644 --- a/docs/supervisor-module/3-is.html +++ b/docs/supervisor-module/3-is.html @@ -154,14 +154,14 @@ should be, so the effect is the same. Architectures::to_codename(A)); #endif linked_list *requirements_list = NEW_LINKED_LIST(attachment_instruction); - PipelineErrors::reset_errors(); + I6Errors::reset_count(); RunningPipelines::run(NULL, SS, NULL, S->associated_copy->location_if_path, requirements_list, S->for_vm, FALSE); PipelineModule::set_architecture_to(saved_A); #ifdef CORE_MODULE SourceProblems::kit_notification(NULL, NULL); #endif - return (PipelineErrors::errors_occurred())?FALSE:TRUE; + return (I6Errors::errors_occurred())?FALSE:TRUE; } else { Errors::nowhere("build-kit pipeline could not be parsed"); return FALSE; diff --git a/inbuild/supervisor-module/Chapter 3/Inter Skill.w b/inbuild/supervisor-module/Chapter 3/Inter Skill.w index 75ffd6e14..f726477eb 100644 --- a/inbuild/supervisor-module/Chapter 3/Inter Skill.w +++ b/inbuild/supervisor-module/Chapter 3/Inter Skill.w @@ -94,14 +94,14 @@ int InterSkill::build_kit_internally(build_skill *skill, build_step *S, Architectures::to_codename(A)); #endif linked_list *requirements_list = NEW_LINKED_LIST(attachment_instruction); - PipelineErrors::reset_errors(); + I6Errors::reset_count(); RunningPipelines::run(NULL, SS, NULL, S->associated_copy->location_if_path, requirements_list, S->for_vm, FALSE); PipelineModule::set_architecture_to(saved_A); #ifdef CORE_MODULE SourceProblems::kit_notification(NULL, NULL); #endif - return (PipelineErrors::errors_occurred())?FALSE:TRUE; + return (I6Errors::errors_occurred())?FALSE:TRUE; } else { Errors::nowhere("build-kit pipeline could not be parsed"); return FALSE; diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt index d94207546..99eb6ebbd 100644 --- a/inform7/Figures/memory-diagnostics.txt +++ b/inform7/Figures/memory-diagnostics.txt @@ -1,9 +1,9 @@ -Total memory consumption was 123104K = 120 MB +Total memory consumption was 123110K = 120 MB ---- was used for 2061850 objects, in 367513 frames in 0 x 800K = 0K = 0 MB: 33.1% inter_tree_node_array 58 x 8192 = 475136 objects, 41813824 bytes - 20.9% text_stream_array 4678 x 100 = 467800 objects, 26346496 bytes + 20.8% text_stream_array 4678 x 100 = 467800 objects, 26346496 bytes 19.7% linked_list 44435 objects, 24883600 bytes 11.2% inter_symbol_array 133 x 1024 = 136192 objects, 14168224 bytes 10.6% inter_error_stash_array 102 x 1024 = 104448 objects, 13372608 bytes @@ -248,7 +248,7 @@ Total memory consumption was 123104K = 120 MB 100.0% was used for memory not allocated for objects: - 57.5% text stream storage 72515996 bytes in 487440 claims + 57.5% text stream storage 72522576 bytes in 487482 claims 4.2% dictionary storage 5315584 bytes in 7623 claims ---- sorting 2720 bytes in 387 claims 5.7% source text 7200000 bytes in 3 claims diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt index 81623043f..fc491527f 100644 --- a/inform7/Figures/timings-diagnostics.txt +++ b/inform7/Figures/timings-diagnostics.txt @@ -1,34 +1,32 @@ 100.0% in inform7 run - 70.8% in compilation to Inter - 50.1% in //Sequence::undertake_queued_tasks// - 4.8% in //MajorNodes::pre_pass// - 3.4% in //MajorNodes::pass_1// - 1.9% in //ImperativeDefinitions::assess_all// - 1.5% in //RTKindConstructors::compile// - 1.5% in //RTPhrasebook::compile_entries// - 1.1% in //Sequence::lint_inter// - 0.5% in //MajorNodes::pass_2// - 0.5% in //Sequence::undertake_queued_tasks// - 0.5% in //Sequence::undertake_queued_tasks// - 0.5% in //World::stage_V// - 0.3% in //ImperativeDefinitions::compile_first_block// - 0.1% in //Closures::compile_closures// - 0.1% in //CompletionModule::compile// - 0.1% in //InferenceSubjects::emit_all// - 0.1% in //RTKindConstructors::compile_permissions// - 0.1% in //Task::make_built_in_kind_constructors// - 0.1% in //World::stages_II_and_III// - 2.3% not specifically accounted for - 25.8% in running Inter pipeline - 9.8% in step 14/15: generate inform6 -> auto.inf - 5.7% in step 5/15: load-binary-kits - 5.2% in step 6/15: make-synoptic-module - 1.7% in step 9/15: make-identifiers-unique - 0.3% in step 12/15: eliminate-redundant-operations - 0.3% in step 4/15: compile-splats - 0.3% in step 7/15: shorten-wiring - 0.3% in step 8/15: detect-indirect-calls - 0.1% in step 11/15: eliminate-redundant-labels - 1.5% not specifically accounted for - 2.8% in supervisor - 0.4% not specifically accounted for + 70.5% in compilation to Inter + 49.7% in //Sequence::undertake_queued_tasks// + 4.9% in //MajorNodes::pre_pass// + 3.5% in //MajorNodes::pass_1// + 1.8% in //ImperativeDefinitions::assess_all// + 1.4% in //RTKindConstructors::compile// + 1.4% in //RTPhrasebook::compile_entries// + 1.0% in //Sequence::lint_inter// + 0.6% in //World::stage_V// + 0.4% in //ImperativeDefinitions::compile_first_block// + 0.4% in //MajorNodes::pass_2// + 0.4% in //Sequence::undertake_queued_tasks// + 0.4% in //Sequence::undertake_queued_tasks// + 0.2% in //CompletionModule::compile// + 0.2% in //InferenceSubjects::emit_all// + 0.2% in //RTKindConstructors::compile_permissions// + 0.2% in //Task::make_built_in_kind_constructors// + 3.3% not specifically accounted for + 25.9% in running Inter pipeline + 9.9% in step 14/15: generate inform6 -> auto.inf + 5.8% in step 5/15: load-binary-kits + 5.3% in step 6/15: make-synoptic-module + 1.8% in step 9/15: make-identifiers-unique + 0.4% in step 12/15: eliminate-redundant-operations + 0.4% in step 4/15: compile-splats + 0.4% in step 7/15: shorten-wiring + 0.2% in step 11/15: eliminate-redundant-labels + 0.2% in step 8/15: detect-indirect-calls + 1.3% not specifically accounted for + 3.1% in supervisor + 0.5% not specifically accounted for diff --git a/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json index bc78e140b..f5770f9ff 100644 --- a/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json +++ b/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "BasicInformExtrasKit", - "version": "10.2.0-beta+6W39" + "version": "10.2.0-beta+6W40" }, "kit-details": { "has-priority": 1 diff --git a/inform7/Internal/Inter/BasicInformKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformKit/kit_metadata.json index eb43216d3..59755728c 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+6W39" + "version": "10.2.0-beta+6W40" }, "needs": [ { "unless": { diff --git a/inform7/Internal/Inter/CommandParserKit/kit_metadata.json b/inform7/Internal/Inter/CommandParserKit/kit_metadata.json index c29ae59af..4eb8549d7 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+6W39" + "version": "10.2.0-beta+6W40" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json b/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json index a531dfefb..e31af07e6 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+6W39" + "version": "10.2.0-beta+6W40" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/WorldModelKit/kit_metadata.json b/inform7/Internal/Inter/WorldModelKit/kit_metadata.json index 4a60ec88b..ff58bd98b 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+6W39" + "version": "10.2.0-beta+6W40" }, "needs": [ { "need": { diff --git a/inform7/Tests/Test Problems/PM_I6SyntaxError.txt b/inform7/Tests/Test Problems/PM_I6SyntaxError.txt new file mode 100644 index 000000000..e0e15fa02 --- /dev/null +++ b/inform7/Tests/Test Problems/PM_I6SyntaxError.txt @@ -0,0 +1,125 @@ +"Disasterama" + +The Scene of the Crime is a room. + +Include (- + +Array supposed string "Banana"; +Array supposed2 struct { 2, 3, 4 }; +Array helium -> ['H' 'e']; +Array lithium -> ['L';; ; 'i']; +Array manganese -> 'M' 'n'; +Array molybdenum -> ['M'; 'b']; +Array sizeplus --> 2 + 7; +Array sizeplusok --> (2 + 7); +Array sizeminus --> 2 - 7; +Array sizeminusok --> (2 - 7); +Array sizetimes --> 2 * 7; +Array sizetimesok --> (2 * 7); +Array sizedivide --> 2 / 7; +Array sizedivideok --> (2 / 7); +Array passwordok -> ['X'; 'y'; 'z'; 'z'; 'y']; +Array password -> 'H' 'e' 'l' 'l' 'o'; + +Hypothetical 10; +Link; + ++namespace(Whatever) [ Banana; ]; + +[ "hello" ]; +#Stub X "banana"; +[ Routine 12 1aa "semolina" _ok ok ok123 OK_456; ]; + ++silly [ Stuff; ]; ++private(23) [ Alpha; ]; ++public(quietly) [ Beta; ]; ++namespace(MammalKit, access whimsical); ++namespace(BirdKit, level 4); ++namespace("This"); ++namespace(10); ++namespace(Main); ++namespace(replaced); ++private(); ++namespace(AmphibianKit, access private); ++private [ FrogMonitor; ]; ++namespace(); ++namespace(ReptileKit, access public); ++public [ CloudLizardMonitor; ]; ++namespace(); ++replacing(sideways) [ This; ]; ++replacing(route=sideways) [ This; ]; + +Verb "grab" * scope=Bogus noun=JustAsBogus; + +Constant STUFF = 200; +#iftrue STUFF == 201; +#endif; +#ifnot; +#endif; +[ Dud1 x y; + x = @mul 12 12 -> y; +]; +[ Dud2; + #ifdef STUFF; +]; +[ Dud3; + #endif; +]; +[ Dud4; + #ifdef; + #endif; +]; +[ Dud4; + #iftrue; + #endif; +]; +[ Dud5 x y; + if (x == @mul 12 12 -> y) print "Ok!"; +]; +[ Dud6; + glk(14, 2, 3); +]; +[ Dud7 x; + x.call(1, 2, 3, 4, 5); +]; +[ Dud8; + print $f05g; +]; +[ Dud9; + print .Label; +]; +[ Dud10; + .1534; +]; +[ Dud11; + print print "Hello"; +]; +[ Dud12; + objectloop(12) print "Yes."; +]; +[ Dud13; + do print "X"; +]; +[ Dud14; + font "Times New Roman"; +]; +[ Dud15 x y; + move x y; +]; +[ Dud16; + for; +]; +[ Dud17; + for (); +]; +[ Dud18; + for (:::::); +]; +[ Dud19; + print 3 + + 17; +]; + +#ifdef Tosh; +[ WontBeCompiled; ]; + +-). diff --git a/inform7/Tests/Test Problems/_Results_Ideal/PM_I6SyntaxError.txt b/inform7/Tests/Test Problems/_Results_Ideal/PM_I6SyntaxError.txt new file mode 100644 index 000000000..a4a8af572 --- /dev/null +++ b/inform7/Tests/Test Problems/_Results_Ideal/PM_I6SyntaxError.txt @@ -0,0 +1,212 @@ +Inform 7 v10.2.0 has started. +I've now read your source text, which is 12 words long. +I've also read Basic Inform by Graham Nelson, which is 7792 words long. +I've also read English Language by Graham Nelson, which is 2330 words long. +I've also read Standard Rules by Graham Nelson, which is 34311 words long. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 24): this is not an + Inform 6 directive. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 25): this Inform 6 + directive is not supported in kits or '(-' inclusions: 'Link;' (only + #Ifdef, #Ifndef, #Iftrue, #Ifnot, #Endif, #Stub, Constant, Global, Array, + Attribute, Property, Verb, Fake_action, Object, Default are supported). +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 36): in a +namespace + annotation, the 'access' must be 'private' or 'public', not 'whimsical'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 37): the +namespace + annotation does not take the term 'level'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 38): this +annotation + is malformed: '+namespace("This");'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 38): this is not an + Inform 6 directive. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 39): the namespace + '10' is not allowed: namespace names should begin with a letter and contain + only alphanumeric characters or '_'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 40): + '+namespace(...)' names are case-sensitive: use 'main', not 'Main', to + return to the global namespace. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 41): the namespace + 'replaced' is reserved, and cannot be used directly. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 42): the annotation + '+private()' seems not to apply to any directive: only '+namespace' can do + that. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 45): '+namespace()' + is not allowed: use '+namespace(main);' to return to the global namespace. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 48): '+namespace()' + is not allowed: use '+namespace(main);' to return to the global namespace. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 55): conditional + compilation is too difficult: #iftrue on 'STUFF==201' (can only test SYMBOL + == DECIMALVALUE, or >, =, +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 57): conditional + compilation wrongly structured: #ifnot at top level. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 58): conditional + compilation wrongly structured: too many #endif. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 123): conditional + compilation wrongly structured: not enough #endif. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 27): the annotation + '+namespace(Whatever)' must be followed by a ';'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 29): invalid Inform 6 + routine declaration: '"hello" ]'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 30): invalid #Stub + declaration: '#Stub X "banana"; '. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 31): invalid Inform 6 + local variable name: '12' in function 'Routine'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 31): invalid Inform 6 + local variable name: '1aa' in function 'Routine'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 31): invalid Inform 6 + local variable name: '"semolina"' in function 'Routine'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 33): the annotation + '+silly' is not one of those allowed. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 34): the +private + annotation does not take any terms. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 35): the +public + annotation does not take any terms. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 44): the +private + annotation is redundant in namespace 'AmphibianKit'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 47): the +public + annotation is redundant in namespace 'ReptileKit'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 49): expected 'from + K' or 'keeping' in '+replacing(...)', not 'sideways'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 50): the +replacing + annotation does not take the term 'route'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 7): cannot make array + 'supposed': the 'string' initialiser is unsupported. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 8): cannot make array + 'supposed2': the initial value syntax is unrecognised. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 9): multiple entries + between ';' markers in array 'helium'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 10): array 'lithium' + contains empty entry. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 10): array 'lithium' + contains empty entry. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 13): array 'sizeplus' + gives its size using operator '+' (use brackets '(' ... ')' around the size + for a calculated array size). +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 15): array + 'sizeminus' gives its size using operator '-' (use brackets '(' ... ')' + around the size for a calculated array size). +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 17): array + 'sizetimes' gives its size using operator '*' (use brackets '(' ... ')' + around the size for a calculated array size). +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 19): array + 'sizedivide' gives its size using operator '/' (use brackets '(' ... ')' + around the size for a calculated array size). +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 52): can't find any + scope routine called 'Bogus'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 52): can't find any + noun routine called 'JustAsBogus'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 60): Inform 6 syntax + error in function 'Dud1': '@mul' was unexpected in expression context. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 63): Inform 6 syntax + error in function 'Dud2': no matching '#endif'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 63): Inform 6 syntax + error in function 'Dud2': misplaced directive. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 66): Inform 6 syntax + error in function 'Dud3': misplaced directive. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 70): Inform 6 syntax + error in function 'Dud4': bare '#ifdef' or '#ifndef'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 70): Inform 6 syntax + error in function 'Dud4': misplaced directive. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 70): Inform 6 syntax + error in function 'Dud4': misplaced directive. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 74): Inform 6 syntax + error in function 'Dud4': malformed '#if...'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 74): Inform 6 syntax + error in function 'Dud4': misplaced directive. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 74): Inform 6 syntax + error in function 'Dud4': misplaced directive. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 77): Inform 6 syntax + error in function 'Dud5': '@mul' was unexpected in expression context. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 80): Inform 6 syntax + error in function 'Dud6': the glk() function is now unsupported. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 83): Inform 6 syntax + error in function 'Dud7': too many arguments for call-message. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 86): Inform 6 syntax + error in function 'Dud8': malformed literal number '$f05g'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 89): Inform 6 syntax + error in function 'Dud9': label in unexpected place. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 92): Inform 6 syntax + error in function 'Dud10': expected label name but found '1534'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 95): Inform 6 syntax + error in function 'Dud11': statement in unexpected place. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 98): Inform 6 syntax + error in function 'Dud12': 'objectloop' without visible variable. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 101): Inform 6 syntax + error in function 'Dud13': do without until. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 104): Inform 6 syntax + error in function 'Dud14': expected 'on' or 'off' after 'font', not 'Times + New Roman'. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 107): Inform 6 syntax + error in function 'Dud15': move without to. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 110): Inform 6 syntax + error in function 'Dud16': 'for' header with too few clauses. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 113): Inform 6 syntax + error in function 'Dud17': 'for' header with too few clauses. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 116): Inform 6 syntax + error in function 'Dud18': 'for' header with too many clauses. +Problem__ PM_I6SyntaxError + >--> Inform 6 syntax error near here (source text, line 119): Inform 6 syntax + error in function 'Dud19': operator '+' used with 1 not 2 operand(s). +Inform 7 has finished. diff --git a/inform7/core-module/Chapter 2/Problems With Source Text.w b/inform7/core-module/Chapter 2/Problems With Source Text.w index ad5a07c01..134a77628 100644 --- a/inform7/core-module/Chapter 2/Problems With Source Text.w +++ b/inform7/core-module/Chapter 2/Problems With Source Text.w @@ -674,7 +674,7 @@ void SourceProblems::I6_level_error(char *message, text_stream *quote, notified_kit_name, notified_architecture_name); trigger_kit_notice = FALSE; } - StandardProblems::handmade_problem(Task::syntax_tree(), _p_(...)); + StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_I6SyntaxError)); Problems::quote_stream(1, M); if (Str::len(kit) > 0) { Problems::quote_stream(2, file); @@ -686,7 +686,7 @@ void SourceProblems::I6_level_error(char *message, text_stream *quote, LOG("%S, line %d:\n", file, line); Problems::problem_quote_file(2, file, line); Problems::issue_problem_segment( - "A mistake was found in the Inform 6-syntax code near here %2: %1."); + "Inform 6 syntax error near here %2: %1."); } else { Problems::issue_problem_segment( "My low-level reader of source code reported a mistake - \"%1\". " diff --git a/inform7/imperative-module/Chapter 4/Compile Schemas.w b/inform7/imperative-module/Chapter 4/Compile Schemas.w index 9d9062146..3e93d38b4 100644 --- a/inform7/imperative-module/Chapter 4/Compile Schemas.w +++ b/inform7/imperative-module/Chapter 4/Compile Schemas.w @@ -82,7 +82,7 @@ void CompileSchemas::sch_emit_inner(i6_schema *sch, pcalc_term *pt1, pcalc_term EmitInterSchemas::emit(Emit::tree(), &VH, sch->compiled, IdentifierFinders::common_names_only(), &CompileSchemas::from_schema_token, NULL, &ems); - InterSchemas::internal_error_on_schema_errors(sch->compiled); + I6Errors::internal_error_on_schema_errors(sch->compiled); } @ So, then, this is called on each token in turn from the original schema. Note diff --git a/inter/building-module/Chapter 2/Emitting Inter Schemas.w b/inter/building-module/Chapter 2/Emitting Inter Schemas.w index 9c09b114d..d1ba33df2 100644 --- a/inter/building-module/Chapter 2/Emitting Inter Schemas.w +++ b/inter/building-module/Chapter 2/Emitting Inter Schemas.w @@ -164,7 +164,7 @@ all conditionals are resolved. at = at->next_node; } if (endif_node == NULL) { - InterSchemas::throw_error(dir_node, I"no matching '#endif'"); + I6Errors::issue_at_node(dir_node, I"no matching '#endif'"); return FALSE; } @@ -177,6 +177,10 @@ all conditionals are resolved. @ = if ((dir_node->dir_clarifier == IFDEF_I6RW) || (dir_node->dir_clarifier == IFNDEF_I6RW)) { + if (dir_node->child_node == NULL) { + I6Errors::issue_at_node(dir_node, I"bare '#ifdef' or '#ifndef'"); + return FALSE; + } symbol_to_check = dir_node->child_node->expression_tokens->material; } else { inter_schema_node *to_eval = dir_node->child_node; @@ -184,7 +188,7 @@ all conditionals are resolved. to_eval = to_eval->child_node; if ((to_eval == NULL) || (to_eval->child_node == NULL) || (to_eval->child_node->expression_tokens == NULL)) { - InterSchemas::throw_error(dir_node, I"malformed '#if...'"); + I6Errors::issue_at_node(dir_node, I"malformed '#if...'"); return FALSE; } symbol_to_check = to_eval->child_node->expression_tokens->material; @@ -328,8 +332,8 @@ void EmitInterSchemas::emit_recursively(inter_tree *I, inter_schema_node *node, Note that recursion in |VAL_PRIM_CAT| mode evaluates |x|, |y| and |z|. @ = - if (prim_cat != CODE_PRIM_CAT) { - InterSchemas::throw_error(node, I"assembly language unexpected here"); + if (prim_cat != CODE_PRIM_CAT) { /* should never in fact happen */ + I6Errors::issue_at_node(node, I"assembly language unexpected here"); return; } inter_schema_node *at = node->child_node; @@ -341,7 +345,7 @@ Note that recursion in |VAL_PRIM_CAT| mode evaluates |x|, |y| and |z|. opcode_text = tok->material; } if (opcode_text == NULL) { /* should never in fact happen */ - InterSchemas::throw_error(node, I"assembly language malformed here"); + I6Errors::issue_at_node(node, I"assembly language malformed here"); return; } Produce::inv_assembly(I, opcode_text); @@ -422,7 +426,7 @@ changed back again very soon after. } else if (Str::eq(tok->material, I"indirect")) { at = at->next_node; } else if (Str::eq(tok->material, I"glk")) { - InterSchemas::throw_error(node, I"the glk() function is now unsupported"); + I6Errors::issue_at_node(node, I"the glk() function is now unsupported"); return; } else { to_call = IdentifierFinders::find_token(I, tok, finder); @@ -460,7 +464,7 @@ somewhere (in fact, always in a property value). int argc = 0; for (inter_schema_node *n = node->child_node; n; n=n->next_node) argc++; if (argc > 4) { - InterSchemas::throw_error(node, I"too many arguments for call-message"); + I6Errors::issue_at_node(node, I"too many arguments for call-message"); return; } inter_ti BIP = Primitives::BIP_for_indirect_call_returning_value(argc-1); @@ -477,7 +481,7 @@ more natural |{ ... }|. @ = if (prim_cat != CODE_PRIM_CAT) { - InterSchemas::throw_error(node, I"unexpected '{ ... }' code block"); + I6Errors::issue_at_node(node, I"unexpected '{ ... }' code block"); return; } if (node->unopened == FALSE) { @@ -496,7 +500,7 @@ other Inform 6 directives are not valid inside function bodies, which is the only part of I6 syntax covered by schemas. Therefore: @ = - InterSchemas::throw_error(node, I"misplaced directive"); + I6Errors::issue_at_node(node, I"misplaced directive"); return; @ An |EVAL_ISNT| node can have any number of children, they are sequentially @@ -504,7 +508,7 @@ evaluated for their potential side-effects, but only the last produces a value. @ = if ((prim_cat != CODE_PRIM_CAT) && (prim_cat != VAL_PRIM_CAT)){ - InterSchemas::throw_error(node, I"expression in unexpected place"); + I6Errors::issue_at_node(node, I"expression in unexpected place"); return; } if (node->child_node == NULL) Produce::val(I, K_value, InterValuePairs::number(1)); @@ -610,7 +614,7 @@ parsing the schema.) if (InterValuePairs::is_undef(val)) { TEMPORARY_TEXT(msg) WRITE_TO(msg, "malformed literal number '%S'", t->material); - InterSchemas::throw_error(node, msg); + I6Errors::issue_at_node(node, msg); DISCARD_TEXT(msg) return; } @@ -642,7 +646,7 @@ parsing the schema.) default: { TEMPORARY_TEXT(msg) WRITE_TO(msg, "'%S' was unexpected in expression context", t->material); - InterSchemas::throw_error(node, msg); + I6Errors::issue_at_node(node, msg); DISCARD_TEXT(msg) break; } @@ -669,7 +673,7 @@ For example, the schema |.{-label:Say}{-counter-up:Say};| results in: @ = if (prim_cat != CODE_PRIM_CAT) { - InterSchemas::throw_error(node, I"label in unexpected place"); + I6Errors::issue_at_node(node, I"label in unexpected place"); return; } TEMPORARY_TEXT(L) @@ -688,7 +692,7 @@ For example, the schema |.{-label:Say}{-counter-up:Say};| results in: } else { TEMPORARY_TEXT(msg) WRITE_TO(msg, "expected label name but found '%S'", t->material); - InterSchemas::throw_error(node, msg); + I6Errors::issue_at_node(node, msg); DISCARD_TEXT(msg) return; } @@ -778,7 +782,7 @@ on others. @ = if (prim_cat != CODE_PRIM_CAT) { - InterSchemas::throw_error(node, I"statement in unexpected place"); + I6Errors::issue_at_node(node, I"statement in unexpected place"); return; } if (node->isn_clarifier == CASE_BIP) Produce::set_level_to_current_code_block_plus(I, 2); @@ -848,7 +852,7 @@ these possibilities: EIS_RECURSE(var_node, REF_PRIM_CAT); EIS_RECURSE(cl_node, VAL_PRIM_CAT); } else { - InterSchemas::throw_error(node, I"malformed 'objectloop' header"); + I6Errors::issue_at_node(node, I"malformed 'objectloop' header"); return; } } else { @@ -861,7 +865,7 @@ these possibilities: EIS_RECURSE(var_node, REF_PRIM_CAT); Produce::val_symbol(I, K_value, IdentifierFinders::find(I, I"Object", finder)); } else { - InterSchemas::throw_error(node, I"'objectloop' without visible variable"); + I6Errors::issue_at_node(node, I"'objectloop' without visible variable"); return; } } diff --git a/inter/building-module/Chapter 2/Inform 6 Syntax Errors.w b/inter/building-module/Chapter 2/Inform 6 Syntax Errors.w new file mode 100644 index 000000000..679d93f27 --- /dev/null +++ b/inter/building-module/Chapter 2/Inform 6 Syntax Errors.w @@ -0,0 +1,128 @@ +[I6Errors::] Inform 6 Syntax Errors. + +To issue problem messages when parsing malformed I6-syntax code. + +@ Errors like these used to be basically failed assertions, but inevitably people +reported that as a bug (Mantis 0001596). It was never intended that Inform 6-syntax +hacking should be part of the outside-facing Inform language; but if you leave +power tools just lying around, people will eventually pick them up and wonder +what the red button marked "danger" does. + +Note that |i6_syntax_error_location| is initially uninitialised and thus has +undefined contents, so we take care to blank it out if it is read before being +written to for the first time. + += +text_provenance i6_syntax_error_location; +int i6_syntax_error_location_set = FALSE; + +text_provenance I6Errors::get_current_location(void) { + if (i6_syntax_error_location_set == FALSE) + I6Errors::clear_current_location(); + return i6_syntax_error_location; +} +void I6Errors::clear_current_location(void) { + I6Errors::set_current_location(Provenance::nowhere()); +} +void I6Errors::set_current_location(text_provenance where) { + i6_syntax_error_location_set = TRUE; + i6_syntax_error_location = where; +} + +void I6Errors::set_current_location_near_splat(inter_tree_node *P) { + I6Errors::clear_current_location(); + if ((P) && (Inode::is(P, SPLAT_IST))) + I6Errors::set_current_location(SplatInstruction::provenance(P)); +} + +@ The issuing mechanism, or rather, the mechanism used if the main Inform +compiler doesn't gazump us (in order to provide something better-looking in +the GUI apps). + += +int i6_syntax_error_count = 0; + +void I6Errors::issue(char *message, text_stream *quote) { + text_provenance at = I6Errors::get_current_location(); + #ifdef CORE_MODULE + SourceProblems::I6_level_error(message, quote, at); + #endif + #ifndef CORE_MODULE + if (Provenance::is_somewhere(at)) { + filename *F = Provenance::get_filename(at); + TEMPORARY_TEXT(M) + WRITE_TO(M, message, quote); + Errors::at_position_S(M, F, Provenance::get_line(at)); + DISCARD_TEXT(M) + } else { + Errors::with_text(message, quote); + } + #endif + i6_syntax_error_count++; +} + +void I6Errors::reset_count(void) { + I6Errors::clear_current_location(); + i6_syntax_error_count = 0; +} + +int I6Errors::errors_occurred(void) { + if (i6_syntax_error_count != 0) return TRUE; + return FALSE; +} + +@ The functions below are for errors detected when parsing text into schemas, or +when emitting code from them. + +Note that the |parsing_errors| field of a schema is null until the first error +is detected -- which, of course, it usually isn't. It holds a linked list of these: + += +typedef struct schema_parsing_error { + struct text_stream *message; + struct text_provenance provenance; + CLASS_DEFINITION +} schema_parsing_error; + +@ = +void I6Errors::issue_at_node(inter_schema_node *at, text_stream *message) { + if (at->parent_schema->parsing_errors == NULL) + at->parent_schema->parsing_errors = NEW_LINKED_LIST(schema_parsing_error); + schema_parsing_error *err = CREATE(schema_parsing_error); + err->message = Str::duplicate(message); + if (at) { + if (Provenance::is_somewhere(at->provenance)) err->provenance = at->provenance; + else if (at->parent_schema) err->provenance = at->parent_schema->provenance; + else err->provenance = Provenance::nowhere(); + } else { + err->provenance = Provenance::nowhere(); + } + ADD_TO_LINKED_LIST(err, schema_parsing_error, at->parent_schema->parsing_errors); + LOG("Schema error: %S\n", message); + if ((at->parent_schema) && (Provenance::is_somewhere(at->parent_schema->provenance))) + LOG("Schema provenance %f, line %d\n", + Provenance::get_filename(at->parent_schema->provenance), + Provenance::get_line(at->parent_schema->provenance)); + LOG("$1\n", at->parent_schema); +} + +@ That function of course caches schema errors for playback later: well, here's +the later. Unless the main Inform compiler takes over from us, the result will +be drastic, halting what is presumably the |inter| tool: + += +void I6Errors::internal_error_on_schema_errors(inter_schema *sch) { + if (LinkedLists::len(sch->parsing_errors) > 0) { + #ifdef CORE_MODULE + SourceProblems::inter_schema_errors(sch); + #endif + #ifndef CORE_MODULE + WRITE_TO(STDERR, "Parsing error(s) in the internal schema '%S':\n", + sch->converted_from); + schema_parsing_error *err; + LOOP_OVER_LINKED_LIST(err, schema_parsing_error, sch->parsing_errors) + WRITE_TO(STDERR, "- %S\n", err->message); + exit(1); + #endif + } +} diff --git a/inter/building-module/Chapter 2/Inter Schemas.w b/inter/building-module/Chapter 2/Inter Schemas.w index cc8aceabc..6211c0c68 100644 --- a/inter/building-module/Chapter 2/Inter Schemas.w +++ b/inter/building-module/Chapter 2/Inter Schemas.w @@ -646,59 +646,3 @@ text_stream *InterSchemas::lint_isn(inter_schema_node *isn, int depth) { } return NULL; } - -@h Errors. -Errors can be detected both when parsing text into schemas, and also when emitting -code from them. In either case, the following is used to attach error message(s) -to the schema itself. - -Note that the |parsing_errors| field is null until the first error is detected -- -which, of course, it usually isn't. - -= -typedef struct schema_parsing_error { - struct text_stream *message; - struct text_provenance provenance; - CLASS_DEFINITION -} schema_parsing_error; - -@ = -void InterSchemas::throw_error(inter_schema_node *at, text_stream *message) { - if (at->parent_schema->parsing_errors == NULL) - at->parent_schema->parsing_errors = NEW_LINKED_LIST(schema_parsing_error); - schema_parsing_error *err = CREATE(schema_parsing_error); - err->message = Str::duplicate(message); - if (at) { - if (Provenance::is_somewhere(at->provenance)) err->provenance = at->provenance; - else if (at->parent_schema) err->provenance = at->parent_schema->provenance; - else err->provenance = Provenance::nowhere(); - } else { - err->provenance = Provenance::nowhere(); - } - ADD_TO_LINKED_LIST(err, schema_parsing_error, at->parent_schema->parsing_errors); - LOG("Schema error: %S\n", message); - if ((at->parent_schema) && (Provenance::is_somewhere(at->parent_schema->provenance))) - LOG("Schema provenance %f, line %d\n", - Provenance::get_filename(at->parent_schema->provenance), - Provenance::get_line(at->parent_schema->provenance)); - LOG("$1\n", at->parent_schema); -} - -@ And this is an especially drastic way to deal with such errors: - -= -void InterSchemas::internal_error_on_schema_errors(inter_schema *sch) { - if (LinkedLists::len(sch->parsing_errors) > 0) { - #ifdef CORE_MODULE - SourceProblems::inter_schema_errors(sch); - #endif - #ifndef CORE_MODULE - WRITE_TO(STDERR, "Parsing error(s) in the internal schema '%S':\n", - sch->converted_from); - schema_parsing_error *err; - LOOP_OVER_LINKED_LIST(err, schema_parsing_error, sch->parsing_errors) - WRITE_TO(STDERR, "- %S\n", err->message); - internal_error("malformed schema"); - #endif - } -} diff --git a/inter/building-module/Chapter 2/Parsing Inter Schemas.w b/inter/building-module/Chapter 2/Parsing Inter Schemas.w index df79b2dbb..b9a61c83d 100644 --- a/inter/building-module/Chapter 2/Parsing Inter Schemas.w +++ b/inter/building-module/Chapter 2/Parsing Inter Schemas.w @@ -50,7 +50,7 @@ inter_schema *ParsingSchemas::from_i6s(text_stream *from, Dictionaries::create(i6s_inter_schema_cache, from); Dictionaries::write_value(i6s_inter_schema_cache, from, (void *) result); - InterSchemas::internal_error_on_schema_errors(result); + I6Errors::internal_error_on_schema_errors(result); return result; } diff --git a/inter/building-module/Chapter 2/Ramification.w b/inter/building-module/Chapter 2/Ramification.w index 8565a0470..d81f1b7e8 100644 --- a/inter/building-module/Chapter 2/Ramification.w +++ b/inter/building-module/Chapter 2/Ramification.w @@ -828,7 +828,7 @@ nodes, which we want to fold into just one: operand1 = InterSchemas::second_dark_token(until_node); cons->next_node = until_node->next_node; } else { - InterSchemas::throw_error(cons, I"do without until"); + I6Errors::issue_at_node(cons, I"do without until"); return FALSE; } @@ -841,7 +841,7 @@ nodes, which we want to fold into just one: TEMPORARY_TEXT(msg) WRITE_TO(msg, "expected 'on' or 'off' after 'font', not '%S'", n->material); - InterSchemas::throw_error(cons, msg); + I6Errors::issue_at_node(cons, msg); DISCARD_TEXT(msg) return FALSE; } @@ -891,7 +891,7 @@ clause at all. We split these possibilities into two different statement nodes. to = InterSchemas::next_dark_token(to); } if (to == NULL) { - InterSchemas::throw_error(cons, I"move without to"); + I6Errors::issue_at_node(cons, I"move without to"); return FALSE; } operand2 = InterSchemas::next_dark_token(to); @@ -1239,7 +1239,7 @@ int Ramification::break_for_statements(inter_schema_node *par, inter_schema_node (isn->node_marked == FALSE)) { inter_schema_node *predicates = isn->child_node; if ((predicates == NULL) || (predicates->isn_type != EXPRESSION_ISNT)) { - InterSchemas::throw_error(isn, I"malformed 'for' loop"); + I6Errors::issue_at_node(isn, I"malformed 'for' loop"); return FALSE; } inter_schema_token *n = predicates->expression_tokens; @@ -1267,7 +1267,7 @@ int Ramification::break_for_statements(inter_schema_node *par, inter_schema_node n = n->next; } if (cw != 3) { - InterSchemas::throw_error(isn, I"'for' header with too few clauses"); + I6Errors::issue_at_node(isn, I"'for' header with too few clauses"); return FALSE; } for (int i=0; i<3; i++) { @@ -1308,7 +1308,7 @@ int Ramification::break_for_statements(inter_schema_node *par, inter_schema_node @ = if (cw >= 3) { - InterSchemas::throw_error(isn, I"'for' header with too many clauses"); + I6Errors::issue_at_node(isn, I"'for' header with too many clauses"); return FALSE; } if (from[cw] == NULL) to[cw] = NULL; @@ -1336,7 +1336,7 @@ int Ramification::add_missing_bodies(inter_schema_node *par, inter_schema_node * int actual = 0; for (inter_schema_node *ch = isn->child_node; ch; ch=ch->next_node) actual++; if ((actual < req-1) || (actual > req)) { - InterSchemas::throw_error(isn, I"malformed statement"); + I6Errors::issue_at_node(isn, I"malformed statement"); return FALSE; } if (actual == req-1) { @@ -1718,7 +1718,7 @@ operation |a.b|. WRITE_TO(msg, "operator '%S' used with %d not %d operand(s)", I6Operators::I6_notation_for(isn->isn_clarifier), a, I6Operators::arity(isn->isn_clarifier)); - InterSchemas::throw_error(isn, msg); + I6Errors::issue_at_node(isn, msg); DISCARD_TEXT(msg) return FALSE; } @@ -1894,32 +1894,32 @@ int Ramification::sanity_check(inter_schema_node *par, inter_schema_node *isn) { for (inter_schema_token *t = isn->expression_tokens; t; t=t->next) { switch (t->ist_type) { case OPCODE_ISTT: asm = TRUE; break; - case RAW_ISTT: InterSchemas::throw_error(isn, I"malformed expression"); break; - case OPEN_BRACE_ISTT: InterSchemas::throw_error(isn, I"unexpected '{'"); break; - case CLOSE_BRACE_ISTT: InterSchemas::throw_error(isn, I"unexpected '}'"); break; - case OPEN_ROUND_ISTT: InterSchemas::throw_error(isn, I"unexpected '('"); break; - case CLOSE_ROUND_ISTT: InterSchemas::throw_error(isn, I"unexpected ')'"); break; - case COMMA_ISTT: InterSchemas::throw_error(isn, I"unexpected ','"); break; - case DIVIDER_ISTT: InterSchemas::throw_error(isn, I"malformed expression"); break; + case RAW_ISTT: I6Errors::issue_at_node(isn, I"malformed expression"); break; + case OPEN_BRACE_ISTT: I6Errors::issue_at_node(isn, I"unexpected '{'"); break; + case CLOSE_BRACE_ISTT: I6Errors::issue_at_node(isn, I"unexpected '}'"); break; + case OPEN_ROUND_ISTT: I6Errors::issue_at_node(isn, I"unexpected '('"); break; + case CLOSE_ROUND_ISTT: I6Errors::issue_at_node(isn, I"unexpected ')'"); break; + case COMMA_ISTT: I6Errors::issue_at_node(isn, I"unexpected ','"); break; + case DIVIDER_ISTT: I6Errors::issue_at_node(isn, I"malformed expression"); break; case RESERVED_ISTT: { TEMPORARY_TEXT(msg) WRITE_TO(msg, "unexpected use of reserved word '%S'", t->material); - InterSchemas::throw_error(isn, msg); + I6Errors::issue_at_node(isn, msg); DISCARD_TEXT(msg) break; } - case COLON_ISTT: InterSchemas::throw_error(isn, I"unexpected ':'"); break; - case DCOLON_ISTT: InterSchemas::throw_error(isn, + case COLON_ISTT: I6Errors::issue_at_node(isn, I"unexpected ':'"); break; + case DCOLON_ISTT: I6Errors::issue_at_node(isn, I"the Inform 6 '::' operator is unsupported"); break; - case OPERATOR_ISTT: InterSchemas::throw_error(isn, I"unexpected operator"); break; + case OPERATOR_ISTT: I6Errors::issue_at_node(isn, I"unexpected operator"); break; } if ((t->ist_type == NUMBER_ISTT) && (t->next) && (t->next->ist_type == NUMBER_ISTT) && (asm == FALSE)) - InterSchemas::throw_error(isn, I"two consecutive numbers"); + I6Errors::issue_at_node(isn, I"two consecutive numbers"); } - if (isn->child_node) InterSchemas::throw_error(isn, I"malformed expression"); + if (isn->child_node) I6Errors::issue_at_node(isn, I"malformed expression"); } else { - if (isn->expression_tokens) InterSchemas::throw_error(isn, I"syntax error"); + if (isn->expression_tokens) I6Errors::issue_at_node(isn, I"syntax error"); } Ramification::sanity_check(isn, isn->child_node); } diff --git a/inter/building-module/Chapter 2/Tokenisation.w b/inter/building-module/Chapter 2/Tokenisation.w index b0b0a547e..329f375b9 100644 --- a/inter/building-module/Chapter 2/Tokenisation.w +++ b/inter/building-module/Chapter 2/Tokenisation.w @@ -409,7 +409,7 @@ of modifiers are allowed. See //calculus: Compilation Schemas//. wchar_t c = Str::get_at(from, ++at); int iss_bitmap = 0; switch (c) { - case '!': InterSchemas::throw_error(sch->node_tree, + case '!': I6Errors::issue_at_node(sch->node_tree, I"the '*!' schema notation has been abolished"); break; case '%': iss_bitmap = iss_bitmap | LVALUE_CONTEXT_ISSBM; c = Str::get_at(from, ++at); break; @@ -454,7 +454,7 @@ of modifiers are allowed. See //calculus: Compilation Schemas//. preceding_token = t; pos = at; } else if (c == '-') { - InterSchemas::throw_error(sch->node_tree, + I6Errors::issue_at_node(sch->node_tree, I"the '*-' schema notation has been abolished"); } else if (c == '*') { int c = '*'; @; diff --git a/inter/building-module/Contents.w b/inter/building-module/Contents.w index 892851cc4..e14b427fc 100644 --- a/inter/building-module/Contents.w +++ b/inter/building-module/Contents.w @@ -26,6 +26,7 @@ Chapter 2: Blueprints Emitting Inter Schemas Identifier Finders Inform 6 Annotations + Inform 6 Syntax Errors Chapter 3: Masonry Produce diff --git a/inter/bytecode-module/Chapter 3/Inter Value Pairs.w b/inter/bytecode-module/Chapter 3/Inter Value Pairs.w index 7899fb4ae..4394db206 100644 --- a/inter/bytecode-module/Chapter 3/Inter Value Pairs.w +++ b/inter/bytecode-module/Chapter 3/Inter Value Pairs.w @@ -81,7 +81,7 @@ inter_pair InterValuePairs::number_from_I6_notation(text_stream *S) { else if ((c >= 'A') && (c <= 'Z')) d = c-'A'+10; else if ((c >= '0') && (c <= '9')) d = c-'0'; else return InterValuePairs::undef(); - if (d > base) return InterValuePairs::undef(); + if (d >= base) return InterValuePairs::undef(); N = base*N + (long long int) d; if (pos.index > 34) return InterValuePairs::undef(); } diff --git a/inter/pipeline-module/Chapter 2/Pipeline Errors.w b/inter/pipeline-module/Chapter 2/Pipeline Errors.w index 97cd1002d..b095cc148 100644 --- a/inter/pipeline-module/Chapter 2/Pipeline Errors.w +++ b/inter/pipeline-module/Chapter 2/Pipeline Errors.w @@ -130,63 +130,3 @@ void PipelineErrors::error_with(pipeline_step *step, char *erm, text_stream *quo do_not_locate_problems = FALSE; if (Log::aspect_switched_on(INTER_DA)) TextualInter::write(DL, Emit::tree(), NULL); - -@h Errors in kit source. -Errors like this used to be basically failed assertions, but inevitably people -reported that as a bug (0001596). It was never intended that Inform 6-syntax -hacking should be part of the outside-facing Inform language; but if you leave -power tools just lying around, people will eventually pick them up and wonder -what the red button marked "danger" does. - -= -text_provenance kit_error_location; -int kit_error_location_set = FALSE; -int kit_error_count = 0; - -text_provenance PipelineErrors::get_kit_error_location(void) { - if (kit_error_location_set == FALSE) - PipelineErrors::clear_kit_error_location(); - return kit_error_location; -} -void PipelineErrors::clear_kit_error_location(void) { - PipelineErrors::set_kit_error_location(Provenance::nowhere()); -} -void PipelineErrors::set_kit_error_location(text_provenance where) { - kit_error_location_set = TRUE; - kit_error_location = where; -} - -void PipelineErrors::set_kit_error_location_near_splat(inter_tree_node *P) { - PipelineErrors::clear_kit_error_location(); - if ((P) && (Inode::is(P, SPLAT_IST))) - PipelineErrors::set_kit_error_location(SplatInstruction::provenance(P)); -} - -void PipelineErrors::kit_error(char *message, text_stream *quote) { - text_provenance at = PipelineErrors::get_kit_error_location(); - #ifdef CORE_MODULE - SourceProblems::I6_level_error(message, quote, at); - #endif - #ifndef CORE_MODULE - if (Provenance::is_somewhere(at)) { - filename *F = Provenance::get_filename(at); - TEMPORARY_TEXT(M) - WRITE_TO(M, message, quote); - Errors::at_position_S(M, F, Provenance::get_line(at)); - DISCARD_TEXT(M) - } else { - Errors::with_text(message, quote); - } - #endif - kit_error_count++; -} - -void PipelineErrors::reset_errors(void) { - PipelineErrors::clear_kit_error_location(); - kit_error_count = 0; -} - -int PipelineErrors::errors_occurred(void) { - if (kit_error_count != 0) return TRUE; - return FALSE; -} diff --git a/inter/pipeline-module/Chapter 3/Compile Splats Stage.w b/inter/pipeline-module/Chapter 3/Compile Splats Stage.w index 68e2faee4..b8ae46974 100644 --- a/inter/pipeline-module/Chapter 3/Compile Splats Stage.w +++ b/inter/pipeline-module/Chapter 3/Compile Splats Stage.w @@ -30,18 +30,18 @@ void CompileSplatsStage::create_pipeline_stage(void) { = int CompileSplatsStage::run(pipeline_step *step) { - PipelineErrors::reset_errors(); + I6Errors::reset_count(); compile_splats_state css; @; inter_tree *I = step->ephemera.tree; InterTree::traverse(I, CompileSplatsStage::visitor1, &css, NULL, SPLAT_IST); InterTree::traverse(I, CompileSplatsStage::visitor2, &css, NULL, 0); - PipelineErrors::clear_kit_error_location(); + I6Errors::clear_current_location(); int errors_found = CompileSplatsStage::function_bodies(step, &css, I); if (errors_found) return FALSE; InterTree::traverse(I, CompileSplatsStage::visitor3, &css, NULL, SPLAT_IST); - PipelineErrors::clear_kit_error_location(); - if (PipelineErrors::errors_occurred()) return FALSE; + I6Errors::clear_current_location(); + if (I6Errors::errors_occurred()) return FALSE; return TRUE; } @@ -136,7 +136,7 @@ void CompileSplatsStage::visitor3(inter_tree *I, inter_tree_node *P, void *state @h How definitions are assimilated. @ = - PipelineErrors::set_kit_error_location_near_splat(P); + I6Errors::set_current_location_near_splat(P); match_results mr = Regexp::create_mr(); text_stream *raw_identifier = NULL, *value = NULL; int proceed = TRUE; @@ -435,11 +435,13 @@ first to work out which of the several array formats this is, then the contents } else if (Regexp::match(&mr, value, L" *buffer *(%c*?) *")) { conts = mr.exp[0]; as_bytes = TRUE; bounded = TRUE; } else if (Regexp::match(&mr, value, L" *string *(%c*?) *")) { - LOG("Identifier = <%S>, Value = <%S>", identifier, value); - PipelineErrors::kit_error("Inform 6 'string' arrays are unsupported", NULL); + I6Errors::issue( + "cannot make array '%S': the 'string' initialiser is unsupported", + identifier); } else { - LOG("Identifier = <%S>, Value = <%S>", identifier, value); - PipelineErrors::kit_error("invalid Inform 6 array declaration", NULL); + I6Errors::issue( + "cannot make array '%S': the initial value syntax is unrecognised", + identifier); } } else { conts = value; grammatical = TRUE; @@ -489,18 +491,16 @@ see why other kits would, either. @ = text_stream *full_conts = entries; - if (from > to) { - PipelineErrors::kit_error("Inform 6 array contains empty entry", NULL); - } else { - int count_before = no_assimilated_array_entries; - TEMPORARY_TEXT(conts) - for (int j=from; j<=to; j++) PUT_TO(conts, Str::get_at(full_conts, j)); - @ - DISCARD_TEXT(conts) - if (no_assimilated_array_entries > count_before+1) - PipelineErrors::kit_error( - "Multiple entries between ';' markers in a '[ ...; ...; ... ]' array", NULL); - } + int count_before = no_assimilated_array_entries; + TEMPORARY_TEXT(conts) + for (int j=from; j<=to; j++) PUT_TO(conts, Str::get_at(full_conts, j)); + @ + DISCARD_TEXT(conts) + if (no_assimilated_array_entries == count_before) + I6Errors::issue("array '%S' contains empty entry", identifier); + if (no_assimilated_array_entries > count_before+1) + I6Errors::issue( + "multiple entries between ';' markers in array '%S'", identifier); @ = string_position spos = Str::start(conts); @@ -514,17 +514,21 @@ see why other kits would, either. @ = if (Str::eq(value, I"+")) - PipelineErrors::kit_error("Inform 6 array declaration using operator '+' " - "(use brackets '(' ... ')' around the size for a calculated array size)", NULL); + I6Errors::issue("array '%S' gives its size using operator '+' " + "(use brackets '(' ... ')' around the size for a calculated array size)", + identifier); else if (Str::eq(value, I"-")) - PipelineErrors::kit_error("Inform 6 array declaration using operator '-' " - "(use brackets '(' ... ')' around the size for a calculated array size)", NULL); + I6Errors::issue("array '%S' gives its size using operator '-' " + "(use brackets '(' ... ')' around the size for a calculated array size)", + identifier); else if (Str::eq(value, I"*")) - PipelineErrors::kit_error("Inform 6 array declaration using operator '*' " - "(use brackets '(' ... ')' around the size for a calculated array size)", NULL); + I6Errors::issue("array '%S' gives its size using operator '*' " + "(use brackets '(' ... ')' around the size for a calculated array size)", + identifier); else if (Str::eq(value, I"/")) - PipelineErrors::kit_error("Inform 6 array declaration using operator '/' " - "(use brackets '(' ... ')' around the size for a calculated array size)", NULL); + I6Errors::issue("array '%S' gives its size using operator '/' " + "(use brackets '(' ... ')' around the size for a calculated array size)", + identifier); else { inter_pair val = InterValuePairs::undef(); @; @@ -671,7 +675,7 @@ equating it to a function definition elsewhere. @ = if (no_assimilated_array_entries >= MAX_ASSIMILATED_ARRAY_ENTRIES) { - PipelineErrors::kit_error("excessively long Verb or Extend", NULL); + I6Errors::issue("excessively long Verb or Extend", NULL); break; } val_pile[no_assimilated_array_entries] = val; @@ -705,7 +709,7 @@ We are concerned more with the surround than with the contents of the function in this section. @ = - PipelineErrors::set_kit_error_location_near_splat(P); + I6Errors::set_current_location_near_splat(P); text_stream *raw_identifier = NULL, *local_var_names = NULL, *body = NULL; match_results mr = Regexp::create_mr(); int line_offset = 0; @@ -728,8 +732,12 @@ in this section. raw_identifier = mr.exp[0]; body = mr.exp[1]; pos = mr.exp_at[1]; } else if (Regexp::match(&mr, S, L" *%[ *([A-Za-z0-9_`]+) *(%c*?); *(%c*)")) { raw_identifier = mr.exp[0]; local_var_names = mr.exp[1]; body = mr.exp[2]; pos = mr.exp_at[2]; + } else if (Regexp::match(&mr, S, L" *%[ *(%c+?) *; *(%c*)")) { + I6Errors::issue("invalid Inform 6 routine declaration: '%S'", mr.exp[0]); } else { - PipelineErrors::kit_error("invalid Inform 6 routine declaration", NULL); + text_stream *start = Str::duplicate(S); + Str::truncate(start, 50); + I6Errors::issue("invalid Inform 6 routine declaration: '%S'", start); } for (int i=0; i15)) N = 1; for (int i=1; i<=N; i++) WRITE_TO(local_var_names, "x%d ", i); body = Str::duplicate(I"rfalse; ];"); - } else PipelineErrors::kit_error("invalid Inform 6 Stub declaration", NULL); + } else { + text_stream *start = Str::duplicate(S); + Str::truncate(start, 50); + I6Errors::issue("invalid #Stub declaration: '%S'", start); + } @ Function packages have a standardised shape in Inter, and though this is a matter of convention rather than a requirement, we will follow it here. So @@ -820,14 +832,14 @@ These have package types |_function| and |_code| respectively. int invalid = FALSE; for (int i=0; i 0) || (Characters::isdigit(c) == FALSE))) - invalid = TRUE; + (Characters::isdigit(c) == FALSE)) invalid = TRUE; } if (invalid) { text_stream *err = Str::new(); WRITE_TO(err, "'%S' in function '%S'", value, identifier); - PipelineErrors::kit_error("invalid Inform 6 local variable name: %S", err); + I6Errors::issue("invalid Inform 6 local variable name: %S", err); } inter_symbol *loc_name = InterSymbolsTable::create_with_unique_name(InterPackage::scope(IP), value); @@ -847,7 +859,7 @@ These have package types |_function| and |_code| respectively. while ((L>0) && (Characters::is_whitespace(Str::get_at(body, L-1)))) L--; Str::truncate(body, L); inter_ti B = (inter_ti) InterBookmark::baseline(IBM) + 1; - text_provenance prov = PipelineErrors::get_kit_error_location(); + text_provenance prov = I6Errors::get_current_location(); Provenance::advance_line(&prov, line_offset); CompileSplatsStage::function_body(css, IBM, IP, B, body, block_bookmark, identifier, SplatInstruction::namespace(P), prov); @@ -860,12 +872,11 @@ void CompileSplatsStage::apply_annotations(text_stream *A, text_stream *NS, inte if (Str::get_last_char(NS) == '+') apply_private = FALSE; if (Str::get_last_char(NS) == '-') apply_private = TRUE; if (apply_private != NOT_APPLICABLE) L--; + TEMPORARY_TEXT(N) if (L > 0) { - TEMPORARY_TEXT(N) for (int i=0; i 0) { LOGIF(INTER_CONNECTORS, "Trying to apply '%S' to $3\n", A, S); @@ -873,18 +884,20 @@ void CompileSplatsStage::apply_annotations(text_stream *A, text_stream *NS, inte if (Str::eq_insensitive(IA->identifier, I"private")) { if ((IA->terms == NULL) || (LinkedLists::len(IA->terms) == 0)) { if (apply_private == TRUE) - PipelineErrors::kit_error("the +private annotation is redundant here", NULL); + I6Errors::issue("the +private annotation is redundant in namespace '%S'", N); apply_private = TRUE; } else { - PipelineErrors::kit_error("the +private annotation does not take any terms", NULL); + I6Errors::issue( + "the +private annotation does not take any terms", NULL); } } else if (Str::eq_insensitive(IA->identifier, I"public")) { if ((IA->terms == NULL) || (LinkedLists::len(IA->terms) == 0)) { if (apply_private == FALSE) - PipelineErrors::kit_error("the +public annotation is redundant here", NULL); + I6Errors::issue("the +public annotation is redundant in namespace '%S'", N); apply_private = FALSE; } else { - PipelineErrors::kit_error("the +public annotation does not take any terms", NULL); + I6Errors::issue( + "the +public annotation does not take any terms", NULL); } } else if (Str::eq_insensitive(IA->identifier, I"replacing")) { text_stream *from = I"_"; int keeping = FALSE; @@ -896,21 +909,28 @@ void CompileSplatsStage::apply_annotations(text_stream *A, text_stream *NS, inte } else if (Str::eq_insensitive(term->key, I"_")) { if (Str::eq(term->value, I"keeping")) keeping = TRUE; else { - PipelineErrors::kit_error("expected 'from K' or 'keeping', not '%S'", term->value); + I6Errors::issue( + "expected 'from K' or 'keeping' in '+replacing(...)', not '%S'", + term->value); } } else - PipelineErrors::kit_error( - "the +replacing annotation does not take the term '%S'", term->key); + I6Errors::issue( + "the +replacing annotation does not take the term '%S'", + term->key); } InterSymbol::set_replacement(S, from); if (keeping) SymbolAnnotation::set_b(S, KEEPING_IANN, TRUE); + } else if (Str::eq_insensitive(IA->identifier, I"namespace")) { + I6Errors::issue( + "the annotation '%S' must be followed by a ';'", A); } else { - PipelineErrors::kit_error( - "annotation '%S' not recognised", IA->identifier); + I6Errors::issue( + "the annotation '+%S' is not one of those allowed", IA->identifier); } } } if (apply_private == TRUE) SymbolAnnotation::set_b(S, PRIVATE_IANN, TRUE); + DISCARD_TEXT(N) } @h Plumbing. @@ -1135,7 +1155,7 @@ inter_pair CompileSplatsStage::value(pipeline_step *step, inter_bookmark *IBM, if (marker) *marker = FALSE; return InterValuePairs::symbolic(IBM, symb); } else { - PipelineErrors::kit_error("unknown scope routine", S); + I6Errors::issue("can't find any scope routine called '%S'", mr.exp[0]); return InterValuePairs::number(1); } } @@ -1145,7 +1165,7 @@ inter_pair CompileSplatsStage::value(pipeline_step *step, inter_bookmark *IBM, if (marker) *marker = TRUE; return InterValuePairs::symbolic(IBM, symb); } else { - PipelineErrors::kit_error("unknown noun routine", S); + I6Errors::issue("can't find any noun routine called '%S'", mr.exp[0]); return InterValuePairs::number(1); } } @@ -1179,12 +1199,12 @@ before they are needed. @ = inter_schema *sch = - ParsingSchemas::from_text(S, PipelineErrors::get_kit_error_location()); + ParsingSchemas::from_text(S, I6Errors::get_current_location()); int excess_tokens = FALSE; inter_symbol *result_s = CompileSplatsStage::compute_r(step, IBM, sch->node_tree, &excess_tokens); - if (result_s == NULL) { - PipelineErrors::kit_error("Inform 6 constant too complex", S); + if (result_s == NULL) { /* a precaution, but should no longer happen */ + I6Errors::issue("Inform 6 constant too complex", S); return InterValuePairs::number(1); } return InterValuePairs::symbolic(IBM, result_s); @@ -1428,12 +1448,12 @@ void CompileSplatsStage::report_kit_errors(inter_schema *sch, function_body_requ if (LinkedLists::len(sch->parsing_errors) > 0) { schema_parsing_error *err; LOOP_OVER_LINKED_LIST(err, schema_parsing_error, sch->parsing_errors) { - PipelineErrors::set_kit_error_location(err->provenance); + I6Errors::set_current_location(err->provenance); TEMPORARY_TEXT(msg) WRITE_TO(msg, "in function '%S': %S", req->identifier, err->message); - PipelineErrors::kit_error("Inform 6 syntax error %S", msg); + I6Errors::issue("Inform 6 syntax error %S", msg); DISCARD_TEXT(msg) } - PipelineErrors::clear_kit_error_location(); + I6Errors::clear_current_location(); } } diff --git a/inter/pipeline-module/Chapter 3/Parsing Stages.w b/inter/pipeline-module/Chapter 3/Parsing Stages.w index e4913c516..3904be32a 100644 --- a/inter/pipeline-module/Chapter 3/Parsing Stages.w +++ b/inter/pipeline-module/Chapter 3/Parsing Stages.w @@ -138,7 +138,7 @@ typedef struct rpi_docket_state { &(ParsingStages::receive_command), &(ParsingStages::receive_bplus), &(ParsingStages::line_marker), - &(PipelineErrors::kit_error), + &(I6Errors::issue), step->ephemera.the_kit, &state); @ Once the I6T reader has unpacked the literate-programming notation, it will @@ -318,71 +318,25 @@ Note that this function empties the splat buffer |R| before exiting. = void ParsingStages::splat(text_stream *R, simple_tangle_docket *docket) { if (Str::len(R) > 0) { + rpi_docket_state *state = (rpi_docket_state *) docket->state; + I6Errors::set_current_location(state->provenance); + TEMPORARY_TEXT(A) @; inter_ti I6_dir = 0; @; - if (I6_dir != WHITESPACE_PLM) { - rpi_docket_state *state = (rpi_docket_state *) docket->state; - inter_bookmark *IBM = state->assimilation_point; - PUT_TO(R, '\n'); - filename *F = NULL; - inter_ti lc = 0; - if (Provenance::is_somewhere(state->provenance)) { - F = Provenance::get_filename(state->provenance); - lc = (inter_ti) Provenance::get_line(state->provenance); - } - Produce::guard(SplatInstruction::new(IBM, R, I6_dir, A, state->namespace, - F, lc, (inter_ti) (InterBookmark::baseline(IBM) + 1), NULL)); - } else if (A) { + if (I6_dir != WHITESPACE_PLM) @ + else if (A) { I6_annotation *IA = I6Annotations::parse(A); if ((IA) && (Str::eq_insensitive(IA->identifier, I"namespace"))) { - rpi_docket_state *state = (rpi_docket_state *) docket->state; - Str::clear(state->namespace); - int private = NOT_APPLICABLE; - I6_annotation_term *term; - LOOP_OVER_LINKED_LIST(term, I6_annotation_term, IA->terms) { - if (Str::eq_insensitive(term->key, I"_")) { - WRITE_TO(state->namespace, "%S", term->value); - } else if (Str::eq_insensitive(term->key, I"access")) { - if (Str::eq_insensitive(term->value, I"private")) private = TRUE; - else if (Str::eq_insensitive(term->value, I"public")) private = FALSE; - else PipelineErrors::kit_error( - "the 'access' must be 'private' or 'public', not '%S'", term->value); - } else { - PipelineErrors::kit_error( - "the +namespace annotation does not take the term '%S'", term->key); - } - } - int bad_name = FALSE; - for (int i=0; inamespace); i++) { - wchar_t c = Str::get_at(state->namespace, i); - if (i == 0) { - if (Characters::isalpha(c) == FALSE) bad_name = TRUE; - } else { - if ((Characters::isalnum(c) == FALSE) && (c != '_')) bad_name = TRUE; - } - } - if (bad_name) - PipelineErrors::kit_error( - "a namespace name should begin with a letter and contain " - "only alphanumeric characters or '_'", NULL); - if (Str::len(state->namespace) == 0) - PipelineErrors::kit_error( - "use '+namespace(main);' to return to the global namespace", NULL); - if (Str::eq(state->namespace, I"main")) Str::clear(state->namespace); - if (Str::eq(state->namespace, I"replaced")) { - PipelineErrors::kit_error( - "the namespace 'replaced' is reserved, and cannot be used directly", NULL); - Str::clear(state->namespace); - } - if (private == TRUE) PUT_TO(state->namespace, '-'); - if (private == FALSE) PUT_TO(state->namespace, '+'); + @; } else { - (*(docket->error_callback))( - "this annotation seems not to apply to any directive: '%S'", A); + I6Errors::issue( + "the annotation '%S' seems not to apply to any directive: " + "only '+namespace' can do that", A); } + I6Errors::clear_current_location(); } Str::clear(R); DISCARD_TEXT(A) @@ -392,8 +346,7 @@ void ParsingStages::splat(text_stream *R, simple_tangle_docket *docket) { @ = int verdict = I6Annotations::check(R); if (verdict == -1) { - (*(docket->error_callback))( - "this Inform 6 annotation is malformed: '%S'", R); + I6Errors::issue("this +annotation is malformed: '%S'", R); } else { for (int i=0; ierror_callback))( - "this Inform 6 directive is not supported in kits or '(-' inclusions: '%S'", R); + if (I6_dir == MYSTERY_PLM) { + int known = FALSE; + if (Str::eq_insensitive(mr.exp[0], I"Ifv3")) known = TRUE; + else if (Str::eq_insensitive(mr.exp[0], I"Ifv5")) known = TRUE; + else if (Str::eq_insensitive(mr.exp[0], I"Iffalse")) known = TRUE; + else if (Str::eq_insensitive(mr.exp[0], I"Abbreviate")) known = TRUE; + else if (Str::eq_insensitive(mr.exp[0], I"Dictionary")) known = TRUE; + else if (Str::eq_insensitive(mr.exp[0], I"Import")) known = TRUE; + else if (Str::eq_insensitive(mr.exp[0], I"Link")) known = TRUE; + else if (Str::eq_insensitive(mr.exp[0], I"Lowstring")) known = TRUE; + else if (Str::eq_insensitive(mr.exp[0], I"Origsource")) known = TRUE; + else if (Str::eq_insensitive(mr.exp[0], I"Replace")) known = TRUE; + else if (Str::eq_insensitive(mr.exp[0], I"Switches")) known = TRUE; + else if (Str::eq_insensitive(mr.exp[0], I"Trace")) known = TRUE; + else if (Str::eq_insensitive(mr.exp[0], I"Undef")) known = TRUE; + else if (Str::eq_insensitive(mr.exp[0], I"Version")) known = TRUE; + if (known) + I6Errors::issue( + "this Inform 6 directive is not supported in kits or '(-' inclusions: '%S' " + "(only #Ifdef, #Ifndef, #Iftrue, #Ifnot, #Endif, #Stub, Constant, Global, " + "Array, Attribute, Property, Verb, Fake_action, Object, Default are " + "supported)", R); + else + I6Errors::issue("this is not an Inform 6 directive", R); + } Regexp::dispose_of(&mr); +@ = + inter_bookmark *IBM = state->assimilation_point; + PUT_TO(R, '\n'); + filename *F = NULL; + inter_ti lc = 0; + if (Provenance::is_somewhere(state->provenance)) { + F = Provenance::get_filename(state->provenance); + lc = (inter_ti) Provenance::get_line(state->provenance); + } + Produce::guard(SplatInstruction::new(IBM, R, I6_dir, A, state->namespace, + F, lc, (inter_ti) (InterBookmark::baseline(IBM) + 1), NULL)); + +@ So the following picks up |+namespace(Whatever)| annotations, which do not +apply to any directive. + +@ = + Str::clear(state->namespace); + int private = NOT_APPLICABLE; + I6_annotation_term *term; + LOOP_OVER_LINKED_LIST(term, I6_annotation_term, IA->terms) { + if (Str::eq_insensitive(term->key, I"_")) { + WRITE_TO(state->namespace, "%S", term->value); + } else if (Str::eq_insensitive(term->key, I"access")) { + if (Str::eq_insensitive(term->value, I"private")) private = TRUE; + else if (Str::eq_insensitive(term->value, I"public")) private = FALSE; + else I6Errors::issue( + "in a +namespace annotation, the 'access' must be 'private' or " + "'public', not '%S'", term->value); + } else { + I6Errors::issue( + "the +namespace annotation does not take the term '%S'", term->key); + } + } + @; + if (private == TRUE) PUT_TO(state->namespace, '-'); + if (private == FALSE) PUT_TO(state->namespace, '+'); + +@ = + int bad_name = FALSE; + for (int i=0; inamespace); i++) { + wchar_t c = Str::get_at(state->namespace, i); + if (i == 0) { + if (Characters::isalpha(c) == FALSE) bad_name = TRUE; + } else { + if ((Characters::isalnum(c) == FALSE) && (c != '_')) bad_name = TRUE; + } + } + if (bad_name) + I6Errors::issue( + "the namespace '%S' is not allowed: namespace names should begin " + "with a letter and contain only alphanumeric characters or '_'", + state->namespace); + if (Str::len(state->namespace) == 0) + I6Errors::issue( + "'+namespace()' is not allowed: use '+namespace(main);' to return " + "to the global namespace", NULL); + if (Str::eq(state->namespace, I"main")) Str::clear(state->namespace); + else if (Str::eq_insensitive(state->namespace, I"main")) + I6Errors::issue( + "'+namespace(...)' names are case-sensitive: use 'main', not '%S', " + "to return to the global namespace", state->namespace); + if (Str::eq(state->namespace, I"replaced")) { + I6Errors::issue( + "the namespace 'replaced' is reserved, and cannot be used directly", NULL); + Str::clear(state->namespace); + } + @ And that's it: the result of these stages is just to break the I6T source they found up into individual directives, and put them into the tree as |SPLAT_IST| nodes. No effort has been made yet to see what directives they are. Subsequent stages diff --git a/inter/pipeline-module/Chapter 3/Resolve Conditional Compilation Stage.w b/inter/pipeline-module/Chapter 3/Resolve Conditional Compilation Stage.w index afa82f9bd..d2415446a 100644 --- a/inter/pipeline-module/Chapter 3/Resolve Conditional Compilation Stage.w +++ b/inter/pipeline-module/Chapter 3/Resolve Conditional Compilation Stage.w @@ -72,8 +72,9 @@ void ResolveConditionalsStage::resolve(inter_tree *I) { state.cc_sp = 0; InterTree::traverse(I, ResolveConditionalsStage::visitor, &state, NULL, 0); if (state.cc_sp != 0) - PipelineErrors::kit_error( + I6Errors::issue( "conditional compilation wrongly structured: not enough #endif", NULL); + I6Errors::clear_current_location(); } @ Note that when the top of the stack is a block whose body is not to be compiled, @@ -86,6 +87,7 @@ void ResolveConditionalsStage::visitor(inter_tree *I, inter_tree_node *P, void * int compile_this = TRUE; for (int i=0; icc_sp; i++) if (state->cc_stack[i] == FALSE) compile_this = FALSE; if (Inode::is(P, SPLAT_IST)) { + I6Errors::set_current_location_near_splat(P); text_stream *S = SplatInstruction::splatter(P); switch (SplatInstruction::plm(P)) { case CONSTANT_PLM: @@ -176,17 +178,55 @@ Inform kits use this only to test |#Iftrue WORDSIZE == 4| or |#Iftrue WORDSIZE = match_results mr2 = Regexp::create_mr(); if (Regexp::match(&mr2, cond, L" *(%C+?) *== *(%d+) *")) { text_stream *identifier = mr2.exp[0]; - inter_symbol *symbol = - LargeScale::architectural_symbol(I, identifier); + inter_symbol *symbol = LargeScale::architectural_symbol(I, identifier); if (symbol) { int V = InterSymbol::evaluate_to_int(symbol); int W = Str::atoi(mr2.exp[1], 0); if ((V >= 0) && (V == W)) result = TRUE; else result = FALSE; } } + if (Regexp::match(&mr2, cond, L" *(%C+?) *>= *(%d+) *")) { + text_stream *identifier = mr2.exp[0]; + inter_symbol *symbol = LargeScale::architectural_symbol(I, identifier); + if (symbol) { + int V = InterSymbol::evaluate_to_int(symbol); + int W = Str::atoi(mr2.exp[1], 0); + if ((V >= 0) && (V >= W)) result = TRUE; else result = FALSE; + } + } + if (Regexp::match(&mr2, cond, L" *(%C+?) *> *(%d+) *")) { + text_stream *identifier = mr2.exp[0]; + inter_symbol *symbol = LargeScale::architectural_symbol(I, identifier); + if (symbol) { + int V = InterSymbol::evaluate_to_int(symbol); + int W = Str::atoi(mr2.exp[1], 0); + if ((V >= 0) && (V > W)) result = TRUE; else result = FALSE; + } + } + if (Regexp::match(&mr2, cond, L" *(%C+?) *<= *(%d+) *")) { + text_stream *identifier = mr2.exp[0]; + inter_symbol *symbol = LargeScale::architectural_symbol(I, identifier); + if (symbol) { + int V = InterSymbol::evaluate_to_int(symbol); + int W = Str::atoi(mr2.exp[1], 0); + if ((V >= 0) && (V <= W)) result = TRUE; else result = FALSE; + } + } + if (Regexp::match(&mr2, cond, L" *(%C+?) *< *(%d+) *")) { + text_stream *identifier = mr2.exp[0]; + inter_symbol *symbol = LargeScale::architectural_symbol(I, identifier); + if (symbol) { + int V = InterSymbol::evaluate_to_int(symbol); + int W = Str::atoi(mr2.exp[1], 0); + if ((V >= 0) && (V < W)) result = TRUE; else result = FALSE; + } + } if (result == NOT_APPLICABLE) { - PipelineErrors::kit_error( - "conditional compilation is too difficult: #iftrue on %S", cond); + I6Errors::issue( + "conditional compilation is too difficult: #iftrue on '%S' " + "(can only test SYMBOL == DECIMALVALUE, or >, <, >=, <=, where " + "the DECIMALVALUE is non-negative, and even then only for a few " + "symbols, of which 'WORDSIZE' is the most useful)", cond); result = FALSE; } LOGIF(RESOLVING_CONDITIONAL_COMPILATION, "Must decide if %S: ", cond); @@ -199,7 +239,7 @@ Inform kits use this only to test |#Iftrue WORDSIZE == 4| or |#Iftrue WORDSIZE = @ = if (state->cc_sp >= MAX_CC_STACK_SIZE) { state->cc_sp = MAX_CC_STACK_SIZE; - PipelineErrors::kit_error( + I6Errors::issue( "conditional compilation wrongly structured: too many nested #ifdef or #iftrue", NULL); } else { state->cc_stack[state->cc_sp++] = result; @@ -208,7 +248,7 @@ Inform kits use this only to test |#Iftrue WORDSIZE == 4| or |#Iftrue WORDSIZE = @ = LOGIF(RESOLVING_CONDITIONAL_COMPILATION, "ifnot\n"); if (state->cc_sp == 0) - PipelineErrors::kit_error("conditional compilation wrongly structured: #ifnot at top level", NULL); + I6Errors::issue("conditional compilation wrongly structured: #ifnot at top level", NULL); else state->cc_stack[state->cc_sp-1] = (state->cc_stack[state->cc_sp-1])?FALSE:TRUE; compile_this = FALSE; @@ -219,7 +259,7 @@ Inform kits use this only to test |#Iftrue WORDSIZE == 4| or |#Iftrue WORDSIZE = state->cc_sp--; if (state->cc_sp < 0) { state->cc_sp = 0; - PipelineErrors::kit_error("conditional compilation wrongly structured: too many #endif", NULL); + I6Errors::issue("conditional compilation wrongly structured: too many #endif", NULL); } compile_this = FALSE; From 04e526f0a676b89fa032d6c886a146499d5e7ae5 Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Sun, 30 Apr 2023 10:31:51 +0100 Subject: [PATCH 017/113] Fix for Jira bug I7-2298 --- README.md | 2 +- build.txt | 4 +- .../BasicInformExtrasKit/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 +- .../building-module/Chapter 2/Inter Schemas.w | 5 + .../building-module/Chapter 2/Ramification.w | 17 + .../Tests/Test Cases/_Results_Ideal/exp.txt | 384 +-- .../Test Cases/_Results_Ideal/schemas.txt | 2343 +++++++++-------- .../Tests/Test Cases/schemas.txt | 8 + 12 files changed, 1444 insertions(+), 1329 deletions(-) diff --git a/README.md b/README.md index 462fd028c..d6b46b84c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inform 7 -[Version](notes/versioning.md): 10.2.0-beta+6W40 'Krypton' (29 April 2023) +[Version](notes/versioning.md): 10.2.0-beta+6W41 'Krypton' (30 April 2023) ## About Inform diff --git a/build.txt b/build.txt index 9382b82be..4ed80aa12 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: beta -Build Date: 29 April 2023 -Build Number: 6W40 +Build Date: 30 April 2023 +Build Number: 6W41 diff --git a/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json index f5770f9ff..13b2dafcc 100644 --- a/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json +++ b/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "BasicInformExtrasKit", - "version": "10.2.0-beta+6W40" + "version": "10.2.0-beta+6W41" }, "kit-details": { "has-priority": 1 diff --git a/inform7/Internal/Inter/BasicInformKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformKit/kit_metadata.json index 59755728c..e151cca96 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+6W40" + "version": "10.2.0-beta+6W41" }, "needs": [ { "unless": { diff --git a/inform7/Internal/Inter/CommandParserKit/kit_metadata.json b/inform7/Internal/Inter/CommandParserKit/kit_metadata.json index 4eb8549d7..f7d87c92a 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+6W40" + "version": "10.2.0-beta+6W41" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json b/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json index e31af07e6..1bbcac06b 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+6W40" + "version": "10.2.0-beta+6W41" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/WorldModelKit/kit_metadata.json b/inform7/Internal/Inter/WorldModelKit/kit_metadata.json index ff58bd98b..6b24bbc99 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+6W40" + "version": "10.2.0-beta+6W41" }, "needs": [ { "need": { diff --git a/inter/building-module/Chapter 2/Inter Schemas.w b/inter/building-module/Chapter 2/Inter Schemas.w index 6211c0c68..48a9ada8a 100644 --- a/inter/building-module/Chapter 2/Inter Schemas.w +++ b/inter/building-module/Chapter 2/Inter Schemas.w @@ -533,6 +533,11 @@ void InterSchemas::log_just(inter_schema_node *isn, int depth) { if (isn->expression_tokens == NULL) LOG(" - empty"); LOG("\n"); for (inter_schema_token *t = isn->expression_tokens; t; t=t->next) { + if (Provenance::is_somewhere(isn->provenance)) { + LOG("%04d ", Provenance::get_line(isn->provenance)); + } else { + LOG(".... "); + } for (int d = 0; d < depth + 1; d++) LOG(" "); InterSchemas::log_ist(t); if (isn != t->owner) LOG(" !!! ownership incorrect here"); diff --git a/inter/building-module/Chapter 2/Ramification.w b/inter/building-module/Chapter 2/Ramification.w index d81f1b7e8..d1ff563fd 100644 --- a/inter/building-module/Chapter 2/Ramification.w +++ b/inter/building-module/Chapter 2/Ramification.w @@ -1921,7 +1921,24 @@ int Ramification::sanity_check(inter_schema_node *par, inter_schema_node *isn) { } else { if (isn->expression_tokens) I6Errors::issue_at_node(isn, I"syntax error"); } + if ((isn->isn_type == STATEMENT_ISNT) && (isn->isn_clarifier == CASE_BIP)) { + if ((isn->child_node) && (isn->child_node->isn_type == EXPRESSION_ISNT)) + Ramification::check_for_to(isn, isn->child_node); + } + if ((isn->isn_type == OPERATION_ISNT) && (isn->isn_clarifier == ALTERNATIVECASE_BIP)) { + if ((isn->child_node) && (isn->child_node->isn_type == EXPRESSION_ISNT)) + Ramification::check_for_to(isn, isn->child_node); + if ((isn->child_node) && (isn->child_node->next_node) && + (isn->child_node->next_node->isn_type == EXPRESSION_ISNT)) + Ramification::check_for_to(isn, isn->child_node->next_node); + } Ramification::sanity_check(isn, isn->child_node); } return FALSE; } + +int Ramification::check_for_to(inter_schema_node *par, inter_schema_node *isn) { + for (inter_schema_token *t = isn->expression_tokens; t; t=t->next) + if ((t->ist_type == IDENTIFIER_ISTT) && (Str::eq(t->material, I"to"))) + I6Errors::issue_at_node(isn, I"'to' ranges are unsupported in switch cases"); +} diff --git a/inter/building-test/Tests/Test Cases/_Results_Ideal/exp.txt b/inter/building-test/Tests/Test Cases/_Results_Ideal/exp.txt index 2a40e6190..2f5a611a4 100644 --- a/inter/building-test/Tests/Test Cases/_Results_Ideal/exp.txt +++ b/inter/building-test/Tests/Test Cases/_Results_Ideal/exp.txt @@ -3,29 +3,29 @@ Test: parse schema from: 0002 * (message) 0002 * (expr) - IDENTIFIER alpha +0002 IDENTIFIER alpha 0002 * (expr) - IDENTIFIER beta +0002 IDENTIFIER beta ========= Test: parse schema from: alpha.beta(x) 0002 * (message) 0002 * (expr) - IDENTIFIER alpha +0002 IDENTIFIER alpha 0002 * (expr) - IDENTIFIER beta +0002 IDENTIFIER beta 0002 * (expr) - IDENTIFIER x +0002 IDENTIFIER x ========= Test: parse schema from: routine.call(x) 0002 * (call-message) 0002 * (expr) - IDENTIFIER routine +0002 IDENTIFIER routine 0002 * (expr) - IDENTIFIER x +0002 IDENTIFIER x ========= Test: parse schema from: (alpha.beta)(x) @@ -34,11 +34,11 @@ Test: parse schema from: 0002 * (subexpression) 0002 * (operation) !propertyvalue 0002 * (expr) - IDENTIFIER alpha +0002 IDENTIFIER alpha 0002 * (expr) - IDENTIFIER beta +0002 IDENTIFIER beta 0002 * (expr) - IDENTIFIER x +0002 IDENTIFIER x ========= Test: parse schema from: debug_rules = 2; say__p = 1; @@ -46,25 +46,25 @@ Test: parse schema from: 0001 * (operation) !store 0001 * (expr) - IDENTIFIER debug_rules +0001 IDENTIFIER debug_rules 0001 * (expr) - NUMBER 2 +0001 NUMBER 2 0001 * (operation) !store 0001 * (expr) - IDENTIFIER say__p +0001 IDENTIFIER say__p 0002 * (expr) - NUMBER 1 +0002 NUMBER 1 0002 * (expr) ; - DQUOTED Rules tracing now switched to "all". Type "rules off" to switch it off again. +0002 DQUOTED Rules tracing now switched to "all". Type "rules off" to switch it off again. ========= Test: parse schema from: @erase_window -1; 0001 * (assembly) 0001 * (expr) - OPCODE @erase_window +0001 OPCODE @erase_window 0002 * (expr) - NUMBER -1 +0002 NUMBER -1 ========= Test: parse schema from: restore Somewhere; @@ -72,20 +72,20 @@ Test: parse schema from: 0001 * (statement) !restore 0001 * (expr) - IDENTIFIER Somewhere +0001 IDENTIFIER Somewhere 0002 * (label) 0002 * (expr) - IDENTIFIER Somewhere +0002 IDENTIFIER Somewhere 0002 * (statement) !print 0002 * (expr) - DQUOTED Here! +0002 DQUOTED Here! ========= Test: parse schema from: "Hello, this is a multiline string literal"; 0002 * (expr) ; - DQUOTED Hello, this is a multiline string literal +0002 DQUOTED Hello, this is a multiline string literal ========= Test: parse schema from: for (n=0:((n10) && (n<10)): n++) @@ -95,35 +95,35 @@ Test: parse schema from: 0001 * (eval) 0001 * (operation) !store 0001 * (expr) - IDENTIFIER n +0001 IDENTIFIER n 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 0001 * (eval) 0001 * (subexpression) 0001 * (operation) !and 0001 * (subexpression) 0001 * (operation) !lt 0001 * (expr) - IDENTIFIER n +0001 IDENTIFIER n 0001 * (operation) !lookup 0001 * (expr) - IDENTIFIER RE_Subexpressions +0001 IDENTIFIER RE_Subexpressions 0001 * (expr) - NUMBER 10 +0001 NUMBER 10 0001 * (subexpression) 0001 * (operation) !lt 0001 * (expr) - IDENTIFIER n +0001 IDENTIFIER n 0001 * (expr) - NUMBER 10 +0001 NUMBER 10 0001 * (eval) 0001 * (operation) !postincrement 0002 * (expr) - IDENTIFIER n +0002 IDENTIFIER n 0002 * (code) 0002 * (statement) !printnumber 0002 * (expr) - IDENTIFIER n +0002 IDENTIFIER n ========= Test: parse schema from: spaces j; @@ -131,12 +131,12 @@ Test: parse schema from: 0001 * (statement) !spaces 0001 * (expr) - IDENTIFIER j +0001 IDENTIFIER j 0002 * (call) 0002 * (expr) - IDENTIFIER I7_String +0002 IDENTIFIER I7_String 0002 * (expr) - IDENTIFIER str +0002 IDENTIFIER str ========= Test: parse schema from: if (i == 1) print "Okay"; @@ -146,25 +146,25 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !eq 0001 * (expr) - IDENTIFIER i +0001 IDENTIFIER i 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (code) 0001 * (statement) !print 0001 * (expr) - DQUOTED Okay +0001 DQUOTED Okay 0002 * (code) 0002 * (expr) ; - DQUOTED *** Arrcpy doesn't support this *** +0002 DQUOTED *** Arrcpy doesn't support this *** ========= Test: parse schema from: a-1 0002 * (operation) !minus 0002 * (expr) - IDENTIFIER a +0002 IDENTIFIER a 0002 * (expr) - NUMBER 1 +0002 NUMBER 1 ========= Test: parse schema from: do { @@ -174,11 +174,11 @@ Test: parse schema from: 0001 * (statement) !do 0001 * (subexpression) 0004 * (expr) - IDENTIFIER x +0004 IDENTIFIER x 0002 * (code) 0002 * (statement) !print 0002 * (expr) - DQUOTED Hi! +0002 DQUOTED Hi! ========= Test: parse schema from: do { @@ -188,16 +188,16 @@ Test: parse schema from: 0001 * (statement) !do 0001 * (subexpression) 0004 * (expr) - IDENTIFIER a +0004 IDENTIFIER a 0002 * (code) 0002 * (statement) !if 0002 * (subexpression) 0002 * (expr) - IDENTIFIER a +0002 IDENTIFIER a 0002 * (code) 0002 * (statement) !return 0002 * (expr) - IDENTIFIER wd +0002 IDENTIFIER wd ========= Test: parse schema from: do { @@ -212,11 +212,11 @@ Test: parse schema from: 0004 * (operation) !eq 0004 * (operation) !lookup 0004 * (expr) - IDENTIFIER line_token +0004 IDENTIFIER line_token 0004 * (expr) - IDENTIFIER index +0004 IDENTIFIER index 0004 * (expr) - IDENTIFIER ENDIT_TOKEN +0004 IDENTIFIER ENDIT_TOKEN 0004 * (subexpression) 0004 * (operation) !eq 0004 * (subexpression) @@ -225,46 +225,46 @@ Test: parse schema from: 0004 * (subexpression) 0004 * (operation) !lookup 0004 * (expr) - IDENTIFIER line_token +0004 IDENTIFIER line_token 0004 * (expr) - IDENTIFIER index +0004 IDENTIFIER index 0004 * (expr) - NUMBER 0 +0004 NUMBER 0 0004 * (expr) - HEX_NUMBER $10 +0004 HEX_NUMBER $10 0005 * (expr) - NUMBER 0 +0005 NUMBER 0 0002 * (code) 0002 * (statement) !if 0002 * (subexpression) 0002 * (operation) !eq 0002 * (operation) !lookup 0002 * (expr) - IDENTIFIER line_tdata +0002 IDENTIFIER line_tdata 0002 * (expr) - IDENTIFIER index +0002 IDENTIFIER index 0002 * (expr) - IDENTIFIER wd +0002 IDENTIFIER wd 0002 * (code) 0002 * (statement) !return 0002 * (expr) - IDENTIFIER wd +0002 IDENTIFIER wd 0002 * (operation) !postincrement 0004 * (expr) - IDENTIFIER index +0004 IDENTIFIER index ========= Test: parse schema from: print ""; 0001 * (statement) !print 0001 * (expr) - DQUOTED +0001 DQUOTED "> ========= Test: parse schema from: switch (Y) { @@ -274,18 +274,18 @@ Test: parse schema from: 0001 * (statement) !switch 0001 * (subexpression) 0001 * (expr) - IDENTIFIER Y +0001 IDENTIFIER Y 0002 * (code) 0002 * (statement) !case 0002 * (expr) - IDENTIFIER X +0002 IDENTIFIER X 0002 * (code) 0002 * (statement) !print 0002 * (expr) - DQUOTED A +0002 DQUOTED A 0002 * (statement) !printstring 0002 * (expr) - IDENTIFIER o +0002 IDENTIFIER o ========= Test: parse schema from: #ifdef RANKING_TABLE; @@ -302,77 +302,77 @@ Test: parse schema from: 0001 * (directive) #ifdef 0001 * (expr) - IDENTIFIER RANKING_TABLE +0001 IDENTIFIER RANKING_TABLE 0002 * (call) 0002 * (expr) - IDENTIFIER ANNOUNCE_SCORE_RM +0002 IDENTIFIER ANNOUNCE_SCORE_RM 0002 * (expr) - SQUOTED B +0002 SQUOTED B 0003 * (operation) !store 0003 * (expr) - IDENTIFIER j +0003 IDENTIFIER j 0004 * (call) 0004 * (expr) - IDENTIFIER TableRows +0004 IDENTIFIER TableRows 0004 * (expr) - IDENTIFIER RANKING_TABLE +0004 IDENTIFIER RANKING_TABLE 0004 * (statement) !for 0005 * (eval) 0005 * (operation) !store 0005 * (expr) - IDENTIFIER i +0005 IDENTIFIER i 0005 * (expr) - IDENTIFIER j +0005 IDENTIFIER j 0005 * (eval) 0005 * (operation) !ge 0005 * (expr) - IDENTIFIER i +0005 IDENTIFIER i 0005 * (expr) - NUMBER 1 +0005 NUMBER 1 0005 * (eval) 0005 * (operation) !postdecrement 0005 * (expr) - IDENTIFIER i +0005 IDENTIFIER i 0005 * (code) 0005 * (statement) !if 0005 * (subexpression) 0005 * (operation) !ge 0005 * (expr) - IDENTIFIER score +0005 IDENTIFIER score 0005 * (call) 0005 * (expr) - IDENTIFIER TableLookUpEntry +0005 IDENTIFIER TableLookUpEntry 0005 * (expr) - IDENTIFIER RANKING_TABLE +0005 IDENTIFIER RANKING_TABLE 0005 * (expr) - NUMBER 1 +0005 NUMBER 1 0005 * (expr) - IDENTIFIER i +0005 IDENTIFIER i 0006 * (code) 0006 * (operation) !store 0006 * (expr) - IDENTIFIER v +0006 IDENTIFIER v 0006 * (call) 0006 * (expr) - IDENTIFIER TableLookUpEntry +0006 IDENTIFIER TableLookUpEntry 0006 * (expr) - IDENTIFIER RANKING_TABLE +0006 IDENTIFIER RANKING_TABLE 0006 * (expr) - NUMBER 2 +0006 NUMBER 2 0007 * (expr) - IDENTIFIER i +0007 IDENTIFIER i 0007 * (call) 0008 * (expr) - IDENTIFIER TEXT_TY_Say +0008 IDENTIFIER TEXT_TY_Say 0008 * (expr) - IDENTIFIER v +0008 IDENTIFIER v 0008 * (expr) ; - DQUOTED . +0008 DQUOTED . 0005 * (directive) #endif 0011 * (expr) ; - DQUOTED . +0011 DQUOTED . 0011 * (expr) - SQUOTED +0011 SQUOTED ========= Test: parse schema from: @@ -382,19 +382,19 @@ Test: parse schema from: 0001 * (statement) !if 0001 * (subexpression) 0001 * (expr) - IDENTIFIER B +0001 IDENTIFIER B 0001 * (code) 0001 * (statement) !if 0001 * (subexpression) 0001 * (expr) - IDENTIFIER A +0001 IDENTIFIER A 0001 * (code) 0001 * (statement) !print 0001 * (expr) - DQUOTED Yes +0001 DQUOTED Yes 0001 * (statement) !print 0002 * (expr) - DQUOTED No +0002 DQUOTED No ========= Test: parse schema from: switch (scope_stage) { @@ -405,24 +405,24 @@ Test: parse schema from: 0001 * (statement) !switch 0001 * (subexpression) 0001 * (expr) - IDENTIFIER scope_stage +0001 IDENTIFIER scope_stage 0002 * (code) < 0002 * (statement) !case 0002 * (expr) - NUMBER 2 +0002 NUMBER 2 0002 * (code) < 0002 * (statement) !objectloop 0002 * (subexpression) 0003 * (expr) - IDENTIFIER obj +0003 IDENTIFIER obj 0003 * (code) 0003 * (call) 0003 * (expr) - IDENTIFIER PlaceInScope +0003 IDENTIFIER PlaceInScope 0003 * (expr) - IDENTIFIER obj +0003 IDENTIFIER obj 0004 * (expr) - NUMBER true +0004 NUMBER true ========= Test: parse schema from: while (token ~= NULL) { @@ -438,66 +438,66 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !ne 0001 * (expr) - IDENTIFIER token +0001 IDENTIFIER token 0001 * (expr) - IDENTIFIER NULL +0001 IDENTIFIER NULL 0002 * (code) 0002 * (statement) !switch 0002 * (subexpression) 0002 * (operation) !lookup 0002 * (expr) - IDENTIFIER token +0002 IDENTIFIER token 0002 * (expr) - IDENTIFIER RE_CCLASS +0002 IDENTIFIER RE_CCLASS 0003 * (code) 0003 * (statement) !case 0003 * (expr) - IDENTIFIER DISJUNCTION_RE_CC +0003 IDENTIFIER DISJUNCTION_RE_CC 0003 * (code) 0003 * (operation) !store 0003 * (operation) !lookup 0003 * (expr) - IDENTIFIER token +0003 IDENTIFIER token 0003 * (expr) - IDENTIFIER RE_CONSTRAINT +0003 IDENTIFIER RE_CONSTRAINT 0004 * (expr) - NUMBER -1 +0004 NUMBER -1 0004 * (statement) !case 0004 * (expr) - IDENTIFIER QUANTIFIER_RE_CC +0004 IDENTIFIER QUANTIFIER_RE_CC 0004 * (code) 0004 * (operation) !store 0004 * (operation) !lookup 0004 * (expr) - IDENTIFIER token +0004 IDENTIFIER token 0004 * (expr) - IDENTIFIER RE_CONSTRAINT +0004 IDENTIFIER RE_CONSTRAINT 0005 * (expr) - NUMBER -1 +0005 NUMBER -1 0003 * (statement) !if 0006 * (subexpression) 0006 * (operation) !lookup 0006 * (expr) - IDENTIFIER token +0006 IDENTIFIER token 0006 * (expr) - IDENTIFIER RE_DOWN +0006 IDENTIFIER RE_DOWN 0007 * (code) 0007 * (call) 0007 * (expr) - IDENTIFIER TEXT_TY_RE_EraseConstraints +0007 IDENTIFIER TEXT_TY_RE_EraseConstraints 0007 * (operation) !lookup 0007 * (expr) - IDENTIFIER token +0007 IDENTIFIER token 0007 * (expr) - IDENTIFIER RE_DOWN +0007 IDENTIFIER RE_DOWN 0007 * (operation) !store 0007 * (expr) - IDENTIFIER token +0007 IDENTIFIER token 0008 * (operation) !lookup 0008 * (expr) - IDENTIFIER token +0008 IDENTIFIER token 0008 * (expr) - IDENTIFIER RE_NEXT +0008 IDENTIFIER RE_NEXT ========= Test: parse schema from: if (b) print 1; else print 2; @@ -505,55 +505,55 @@ Test: parse schema from: 0001 * (statement) !ifelse 0001 * (subexpression) 0001 * (expr) - IDENTIFIER b +0001 IDENTIFIER b 0001 * (code) 0001 * (statement) !printnumber 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (code) 0001 * (statement) !printnumber 0001 * (expr) - NUMBER 2 +0001 NUMBER 2 ========= Test: parse schema from: a: if (b) print 1; else print 2; 0001 * (statement) !case 0001 * (expr) - IDENTIFIER a +0001 IDENTIFIER a 0001 * (code) < 0001 * (statement) !ifelse 0001 * (subexpression) 0001 * (expr) - IDENTIFIER b +0001 IDENTIFIER b 0001 * (code) 0001 * (statement) !printnumber 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (code) 0001 * (statement) !printnumber 0001 * (expr) - NUMBER 2 +0001 NUMBER 2 ========= Test: parse schema from: print_ret "This is ", (char) X, "."; 0001 * (statement) !print 0001 * (expr) - DQUOTED This is +0001 DQUOTED This is 0001 * (statement) !printchar 0001 * (expr) - IDENTIFIER X +0001 IDENTIFIER X 0001 * (statement) !print 0001 * (expr) - DQUOTED . +0001 DQUOTED . 0001 * (statement) !print 0001 * (expr) - DQUOTED +0001 DQUOTED 0001 * (statement) !return 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: @jl y 0 ?X; @@ -565,58 +565,58 @@ Test: parse schema from: 0001 * (assembly) 0001 * (expr) - OPCODE @jl +0001 OPCODE @jl 0001 * (expr) - IDENTIFIER y +0001 IDENTIFIER y 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 0002 * (expr) - ASM_LABEL X +0002 ASM_LABEL X 0002 * (assembly) 0002 * (expr) - OPCODE @jl +0002 OPCODE @jl 0002 * (expr) - IDENTIFIER y +0002 IDENTIFIER y 0002 * (expr) - NUMBER 0 +0002 NUMBER 0 0003 * (expr) - NEGASM_LABEL X +0003 NEGASM_LABEL X 0003 * (assembly) 0003 * (expr) - OPCODE @jl +0003 OPCODE @jl 0003 * (expr) - IDENTIFIER y +0003 IDENTIFIER y 0003 * (expr) - NUMBER 0 +0003 NUMBER 0 0004 * (expr) - ASM_LABEL rtrue +0004 ASM_LABEL rtrue 0004 * (assembly) 0004 * (expr) - OPCODE @jl +0004 OPCODE @jl 0004 * (expr) - IDENTIFIER y +0004 IDENTIFIER y 0004 * (expr) - NUMBER 0 +0004 NUMBER 0 0005 * (expr) - ASM_LABEL rfalse +0005 ASM_LABEL rfalse 0005 * (assembly) 0005 * (expr) - OPCODE @jl +0005 OPCODE @jl 0005 * (expr) - IDENTIFIER y +0005 IDENTIFIER y 0005 * (expr) - NUMBER 0 +0005 NUMBER 0 0006 * (expr) - NEGASM_LABEL rtrue +0006 NEGASM_LABEL rtrue 0006 * (assembly) 0006 * (expr) - OPCODE @jl +0006 OPCODE @jl 0006 * (expr) - IDENTIFIER y +0006 IDENTIFIER y 0006 * (expr) - NUMBER 0 +0006 NUMBER 0 0007 * (expr) - NEGASM_LABEL rfalse +0007 NEGASM_LABEL rfalse ========= Test: parse schema from: switch (token-->RE_CCLASS) { @@ -649,114 +649,114 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !lookup 0001 * (expr) - IDENTIFIER token +0001 IDENTIFIER token 0001 * (expr) - IDENTIFIER RE_CCLASS +0001 IDENTIFIER RE_CCLASS 0002 * (code) 0002 * (statement) !case 0005 * (expr) - IDENTIFIER CHOICE_RE_CC +0005 IDENTIFIER CHOICE_RE_CC 0005 * (code) 0005 * (statement) !return 0005 * (expr) - DQUOTED internal error +0005 DQUOTED internal error 0006 * (statement) !case 0010 * (expr) - IDENTIFIER SENSITIVITY_RE_CC +0010 IDENTIFIER SENSITIVITY_RE_CC 0010 * (code) 0010 * (statement) !ifelse 0010 * (subexpression) 0010 * (operation) !lookup 0010 * (expr) - IDENTIFIER token +0010 IDENTIFIER token 0010 * (expr) - IDENTIFIER RE_PAR1 +0010 IDENTIFIER RE_PAR1 0010 * (code) 0010 * (operation) !store 0010 * (expr) - IDENTIFIER mode_flags +0010 IDENTIFIER mode_flags 0010 * (operation) !bitwiseor 0010 * (expr) - IDENTIFIER mode_flags +0010 IDENTIFIER mode_flags 0011 * (expr) - IDENTIFIER CIS_MFLAG +0011 IDENTIFIER CIS_MFLAG 0011 * (code) 0011 * (operation) !store 0011 * (expr) - IDENTIFIER mode_flags +0011 IDENTIFIER mode_flags 0011 * (operation) !bitwiseand 0011 * (expr) - IDENTIFIER mode_flags +0011 IDENTIFIER mode_flags 0012 * (subexpression) 0012 * (operation) !bitwisenot 0012 * (expr) - IDENTIFIER CIS_MFLAG +0012 IDENTIFIER CIS_MFLAG 0011 * (operation) !store 0012 * (expr) - IDENTIFIER outcome +0012 IDENTIFIER outcome 0013 * (expr) - NUMBER true +0013 NUMBER true 0013 * (statement) !case 0017 * (expr) - IDENTIFIER ALWAYS_RE_CC +0017 IDENTIFIER ALWAYS_RE_CC 0017 * (code) 0017 * (operation) !store 0017 * (expr) - IDENTIFIER outcome +0017 IDENTIFIER outcome 0018 * (expr) - NUMBER true +0018 NUMBER true 0018 * (statement) !case 0019 * (expr) - IDENTIFIER NEVER_RE_CC +0019 IDENTIFIER NEVER_RE_CC 0019 * (code) 0019 * (statement) !case 0020 * (expr) - IDENTIFIER START_RE_CC +0020 IDENTIFIER START_RE_CC 0020 * (code) 0020 * (statement) !if 0020 * (subexpression) 0020 * (operation) !eq 0020 * (expr) - IDENTIFIER ipos +0020 IDENTIFIER ipos 0020 * (expr) - NUMBER 0 +0020 NUMBER 0 0020 * (code) 0020 * (operation) !store 0020 * (expr) - IDENTIFIER outcome +0020 IDENTIFIER outcome 0021 * (expr) - NUMBER true +0021 NUMBER true 0020 * (statement) !case 0022 * (expr) - IDENTIFIER END_RE_CC +0022 IDENTIFIER END_RE_CC 0022 * (code) 0022 * (statement) !if 0022 * (subexpression) 0022 * (operation) !eq 0022 * (call) 0022 * (expr) - IDENTIFIER BlkValueRead +0022 IDENTIFIER BlkValueRead 0022 * (expr) - IDENTIFIER txt +0022 IDENTIFIER txt 0022 * (expr) - IDENTIFIER ipos +0022 IDENTIFIER ipos 0022 * (expr) - NUMBER 0 +0022 NUMBER 0 0022 * (code) 0022 * (operation) !store 0022 * (expr) - IDENTIFIER outcome +0022 IDENTIFIER outcome 0023 * (expr) - NUMBER true +0023 NUMBER true 0022 * (statement) !case 0024 * (expr) - IDENTIFIER SOMETIMES_RE_CC +0024 IDENTIFIER SOMETIMES_RE_CC 0024 * (code) 0024 * (operation) !store 0024 * (expr) - IDENTIFIER outcome +0024 IDENTIFIER outcome 0025 * (expr) - NUMBER true +0025 NUMBER true ========= Test: parse schema from: print (char) 'a'; @@ -764,8 +764,8 @@ Test: parse schema from: 0001 * (statement) !printchar 0001 * (expr) - SQUOTED a +0001 SQUOTED a 0002 * (statement) !printchar 0002 * (expr) - SQUOTED ' +0002 SQUOTED ' ========= diff --git a/inter/building-test/Tests/Test Cases/_Results_Ideal/schemas.txt b/inter/building-test/Tests/Test Cases/_Results_Ideal/schemas.txt index ea487aa08..0d68b50da 100644 --- a/inter/building-test/Tests/Test Cases/_Results_Ideal/schemas.txt +++ b/inter/building-test/Tests/Test Cases/_Results_Ideal/schemas.txt @@ -2,100 +2,100 @@ Test: parse schema from: {-say:val:K} 0001 * (expr) - INLINE -say:val:K +0001 INLINE -say:val:K ========= Test: parse schema from: print (number) say__n=({something}); 0001 * (call) 0001 * (expr) - IDENTIFIER LanguageNumber +0001 IDENTIFIER LanguageNumber 0001 * (operation) !store 0001 * (expr) - IDENTIFIER say__n +0001 IDENTIFIER say__n 0001 * (subexpression) 0001 * (expr) - INLINE something +0001 INLINE something ========= Test: parse schema from: STextSubstitution(); 0001 * (call) 0001 * (expr) - IDENTIFIER STextSubstitution +0001 IDENTIFIER STextSubstitution ========= Test: parse schema from: print (PrintTimeOfDayEnglish) {something}; 0001 * (call) 0001 * (expr) - IDENTIFIER PrintTimeOfDayEnglish +0001 IDENTIFIER PrintTimeOfDayEnglish 0001 * (expr) - INLINE something +0001 INLINE something ========= Test: parse schema from: print (a) {something}; 0001 * (call) 0001 * (expr) - IDENTIFIER IndefArt +0001 IDENTIFIER IndefArt 0001 * (expr) - INLINE something +0001 INLINE something ========= Test: parse schema from: print (a) {something}; 0001 * (call) 0001 * (expr) - IDENTIFIER IndefArt +0001 IDENTIFIER IndefArt 0001 * (expr) - INLINE something +0001 INLINE something ========= Test: parse schema from: CIndefArt({something}); 0001 * (call) 0001 * (expr) - IDENTIFIER CIndefArt +0001 IDENTIFIER CIndefArt 0001 * (expr) - INLINE something +0001 INLINE something ========= Test: parse schema from: CIndefArt({something}); 0001 * (call) 0001 * (expr) - IDENTIFIER CIndefArt +0001 IDENTIFIER CIndefArt 0001 * (expr) - INLINE something +0001 INLINE something ========= Test: parse schema from: print (the) {something}; 0001 * (call) 0001 * (expr) - IDENTIFIER DefArt +0001 IDENTIFIER DefArt 0001 * (expr) - INLINE something +0001 INLINE something ========= Test: parse schema from: print (The) {something}; 0001 * (call) 0001 * (expr) - IDENTIFIER CDefArt +0001 IDENTIFIER CDefArt 0001 * (expr) - INLINE something +0001 INLINE something ========= Test: parse schema from: @nop; {-segment-count}: 0001 * (assembly) 0001 * (expr) - OPCODE @nop +0001 OPCODE @nop 0001 * (statement) !case 0001 * (expr) - INLINE -segment-count +0001 INLINE -segment-count 0001 * (code) < ========= Test: parse schema from: @@ -153,7 +153,7 @@ Test: parse schema from: 0001 * (statement) !print 0001 * (expr) - DQUOTED +0001 DQUOTED ========= Test: parse schema from: @@ -161,24 +161,24 @@ Test: parse schema from: 0001 * (call) 0001 * (expr) - IDENTIFIER DivideParagraphPoint +0001 IDENTIFIER DivideParagraphPoint ========= Test: parse schema from: CommandClarificationBreak(); 0001 * (call) 0001 * (expr) - IDENTIFIER CommandClarificationBreak +0001 IDENTIFIER CommandClarificationBreak ========= Test: parse schema from: DivideParagraphPoint(); new_line; 0001 * (call) 0001 * (expr) - IDENTIFIER DivideParagraphPoint +0001 IDENTIFIER DivideParagraphPoint 0001 * (statement) !print 0001 * (expr) - DQUOTED +0001 DQUOTED ========= Test: parse schema from: @@ -186,629 +186,629 @@ Test: parse schema from: 0001 * (call) 0001 * (expr) - IDENTIFIER RunParagraphOn +0001 IDENTIFIER RunParagraphOn ========= Test: parse schema from: SpecialLookSpacingBreak(); 0001 * (call) 0001 * (expr) - IDENTIFIER SpecialLookSpacingBreak +0001 IDENTIFIER SpecialLookSpacingBreak ========= Test: parse schema from: (say__p) 0001 * (subexpression) 0001 * (expr) - IDENTIFIER say__p +0001 IDENTIFIER say__p ========= Test: parse schema from: print "["; 0001 * (statement) !print 0001 * (expr) - DQUOTED [ +0001 DQUOTED [ ========= Test: parse schema from: print "]"; 0001 * (statement) !print 0001 * (expr) - DQUOTED ] +0001 DQUOTED ] ========= Test: parse schema from: print "'"; 0001 * (statement) !print 0001 * (expr) - DQUOTED ' +0001 DQUOTED ' ========= Test: parse schema from: print "~"; 0001 * (statement) !print 0001 * (expr) - DQUOTED " +0001 DQUOTED " ========= Test: parse schema from: style bold; 0001 * (statement) !style 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: style underline; 0001 * (statement) !style 0001 * (expr) - NUMBER 2 +0001 NUMBER 2 ========= Test: parse schema from: style roman; 0001 * (statement) !style 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: font off; 0001 * (statement) !font 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: font on; 0001 * (statement) !font 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: DisplayBoxedQuotation({-box-quotation-text:Q}); 0001 * (call) 0001 * (expr) - IDENTIFIER DisplayBoxedQuotation +0001 IDENTIFIER DisplayBoxedQuotation 0001 * (expr) - INLINE -box-quotation-text:Q +0001 INLINE -box-quotation-text:Q ========= Test: parse schema from: Banner(); 0001 * (call) 0001 * (expr) - IDENTIFIER Banner +0001 IDENTIFIER Banner ========= Test: parse schema from: ShowExtensionVersions(); 0001 * (call) 0001 * (expr) - IDENTIFIER ShowExtensionVersions +0001 IDENTIFIER ShowExtensionVersions ========= Test: parse schema from: ShowFullExtensionVersions(); 0001 * (call) 0001 * (expr) - IDENTIFIER ShowFullExtensionVersions +0001 IDENTIFIER ShowFullExtensionVersions ========= Test: parse schema from: SL_Location(true); 0001 * (call) 0001 * (expr) - IDENTIFIER SL_Location +0001 IDENTIFIER SL_Location 0001 * (expr) - NUMBER true +0001 NUMBER true ========= Test: parse schema from: WriteListFrom(child({O}), {phrase options}); 0001 * (call) 0001 * (expr) - IDENTIFIER WriteListFrom +0001 IDENTIFIER WriteListFrom 0001 * (call) 0001 * (expr) - IDENTIFIER child +0001 IDENTIFIER child 0001 * (expr) - INLINE O +0001 INLINE O 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: c_style = c_style &~ (RECURSE_BIT+FULLINV_BIT+PARTINV_BIT); 0001 * (operation) !store 0001 * (expr) - IDENTIFIER c_style +0001 IDENTIFIER c_style 0001 * (operation) !bitwiseand 0001 * (expr) - IDENTIFIER c_style +0001 IDENTIFIER c_style 0001 * (operation) !bitwisenot 0001 * (subexpression) 0001 * (operation) !plus 0001 * (operation) !plus 0001 * (expr) - IDENTIFIER RECURSE_BIT +0001 IDENTIFIER RECURSE_BIT 0001 * (expr) - IDENTIFIER FULLINV_BIT +0001 IDENTIFIER FULLINV_BIT 0001 * (expr) - IDENTIFIER PARTINV_BIT +0001 IDENTIFIER PARTINV_BIT ========= Test: parse schema from: LIST_OF_TY_Say({-by-reference:L}, 1); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_Say +0001 IDENTIFIER LIST_OF_TY_Say 0001 * (expr) - INLINE -by-reference:L +0001 INLINE -by-reference:L 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_Say({-by-reference:L}, 2); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_Say +0001 IDENTIFIER LIST_OF_TY_Say 0001 * (expr) - INLINE -by-reference:L +0001 INLINE -by-reference:L 0001 * (expr) - NUMBER 2 +0001 NUMBER 2 ========= Test: parse schema from: LIST_OF_TY_Say({-by-reference:L}, 3); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_Say +0001 IDENTIFIER LIST_OF_TY_Say 0001 * (expr) - INLINE -by-reference:L +0001 INLINE -by-reference:L 0001 * (expr) - NUMBER 3 +0001 NUMBER 3 ========= Test: parse schema from: list_filter_routine = {D}; 0001 * (operation) !store 0001 * (expr) - IDENTIFIER list_filter_routine +0001 IDENTIFIER list_filter_routine 0001 * (expr) - INLINE D +0001 INLINE D ========= Test: parse schema from: list_filter_routine = 0; 0001 * (operation) !store 0001 * (expr) - IDENTIFIER list_filter_routine +0001 IDENTIFIER list_filter_routine 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: {cn} 0001 * (expr) - INLINE cn +0001 INLINE cn ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) 0001 * (subexpression) 0001 * (expr) - INLINE -arithmetic-operation:X:Y +0001 INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) 0001 * (subexpression) 0001 * (expr) - INLINE -arithmetic-operation:X:Y +0001 INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) 0001 * (subexpression) 0001 * (expr) - INLINE -arithmetic-operation:X:Y +0001 INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) 0001 * (subexpression) 0001 * (expr) - INLINE -arithmetic-operation:X:Y +0001 INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) 0001 * (subexpression) 0001 * (expr) - INLINE -arithmetic-operation:X:Y +0001 INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) 0001 * (subexpression) 0001 * (expr) - INLINE -arithmetic-operation:X:Y +0001 INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) 0001 * (subexpression) 0001 * (expr) - INLINE -arithmetic-operation:X:Y +0001 INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) 0001 * (subexpression) 0001 * (expr) - INLINE -arithmetic-operation:X:Y +0001 INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) 0001 * (subexpression) 0001 * (expr) - INLINE -arithmetic-operation:X:Y +0001 INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) 0001 * (subexpression) 0001 * (expr) - INLINE -arithmetic-operation:X:Y +0001 INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X:Y}) 0001 * (subexpression) 0001 * (expr) - INLINE -arithmetic-operation:X:Y +0001 INLINE -arithmetic-operation:X:Y ========= Test: parse schema from: ({-arithmetic-operation:X}) 0001 * (subexpression) 0001 * (expr) - INLINE -arithmetic-operation:X +0001 INLINE -arithmetic-operation:X ========= Test: parse schema from: ({-arithmetic-operation:X}) 0001 * (subexpression) 0001 * (expr) - INLINE -arithmetic-operation:X +0001 INLINE -arithmetic-operation:X ========= Test: parse schema from: {-primitive-definition:total-of} 0001 * (expr) - INLINE -primitive-definition:total-of +0001 INLINE -primitive-definition:total-of ========= Test: parse schema from: Float({R}, {N}); 0001 * (call) 0001 * (expr) - IDENTIFIER Float +0001 IDENTIFIER Float 0001 * (expr) - INLINE R +0001 INLINE R 0001 * (expr) - INLINE N +0001 INLINE N ========= Test: parse schema from: FloatDec({R}); 0001 * (call) 0001 * (expr) - IDENTIFIER FloatDec +0001 IDENTIFIER FloatDec 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: FloatDec({R}, {N}); 0001 * (call) 0001 * (expr) - IDENTIFIER FloatDec +0001 IDENTIFIER FloatDec 0001 * (expr) - INLINE R +0001 INLINE R 0001 * (expr) - INLINE N +0001 INLINE N ========= Test: parse schema from: FloatExp({R}); 0001 * (call) 0001 * (expr) - IDENTIFIER FloatExp +0001 IDENTIFIER FloatExp 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: FloatExp({R}, {N}); 0001 * (call) 0001 * (expr) - IDENTIFIER FloatExp +0001 IDENTIFIER FloatExp 0001 * (expr) - INLINE R +0001 INLINE R 0001 * (expr) - INLINE N +0001 INLINE N ========= Test: parse schema from: REAL_NUMBER_TY_Reciprocal({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Reciprocal +0001 IDENTIFIER REAL_NUMBER_TY_Reciprocal 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Abs({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Abs +0001 IDENTIFIER REAL_NUMBER_TY_Abs 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Root({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Root +0001 IDENTIFIER REAL_NUMBER_TY_Root 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Ceiling({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Ceiling +0001 IDENTIFIER REAL_NUMBER_TY_Ceiling 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Floor({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Floor +0001 IDENTIFIER REAL_NUMBER_TY_Floor 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_to_NUMBER_TY({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_to_NUMBER_TY +0001 IDENTIFIER REAL_NUMBER_TY_to_NUMBER_TY 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Log({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Log +0001 IDENTIFIER REAL_NUMBER_TY_Log 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_BLog({R}, {N}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_BLog +0001 IDENTIFIER REAL_NUMBER_TY_BLog 0001 * (expr) - INLINE R +0001 INLINE R 0001 * (expr) - INLINE N +0001 INLINE N ========= Test: parse schema from: REAL_NUMBER_TY_Exp({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Exp +0001 IDENTIFIER REAL_NUMBER_TY_Exp 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Pow({R}, {P}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Pow +0001 IDENTIFIER REAL_NUMBER_TY_Pow 0001 * (expr) - INLINE R +0001 INLINE R 0001 * (expr) - INLINE P +0001 INLINE P ========= Test: parse schema from: REAL_NUMBER_TY_Times({R}, $+0.0174532925) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Times +0001 IDENTIFIER REAL_NUMBER_TY_Times 0001 * (expr) - INLINE R +0001 INLINE R 0001 * (expr) - REAL_NUMBER $+0.0174532925 +0001 REAL_NUMBER $+0.0174532925 ========= Test: parse schema from: REAL_NUMBER_TY_Sin({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Sin +0001 IDENTIFIER REAL_NUMBER_TY_Sin 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Cos({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Cos +0001 IDENTIFIER REAL_NUMBER_TY_Cos 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Tan({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Tan +0001 IDENTIFIER REAL_NUMBER_TY_Tan 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Arcsin({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Arcsin +0001 IDENTIFIER REAL_NUMBER_TY_Arcsin 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Arccos({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Arccos +0001 IDENTIFIER REAL_NUMBER_TY_Arccos 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Arctan({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Arctan +0001 IDENTIFIER REAL_NUMBER_TY_Arctan 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Sinh({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Sinh +0001 IDENTIFIER REAL_NUMBER_TY_Sinh 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Cosh({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Cosh +0001 IDENTIFIER REAL_NUMBER_TY_Cosh 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: REAL_NUMBER_TY_Tanh({R}) 0001 * (call) 0001 * (expr) - IDENTIFIER REAL_NUMBER_TY_Tanh +0001 IDENTIFIER REAL_NUMBER_TY_Tanh 0001 * (expr) - INLINE R +0001 INLINE R ========= Test: parse schema from: {-primitive-definition:number-of} 0001 * (expr) - INLINE -primitive-definition:number-of +0001 INLINE -primitive-definition:number-of ========= Test: parse schema from: {-next-routine:K}({X}) 0001 * (call) 0001 * (expr) - INLINE -next-routine:K +0001 INLINE -next-routine:K 0001 * (expr) - INLINE X +0001 INLINE X ========= Test: parse schema from: {-previous-routine:K}({X}) 0001 * (call) 0001 * (expr) - INLINE -previous-routine:K +0001 INLINE -previous-routine:K 0001 * (expr) - INLINE X +0001 INLINE X ========= Test: parse schema from: ({C}) 0001 * (subexpression) 0001 * (expr) - INLINE C +0001 INLINE C ========= Test: parse schema from: {-primitive-definition:random-of} 0001 * (expr) - INLINE -primitive-definition:random-of +0001 INLINE -primitive-definition:random-of ========= Test: parse schema from: {-ranger-routine:K}({first value}, {second value}) 0001 * (call) 0001 * (expr) - INLINE -ranger-routine:K +0001 INLINE -ranger-routine:K 0001 * (expr) - INLINE first value +0001 INLINE first value 0001 * (expr) - INLINE second value +0001 INLINE second value ========= Test: parse schema from: {-ranger-routine:K}({first value}, {second value}) 0001 * (call) 0001 * (expr) - INLINE -ranger-routine:K +0001 INLINE -ranger-routine:K 0001 * (expr) - INLINE first value +0001 INLINE first value 0001 * (expr) - INLINE second value +0001 INLINE second value ========= Test: parse schema from: {-ranger-routine:K}({first value}, {second value}) 0001 * (call) 0001 * (expr) - INLINE -ranger-routine:K +0001 INLINE -ranger-routine:K 0001 * (expr) - INLINE first value +0001 INLINE first value 0001 * (expr) - INLINE second value +0001 INLINE second value ========= Test: parse schema from: {-ranger-routine:K}({first value}, {second value}) 0001 * (call) 0001 * (expr) - INLINE -ranger-routine:K +0001 INLINE -ranger-routine:K 0001 * (expr) - INLINE first value +0001 INLINE first value 0001 * (expr) - INLINE second value +0001 INLINE second value ========= Test: parse schema from: (GenerateRandomNumber(1, {M}) <= {N}) @@ -817,125 +817,125 @@ Test: parse schema from: 0001 * (operation) !le 0001 * (call) 0001 * (expr) - IDENTIFIER GenerateRandomNumber +0001 IDENTIFIER GenerateRandomNumber 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (expr) - INLINE M +0001 INLINE M 0001 * (expr) - INLINE N +0001 INLINE N ========= Test: parse schema from: VM_Seed_RNG({N}); 0001 * (call) 0001 * (expr) - IDENTIFIER VM_Seed_RNG +0001 IDENTIFIER VM_Seed_RNG 0001 * (expr) - INLINE N +0001 INLINE N ========= Test: parse schema from: {-my:ct_0} = {T}; {-my:ct_1} = {N}; 0001 * (operation) !store 0001 * (expr) - INLINE -my:ct_0 +0001 INLINE -my:ct_0 0001 * (expr) - INLINE T +0001 INLINE T 0001 * (operation) !store 0001 * (expr) - INLINE -my:ct_1 +0001 INLINE -my:ct_1 0001 * (expr) - INLINE N +0001 INLINE N ========= Test: parse schema from: {-my:ct_0} = {T}; {-my:ct_1} = TableRowCorr(ct_0, {TC}, {w}); 0001 * (operation) !store 0001 * (expr) - INLINE -my:ct_0 +0001 INLINE -my:ct_0 0001 * (expr) - INLINE T +0001 INLINE T 0001 * (operation) !store 0001 * (expr) - INLINE -my:ct_1 +0001 INLINE -my:ct_1 0001 * (call) 0001 * (expr) - IDENTIFIER TableRowCorr +0001 IDENTIFIER TableRowCorr 0001 * (expr) - IDENTIFIER ct_0 +0001 IDENTIFIER ct_0 0001 * (expr) - INLINE TC +0001 INLINE TC 0001 * (expr) - INLINE w +0001 INLINE w ========= Test: parse schema from: {-my:ct_0} = {T}; {-my:ct_1} = TableBlankRow(ct_0); 0001 * (operation) !store 0001 * (expr) - INLINE -my:ct_0 +0001 INLINE -my:ct_0 0001 * (expr) - INLINE T +0001 INLINE T 0001 * (operation) !store 0001 * (expr) - INLINE -my:ct_1 +0001 INLINE -my:ct_1 0001 * (call) 0001 * (expr) - IDENTIFIER TableBlankRow +0001 IDENTIFIER TableBlankRow 0001 * (expr) - IDENTIFIER ct_0 +0001 IDENTIFIER ct_0 ========= Test: parse schema from: {-my:ct_0} = {T}; {-my:ct_1} = TableRandomRow(ct_0); 0001 * (operation) !store 0001 * (expr) - INLINE -my:ct_0 +0001 INLINE -my:ct_0 0001 * (expr) - INLINE T +0001 INLINE T 0001 * (operation) !store 0001 * (expr) - INLINE -my:ct_1 +0001 INLINE -my:ct_1 0001 * (call) 0001 * (expr) - IDENTIFIER TableRandomRow +0001 IDENTIFIER TableRandomRow 0001 * (expr) - IDENTIFIER ct_0 +0001 IDENTIFIER ct_0 ========= Test: parse schema from: TableRows({T}) 0001 * (call) 0001 * (expr) - IDENTIFIER TableRows +0001 IDENTIFIER TableRows 0001 * (expr) - INLINE T +0001 INLINE T ========= Test: parse schema from: TableBlankRows({T}) 0001 * (call) 0001 * (expr) - IDENTIFIER TableBlankRows +0001 IDENTIFIER TableBlankRows 0001 * (expr) - INLINE T +0001 INLINE T ========= Test: parse schema from: TableFilledRows({T}) 0001 * (call) 0001 * (expr) - IDENTIFIER TableFilledRows +0001 IDENTIFIER TableFilledRows 0001 * (expr) - INLINE T +0001 INLINE T ========= Test: parse schema from: ({-reference-exists:TR}) 0001 * (subexpression) 0001 * (expr) - INLINE -reference-exists:TR +0001 INLINE -reference-exists:TR ========= Test: parse schema from: ({-reference-exists:TR} == false) @@ -943,877 +943,877 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !eq 0001 * (expr) - INLINE -reference-exists:TR +0001 INLINE -reference-exists:TR 0001 * (expr) - NUMBER false +0001 NUMBER false ========= Test: parse schema from: {-by-reference-blank-out:tr}; 0001 * (expr) ; - INLINE -by-reference-blank-out:tr +0001 INLINE -by-reference-blank-out:tr ========= Test: parse schema from: TableBlankOutRow({-my:ct_0}, {-my:ct_1}); 0001 * (call) 0001 * (expr) - IDENTIFIER TableBlankOutRow +0001 IDENTIFIER TableBlankOutRow 0001 * (expr) - INLINE -my:ct_0 +0001 INLINE -my:ct_0 0001 * (expr) - INLINE -my:ct_1 +0001 INLINE -my:ct_1 ========= Test: parse schema from: TableBlankOutColumn({T}, {TC}); 0001 * (call) 0001 * (expr) - IDENTIFIER TableBlankOutColumn +0001 IDENTIFIER TableBlankOutColumn 0001 * (expr) - INLINE T +0001 INLINE T 0001 * (expr) - INLINE TC +0001 INLINE TC ========= Test: parse schema from: TableBlankOutAll({T}); 0001 * (call) 0001 * (expr) - IDENTIFIER TableBlankOutAll +0001 IDENTIFIER TableBlankOutAll 0001 * (expr) - INLINE T +0001 INLINE T ========= Test: parse schema from: TableDebug({T}); 0001 * (call) 0001 * (expr) - IDENTIFIER TableDebug +0001 IDENTIFIER TableDebug 0001 * (expr) - INLINE T +0001 INLINE T ========= Test: parse schema from: TableRowDebug({-my:ct_0}, {-my:ct_1}); 0001 * (call) 0001 * (expr) - IDENTIFIER TableRowDebug +0001 IDENTIFIER TableRowDebug 0001 * (expr) - INLINE -my:ct_0 +0001 INLINE -my:ct_0 0001 * (expr) - INLINE -my:ct_1 +0001 INLINE -my:ct_1 ========= Test: parse schema from: TableRowDebug({T}, {N}); 0001 * (call) 0001 * (expr) - IDENTIFIER TableRowDebug +0001 IDENTIFIER TableRowDebug 0001 * (expr) - INLINE T +0001 INLINE T 0001 * (expr) - INLINE N +0001 INLINE N ========= Test: parse schema from: TableColumnDebug({T}, {TC}); 0001 * (call) 0001 * (expr) - IDENTIFIER TableColumnDebug +0001 IDENTIFIER TableColumnDebug 0001 * (expr) - INLINE T +0001 INLINE T 0001 * (expr) - INLINE TC +0001 INLINE TC ========= Test: parse schema from: TableShuffle({T}); 0001 * (call) 0001 * (expr) - IDENTIFIER TableShuffle +0001 IDENTIFIER TableShuffle 0001 * (expr) - INLINE T +0001 INLINE T ========= Test: parse schema from: TableSort({T}, {TC}, 1); 0001 * (call) 0001 * (expr) - IDENTIFIER TableSort +0001 IDENTIFIER TableSort 0001 * (expr) - INLINE T +0001 INLINE T 0001 * (expr) - INLINE TC +0001 INLINE TC 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: TableSort({T}, {TC}, -1); 0001 * (call) 0001 * (expr) - IDENTIFIER TableSort +0001 IDENTIFIER TableSort 0001 * (expr) - INLINE T +0001 INLINE T 0001 * (expr) - INLINE TC +0001 INLINE TC 0001 * (operation) !unaryminus 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: TEXT_TY_BlobAccess({-by-reference:T}, CHR_BLOB) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_BlobAccess +0001 IDENTIFIER TEXT_TY_BlobAccess 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - IDENTIFIER CHR_BLOB +0001 IDENTIFIER CHR_BLOB ========= Test: parse schema from: TEXT_TY_BlobAccess({-by-reference:T}, WORD_BLOB) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_BlobAccess +0001 IDENTIFIER TEXT_TY_BlobAccess 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - IDENTIFIER WORD_BLOB +0001 IDENTIFIER WORD_BLOB ========= Test: parse schema from: TEXT_TY_BlobAccess({-by-reference:T}, PWORD_BLOB) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_BlobAccess +0001 IDENTIFIER TEXT_TY_BlobAccess 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - IDENTIFIER PWORD_BLOB +0001 IDENTIFIER PWORD_BLOB ========= Test: parse schema from: TEXT_TY_BlobAccess({-by-reference:T}, UWORD_BLOB) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_BlobAccess +0001 IDENTIFIER TEXT_TY_BlobAccess 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - IDENTIFIER UWORD_BLOB +0001 IDENTIFIER UWORD_BLOB ========= Test: parse schema from: TEXT_TY_BlobAccess({-by-reference:T}, LINE_BLOB) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_BlobAccess +0001 IDENTIFIER TEXT_TY_BlobAccess 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - IDENTIFIER LINE_BLOB +0001 IDENTIFIER LINE_BLOB ========= Test: parse schema from: TEXT_TY_BlobAccess({-by-reference:T}, PARA_BLOB) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_BlobAccess +0001 IDENTIFIER TEXT_TY_BlobAccess 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - IDENTIFIER PARA_BLOB +0001 IDENTIFIER PARA_BLOB ========= Test: parse schema from: TEXT_TY_GetBlob({-new:text}, {-by-reference:T}, {N}, CHR_BLOB) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_GetBlob +0001 IDENTIFIER TEXT_TY_GetBlob 0001 * (expr) - INLINE -new:text +0001 INLINE -new:text 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - IDENTIFIER CHR_BLOB +0001 IDENTIFIER CHR_BLOB ========= Test: parse schema from: TEXT_TY_GetBlob({-new:text}, {-by-reference:T}, {N}, WORD_BLOB) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_GetBlob +0001 IDENTIFIER TEXT_TY_GetBlob 0001 * (expr) - INLINE -new:text +0001 INLINE -new:text 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - IDENTIFIER WORD_BLOB +0001 IDENTIFIER WORD_BLOB ========= Test: parse schema from: TEXT_TY_GetBlob({-new:text}, {-by-reference:T}, {N}, PWORD_BLOB) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_GetBlob +0001 IDENTIFIER TEXT_TY_GetBlob 0001 * (expr) - INLINE -new:text +0001 INLINE -new:text 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - IDENTIFIER PWORD_BLOB +0001 IDENTIFIER PWORD_BLOB ========= Test: parse schema from: TEXT_TY_GetBlob({-new:text}, {-by-reference:T}, {N}, UWORD_BLOB) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_GetBlob +0001 IDENTIFIER TEXT_TY_GetBlob 0001 * (expr) - INLINE -new:text +0001 INLINE -new:text 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - IDENTIFIER UWORD_BLOB +0001 IDENTIFIER UWORD_BLOB ========= Test: parse schema from: TEXT_TY_GetBlob({-new:text}, {-by-reference:T}, {N}, LINE_BLOB) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_GetBlob +0001 IDENTIFIER TEXT_TY_GetBlob 0001 * (expr) - INLINE -new:text +0001 INLINE -new:text 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - IDENTIFIER LINE_BLOB +0001 IDENTIFIER LINE_BLOB ========= Test: parse schema from: TEXT_TY_GetBlob({-new:text}, {-by-reference:T}, {N}, PARA_BLOB) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_GetBlob +0001 IDENTIFIER TEXT_TY_GetBlob 0001 * (expr) - INLINE -new:text +0001 INLINE -new:text 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - IDENTIFIER PARA_BLOB +0001 IDENTIFIER PARA_BLOB ========= Test: parse schema from: TEXT_TY_SubstitutedForm({-new:text}, {-by-reference:T}) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_SubstitutedForm +0001 IDENTIFIER TEXT_TY_SubstitutedForm 0001 * (expr) - INLINE -new:text +0001 INLINE -new:text 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T ========= Test: parse schema from: TEXT_TY_Replace_RE(CHR_BLOB,{-by-reference:T},{-by-reference:find},0,{phrase options},1) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_Replace_RE +0001 IDENTIFIER TEXT_TY_Replace_RE 0001 * (expr) - IDENTIFIER CHR_BLOB +0001 IDENTIFIER CHR_BLOB 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - INLINE -by-reference:find +0001 INLINE -by-reference:find 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: TEXT_TY_Replace_RE(CHR_BLOB,{-by-reference:T},{-by-reference:find},0,{phrase options}) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_Replace_RE +0001 IDENTIFIER TEXT_TY_Replace_RE 0001 * (expr) - IDENTIFIER CHR_BLOB +0001 IDENTIFIER CHR_BLOB 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - INLINE -by-reference:find +0001 INLINE -by-reference:find 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: TEXT_TY_Replace_RE(CHR_BLOB,{-by-reference:T},{-by-reference:find},1,{phrase options}) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_Replace_RE +0001 IDENTIFIER TEXT_TY_Replace_RE 0001 * (expr) - IDENTIFIER CHR_BLOB +0001 IDENTIFIER CHR_BLOB 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - INLINE -by-reference:find +0001 INLINE -by-reference:find 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: TEXT_TY_Replace_RE(REGEXP_BLOB,{-by-reference:T},{-by-reference:find},0,{phrase options},1) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_Replace_RE +0001 IDENTIFIER TEXT_TY_Replace_RE 0001 * (expr) - IDENTIFIER REGEXP_BLOB +0001 IDENTIFIER REGEXP_BLOB 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - INLINE -by-reference:find +0001 INLINE -by-reference:find 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: TEXT_TY_Replace_RE(REGEXP_BLOB,{-by-reference:T},{-by-reference:find},0,{phrase options}) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_Replace_RE +0001 IDENTIFIER TEXT_TY_Replace_RE 0001 * (expr) - IDENTIFIER REGEXP_BLOB +0001 IDENTIFIER REGEXP_BLOB 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - INLINE -by-reference:find +0001 INLINE -by-reference:find 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: TEXT_TY_RE_GetMatchVar(0) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_RE_GetMatchVar +0001 IDENTIFIER TEXT_TY_RE_GetMatchVar 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: TEXT_TY_RE_GetMatchVar({N}) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_RE_GetMatchVar +0001 IDENTIFIER TEXT_TY_RE_GetMatchVar 0001 * (expr) - INLINE N +0001 INLINE N ========= Test: parse schema from: TEXT_TY_Replace_RE(REGEXP_BLOB,{-by-reference:T},{-by-reference:find},1,{phrase options}) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_Replace_RE +0001 IDENTIFIER TEXT_TY_Replace_RE 0001 * (expr) - IDENTIFIER REGEXP_BLOB +0001 IDENTIFIER REGEXP_BLOB 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - INLINE -by-reference:find +0001 INLINE -by-reference:find 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: TEXT_TY_ReplaceText(WORD_BLOB, {-lvalue-by-reference:T}, {-by-reference:find}, {-by-reference:replace}); 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_ReplaceText +0001 IDENTIFIER TEXT_TY_ReplaceText 0001 * (expr) - IDENTIFIER WORD_BLOB +0001 IDENTIFIER WORD_BLOB 0001 * (expr) - INLINE -lvalue-by-reference:T +0001 INLINE -lvalue-by-reference:T 0001 * (expr) - INLINE -by-reference:find +0001 INLINE -by-reference:find 0001 * (expr) - INLINE -by-reference:replace +0001 INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_ReplaceText(PWORD_BLOB, {-lvalue-by-reference:T}, {-by-reference:find}, {-by-reference:replace}); 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_ReplaceText +0001 IDENTIFIER TEXT_TY_ReplaceText 0001 * (expr) - IDENTIFIER PWORD_BLOB +0001 IDENTIFIER PWORD_BLOB 0001 * (expr) - INLINE -lvalue-by-reference:T +0001 INLINE -lvalue-by-reference:T 0001 * (expr) - INLINE -by-reference:find +0001 INLINE -by-reference:find 0001 * (expr) - INLINE -by-reference:replace +0001 INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_ReplaceBlob(CHR_BLOB, {-lvalue-by-reference:T}, {N}, {-by-reference:replace}); 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_ReplaceBlob +0001 IDENTIFIER TEXT_TY_ReplaceBlob 0001 * (expr) - IDENTIFIER CHR_BLOB +0001 IDENTIFIER CHR_BLOB 0001 * (expr) - INLINE -lvalue-by-reference:T +0001 INLINE -lvalue-by-reference:T 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - INLINE -by-reference:replace +0001 INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_ReplaceBlob(WORD_BLOB, {-lvalue-by-reference:T}, {N}, {-by-reference:replace}); 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_ReplaceBlob +0001 IDENTIFIER TEXT_TY_ReplaceBlob 0001 * (expr) - IDENTIFIER WORD_BLOB +0001 IDENTIFIER WORD_BLOB 0001 * (expr) - INLINE -lvalue-by-reference:T +0001 INLINE -lvalue-by-reference:T 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - INLINE -by-reference:replace +0001 INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_ReplaceBlob(PWORD_BLOB, {-lvalue-by-reference:T}, {N}, {-by-reference:replace}); 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_ReplaceBlob +0001 IDENTIFIER TEXT_TY_ReplaceBlob 0001 * (expr) - IDENTIFIER PWORD_BLOB +0001 IDENTIFIER PWORD_BLOB 0001 * (expr) - INLINE -lvalue-by-reference:T +0001 INLINE -lvalue-by-reference:T 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - INLINE -by-reference:replace +0001 INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_ReplaceBlob(UWORD_BLOB, {-lvalue-by-reference:T}, {N}, {-by-reference:replace}); 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_ReplaceBlob +0001 IDENTIFIER TEXT_TY_ReplaceBlob 0001 * (expr) - IDENTIFIER UWORD_BLOB +0001 IDENTIFIER UWORD_BLOB 0001 * (expr) - INLINE -lvalue-by-reference:T +0001 INLINE -lvalue-by-reference:T 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - INLINE -by-reference:replace +0001 INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_ReplaceBlob(LINE_BLOB, {-lvalue-by-reference:T}, {N}, {-by-reference:replace}); 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_ReplaceBlob +0001 IDENTIFIER TEXT_TY_ReplaceBlob 0001 * (expr) - IDENTIFIER LINE_BLOB +0001 IDENTIFIER LINE_BLOB 0001 * (expr) - INLINE -lvalue-by-reference:T +0001 INLINE -lvalue-by-reference:T 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - INLINE -by-reference:replace +0001 INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_ReplaceBlob(PARA_BLOB, {-lvalue-by-reference:T}, {N}, {-by-reference:replace}); 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_ReplaceBlob +0001 IDENTIFIER TEXT_TY_ReplaceBlob 0001 * (expr) - IDENTIFIER PARA_BLOB +0001 IDENTIFIER PARA_BLOB 0001 * (expr) - INLINE -lvalue-by-reference:T +0001 INLINE -lvalue-by-reference:T 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - INLINE -by-reference:replace +0001 INLINE -by-reference:replace ========= Test: parse schema from: TEXT_TY_CharactersToCase({-new:text}, {-by-reference:T}, 0) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_CharactersToCase +0001 IDENTIFIER TEXT_TY_CharactersToCase 0001 * (expr) - INLINE -new:text +0001 INLINE -new:text 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: TEXT_TY_CharactersToCase({-new:text}, {-by-reference:T}, 1) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_CharactersToCase +0001 IDENTIFIER TEXT_TY_CharactersToCase 0001 * (expr) - INLINE -new:text +0001 INLINE -new:text 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: TEXT_TY_CharactersToCase({-new:text}, {-by-reference:T}, 2) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_CharactersToCase +0001 IDENTIFIER TEXT_TY_CharactersToCase 0001 * (expr) - INLINE -new:text +0001 INLINE -new:text 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - NUMBER 2 +0001 NUMBER 2 ========= Test: parse schema from: TEXT_TY_CharactersToCase({-new:text}, {-by-reference:T}, 3) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_CharactersToCase +0001 IDENTIFIER TEXT_TY_CharactersToCase 0001 * (expr) - INLINE -new:text +0001 INLINE -new:text 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - NUMBER 3 +0001 NUMBER 3 ========= Test: parse schema from: TEXT_TY_CharactersOfCase({-by-reference:T}, 0) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_CharactersOfCase +0001 IDENTIFIER TEXT_TY_CharactersOfCase 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: TEXT_TY_CharactersOfCase({-by-reference:T}, 1) 0001 * (call) 0001 * (expr) - IDENTIFIER TEXT_TY_CharactersOfCase +0001 IDENTIFIER TEXT_TY_CharactersOfCase 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: {V}(1); 0001 * (call) 0001 * (expr) - INLINE V +0001 INLINE V 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: {V}(2); 0001 * (call) 0001 * (expr) - INLINE V +0001 INLINE V 0001 * (expr) - NUMBER 2 +0001 NUMBER 2 ========= Test: parse schema from: {V}(3); 0001 * (call) 0001 * (expr) - INLINE V +0001 INLINE V 0001 * (expr) - NUMBER 3 +0001 NUMBER 3 ========= Test: parse schema from: {V}(CV_POS, PNToVP(), story_tense); 0001 * (call) 0001 * (expr) - INLINE V +0001 INLINE V 0001 * (expr) - IDENTIFIER CV_POS +0001 IDENTIFIER CV_POS 0001 * (call) 0001 * (expr) - IDENTIFIER PNToVP +0001 IDENTIFIER PNToVP 0001 * (expr) - IDENTIFIER story_tense +0001 IDENTIFIER story_tense ========= Test: parse schema from: {V}(CV_POS, PNToVP(), {T}); 0001 * (call) 0001 * (expr) - INLINE V +0001 INLINE V 0001 * (expr) - IDENTIFIER CV_POS +0001 IDENTIFIER CV_POS 0001 * (call) 0001 * (expr) - IDENTIFIER PNToVP +0001 IDENTIFIER PNToVP 0001 * (expr) - INLINE T +0001 INLINE T ========= Test: parse schema from: {V}(CV_POS, {P}, story_tense); 0001 * (call) 0001 * (expr) - INLINE V +0001 INLINE V 0001 * (expr) - IDENTIFIER CV_POS +0001 IDENTIFIER CV_POS 0001 * (expr) - INLINE P +0001 INLINE P 0001 * (expr) - IDENTIFIER story_tense +0001 IDENTIFIER story_tense ========= Test: parse schema from: {V}(CV_POS, {P}, {T}); 0001 * (call) 0001 * (expr) - INLINE V +0001 INLINE V 0001 * (expr) - IDENTIFIER CV_POS +0001 IDENTIFIER CV_POS 0001 * (expr) - INLINE P +0001 INLINE P 0001 * (expr) - INLINE T +0001 INLINE T ========= Test: parse schema from: {V}(CV_NEG, PNToVP(), story_tense); 0001 * (call) 0001 * (expr) - INLINE V +0001 INLINE V 0001 * (expr) - IDENTIFIER CV_NEG +0001 IDENTIFIER CV_NEG 0001 * (call) 0001 * (expr) - IDENTIFIER PNToVP +0001 IDENTIFIER PNToVP 0001 * (expr) - IDENTIFIER story_tense +0001 IDENTIFIER story_tense ========= Test: parse schema from: {V}(CV_NEG, PNToVP(), {T}); 0001 * (call) 0001 * (expr) - INLINE V +0001 INLINE V 0001 * (expr) - IDENTIFIER CV_NEG +0001 IDENTIFIER CV_NEG 0001 * (call) 0001 * (expr) - IDENTIFIER PNToVP +0001 IDENTIFIER PNToVP 0001 * (expr) - INLINE T +0001 INLINE T ========= Test: parse schema from: {V}(CV_NEG, {P}, story_tense); 0001 * (call) 0001 * (expr) - INLINE V +0001 INLINE V 0001 * (expr) - IDENTIFIER CV_NEG +0001 IDENTIFIER CV_NEG 0001 * (expr) - INLINE P +0001 INLINE P 0001 * (expr) - IDENTIFIER story_tense +0001 IDENTIFIER story_tense ========= Test: parse schema from: {V}(CV_NEG, {P}, {T}); 0001 * (call) 0001 * (expr) - INLINE V +0001 INLINE V 0001 * (expr) - IDENTIFIER CV_NEG +0001 IDENTIFIER CV_NEG 0001 * (expr) - INLINE P +0001 INLINE P 0001 * (expr) - INLINE T +0001 INLINE T ========= Test: parse schema from: {V}(CV_MEANING) 0001 * (call) 0001 * (expr) - INLINE V +0001 INLINE V 0001 * (expr) - IDENTIFIER CV_MEANING +0001 IDENTIFIER CV_MEANING ========= Test: parse schema from: LIST_OF_TY_InsertItem({-lvalue-by-reference:L}, {new entry}, 0, 0, {phrase options}); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_InsertItem +0001 IDENTIFIER LIST_OF_TY_InsertItem 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - INLINE new entry +0001 INLINE new entry 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: LIST_OF_TY_InsertItem({-lvalue-by-reference:L}, {new entry}, 1, {E}, {phrase options}); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_InsertItem +0001 IDENTIFIER LIST_OF_TY_InsertItem 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - INLINE new entry +0001 INLINE new entry 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (expr) - INLINE E +0001 INLINE E 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: LIST_OF_TY_AppendList({-lvalue-by-reference:L}, {-by-reference:LX}, 0, 0, {phrase options}); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_AppendList +0001 IDENTIFIER LIST_OF_TY_AppendList 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - INLINE -by-reference:LX +0001 INLINE -by-reference:LX 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: LIST_OF_TY_AppendList({-lvalue-by-reference:L}, {-by-reference:LX}, 1, {E}, 0); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_AppendList +0001 IDENTIFIER LIST_OF_TY_AppendList 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - INLINE -by-reference:LX +0001 INLINE -by-reference:LX 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (expr) - INLINE E +0001 INLINE E 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: LIST_OF_TY_RemoveValue({-lvalue-by-reference:L}, {existing entry}, {phrase options}); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_RemoveValue +0001 IDENTIFIER LIST_OF_TY_RemoveValue 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - INLINE existing entry +0001 INLINE existing entry 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: LIST_OF_TY_Remove_List({-lvalue-by-reference:L}, {-by-reference:N}, {phrase options}); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_Remove_List +0001 IDENTIFIER LIST_OF_TY_Remove_List 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - INLINE -by-reference:N +0001 INLINE -by-reference:N 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: LIST_OF_TY_RemoveItemRange({-lvalue-by-reference:L}, {N}, {N}, {phrase options}); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_RemoveItemRange +0001 IDENTIFIER LIST_OF_TY_RemoveItemRange 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: LIST_OF_TY_RemoveItemRange({-lvalue-by-reference:L}, {N}, {N2}, {phrase options}); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_RemoveItemRange +0001 IDENTIFIER LIST_OF_TY_RemoveItemRange 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - INLINE N2 +0001 INLINE N2 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: (LIST_OF_TY_FindItem({-by-reference:L}, {N})) @@ -1821,11 +1821,11 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_FindItem +0001 IDENTIFIER LIST_OF_TY_FindItem 0001 * (expr) - INLINE -by-reference:L +0001 INLINE -by-reference:L 0001 * (expr) - INLINE N +0001 INLINE N ========= Test: parse schema from: (LIST_OF_TY_FindItem({-by-reference:L}, {N}) == false) @@ -1834,513 +1834,513 @@ Test: parse schema from: 0001 * (operation) !eq 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_FindItem +0001 IDENTIFIER LIST_OF_TY_FindItem 0001 * (expr) - INLINE -by-reference:L +0001 INLINE -by-reference:L 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - NUMBER false +0001 NUMBER false ========= Test: parse schema from: {-new-list-of:list of K} 0001 * (expr) - INLINE -new-list-of:list of K +0001 INLINE -new-list-of:list of K ========= Test: parse schema from: LIST_OF_TY_Mol({-new:list of objects}) 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_Mol +0001 IDENTIFIER LIST_OF_TY_Mol 0001 * (expr) - INLINE -new:list of objects +0001 INLINE -new:list of objects ========= Test: parse schema from: LIST_OF_TY_Set_Mol({-by-reference:L}); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_Set_Mol +0001 IDENTIFIER LIST_OF_TY_Set_Mol 0001 * (expr) - INLINE -by-reference:L +0001 INLINE -by-reference:L ========= Test: parse schema from: LIST_OF_TY_GetLength({-by-reference:L}) 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_GetLength +0001 IDENTIFIER LIST_OF_TY_GetLength 0001 * (expr) - INLINE -by-reference:L +0001 INLINE -by-reference:L ========= Test: parse schema from: LIST_OF_TY_SetLength({-lvalue-by-reference:L}, {N}, -1, 1); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_SetLength +0001 IDENTIFIER LIST_OF_TY_SetLength 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (operation) !unaryminus 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_SetLength({-lvalue-by-reference:L}, {N}, -1, 1); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_SetLength +0001 IDENTIFIER LIST_OF_TY_SetLength 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (operation) !unaryminus 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_SetLength({-lvalue-by-reference:L}, {N}, -1, -1); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_SetLength +0001 IDENTIFIER LIST_OF_TY_SetLength 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (operation) !unaryminus 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (operation) !unaryminus 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_SetLength({-lvalue-by-reference:L}, {N}, 1); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_SetLength +0001 IDENTIFIER LIST_OF_TY_SetLength 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_SetLength({-lvalue-by-reference:L}, {N}, 0); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_SetLength +0001 IDENTIFIER LIST_OF_TY_SetLength 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - INLINE N +0001 INLINE N 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: LIST_OF_TY_Reverse({-lvalue-by-reference:L}); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_Reverse +0001 IDENTIFIER LIST_OF_TY_Reverse 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L ========= Test: parse schema from: LIST_OF_TY_Rotate({-lvalue-by-reference:L}, 0); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_Rotate +0001 IDENTIFIER LIST_OF_TY_Rotate 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: LIST_OF_TY_Rotate({-lvalue-by-reference:L}, 1); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_Rotate +0001 IDENTIFIER LIST_OF_TY_Rotate 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_Sort({-lvalue-by-reference:L}, 1); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_Sort +0001 IDENTIFIER LIST_OF_TY_Sort 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_Sort({-lvalue-by-reference:L}, -1); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_Sort +0001 IDENTIFIER LIST_OF_TY_Sort 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (operation) !unaryminus 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: LIST_OF_TY_Sort({-lvalue-by-reference:L}, 2); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_Sort +0001 IDENTIFIER LIST_OF_TY_Sort 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - NUMBER 2 +0001 NUMBER 2 ========= Test: parse schema from: LIST_OF_TY_Sort({-lvalue-by-reference:L}, 1, {P}, {-property-holds-block-value:P}); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_Sort +0001 IDENTIFIER LIST_OF_TY_Sort 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (expr) - INLINE P +0001 INLINE P 0001 * (expr) - INLINE -property-holds-block-value:P +0001 INLINE -property-holds-block-value:P ========= Test: parse schema from: LIST_OF_TY_Sort({-lvalue-by-reference:L}, -1, {P}, {-property-holds-block-value:P}); 0001 * (call) 0001 * (expr) - IDENTIFIER LIST_OF_TY_Sort +0001 IDENTIFIER LIST_OF_TY_Sort 0001 * (expr) - INLINE -lvalue-by-reference:L +0001 INLINE -lvalue-by-reference:L 0001 * (operation) !unaryminus 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (expr) - INLINE P +0001 INLINE P 0001 * (expr) - INLINE -property-holds-block-value:P +0001 INLINE -property-holds-block-value:P ========= Test: parse schema from: {-show-me:R}; RelationTest({-by-reference:R}, RELS_SHOW); 0001 * (expr) ; - INLINE -show-me:R +0001 INLINE -show-me:R 0001 * (call) 0001 * (expr) - IDENTIFIER RelationTest +0001 IDENTIFIER RelationTest 0001 * (expr) - INLINE -by-reference:R +0001 INLINE -by-reference:R 0001 * (expr) - IDENTIFIER RELS_SHOW +0001 IDENTIFIER RELS_SHOW ========= Test: parse schema from: RelationRouteTo({-by-reference:R},{O1},{O2},false) 0001 * (call) 0001 * (expr) - IDENTIFIER RelationRouteTo +0001 IDENTIFIER RelationRouteTo 0001 * (expr) - INLINE -by-reference:R +0001 INLINE -by-reference:R 0001 * (expr) - INLINE O1 +0001 INLINE O1 0001 * (expr) - INLINE O2 +0001 INLINE O2 0001 * (expr) - NUMBER false +0001 NUMBER false ========= Test: parse schema from: RelationRouteTo({-by-reference:R},{O1},{O2},true) 0001 * (call) 0001 * (expr) - IDENTIFIER RelationRouteTo +0001 IDENTIFIER RelationRouteTo 0001 * (expr) - INLINE -by-reference:R +0001 INLINE -by-reference:R 0001 * (expr) - INLINE O1 +0001 INLINE O1 0001 * (expr) - INLINE O2 +0001 INLINE O2 0001 * (expr) - NUMBER true +0001 NUMBER true ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LIST, {-new:list of K}, RLIST_ALL_X) 0001 * (call) 0001 * (expr) - IDENTIFIER RelationTest +0001 IDENTIFIER RelationTest 0001 * (expr) - INLINE -by-reference:R +0001 INLINE -by-reference:R 0001 * (expr) - IDENTIFIER RELS_LIST +0001 IDENTIFIER RELS_LIST 0001 * (expr) - INLINE -new:list of K +0001 INLINE -new:list of K 0001 * (expr) - IDENTIFIER RLIST_ALL_X +0001 IDENTIFIER RLIST_ALL_X ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LIST, {-new:list of L}, RLIST_ALL_Y) 0001 * (call) 0001 * (expr) - IDENTIFIER RelationTest +0001 IDENTIFIER RelationTest 0001 * (expr) - INLINE -by-reference:R +0001 INLINE -by-reference:R 0001 * (expr) - IDENTIFIER RELS_LIST +0001 IDENTIFIER RELS_LIST 0001 * (expr) - INLINE -new:list of L +0001 INLINE -new:list of L 0001 * (expr) - IDENTIFIER RLIST_ALL_Y +0001 IDENTIFIER RLIST_ALL_Y ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LIST, {-new:list of L}, RLIST_ALL_Y) 0001 * (call) 0001 * (expr) - IDENTIFIER RelationTest +0001 IDENTIFIER RelationTest 0001 * (expr) - INLINE -by-reference:R +0001 INLINE -by-reference:R 0001 * (expr) - IDENTIFIER RELS_LIST +0001 IDENTIFIER RELS_LIST 0001 * (expr) - INLINE -new:list of L +0001 INLINE -new:list of L 0001 * (expr) - IDENTIFIER RLIST_ALL_Y +0001 IDENTIFIER RLIST_ALL_Y ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ALL_X, {Y}, {-new:list of K}) 0001 * (call) 0001 * (expr) - IDENTIFIER RelationTest +0001 IDENTIFIER RelationTest 0001 * (expr) - INLINE -by-reference:R +0001 INLINE -by-reference:R 0001 * (expr) - IDENTIFIER RELS_LOOKUP_ALL_X +0001 IDENTIFIER RELS_LOOKUP_ALL_X 0001 * (expr) - INLINE Y +0001 INLINE Y 0001 * (expr) - INLINE -new:list of K +0001 INLINE -new:list of K ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ALL_Y, {X}, {-new:list of L}) 0001 * (call) 0001 * (expr) - IDENTIFIER RelationTest +0001 IDENTIFIER RelationTest 0001 * (expr) - INLINE -by-reference:R +0001 INLINE -by-reference:R 0001 * (expr) - IDENTIFIER RELS_LOOKUP_ALL_Y +0001 IDENTIFIER RELS_LOOKUP_ALL_Y 0001 * (expr) - INLINE X +0001 INLINE X 0001 * (expr) - INLINE -new:list of L +0001 INLINE -new:list of L ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ALL_Y, {X}, {-new:list of L}) 0001 * (call) 0001 * (expr) - IDENTIFIER RelationTest +0001 IDENTIFIER RelationTest 0001 * (expr) - INLINE -by-reference:R +0001 INLINE -by-reference:R 0001 * (expr) - IDENTIFIER RELS_LOOKUP_ALL_Y +0001 IDENTIFIER RELS_LOOKUP_ALL_Y 0001 * (expr) - INLINE X +0001 INLINE X 0001 * (expr) - INLINE -new:list of L +0001 INLINE -new:list of L ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ANY, {Y}, RLANY_CAN_GET_X) 0001 * (call) 0001 * (expr) - IDENTIFIER RelationTest +0001 IDENTIFIER RelationTest 0001 * (expr) - INLINE -by-reference:R +0001 INLINE -by-reference:R 0001 * (expr) - IDENTIFIER RELS_LOOKUP_ANY +0001 IDENTIFIER RELS_LOOKUP_ANY 0001 * (expr) - INLINE Y +0001 INLINE Y 0001 * (expr) - IDENTIFIER RLANY_CAN_GET_X +0001 IDENTIFIER RLANY_CAN_GET_X ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ANY, {X}, RLANY_CAN_GET_Y) 0001 * (call) 0001 * (expr) - IDENTIFIER RelationTest +0001 IDENTIFIER RelationTest 0001 * (expr) - INLINE -by-reference:R +0001 INLINE -by-reference:R 0001 * (expr) - IDENTIFIER RELS_LOOKUP_ANY +0001 IDENTIFIER RELS_LOOKUP_ANY 0001 * (expr) - INLINE X +0001 INLINE X 0001 * (expr) - IDENTIFIER RLANY_CAN_GET_Y +0001 IDENTIFIER RLANY_CAN_GET_Y ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ANY, {Y}, RLANY_GET_X) 0001 * (call) 0001 * (expr) - IDENTIFIER RelationTest +0001 IDENTIFIER RelationTest 0001 * (expr) - INLINE -by-reference:R +0001 INLINE -by-reference:R 0001 * (expr) - IDENTIFIER RELS_LOOKUP_ANY +0001 IDENTIFIER RELS_LOOKUP_ANY 0001 * (expr) - INLINE Y +0001 INLINE Y 0001 * (expr) - IDENTIFIER RLANY_GET_X +0001 IDENTIFIER RLANY_GET_X ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ANY, {X}, RLANY_GET_Y) 0001 * (call) 0001 * (expr) - IDENTIFIER RelationTest +0001 IDENTIFIER RelationTest 0001 * (expr) - INLINE -by-reference:R +0001 INLINE -by-reference:R 0001 * (expr) - IDENTIFIER RELS_LOOKUP_ANY +0001 IDENTIFIER RELS_LOOKUP_ANY 0001 * (expr) - INLINE X +0001 INLINE X 0001 * (expr) - IDENTIFIER RLANY_GET_Y +0001 IDENTIFIER RLANY_GET_Y ========= Test: parse schema from: RelationTest({-by-reference:R}, RELS_LOOKUP_ANY, {X}, RLANY_GET_Y) 0001 * (call) 0001 * (expr) - IDENTIFIER RelationTest +0001 IDENTIFIER RelationTest 0001 * (expr) - INLINE -by-reference:R +0001 INLINE -by-reference:R 0001 * (expr) - IDENTIFIER RELS_LOOKUP_ANY +0001 IDENTIFIER RELS_LOOKUP_ANY 0001 * (expr) - INLINE X +0001 INLINE X 0001 * (expr) - IDENTIFIER RLANY_GET_Y +0001 IDENTIFIER RLANY_GET_Y ========= Test: parse schema from: {-primitive-definition:description-application} 0001 * (expr) - INLINE -primitive-definition:description-application +0001 INLINE -primitive-definition:description-application ========= Test: parse schema from: {-primitive-definition:function-application} 0001 * (expr) - INLINE -primitive-definition:function-application +0001 INLINE -primitive-definition:function-application ========= Test: parse schema from: {-primitive-definition:function-application} 0001 * (expr) - INLINE -primitive-definition:function-application +0001 INLINE -primitive-definition:function-application ========= Test: parse schema from: {-primitive-definition:function-application} 0001 * (expr) - INLINE -primitive-definition:function-application +0001 INLINE -primitive-definition:function-application ========= Test: parse schema from: {-primitive-definition:function-application} 0001 * (expr) - INLINE -primitive-definition:function-application +0001 INLINE -primitive-definition:function-application ========= Test: parse schema from: {-primitive-definition:function-application}; 0001 * (expr) ; - INLINE -primitive-definition:function-application +0001 INLINE -primitive-definition:function-application ========= Test: parse schema from: {-primitive-definition:function-application}; 0001 * (expr) ; - INLINE -primitive-definition:function-application +0001 INLINE -primitive-definition:function-application ========= Test: parse schema from: {-primitive-definition:function-application}; 0001 * (expr) ; - INLINE -primitive-definition:function-application +0001 INLINE -primitive-definition:function-application ========= Test: parse schema from: {-primitive-definition:function-application}; 0001 * (expr) ; - INLINE -primitive-definition:function-application +0001 INLINE -primitive-definition:function-application ========= Test: parse schema from: {-show-me:V} 0001 * (expr) - INLINE -show-me:V +0001 INLINE -show-me:V ========= Test: parse schema from: {-new:K} 0001 * (expr) - INLINE -new:K +0001 INLINE -new:K ========= Test: parse schema from: FileIO_GetTable({filename}, {T}); 0001 * (call) 0001 * (expr) - IDENTIFIER FileIO_GetTable +0001 IDENTIFIER FileIO_GetTable 0001 * (expr) - INLINE filename +0001 INLINE filename 0001 * (expr) - INLINE T +0001 INLINE T ========= Test: parse schema from: FileIO_PutTable({filename}, {T}); 0001 * (call) 0001 * (expr) - IDENTIFIER FileIO_PutTable +0001 IDENTIFIER FileIO_PutTable 0001 * (expr) - INLINE filename +0001 INLINE filename 0001 * (expr) - INLINE T +0001 INLINE T ========= Test: parse schema from: (FileIO_Exists({filename}, false)) @@ -2348,11 +2348,11 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER FileIO_Exists +0001 IDENTIFIER FileIO_Exists 0001 * (expr) - INLINE filename +0001 INLINE filename 0001 * (expr) - NUMBER false +0001 NUMBER false ========= Test: parse schema from: (FileIO_Ready({filename}, false)) @@ -2360,125 +2360,125 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER FileIO_Ready +0001 IDENTIFIER FileIO_Ready 0001 * (expr) - INLINE filename +0001 INLINE filename 0001 * (expr) - NUMBER false +0001 NUMBER false ========= Test: parse schema from: FileIO_MarkReady({filename}, true); 0001 * (call) 0001 * (expr) - IDENTIFIER FileIO_MarkReady +0001 IDENTIFIER FileIO_MarkReady 0001 * (expr) - INLINE filename +0001 INLINE filename 0001 * (expr) - NUMBER true +0001 NUMBER true ========= Test: parse schema from: FileIO_MarkReady({filename}, false); 0001 * (call) 0001 * (expr) - IDENTIFIER FileIO_MarkReady +0001 IDENTIFIER FileIO_MarkReady 0001 * (expr) - INLINE filename +0001 INLINE filename 0001 * (expr) - NUMBER false +0001 NUMBER false ========= Test: parse schema from: FileIO_PutContents({FN}, {T}, false); 0001 * (call) 0001 * (expr) - IDENTIFIER FileIO_PutContents +0001 IDENTIFIER FileIO_PutContents 0001 * (expr) - INLINE FN +0001 INLINE FN 0001 * (expr) - INLINE T +0001 INLINE T 0001 * (expr) - NUMBER false +0001 NUMBER false ========= Test: parse schema from: FileIO_PutContents({FN}, {T}, true); 0001 * (call) 0001 * (expr) - IDENTIFIER FileIO_PutContents +0001 IDENTIFIER FileIO_PutContents 0001 * (expr) - INLINE FN +0001 INLINE FN 0001 * (expr) - INLINE T +0001 INLINE T 0001 * (expr) - NUMBER true +0001 NUMBER true ========= Test: parse schema from: FileIO_PrintContents({FN}); say__p = 1; 0001 * (call) 0001 * (expr) - IDENTIFIER FileIO_PrintContents +0001 IDENTIFIER FileIO_PrintContents 0001 * (expr) - INLINE FN +0001 INLINE FN 0001 * (operation) !store 0001 * (expr) - IDENTIFIER say__p +0001 IDENTIFIER say__p 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: DisplayFigure(ResourceIDsOfFigures-->{F}, {phrase options}); 0001 * (call) 0001 * (expr) - IDENTIFIER DisplayFigure +0001 IDENTIFIER DisplayFigure 0001 * (operation) !lookup 0001 * (expr) - IDENTIFIER ResourceIDsOfFigures +0001 IDENTIFIER ResourceIDsOfFigures 0001 * (expr) - INLINE F +0001 INLINE F 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: ResourceIDsOfFigures-->{F} 0001 * (operation) !lookup 0001 * (expr) - IDENTIFIER ResourceIDsOfFigures +0001 IDENTIFIER ResourceIDsOfFigures 0001 * (expr) - INLINE F +0001 INLINE F ========= Test: parse schema from: PlaySound(ResourceIDsOfSounds-->{SFX}, {phrase options}); 0001 * (call) 0001 * (expr) - IDENTIFIER PlaySound +0001 IDENTIFIER PlaySound 0001 * (operation) !lookup 0001 * (expr) - IDENTIFIER ResourceIDsOfSounds +0001 IDENTIFIER ResourceIDsOfSounds 0001 * (expr) - INLINE SFX +0001 INLINE SFX 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: ResourceIDsOfSounds-->{SFX} 0001 * (operation) !lookup 0001 * (expr) - IDENTIFIER ResourceIDsOfSounds +0001 IDENTIFIER ResourceIDsOfSounds 0001 * (expr) - INLINE SFX +0001 INLINE SFX ========= Test: parse schema from: {c} 0001 * (expr) - INLINE c +0001 INLINE c ========= Test: parse schema from: (~~{c}) @@ -2486,7 +2486,7 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !not 0001 * (expr) - INLINE c +0001 INLINE c ========= Test: parse schema from: end @@ -2494,9 +2494,9 @@ Test: parse schema from: schemawhile {c} 0002 * (expr) - IDENTIFIER end - IDENTIFIER schemawhile - INLINE c +0002 IDENTIFIER end +0002 IDENTIFIER schemawhile +0002 INLINE c ========= Test: parse schema from: for ({loopvar}={v}: {loopvar}<={w}: {loopvar}++) @@ -2505,19 +2505,19 @@ Test: parse schema from: 0001 * (eval) 0001 * (operation) !store 0001 * (expr) - INLINE loopvar +0001 INLINE loopvar 0001 * (expr) - INLINE v +0001 INLINE v 0001 * (eval) 0001 * (operation) !le 0001 * (expr) - INLINE loopvar +0001 INLINE loopvar 0001 * (expr) - INLINE w +0001 INLINE w 0001 * (eval) 0001 * (operation) !postincrement 0001 * (expr) - INLINE loopvar +0001 INLINE loopvar 0001 * (code) < ========= Test: parse schema from: @@ -2527,38 +2527,38 @@ Test: parse schema from: 0001 * (eval) 0001 * (operation) !store 0001 * (expr) - INLINE loopvar +0001 INLINE loopvar 0001 * (expr) - INLINE v +0001 INLINE v 0001 * (eval) 0001 * (operation) !le 0001 * (expr) - INLINE loopvar +0001 INLINE loopvar 0001 * (expr) - INLINE w +0001 INLINE w 0001 * (eval) 0001 * (operation) !postincrement 0001 * (expr) - INLINE loopvar +0001 INLINE loopvar 0001 * (code) < ========= Test: parse schema from: {-primitive-definition:repeat-through} 0001 * (expr) - INLINE -primitive-definition:repeat-through +0001 INLINE -primitive-definition:repeat-through ========= Test: parse schema from: {-primitive-definition:repeat-through-list} 0001 * (expr) - INLINE -primitive-definition:repeat-through-list +0001 INLINE -primitive-definition:repeat-through-list ========= Test: parse schema from: {-primitive-definition:break} 0001 * (expr) - INLINE -primitive-definition:break +0001 INLINE -primitive-definition:break ========= Test: parse schema from: continue; @@ -2570,35 +2570,35 @@ Test: parse schema from: 0001 * (statement) !return 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: rtrue; 0001 * (statement) !return 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: rfalse; 0001 * (statement) !return 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: rfalse; 0001 * (statement) !return 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: return {-return-value:something}; 0001 * (statement) !return 0001 * (expr) - INLINE -return-value:something +0001 INLINE -return-value:something ========= Test: parse schema from: ; @@ -2610,25 +2610,25 @@ Test: parse schema from: 0001 * (statement) !return 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: {-try-action:S} 0001 * (expr) - INLINE -try-action:S +0001 INLINE -try-action:S ========= Test: parse schema from: {-try-action-silently:S} 0001 * (expr) - INLINE -try-action-silently:S +0001 INLINE -try-action-silently:S ========= Test: parse schema from: {-try-action-silently:S} 0001 * (expr) - INLINE -try-action-silently:S +0001 INLINE -try-action-silently:S ========= Test: parse schema from: (keep_silent == false) @@ -2636,9 +2636,9 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !eq 0001 * (expr) - IDENTIFIER keep_silent +0001 IDENTIFIER keep_silent 0001 * (expr) - NUMBER false +0001 NUMBER false ========= Test: parse schema from: (NeedToTouchNoun()) @@ -2646,7 +2646,7 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER NeedToTouchNoun +0001 IDENTIFIER NeedToTouchNoun ========= Test: parse schema from: (NeedToTouchSecondNoun()) @@ -2654,7 +2654,7 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER NeedToTouchSecondNoun +0001 IDENTIFIER NeedToTouchSecondNoun ========= Test: parse schema from: (NeedToCarryNoun()) @@ -2662,7 +2662,7 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER NeedToCarryNoun +0001 IDENTIFIER NeedToCarryNoun ========= Test: parse schema from: (NeedToCarrySecondNoun()) @@ -2670,7 +2670,7 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER NeedToCarrySecondNoun +0001 IDENTIFIER NeedToCarrySecondNoun ========= Test: parse schema from: (NeedLightForAction()) @@ -2678,36 +2678,36 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER NeedLightForAction +0001 IDENTIFIER NeedLightForAction ========= Test: parse schema from: rtrue; 0001 * (statement) !return 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: rfalse; 0001 * (statement) !return 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: STORED_ACTION_TY_Current({-new:action}) 0001 * (call) 0001 * (expr) - IDENTIFIER STORED_ACTION_TY_Current +0001 IDENTIFIER STORED_ACTION_TY_Current 0001 * (expr) - INLINE -new:action +0001 INLINE -new:action ========= Test: parse schema from: {A} 0001 * (expr) - INLINE A +0001 INLINE A ========= Test: parse schema from: (STORED_ACTION_TY_Involves({-by-reference:act}, {X})) @@ -2715,11 +2715,11 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER STORED_ACTION_TY_Involves +0001 IDENTIFIER STORED_ACTION_TY_Involves 0001 * (expr) - INLINE -by-reference:act +0001 INLINE -by-reference:act 0001 * (expr) - INLINE X +0001 INLINE X ========= Test: parse schema from: (STORED_ACTION_TY_Part({-by-reference:act}, STORA_ACTION_F)) @@ -2727,11 +2727,11 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER STORED_ACTION_TY_Part +0001 IDENTIFIER STORED_ACTION_TY_Part 0001 * (expr) - INLINE -by-reference:act +0001 INLINE -by-reference:act 0001 * (expr) - IDENTIFIER STORA_ACTION_F +0001 IDENTIFIER STORA_ACTION_F ========= Test: parse schema from: (STORED_ACTION_TY_Part({-by-reference:act}, STORA_NOUN_F)) @@ -2739,11 +2739,11 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER STORED_ACTION_TY_Part +0001 IDENTIFIER STORED_ACTION_TY_Part 0001 * (expr) - INLINE -by-reference:act +0001 INLINE -by-reference:act 0001 * (expr) - IDENTIFIER STORA_NOUN_F +0001 IDENTIFIER STORA_NOUN_F ========= Test: parse schema from: (STORED_ACTION_TY_Part({-by-reference:act}, STORA_SECOND_F)) @@ -2751,11 +2751,11 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER STORED_ACTION_TY_Part +0001 IDENTIFIER STORED_ACTION_TY_Part 0001 * (expr) - INLINE -by-reference:act +0001 INLINE -by-reference:act 0001 * (expr) - IDENTIFIER STORA_SECOND_F +0001 IDENTIFIER STORA_SECOND_F ========= Test: parse schema from: (STORED_ACTION_TY_Part({-by-reference:act}, STORA_ACTOR_F)) @@ -2763,58 +2763,58 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER STORED_ACTION_TY_Part +0001 IDENTIFIER STORED_ACTION_TY_Part 0001 * (expr) - INLINE -by-reference:act +0001 INLINE -by-reference:act 0001 * (expr) - IDENTIFIER STORA_ACTOR_F +0001 IDENTIFIER STORA_ACTOR_F ========= Test: parse schema from: CarryOutActivity({A}); 0001 * (call) 0001 * (expr) - IDENTIFIER CarryOutActivity +0001 IDENTIFIER CarryOutActivity 0001 * (expr) - INLINE A +0001 INLINE A ========= Test: parse schema from: CarryOutActivity({A}, {val}); 0001 * (call) 0001 * (expr) - IDENTIFIER CarryOutActivity +0001 IDENTIFIER CarryOutActivity 0001 * (expr) - INLINE A +0001 INLINE A 0001 * (expr) - INLINE val +0001 INLINE val ========= Test: parse schema from: rfalse; 0001 * (statement) !return 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: BeginActivity({A}); 0001 * (call) 0001 * (expr) - IDENTIFIER BeginActivity +0001 IDENTIFIER BeginActivity 0001 * (expr) - INLINE A +0001 INLINE A ========= Test: parse schema from: BeginActivity({A}, {val}); 0001 * (call) 0001 * (expr) - IDENTIFIER BeginActivity +0001 IDENTIFIER BeginActivity 0001 * (expr) - INLINE A +0001 INLINE A 0001 * (expr) - INLINE val +0001 INLINE val ========= Test: parse schema from: (~~(ForActivity({A}))) @@ -2824,9 +2824,9 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER ForActivity +0001 IDENTIFIER ForActivity 0001 * (expr) - INLINE A +0001 INLINE A ========= Test: parse schema from: (~~(ForActivity({A}, {val}))) @@ -2836,127 +2836,127 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER ForActivity +0001 IDENTIFIER ForActivity 0001 * (expr) - INLINE A +0001 INLINE A 0001 * (expr) - INLINE val +0001 INLINE val ========= Test: parse schema from: EndActivity({A}); 0001 * (call) 0001 * (expr) - IDENTIFIER EndActivity +0001 IDENTIFIER EndActivity 0001 * (expr) - INLINE A +0001 INLINE A ========= Test: parse schema from: EndActivity({A}, {val}); 0001 * (call) 0001 * (expr) - IDENTIFIER EndActivity +0001 IDENTIFIER EndActivity 0001 * (expr) - INLINE A +0001 INLINE A 0001 * (expr) - INLINE val +0001 INLINE val ========= Test: parse schema from: AbandonActivity({A}); 0001 * (call) 0001 * (expr) - IDENTIFIER AbandonActivity +0001 IDENTIFIER AbandonActivity 0001 * (expr) - INLINE A +0001 INLINE A ========= Test: parse schema from: AbandonActivity({A}, {val}); 0001 * (call) 0001 * (expr) - IDENTIFIER AbandonActivity +0001 IDENTIFIER AbandonActivity 0001 * (expr) - INLINE A +0001 INLINE A 0001 * (expr) - INLINE val +0001 INLINE val ========= Test: parse schema from: FollowRulebook({RL}); 0001 * (call) 0001 * (expr) - IDENTIFIER FollowRulebook +0001 IDENTIFIER FollowRulebook 0001 * (expr) - INLINE RL +0001 INLINE RL ========= Test: parse schema from: FollowRulebook({RL}, {V}, true); 0001 * (call) 0001 * (expr) - IDENTIFIER FollowRulebook +0001 IDENTIFIER FollowRulebook 0001 * (expr) - INLINE RL +0001 INLINE RL 0001 * (expr) - INLINE V +0001 INLINE V 0001 * (expr) - NUMBER true +0001 NUMBER true ========= Test: parse schema from: FollowRulebook({RL}); 0001 * (call) 0001 * (expr) - IDENTIFIER FollowRulebook +0001 IDENTIFIER FollowRulebook 0001 * (expr) - INLINE RL +0001 INLINE RL ========= Test: parse schema from: ResultOfRule({RL}, 0, true, {-strong-kind:K}) 0001 * (call) 0001 * (expr) - IDENTIFIER ResultOfRule +0001 IDENTIFIER ResultOfRule 0001 * (expr) - INLINE RL +0001 INLINE RL 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 0001 * (expr) - NUMBER true +0001 NUMBER true 0001 * (expr) - INLINE -strong-kind:K +0001 INLINE -strong-kind:K ========= Test: parse schema from: ResultOfRule({RL}, {V}, true, {-strong-kind:L}) 0001 * (call) 0001 * (expr) - IDENTIFIER ResultOfRule +0001 IDENTIFIER ResultOfRule 0001 * (expr) - INLINE RL +0001 INLINE RL 0001 * (expr) - INLINE V +0001 INLINE V 0001 * (expr) - NUMBER true +0001 NUMBER true 0001 * (expr) - INLINE -strong-kind:L +0001 INLINE -strong-kind:L ========= Test: parse schema from: ResultOfRule({RL}, 0, true, {-strong-kind:K}) 0001 * (call) 0001 * (expr) - IDENTIFIER ResultOfRule +0001 IDENTIFIER ResultOfRule 0001 * (expr) - INLINE RL +0001 INLINE RL 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 0001 * (expr) - NUMBER true +0001 NUMBER true 0001 * (expr) - INLINE -strong-kind:K +0001 INLINE -strong-kind:K ========= Test: parse schema from: if (FollowRulebook({RL})) rtrue; @@ -2965,13 +2965,13 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER FollowRulebook +0001 IDENTIFIER FollowRulebook 0001 * (expr) - INLINE RL +0001 INLINE RL 0001 * (code) 0001 * (statement) !return 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: if (FollowRulebook({RL}, {V}, true)) rtrue; @@ -2980,17 +2980,17 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER FollowRulebook +0001 IDENTIFIER FollowRulebook 0001 * (expr) - INLINE RL +0001 INLINE RL 0001 * (expr) - INLINE V +0001 INLINE V 0001 * (expr) - NUMBER true +0001 NUMBER true 0001 * (code) 0001 * (statement) !return 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: if (FollowRulebook({RL})) rtrue; @@ -2999,54 +2999,54 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER FollowRulebook +0001 IDENTIFIER FollowRulebook 0001 * (expr) - INLINE RL +0001 INLINE RL 0001 * (code) 0001 * (statement) !return 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: rfalse; 0001 * (statement) !return 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: RulebookSucceeds(); rtrue; 0001 * (call) 0001 * (expr) - IDENTIFIER RulebookSucceeds +0001 IDENTIFIER RulebookSucceeds 0001 * (statement) !return 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: RulebookFails(); rtrue; 0001 * (call) 0001 * (expr) - IDENTIFIER RulebookFails +0001 IDENTIFIER RulebookFails 0001 * (statement) !return 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: RulebookSucceeds({-weak-kind:rule-return-kind},{-return-value-from-rule:val}); rtrue; 0001 * (call) 0001 * (expr) - IDENTIFIER RulebookSucceeds +0001 IDENTIFIER RulebookSucceeds 0001 * (expr) - INLINE -weak-kind:rule-return-kind +0001 INLINE -weak-kind:rule-return-kind 0001 * (expr) - INLINE -return-value-from-rule:val +0001 INLINE -return-value-from-rule:val 0001 * (statement) !return 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: (RulebookSucceeded()) @@ -3054,7 +3054,7 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER RulebookSucceeded +0001 IDENTIFIER RulebookSucceeded ========= Test: parse schema from: (RulebookFailed()) @@ -3062,7 +3062,7 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER RulebookFailed +0001 IDENTIFIER RulebookFailed ========= Test: parse schema from: (ResultOfRule()) @@ -3070,63 +3070,63 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER ResultOfRule +0001 IDENTIFIER ResultOfRule ========= Test: parse schema from: deadflag=3; story_complete=false; 0001 * (operation) !store 0001 * (expr) - IDENTIFIER deadflag +0001 IDENTIFIER deadflag 0001 * (expr) - NUMBER 3 +0001 NUMBER 3 0001 * (operation) !store 0001 * (expr) - IDENTIFIER story_complete +0001 IDENTIFIER story_complete 0001 * (expr) - NUMBER false +0001 NUMBER false ========= Test: parse schema from: deadflag=3; story_complete=true; 0001 * (operation) !store 0001 * (expr) - IDENTIFIER deadflag +0001 IDENTIFIER deadflag 0001 * (expr) - NUMBER 3 +0001 NUMBER 3 0001 * (operation) !store 0001 * (expr) - IDENTIFIER story_complete +0001 IDENTIFIER story_complete 0001 * (expr) - NUMBER true +0001 NUMBER true ========= Test: parse schema from: deadflag={-by-reference:finale}; story_complete=false; 0001 * (operation) !store 0001 * (expr) - IDENTIFIER deadflag +0001 IDENTIFIER deadflag 0001 * (expr) - INLINE -by-reference:finale +0001 INLINE -by-reference:finale 0001 * (operation) !store 0001 * (expr) - IDENTIFIER story_complete +0001 IDENTIFIER story_complete 0001 * (expr) - NUMBER false +0001 NUMBER false ========= Test: parse schema from: deadflag={-by-reference:finale}; story_complete=true; 0001 * (operation) !store 0001 * (expr) - IDENTIFIER deadflag +0001 IDENTIFIER deadflag 0001 * (expr) - INLINE -by-reference:finale +0001 INLINE -by-reference:finale 0001 * (operation) !store 0001 * (expr) - IDENTIFIER story_complete +0001 IDENTIFIER story_complete 0001 * (expr) - NUMBER true +0001 NUMBER true ========= Test: parse schema from: (deadflag~=0) @@ -3134,16 +3134,16 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !ne 0001 * (expr) - IDENTIFIER deadflag +0001 IDENTIFIER deadflag 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: (story_complete) 0001 * (subexpression) 0001 * (expr) - IDENTIFIER story_complete +0001 IDENTIFIER story_complete ========= Test: parse schema from: (deadflag==0) @@ -3151,9 +3151,9 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !eq 0001 * (expr) - IDENTIFIER deadflag +0001 IDENTIFIER deadflag 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: (story_complete==false) @@ -3161,18 +3161,18 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !eq 0001 * (expr) - IDENTIFIER story_complete +0001 IDENTIFIER story_complete 0001 * (expr) - NUMBER false +0001 NUMBER false ========= Test: parse schema from: resurrect_please = true; 0001 * (operation) !store 0001 * (expr) - IDENTIFIER resurrect_please +0001 IDENTIFIER resurrect_please 0001 * (expr) - NUMBER true +0001 NUMBER true ========= Test: parse schema from: ({t}%ONE_HOUR) @@ -3180,9 +3180,9 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !modulo 0001 * (expr) - INLINE t +0001 INLINE t 0001 * (expr) - IDENTIFIER ONE_HOUR +0001 IDENTIFIER ONE_HOUR ========= Test: parse schema from: ({t}/ONE_HOUR) @@ -3190,9 +3190,9 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !divide 0001 * (expr) - INLINE t +0001 INLINE t 0001 * (expr) - IDENTIFIER ONE_HOUR +0001 IDENTIFIER ONE_HOUR ========= Test: parse schema from: ((({t}+20*ONE_HOUR)%(TWENTY_FOUR_HOURS))<(({t2}+20*ONE_HOUR)%(TWENTY_FOUR_HOURS))) @@ -3204,29 +3204,29 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !plus 0001 * (expr) - INLINE t +0001 INLINE t 0001 * (operation) !times 0001 * (expr) - NUMBER 20 +0001 NUMBER 20 0001 * (expr) - IDENTIFIER ONE_HOUR +0001 IDENTIFIER ONE_HOUR 0001 * (subexpression) 0001 * (expr) - IDENTIFIER TWENTY_FOUR_HOURS +0001 IDENTIFIER TWENTY_FOUR_HOURS 0001 * (subexpression) 0001 * (operation) !modulo 0001 * (subexpression) 0001 * (operation) !plus 0001 * (expr) - INLINE t2 +0001 INLINE t2 0001 * (operation) !times 0001 * (expr) - NUMBER 20 +0001 NUMBER 20 0001 * (expr) - IDENTIFIER ONE_HOUR +0001 IDENTIFIER ONE_HOUR 0001 * (subexpression) 0001 * (expr) - IDENTIFIER TWENTY_FOUR_HOURS +0001 IDENTIFIER TWENTY_FOUR_HOURS ========= Test: parse schema from: ((({t}+20*ONE_HOUR)%(TWENTY_FOUR_HOURS))>(({t2}+20*ONE_HOUR)%(TWENTY_FOUR_HOURS))) @@ -3238,29 +3238,29 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !plus 0001 * (expr) - INLINE t +0001 INLINE t 0001 * (operation) !times 0001 * (expr) - NUMBER 20 +0001 NUMBER 20 0001 * (expr) - IDENTIFIER ONE_HOUR +0001 IDENTIFIER ONE_HOUR 0001 * (subexpression) 0001 * (expr) - IDENTIFIER TWENTY_FOUR_HOURS +0001 IDENTIFIER TWENTY_FOUR_HOURS 0001 * (subexpression) 0001 * (operation) !modulo 0001 * (subexpression) 0001 * (operation) !plus 0001 * (expr) - INLINE t2 +0001 INLINE t2 0001 * (operation) !times 0001 * (expr) - NUMBER 20 +0001 NUMBER 20 0001 * (expr) - IDENTIFIER ONE_HOUR +0001 IDENTIFIER ONE_HOUR 0001 * (subexpression) 0001 * (expr) - IDENTIFIER TWENTY_FOUR_HOURS +0001 IDENTIFIER TWENTY_FOUR_HOURS ========= Test: parse schema from: (({t2}-{t}+TWENTY_FOUR_HOURS)%(TWENTY_FOUR_HOURS)) @@ -3271,14 +3271,14 @@ Test: parse schema from: 0001 * (operation) !plus 0001 * (operation) !minus 0001 * (expr) - INLINE t2 +0001 INLINE t2 0001 * (expr) - INLINE t +0001 INLINE t 0001 * (expr) - IDENTIFIER TWENTY_FOUR_HOURS +0001 IDENTIFIER TWENTY_FOUR_HOURS 0001 * (subexpression) 0001 * (expr) - IDENTIFIER TWENTY_FOUR_HOURS +0001 IDENTIFIER TWENTY_FOUR_HOURS ========= Test: parse schema from: (({t2}+{t}+TWENTY_FOUR_HOURS)%(TWENTY_FOUR_HOURS)) @@ -3289,14 +3289,14 @@ Test: parse schema from: 0001 * (operation) !plus 0001 * (operation) !plus 0001 * (expr) - INLINE t2 +0001 INLINE t2 0001 * (expr) - INLINE t +0001 INLINE t 0001 * (expr) - IDENTIFIER TWENTY_FOUR_HOURS +0001 IDENTIFIER TWENTY_FOUR_HOURS 0001 * (subexpression) 0001 * (expr) - IDENTIFIER TWENTY_FOUR_HOURS +0001 IDENTIFIER TWENTY_FOUR_HOURS ========= Test: parse schema from: (({n})%(TWENTY_FOUR_HOURS)) @@ -3305,10 +3305,10 @@ Test: parse schema from: 0001 * (operation) !modulo 0001 * (subexpression) 0001 * (expr) - INLINE n +0001 INLINE n 0001 * (subexpression) 0001 * (expr) - IDENTIFIER TWENTY_FOUR_HOURS +0001 IDENTIFIER TWENTY_FOUR_HOURS ========= Test: parse schema from: (({n}*ONE_HOUR)%(TWENTY_FOUR_HOURS)) @@ -3318,62 +3318,62 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !times 0001 * (expr) - INLINE n +0001 INLINE n 0001 * (expr) - IDENTIFIER ONE_HOUR +0001 IDENTIFIER ONE_HOUR 0001 * (subexpression) 0001 * (expr) - IDENTIFIER TWENTY_FOUR_HOURS +0001 IDENTIFIER TWENTY_FOUR_HOURS ========= Test: parse schema from: SetTimedEvent({-mark-event-used:R}, {t}+1, 0); 0001 * (call) 0001 * (expr) - IDENTIFIER SetTimedEvent +0001 IDENTIFIER SetTimedEvent 0001 * (expr) - INLINE -mark-event-used:R +0001 INLINE -mark-event-used:R 0001 * (operation) !plus 0001 * (expr) - INLINE t +0001 INLINE t 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: SetTimedEvent({-mark-event-used:R}, {t}, 1); 0001 * (call) 0001 * (expr) - IDENTIFIER SetTimedEvent +0001 IDENTIFIER SetTimedEvent 0001 * (expr) - INLINE -mark-event-used:R +0001 INLINE -mark-event-used:R 0001 * (expr) - INLINE t +0001 INLINE t 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: SetTimedEvent({-mark-event-used:R}, (the_time+{t})%(TWENTY_FOUR_HOURS), 1); 0001 * (call) 0001 * (expr) - IDENTIFIER SetTimedEvent +0001 IDENTIFIER SetTimedEvent 0001 * (expr) - INLINE -mark-event-used:R +0001 INLINE -mark-event-used:R 0001 * (operation) !modulo 0001 * (subexpression) 0001 * (operation) !plus 0001 * (expr) - IDENTIFIER the_time +0001 IDENTIFIER the_time 0001 * (expr) - INLINE t +0001 INLINE t 0001 * (subexpression) 0001 * (expr) - IDENTIFIER TWENTY_FOUR_HOURS +0001 IDENTIFIER TWENTY_FOUR_HOURS 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: (scene_endings-->({sc}-1)) @@ -3381,13 +3381,13 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !lookup 0001 * (expr) - IDENTIFIER scene_endings +0001 IDENTIFIER scene_endings 0001 * (subexpression) 0001 * (operation) !minus 0001 * (expr) - INLINE sc +0001 INLINE sc 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: (scene_endings-->({sc}-1) == 0) @@ -3396,15 +3396,15 @@ Test: parse schema from: 0001 * (operation) !eq 0001 * (operation) !lookup 0001 * (expr) - IDENTIFIER scene_endings +0001 IDENTIFIER scene_endings 0001 * (subexpression) 0001 * (operation) !minus 0001 * (expr) - INLINE sc +0001 INLINE sc 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: (scene_endings-->({sc}-1) > 1) @@ -3413,15 +3413,15 @@ Test: parse schema from: 0001 * (operation) !gt 0001 * (operation) !lookup 0001 * (expr) - IDENTIFIER scene_endings +0001 IDENTIFIER scene_endings 0001 * (subexpression) 0001 * (operation) !minus 0001 * (expr) - INLINE sc +0001 INLINE sc 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: (scene_endings-->({sc}-1) <= 1) @@ -3430,15 +3430,15 @@ Test: parse schema from: 0001 * (operation) !le 0001 * (operation) !lookup 0001 * (expr) - IDENTIFIER scene_endings +0001 IDENTIFIER scene_endings 0001 * (subexpression) 0001 * (operation) !minus 0001 * (expr) - INLINE sc +0001 INLINE sc 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: (SceneUtility({sc}, 1)) @@ -3446,11 +3446,11 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER SceneUtility +0001 IDENTIFIER SceneUtility 0001 * (expr) - INLINE sc +0001 INLINE sc 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: (SceneUtility({sc}, 2)) @@ -3458,11 +3458,11 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER SceneUtility +0001 IDENTIFIER SceneUtility 0001 * (expr) - INLINE sc +0001 INLINE sc 0001 * (expr) - NUMBER 2 +0001 NUMBER 2 ========= Test: parse schema from: (SceneUtility({sc}, 3)) @@ -3470,11 +3470,11 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER SceneUtility +0001 IDENTIFIER SceneUtility 0001 * (expr) - INLINE sc +0001 INLINE sc 0001 * (expr) - NUMBER 3 +0001 NUMBER 3 ========= Test: parse schema from: (SceneUtility({sc}, 4)) @@ -3482,11 +3482,11 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER SceneUtility +0001 IDENTIFIER SceneUtility 0001 * (expr) - INLINE sc +0001 INLINE sc 0001 * (expr) - NUMBER 4 +0001 NUMBER 4 ========= Test: parse schema from: (location==thedark) @@ -3494,223 +3494,223 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !eq 0001 * (expr) - IDENTIFIER location +0001 IDENTIFIER location 0001 * (expr) - IDENTIFIER thedark +0001 IDENTIFIER thedark ========= Test: parse schema from: MoveObject({something}, {something else}, {phrase options}, false); 0001 * (call) 0001 * (expr) - IDENTIFIER MoveObject +0001 IDENTIFIER MoveObject 0001 * (expr) - INLINE something +0001 INLINE something 0001 * (expr) - INLINE something else +0001 INLINE something else 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options 0001 * (expr) - NUMBER false +0001 NUMBER false ========= Test: parse schema from: RemoveFromPlay({something}); 0001 * (call) 0001 * (expr) - IDENTIFIER RemoveFromPlay +0001 IDENTIFIER RemoveFromPlay 0001 * (expr) - INLINE something +0001 INLINE something ========= Test: parse schema from: MoveBackdrop({O}, {D}); 0001 * (call) 0001 * (expr) - IDENTIFIER MoveBackdrop +0001 IDENTIFIER MoveBackdrop 0001 * (expr) - INLINE O +0001 INLINE O 0001 * (expr) - INLINE D +0001 INLINE D ========= Test: parse schema from: MoveFloatingObjects(); 0001 * (call) 0001 * (expr) - IDENTIFIER MoveFloatingObjects +0001 IDENTIFIER MoveFloatingObjects ========= Test: parse schema from: LocationOf({O}) 0001 * (call) 0001 * (expr) - IDENTIFIER LocationOf +0001 IDENTIFIER LocationOf 0001 * (expr) - INLINE O +0001 INLINE O ========= Test: parse schema from: MapConnection({R1},{D}) 0001 * (call) 0001 * (expr) - IDENTIFIER MapConnection +0001 IDENTIFIER MapConnection 0001 * (expr) - INLINE R1 +0001 INLINE R1 0001 * (expr) - INLINE D +0001 INLINE D ========= Test: parse schema from: DoorFrom({R1},{D}) 0001 * (call) 0001 * (expr) - IDENTIFIER DoorFrom +0001 IDENTIFIER DoorFrom 0001 * (expr) - INLINE R1 +0001 INLINE R1 0001 * (expr) - INLINE D +0001 INLINE D ========= Test: parse schema from: OtherSideOfDoor({D},{R1}) 0001 * (call) 0001 * (expr) - IDENTIFIER OtherSideOfDoor +0001 IDENTIFIER OtherSideOfDoor 0001 * (expr) - INLINE D +0001 INLINE D 0001 * (expr) - INLINE R1 +0001 INLINE R1 ========= Test: parse schema from: DirectionDoorLeadsIn({D},{R1}) 0001 * (call) 0001 * (expr) - IDENTIFIER DirectionDoorLeadsIn +0001 IDENTIFIER DirectionDoorLeadsIn 0001 * (expr) - INLINE D +0001 INLINE D 0001 * (expr) - INLINE R1 +0001 INLINE R1 ========= Test: parse schema from: RoomOrDoorFrom({R1},{D}) 0001 * (call) 0001 * (expr) - IDENTIFIER RoomOrDoorFrom +0001 IDENTIFIER RoomOrDoorFrom 0001 * (expr) - INLINE R1 +0001 INLINE R1 0001 * (expr) - INLINE D +0001 INLINE D ========= Test: parse schema from: AssertMapConnection({R1},{D},{R2}); 0001 * (call) 0001 * (expr) - IDENTIFIER AssertMapConnection +0001 IDENTIFIER AssertMapConnection 0001 * (expr) - INLINE R1 +0001 INLINE R1 0001 * (expr) - INLINE D +0001 INLINE D 0001 * (expr) - INLINE R2 +0001 INLINE R2 ========= Test: parse schema from: AssertMapConnection({R1},{D},nothing); 0001 * (call) 0001 * (expr) - IDENTIFIER AssertMapConnection +0001 IDENTIFIER AssertMapConnection 0001 * (expr) - INLINE R1 +0001 INLINE R1 0001 * (expr) - INLINE D +0001 INLINE D 0001 * (expr) - NUMBER nothing +0001 NUMBER nothing ========= Test: parse schema from: FrontSideOfDoor({D}) 0001 * (call) 0001 * (expr) - IDENTIFIER FrontSideOfDoor +0001 IDENTIFIER FrontSideOfDoor 0001 * (expr) - INLINE D +0001 INLINE D ========= Test: parse schema from: BackSideOfDoor({D}) 0001 * (call) 0001 * (expr) - IDENTIFIER BackSideOfDoor +0001 IDENTIFIER BackSideOfDoor 0001 * (expr) - INLINE D +0001 INLINE D ========= Test: parse schema from: MapRouteTo({R1},{R2},0,{phrase options}) 0001 * (call) 0001 * (expr) - IDENTIFIER MapRouteTo +0001 IDENTIFIER MapRouteTo 0001 * (expr) - INLINE R1 +0001 INLINE R1 0001 * (expr) - INLINE R2 +0001 INLINE R2 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: MapRouteTo({R1},{R2},0,{phrase options},true) 0001 * (call) 0001 * (expr) - IDENTIFIER MapRouteTo +0001 IDENTIFIER MapRouteTo 0001 * (expr) - INLINE R1 +0001 INLINE R1 0001 * (expr) - INLINE R2 +0001 INLINE R2 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options 0001 * (expr) - NUMBER true +0001 NUMBER true ========= Test: parse schema from: MapRouteTo({R1},{R2},{RS},{phrase options}) 0001 * (call) 0001 * (expr) - IDENTIFIER MapRouteTo +0001 IDENTIFIER MapRouteTo 0001 * (expr) - INLINE R1 +0001 INLINE R1 0001 * (expr) - INLINE R2 +0001 INLINE R2 0001 * (expr) - INLINE RS +0001 INLINE RS 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: MapRouteTo({R1},{R2},{RS},{phrase options},true) 0001 * (call) 0001 * (expr) - IDENTIFIER MapRouteTo +0001 IDENTIFIER MapRouteTo 0001 * (expr) - INLINE R1 +0001 INLINE R1 0001 * (expr) - INLINE R2 +0001 INLINE R2 0001 * (expr) - INLINE RS +0001 INLINE RS 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options 0001 * (expr) - NUMBER true +0001 NUMBER true ========= Test: parse schema from: (HolderOf({something})) @@ -3718,9 +3718,9 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER HolderOf +0001 IDENTIFIER HolderOf 0001 * (expr) - INLINE something +0001 INLINE something ========= Test: parse schema from: (sibling({something})) @@ -3728,9 +3728,9 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER sibling +0001 IDENTIFIER sibling 0001 * (expr) - INLINE something +0001 INLINE something ========= Test: parse schema from: (child({something})) @@ -3738,16 +3738,16 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER child +0001 IDENTIFIER child 0001 * (expr) - INLINE something +0001 INLINE something ========= Test: parse schema from: YesOrNo() 0001 * (call) 0001 * (expr) - IDENTIFIER YesOrNo +0001 IDENTIFIER YesOrNo ========= Test: parse schema from: (SnippetMatches({S}, {T})) @@ -3755,11 +3755,11 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER SnippetMatches +0001 IDENTIFIER SnippetMatches 0001 * (expr) - INLINE S +0001 INLINE S 0001 * (expr) - INLINE T +0001 INLINE T ========= Test: parse schema from: (SnippetMatches({S}, {T}) == false) @@ -3768,13 +3768,13 @@ Test: parse schema from: 0001 * (operation) !eq 0001 * (call) 0001 * (expr) - IDENTIFIER SnippetMatches +0001 IDENTIFIER SnippetMatches 0001 * (expr) - INLINE S +0001 INLINE S 0001 * (expr) - INLINE T +0001 INLINE T 0001 * (expr) - NUMBER false +0001 NUMBER false ========= Test: parse schema from: (matched_text=SnippetIncludes({T},{S})) @@ -3782,14 +3782,14 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !store 0001 * (expr) - IDENTIFIER matched_text +0001 IDENTIFIER matched_text 0001 * (call) 0001 * (expr) - IDENTIFIER SnippetIncludes +0001 IDENTIFIER SnippetIncludes 0001 * (expr) - INLINE T +0001 INLINE T 0001 * (expr) - INLINE S +0001 INLINE S ========= Test: parse schema from: (SnippetIncludes({T},{S})==0) @@ -3798,127 +3798,127 @@ Test: parse schema from: 0001 * (operation) !eq 0001 * (call) 0001 * (expr) - IDENTIFIER SnippetIncludes +0001 IDENTIFIER SnippetIncludes 0001 * (expr) - INLINE T +0001 INLINE T 0001 * (expr) - INLINE S +0001 INLINE S 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: SetPlayersCommand({-by-reference:T}); 0001 * (call) 0001 * (expr) - IDENTIFIER SetPlayersCommand +0001 IDENTIFIER SetPlayersCommand 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T ========= Test: parse schema from: SpliceSnippet({S}, {-by-reference:T}); 0001 * (call) 0001 * (expr) - IDENTIFIER SpliceSnippet +0001 IDENTIFIER SpliceSnippet 0001 * (expr) - INLINE S +0001 INLINE S 0001 * (expr) - INLINE -by-reference:T +0001 INLINE -by-reference:T ========= Test: parse schema from: SpliceSnippet({S}, 0); 0001 * (call) 0001 * (expr) - IDENTIFIER SpliceSnippet +0001 IDENTIFIER SpliceSnippet 0001 * (expr) - INLINE S +0001 INLINE S 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: RulebookFails(); rtrue; 0001 * (call) 0001 * (expr) - IDENTIFIER RulebookFails +0001 IDENTIFIER RulebookFails 0001 * (statement) !return 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: PlaceInScope({O}, {phrase options}); 0001 * (call) 0001 * (expr) - IDENTIFIER PlaceInScope +0001 IDENTIFIER PlaceInScope 0001 * (expr) - INLINE O +0001 INLINE O 0001 * (expr) - INLINE phrase options +0001 INLINE phrase options ========= Test: parse schema from: ScopeWithin({O}); 0001 * (call) 0001 * (expr) - IDENTIFIER ScopeWithin +0001 IDENTIFIER ScopeWithin 0001 * (expr) - INLINE O +0001 INLINE O ========= Test: parse schema from: PronounNotice({O}); 0001 * (call) 0001 * (expr) - IDENTIFIER PronounNotice +0001 IDENTIFIER PronounNotice 0001 * (expr) - INLINE O +0001 INLINE O ========= Test: parse schema from: NotifyTheScore(); 0001 * (call) 0001 * (expr) - IDENTIFIER NotifyTheScore +0001 IDENTIFIER NotifyTheScore ========= Test: parse schema from: print (address) pronoun_word; 0001 * (statement) !printdword 0001 * (expr) - IDENTIFIER pronoun_word +0001 IDENTIFIER pronoun_word ========= Test: parse schema from: PrintCommand(); 0001 * (call) 0001 * (expr) - IDENTIFIER PrintCommand +0001 IDENTIFIER PrintCommand ========= Test: parse schema from: print (address) pronoun_word; 0001 * (statement) !printdword 0001 * (expr) - IDENTIFIER pronoun_word +0001 IDENTIFIER pronoun_word ========= Test: parse schema from: PrintCommand(); 0001 * (call) 0001 * (expr) - IDENTIFIER PrintCommand +0001 IDENTIFIER PrintCommand ========= Test: parse schema from: CoreOf({X}) 0001 * (call) 0001 * (expr) - IDENTIFIER CoreOf +0001 IDENTIFIER CoreOf 0001 * (expr) - INLINE X +0001 INLINE X ========= Test: parse schema from: (CommonAncestor({O}, {P})) @@ -3926,11 +3926,11 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER CommonAncestor +0001 IDENTIFIER CommonAncestor 0001 * (expr) - INLINE O +0001 INLINE O 0001 * (expr) - INLINE P +0001 INLINE P ========= Test: parse schema from: (CoreOfParentOfCoreOf({O})) @@ -3938,70 +3938,70 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (call) 0001 * (expr) - IDENTIFIER CoreOfParentOfCoreOf +0001 IDENTIFIER CoreOfParentOfCoreOf 0001 * (expr) - INLINE O +0001 INLINE O ========= Test: parse schema from: VisibilityParent({O}) 0001 * (call) 0001 * (expr) - IDENTIFIER VisibilityParent +0001 IDENTIFIER VisibilityParent 0001 * (expr) - INLINE O +0001 INLINE O ========= Test: parse schema from: FindVisibilityLevels(); 0001 * (call) 0001 * (expr) - IDENTIFIER FindVisibilityLevels +0001 IDENTIFIER FindVisibilityLevels ========= Test: parse schema from: TouchabilityCeiling({O}) 0001 * (call) 0001 * (expr) - IDENTIFIER TouchabilityCeiling +0001 IDENTIFIER TouchabilityCeiling 0001 * (expr) - INLINE O +0001 INLINE O ========= Test: parse schema from: visibility_levels 0001 * (expr) - IDENTIFIER visibility_levels +0001 IDENTIFIER visibility_levels ========= Test: parse schema from: visibility_ceiling 0001 * (expr) - IDENTIFIER visibility_ceiling +0001 IDENTIFIER visibility_ceiling ========= Test: parse schema from: LookAfterGoing(); 0001 * (call) 0001 * (expr) - IDENTIFIER LookAfterGoing +0001 IDENTIFIER LookAfterGoing ========= Test: parse schema from: PrintOrRun(location, description); 0001 * (call) 0001 * (expr) - IDENTIFIER PrintOrRun +0001 IDENTIFIER PrintOrRun 0001 * (expr) - IDENTIFIER location +0001 IDENTIFIER location 0001 * (expr) - IDENTIFIER description +0001 IDENTIFIER description ========= Test: parse schema from: say__comp 0001 * (expr) - IDENTIFIER say__comp +0001 IDENTIFIER say__comp ========= Test: parse schema from: (multiflag==1) @@ -4009,9 +4009,9 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !eq 0001 * (expr) - IDENTIFIER multiflag +0001 IDENTIFIER multiflag 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: (lookmode == 1) @@ -4019,9 +4019,9 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !eq 0001 * (expr) - IDENTIFIER lookmode +0001 IDENTIFIER lookmode 0001 * (expr) - NUMBER 1 +0001 NUMBER 1 ========= Test: parse schema from: (lookmode == 2) @@ -4029,9 +4029,9 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !eq 0001 * (expr) - IDENTIFIER lookmode +0001 IDENTIFIER lookmode 0001 * (expr) - NUMBER 2 +0001 NUMBER 2 ========= Test: parse schema from: (lookmode == 3) @@ -4039,9 +4039,9 @@ Test: parse schema from: 0001 * (subexpression) 0001 * (operation) !eq 0001 * (expr) - IDENTIFIER lookmode +0001 IDENTIFIER lookmode 0001 * (expr) - NUMBER 3 +0001 NUMBER 3 ========= Test: parse schema from: return GVS_Convert({AN},{O},0); @@ -4049,13 +4049,13 @@ Test: parse schema from: 0001 * (statement) !return 0001 * (call) 0001 * (expr) - IDENTIFIER GVS_Convert +0001 IDENTIFIER GVS_Convert 0001 * (expr) - INLINE AN +0001 INLINE AN 0001 * (expr) - INLINE O +0001 INLINE O 0001 * (expr) - NUMBER 0 +0001 NUMBER 0 ========= Test: parse schema from: return ConvertToRequest({X}, {AN}, {Y}, {Z}); @@ -4063,15 +4063,15 @@ Test: parse schema from: 0001 * (statement) !return 0001 * (call) 0001 * (expr) - IDENTIFIER ConvertToRequest +0001 IDENTIFIER ConvertToRequest 0001 * (expr) - INLINE X +0001 INLINE X 0001 * (expr) - INLINE AN +0001 INLINE AN 0001 * (expr) - INLINE Y +0001 INLINE Y 0001 * (expr) - INLINE Z +0001 INLINE Z ========= Test: parse schema from: return ConvertToGoingWithPush(); @@ -4079,46 +4079,46 @@ Test: parse schema from: 0001 * (statement) !return 0001 * (call) 0001 * (expr) - IDENTIFIER ConvertToGoingWithPush +0001 IDENTIFIER ConvertToGoingWithPush ========= Test: parse schema from: move {something} to {something else}; 0001 * (statement) !move 0001 * (expr) - INLINE something +0001 INLINE something 0001 * (expr) - INLINE something else +0001 INLINE something else ========= Test: parse schema from: MoveDuringGoing({something}, {something else}); 0001 * (call) 0001 * (expr) - IDENTIFIER MoveDuringGoing +0001 IDENTIFIER MoveDuringGoing 0001 * (expr) - INLINE something +0001 INLINE something 0001 * (expr) - INLINE something else +0001 INLINE something else ========= Test: parse schema from: SilentlyConsiderLight(); 0001 * (call) 0001 * (expr) - IDENTIFIER SilentlyConsiderLight +0001 IDENTIFIER SilentlyConsiderLight ========= Test: parse schema from: {-primitive-definition:verbose-checking} 0001 * (expr) - INLINE -primitive-definition:verbose-checking +0001 INLINE -primitive-definition:verbose-checking ========= Test: parse schema from: {-primitive-definition:verbose-checking} 0001 * (expr) - INLINE -primitive-definition:verbose-checking +0001 INLINE -primitive-definition:verbose-checking ========= Test: parse schema from: @log_shift xorshift_seed -3 -> temp; @@ -4126,33 +4126,33 @@ Test: parse schema from: 0001 * (assembly) 0001 * (expr) - OPCODE @log_shift +0001 OPCODE @log_shift 0001 * (expr) - IDENTIFIER xorshift_seed +0001 IDENTIFIER xorshift_seed 0001 * (expr) - NUMBER -3 +0001 NUMBER -3 0001 * (expr) - ASM_ARROW -> +0001 ASM_ARROW -> 0001 * (expr) - IDENTIFIER temp +0001 IDENTIFIER temp 0002 * (assembly) 0002 * (expr) - OPCODE @log_shift +0002 OPCODE @log_shift 0002 * (expr) - IDENTIFIER xorshift_seed +0002 IDENTIFIER xorshift_seed 0002 * (expr) - NUMBER -3 +0002 NUMBER -3 0002 * (expr) - ASM_ARROW -> +0002 ASM_ARROW -> 0001 * (expr) - IDENTIFIER temp +0001 IDENTIFIER temp ========= Test: parse schema from: print ""; 0001 * (statement) !print 0001 * (expr) - DQUOTED +0001 DQUOTED ========= Test: parse schema from: print '^'; @@ -4164,37 +4164,37 @@ Test: parse schema from: 0001 * (statement) !printnumber 0001 * (expr) - SQUOTED ^ +0001 SQUOTED ^ 0002 * (statement) !printnumber 0002 * (expr) - SQUOTED helen's// +0002 SQUOTED helen's// 0003 * (statement) !printchar 0003 * (expr) - SQUOTED ß +0003 SQUOTED ß 0003 * (statement) !print 0003 * (expr) - DQUOTED might be an ß, who knows. +0003 DQUOTED might be an ß, who knows. 0004 * (statement) !printdword 0004 * (expr) - SQUOTED xß +0004 SQUOTED xß 0004 * (statement) !print 0004 * (expr) - DQUOTED might be an xß, who knows. +0004 DQUOTED might be an xß, who knows. 0005 * (statement) !printchar 0005 * (expr) - SQUOTED A +0005 SQUOTED A 0005 * (statement) !print 0005 * (expr) - DQUOTED might be an A, who knows. +0005 DQUOTED might be an A, who knows. 0006 * (statement) !printdword 0006 * (expr) - SQUOTED xA +0006 SQUOTED xA 0006 * (statement) !print 0006 * (expr) - DQUOTED might be an xA, who knows. +0006 DQUOTED might be an xA, who knows. ========= Test: parse schema from: @@ -4278,235 +4278,235 @@ Test: parse schema from: 0001 * (statement) !print 0001 * (expr) - DQUOTED Les œuvres d'Æsop en français, mon élève! +0001 DQUOTED Les œuvres d'Æsop en français, mon élève! 0002 * (statement) !print 0002 * (expr) - DQUOTED Naïve readers of the New Yorker reëlected Mr Clinton. +0002 DQUOTED Naïve readers of the New Yorker reëlected Mr Clinton. 0003 * (statement) !print 0003 * (expr) - DQUOTED Gauß first proved the Fundamental Theorem of Algebra. +0003 DQUOTED Gauß first proved the Fundamental Theorem of Algebra. 0004 * (statement) !print 0004 * (expr) - DQUOTED áéíóúýÁÉÍÓÚÝàèìòùÀÈÌÒÙâêîôûÂÊÎÔÛäëïöüÿÄËÏÖÜŸ +0004 DQUOTED áéíóúýÁÉÍÓÚÝàèìòùÀÈÌÒÙâêîôûÂÊÎÔÛäëïöüÿÄËÏÖÜŸ 0005 * (statement) !print 0005 * (expr) - DQUOTED ãñõÃÑÕçÇøØæÆðÐþΣ¡¿«»ßåÅœŒ +0005 DQUOTED ãñõÃÑÕçÇøØæÆðÐþΣ¡¿«»ßåÅœŒ 0006 * (statement) !print 0006 * (expr) - DQUOTED So © is a copyright sign, and Ф is a capital Cyrillic ef, and ▲ is a triangle +0006 DQUOTED So © is a copyright sign, and Ф is a capital Cyrillic ef, and ▲ is a triangle 0007 * (statement) !print 0007 * (expr) - DQUOTED Backslash: \ At sign: @ Caret: ^ Tilde: ~ +0007 DQUOTED Backslash: \ At sign: @ Caret: ^ Tilde: ~ 0008 * (statement) !print 0008 * (expr) - DQUOTED a-diarhesis: ä. +0008 DQUOTED a-diarhesis: ä. 0009 * (statement) !print 0009 * (expr) - DQUOTED o-diarhesis: ö. +0009 DQUOTED o-diarhesis: ö. 0010 * (statement) !print 0010 * (expr) - DQUOTED u-diarhesis: ü. +0010 DQUOTED u-diarhesis: ü. 0011 * (statement) !print 0011 * (expr) - DQUOTED A-diarhesis: Ä. +0011 DQUOTED A-diarhesis: Ä. 0012 * (statement) !print 0012 * (expr) - DQUOTED O-diarhesis: Ö. +0012 DQUOTED O-diarhesis: Ö. 0013 * (statement) !print 0013 * (expr) - DQUOTED U-diarhesis: Ü. +0013 DQUOTED U-diarhesis: Ü. 0014 * (statement) !print 0014 * (expr) - DQUOTED sharp s: ß. +0014 DQUOTED sharp s: ß. 0015 * (statement) !print 0015 * (expr) - DQUOTED close double-angle quotation mark: ». +0015 DQUOTED close double-angle quotation mark: ». 0016 * (statement) !print 0016 * (expr) - DQUOTED open double-angle quotation mark: «. +0016 DQUOTED open double-angle quotation mark: «. 0017 * (statement) !print 0017 * (expr) - DQUOTED e-diarhesis: ë. +0017 DQUOTED e-diarhesis: ë. 0018 * (statement) !print 0018 * (expr) - DQUOTED i-diarhesis: ï. +0018 DQUOTED i-diarhesis: ï. 0019 * (statement) !print 0019 * (expr) - DQUOTED y-diarhesis: ÿ. +0019 DQUOTED y-diarhesis: ÿ. 0020 * (statement) !print 0020 * (expr) - DQUOTED E-diarhesis: Ë. +0020 DQUOTED E-diarhesis: Ë. 0021 * (statement) !print 0021 * (expr) - DQUOTED I-diarhesis: Ï. +0021 DQUOTED I-diarhesis: Ï. 0022 * (statement) !print 0022 * (expr) - DQUOTED a-acute: á. +0022 DQUOTED a-acute: á. 0023 * (statement) !print 0023 * (expr) - DQUOTED e-acute: é. +0023 DQUOTED e-acute: é. 0024 * (statement) !print 0024 * (expr) - DQUOTED i-acute: í. +0024 DQUOTED i-acute: í. 0025 * (statement) !print 0025 * (expr) - DQUOTED o-acute: ó. +0025 DQUOTED o-acute: ó. 0026 * (statement) !print 0026 * (expr) - DQUOTED u-acute: ú. +0026 DQUOTED u-acute: ú. 0027 * (statement) !print 0027 * (expr) - DQUOTED y-acute: ý. +0027 DQUOTED y-acute: ý. 0028 * (statement) !print 0028 * (expr) - DQUOTED A-acute: Á. +0028 DQUOTED A-acute: Á. 0029 * (statement) !print 0029 * (expr) - DQUOTED E-acute: É. +0029 DQUOTED E-acute: É. 0030 * (statement) !print 0030 * (expr) - DQUOTED I-acute: Í. +0030 DQUOTED I-acute: Í. 0031 * (statement) !print 0031 * (expr) - DQUOTED O-acute: Ó. +0031 DQUOTED O-acute: Ó. 0032 * (statement) !print 0032 * (expr) - DQUOTED U-acute: Ú. +0032 DQUOTED U-acute: Ú. 0033 * (statement) !print 0033 * (expr) - DQUOTED Y-acute: Ý. +0033 DQUOTED Y-acute: Ý. 0034 * (statement) !print 0034 * (expr) - DQUOTED a-grave: à. +0034 DQUOTED a-grave: à. 0035 * (statement) !print 0035 * (expr) - DQUOTED e-grave: è. +0035 DQUOTED e-grave: è. 0036 * (statement) !print 0036 * (expr) - DQUOTED i-grave: ì. +0036 DQUOTED i-grave: ì. 0037 * (statement) !print 0037 * (expr) - DQUOTED o-grave: ò. +0037 DQUOTED o-grave: ò. 0038 * (statement) !print 0038 * (expr) - DQUOTED u-grave: ù. +0038 DQUOTED u-grave: ù. 0039 * (statement) !print 0039 * (expr) - DQUOTED A-grave: À. +0039 DQUOTED A-grave: À. 0040 * (statement) !print 0040 * (expr) - DQUOTED E-grave: È. +0040 DQUOTED E-grave: È. 0041 * (statement) !print 0041 * (expr) - DQUOTED I-grave: Ì. +0041 DQUOTED I-grave: Ì. 0042 * (statement) !print 0042 * (expr) - DQUOTED O-grave: Ò. +0042 DQUOTED O-grave: Ò. 0043 * (statement) !print 0043 * (expr) - DQUOTED U-grave: Ù. +0043 DQUOTED U-grave: Ù. 0044 * (statement) !print 0044 * (expr) - DQUOTED a-circumflex: â. +0044 DQUOTED a-circumflex: â. 0045 * (statement) !print 0045 * (expr) - DQUOTED e-circumflex: ê. +0045 DQUOTED e-circumflex: ê. 0046 * (statement) !print 0046 * (expr) - DQUOTED i-circumflex: î. +0046 DQUOTED i-circumflex: î. 0047 * (statement) !print 0047 * (expr) - DQUOTED o-circumflex: ô. +0047 DQUOTED o-circumflex: ô. 0048 * (statement) !print 0048 * (expr) - DQUOTED u-circumflex: û. +0048 DQUOTED u-circumflex: û. 0049 * (statement) !print 0049 * (expr) - DQUOTED A-circumflex: Â. +0049 DQUOTED A-circumflex: Â. 0050 * (statement) !print 0050 * (expr) - DQUOTED E-circumflex: Ê. +0050 DQUOTED E-circumflex: Ê. 0051 * (statement) !print 0051 * (expr) - DQUOTED I-circumflex: Î. +0051 DQUOTED I-circumflex: Î. 0052 * (statement) !print 0052 * (expr) - DQUOTED O-circumflex: Ô. +0052 DQUOTED O-circumflex: Ô. 0053 * (statement) !print 0053 * (expr) - DQUOTED U-circumflex: Û. +0053 DQUOTED U-circumflex: Û. 0054 * (statement) !print 0054 * (expr) - DQUOTED a-ring: æ. +0054 DQUOTED a-ring: æ. 0055 * (statement) !print 0055 * (expr) - DQUOTED A-ring: Æ. +0055 DQUOTED A-ring: Æ. 0056 * (statement) !print 0056 * (expr) - DQUOTED o-stroke: ø. +0056 DQUOTED o-stroke: ø. 0057 * (statement) !print 0057 * (expr) - DQUOTED O-stroke: Ø. +0057 DQUOTED O-stroke: Ø. 0058 * (statement) !print 0058 * (expr) - DQUOTED a-tilde: ã. +0058 DQUOTED a-tilde: ã. 0059 * (statement) !print 0059 * (expr) - DQUOTED n-tilde: ñ. +0059 DQUOTED n-tilde: ñ. 0060 * (statement) !print 0060 * (expr) - DQUOTED o-tilde: õ. +0060 DQUOTED o-tilde: õ. 0061 * (statement) !print 0061 * (expr) - DQUOTED A-tilde: Ã. +0061 DQUOTED A-tilde: Ã. 0062 * (statement) !print 0062 * (expr) - DQUOTED N-tilde: Ñ. +0062 DQUOTED N-tilde: Ñ. 0063 * (statement) !print 0063 * (expr) - DQUOTED O-tilde: Õ. +0063 DQUOTED O-tilde: Õ. 0064 * (statement) !print 0064 * (expr) - DQUOTED ae: æ. +0064 DQUOTED ae: æ. 0065 * (statement) !print 0065 * (expr) - DQUOTED AE: Æ. +0065 DQUOTED AE: Æ. 0066 * (statement) !print 0066 * (expr) - DQUOTED c-cedilla: ç. +0066 DQUOTED c-cedilla: ç. 0067 * (statement) !print 0067 * (expr) - DQUOTED C-cedilla: Ç. +0067 DQUOTED C-cedilla: Ç. 0068 * (statement) !print 0068 * (expr) - DQUOTED thorn: þ. +0068 DQUOTED thorn: þ. 0069 * (statement) !print 0069 * (expr) - DQUOTED eth: ð. +0069 DQUOTED eth: ð. 0070 * (statement) !print 0070 * (expr) - DQUOTED Thorn: Þ. +0070 DQUOTED Thorn: Þ. 0071 * (statement) !print 0071 * (expr) - DQUOTED Eth: Ð. +0071 DQUOTED Eth: Ð. 0072 * (statement) !print 0072 * (expr) - DQUOTED pound sterling sign: £. +0072 DQUOTED pound sterling sign: £. 0073 * (statement) !print 0073 * (expr) - DQUOTED oe: œ. +0073 DQUOTED oe: œ. 0074 * (statement) !print 0074 * (expr) - DQUOTED OE: Œ. +0074 DQUOTED OE: Œ. 0075 * (statement) !print 0075 * (expr) - DQUOTED inverted !: ¡. +0075 DQUOTED inverted !: ¡. 0076 * (statement) !print 0076 * (expr) - DQUOTED inverted ?: ¿. +0076 DQUOTED inverted ?: ¿. 0077 * (statement) !print 0077 * (expr) - DQUOTED © is a copyright sign. Ф is a capital Cyrillic ef, and ▲ is a triangle. +0077 DQUOTED © is a copyright sign. Ф is a capital Cyrillic ef, and ▲ is a triangle. ========= Test: parse schema from: print BasicInformKit`stuff(); @@ -4515,12 +4515,12 @@ Test: parse schema from: 0001 * (statement) !printnumber 0001 * (call) 0002 * (expr) - IDENTIFIER BasicInformKit`stuff +0002 IDENTIFIER BasicInformKit`stuff 0002 * (operation) !store 0002 * (expr) - IDENTIFIER DialogueKit`temp +0002 IDENTIFIER DialogueKit`temp 0003 * (expr) - NUMBER 1 +0003 NUMBER 1 ========= Test: parse schema from: @@ -4534,10 +4534,95 @@ Test: parse schema from: 0004 * (statement) !printnumber 0004 * (call) 0005 * (expr) - IDENTIFIER BasicInformKit`stuff +0005 IDENTIFIER BasicInformKit`stuff 0005 * (operation) !store 0007 * (expr) - IDENTIFIER DialogueKit`temp +0007 IDENTIFIER DialogueKit`temp 0008 * (expr) - NUMBER 1 +0008 NUMBER 1 +========= +Test: parse schema from: + switch (num) { + 8, 10: print "a test-flight."; + 11, 12, 14 to 17: print "a landing."; + 13: print "it back."; + } + +Schema error: 'to' ranges are unsupported in switch cases +Schema provenance hypothetical.txt, line 1 +0001 * (statement) !switch +0001 * (subexpression) +0001 * (expr) +0001 IDENTIFIER num +0002 * (code) +0002 * (statement) !case +0002 * (operation) !alternativecase +0002 * (expr) +0002 NUMBER 8 +0002 * (expr) +0002 NUMBER 10 +0002 * (code) +0002 * (statement) !print +0002 * (expr) +0002 DQUOTED a test-flight. +0003 * (statement) !case +0003 * (operation) !alternativecase +0003 * (operation) !alternativecase +0003 * (expr) +0003 NUMBER 11 +0003 * (expr) +0003 NUMBER 12 +0003 * (expr) +0003 NUMBER 14 +0003 IDENTIFIER to +0003 NUMBER 17 +0003 * (code) +0003 * (statement) !print +0003 * (expr) +0003 DQUOTED a landing. +0004 * (statement) !case +0004 * (expr) +0004 NUMBER 13 +0004 * (code) +0004 * (statement) !print +0004 * (expr) +0004 DQUOTED it back. + +0001 * (statement) !switch +0001 * (subexpression) +0001 * (expr) +0001 IDENTIFIER num +0002 * (code) +0002 * (statement) !case +0002 * (operation) !alternativecase +0002 * (expr) +0002 NUMBER 8 +0002 * (expr) +0002 NUMBER 10 +0002 * (code) +0002 * (statement) !print +0002 * (expr) +0002 DQUOTED a test-flight. +0003 * (statement) !case +0003 * (operation) !alternativecase +0003 * (operation) !alternativecase +0003 * (expr) +0003 NUMBER 11 +0003 * (expr) +0003 NUMBER 12 +0003 * (expr) +0003 NUMBER 14 +0003 IDENTIFIER to +0003 NUMBER 17 +0003 * (code) +0003 * (statement) !print +0003 * (expr) +0003 DQUOTED a landing. +0004 * (statement) !case +0004 * (expr) +0004 NUMBER 13 +0004 * (code) +0004 * (statement) !print +0004 * (expr) +0004 DQUOTED it back. ========= diff --git a/inter/building-test/Tests/Test Cases/schemas.txt b/inter/building-test/Tests/Test Cases/schemas.txt index 312bf203b..c941bf61c 100644 --- a/inter/building-test/Tests/Test Cases/schemas.txt +++ b/inter/building-test/Tests/Test Cases/schemas.txt @@ -1647,3 +1647,11 @@ schema DialogueKit`temp = 1; end + +schema + switch (num) { + 8, 10: print "a test-flight."; + 11, 12, 14 to 17: print "a landing."; + 13: print "it back."; + } +end From 29e5206d42aede7822b33329720cc15f33932304 Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Sun, 30 Apr 2023 10:40:31 +0100 Subject: [PATCH 018/113] Updated notes --- docs/building-module/2-is.html | 5 ++++ docs/building-module/2-rmf.html | 17 +++++++++++++ inform7/Figures/memory-diagnostics.txt | 4 +-- inform7/Figures/timings-diagnostics.txt | 33 +++++++++++++------------ notes/release/pending.md | 9 ++++++- 5 files changed, 49 insertions(+), 19 deletions(-) diff --git a/docs/building-module/2-is.html b/docs/building-module/2-is.html index baa799107..7a0326db9 100644 --- a/docs/building-module/2-is.html +++ b/docs/building-module/2-is.html @@ -620,6 +620,11 @@ we go to some trouble here. if (isn->expression_tokens == NULL) LOG(" - empty"); LOG("\n"); for (inter_schema_token *t = isn->expression_tokens; t; t=t->next) { + if (Provenance::is_somewhere(isn->provenance)) { + LOG("%04d ", Provenance::get_line(isn->provenance)); + } else { + LOG(".... "); + } for (int d = 0; d < depth + 1; d++) LOG(" "); InterSchemas::log_ist(t); if (isn != t->owner) LOG(" !!! ownership incorrect here"); diff --git a/docs/building-module/2-rmf.html b/docs/building-module/2-rmf.html index 2714566a9..72e1e0949 100644 --- a/docs/building-module/2-rmf.html +++ b/docs/building-module/2-rmf.html @@ -2186,10 +2186,27 @@ to cause trouble later. If no error is thrown, the schema is unchanged. } else { if (isn->expression_tokens) I6Errors::issue_at_node(isn, I"syntax error"); } + if ((isn->isn_type == STATEMENT_ISNT) && (isn->isn_clarifier == CASE_BIP)) { + if ((isn->child_node) && (isn->child_node->isn_type == EXPRESSION_ISNT)) + Ramification::check_for_to(isn, isn->child_node); + } + if ((isn->isn_type == OPERATION_ISNT) && (isn->isn_clarifier == ALTERNATIVECASE_BIP)) { + if ((isn->child_node) && (isn->child_node->isn_type == EXPRESSION_ISNT)) + Ramification::check_for_to(isn, isn->child_node); + if ((isn->child_node) && (isn->child_node->next_node) && + (isn->child_node->next_node->isn_type == EXPRESSION_ISNT)) + Ramification::check_for_to(isn, isn->child_node->next_node); + } Ramification::sanity_check(isn, isn->child_node); } return FALSE; } + +int Ramification::check_for_to(inter_schema_node *par, inter_schema_node *isn) { + for (inter_schema_token *t = isn->expression_tokens; t; t=t->next) + if ((t->ist_type == IDENTIFIER_ISTT) && (Str::eq(t->material, I"to"))) + I6Errors::issue_at_node(isn, I"'to' ranges are unsupported in switch cases"); +}