Import v6.12.5 of the Inform 6 standard library
[informlib.git] / parser.h
index c5b184a879a3de75e295ae521b4be04c138ccbe7..9ef53b10db275e615b1c90d28116f7f814641ec8 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -1,9 +1,9 @@
 ! ==============================================================================
 !   PARSER:  Front end to parser.
 !
-!   Supplied for use with Inform 6 -- Release 6.12.4 -- Serial number 200718
+!   Supplied for use with Inform 6 -- Release 6.12.5 -- Serial number 210605
 !
-!   Copyright Graham Nelson 1993-2004 and David Griffith 2012-2020
+!   Copyright Graham Nelson 1993-2004 and David Griffith 2012-2021
 !
 !   This file is free software: you can redistribute it and/or modify
 !   it under the terms of the GNU Affero General Public License as
 !   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 !   Affero General Public License for more details.
 !
+!   You should have received a copy of the GNU Affero General Public
+!   License along with this program. If not, see
+!   https://gnu.org/licenses/
+!
 !   In your game file, Include three library files in this order:
 !       Include "parser";
-!       Include "berblib";
+!       Include "verblib";
 !       Include "grammar";
 !
 ! ------------------------------------------------------------------------------
@@ -66,7 +70,7 @@ System_file;
 ! ------------------------------------------------------------------------------
 
 #Ifndef VN_1633;
-Message fatalerror "*** Library 6.12.3 needs Inform v6.33 or later to work ***";
+Message fatalerror "*** Library 6.12.x needs Inform v6.33 or later to work ***";
 #Endif; ! VN_
 
 Include "version";
@@ -1505,7 +1509,7 @@ Object  InformParser "(Inform Parser)"
     i = (~~i);
     #Endif; ! TARGET_
     if (i == 0) {    L__M(##Miscellany, 7); return 0; }
-    L__M(##Miscellany, 1);
+    L__M(##Miscellany, 6);
     return 1;
 ];
 
@@ -2237,7 +2241,7 @@ Object  InformParser "(Inform Parser)"
                 oops_from = 0;
 
                 ! ...explain any inferences made (using the pattern)...
-
+               ! This is where the parser replies (the sword) if things aren't clear.
                 if (inferfrom ~= 0 && no_infer_message == false) {
                     print "("; PrintCommand(inferfrom); print ")^";
                 }
@@ -2381,13 +2385,7 @@ Object  InformParser "(Inform Parser)"
     if (etype == NUMBER_PE)     L__M(##Miscellany, 29);
     if (etype == CANTSEE_PE) {  L__M(##Miscellany, 30); oops_from=saved_oops;}
     if (etype == TOOLIT_PE)     L__M(##Miscellany, 31);
-    if (etype == NOTHELD_PE) {
-               if (parent(noun) has container)
-                       L__M(##Take, 14, noun);
-               else
-                       L__M(##Miscellany, 32, not_holding);
-               oops_from=saved_oops;
-    }
+    if (etype == NOTHELD_PE) {  L__M(##Miscellany, 32, not_holding); oops_from=saved_oops; }
     if (etype == MULTI_PE)      L__M(##Miscellany, 33);
     if (etype == MMULTI_PE)     L__M(##Miscellany, 34);
     if (etype == VAGUE_PE)      L__M(##Miscellany, 35, pronoun_word);
@@ -2523,14 +2521,19 @@ Constant UNLIT_BIT  =  32;
     indef_nspec_at = 0;
 ];
 
-[ Descriptors  allows_multiple o x flag cto type m n;
+[ Descriptors  allows_multiple o x flag cto type m n;
     ResetDescriptors();
     if (wn > num_words) return 0;
     m = wn;
     for (flag=true : flag :) {
         o = NextWordStopped(); flag = false;
-       for (x=1 : x<=LanguageDescriptors-->0 : x=x+4)
+       for (x=1 : x<=LanguageDescriptors-->0 : x=x+4) {
             if (o == LanguageDescriptors-->x) {
+                ! Attempt to compensate for her-her confusion.
+                for (y = 1 : y<=LanguagePronouns-->0 : y=y+2) {
+                    if (o == LanguagePronouns-->y)
+                        jump PersonalPronoun;
+                }
                 flag = true;
                 type = LanguageDescriptors-->(x+2);
                 if (type ~= DEFART_PK) indef_mode = true;
@@ -2549,6 +2552,9 @@ Constant UNLIT_BIT  =  32;
                 if (type == light)  indef_type = indef_type | LIT_BIT;
                 if (type == -light) indef_type = indef_type | UNLIT_BIT;
             }
+        }
+        .PersonalPronoun;
+
         if (o == OTHER1__WD or OTHER2__WD or OTHER3__WD) {
             indef_mode = 1; flag = 1;
             indef_type = indef_type | OTHER_BIT;
@@ -2584,7 +2590,7 @@ Constant UNLIT_BIT  =  32;
     if (actor ~= player) rtrue;
     if (obj has animate) rtrue;
     if (obj hasnt talkable) rfalse;
-    if (action_to_be == ##Ask or ##Answer or ##Tell or ##AskFor) rtrue;
+    if (action_to_be == ##Ask or ##Answer or ##Tell or ##AskFor or ##AskTo) rtrue;
     rfalse;
 ];
 
@@ -2669,7 +2675,7 @@ Constant UNLIT_BIT  =  32;
             parsed_number = l; return GPR_NUMBER;
 
           CREATURE_TOKEN:
-            if (action_to_be == ##Answer or ##Ask or ##AskFor or ##Tell)
+            if (action_to_be == ##Answer or ##Ask or ##AskFor or ##AskTo or ##Tell)
                 scope_reason = TALKING_REASON;
 
           TOPIC_TOKEN:
@@ -2861,12 +2867,6 @@ Constant UNLIT_BIT  =  32;
         #Endif; ! DEBUG
         l = NounDomain(actors_location, actor, token);
         if (l == REPARSE_CODE) return l;                  ! Reparse after Q&A
-        if ((metaclass(l) == Class || metaclass(l) == Object) && l ~= 1 && l notin actor && token == MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN) {
-           if (ImplicitTake(l)) {
-               etype = NOTHELD_PE;
-               jump FailToken;
-           }
-       }
 
         if (indef_wanted == 100 && l == 0 && number_matched == 0)
             l = 1;  ! ReviseMulti if TAKE ALL FROM empty container
@@ -3071,7 +3071,6 @@ Constant UNLIT_BIT  =  32;
     ! allowing singulars (so that words like "six" are not swallowed up as
     ! Descriptors)
 
-    noun = l;  ! Allow the noun to be mentioned by the *_PE error messages.
     if (allow_plurals && indef_guess_p == 1) {
         #Ifdef DEBUG;
         if (parser_trace >= 4) print "   [Retrying singulars after failure ", etype, "]^";
@@ -3670,6 +3669,18 @@ Constant SCORE__DIVISOR     = 20;
             }
 
         if (flag) {
+           if(match_length == 1) {
+               k = 0;
+               for (i=1 : i<=number_of_classes : i++) {
+                   while ((match_classes-->k) ~= i or -i) k++;
+                   j = match_list-->k;
+
+                   if(MatchWord(j, match_from)) {
+                       no_infer_message = true;
+                       return j;
+                   }
+               }
+           }
             #Ifdef DEBUG;
             if (parser_trace >= 4) print "   Unable to choose best group, so ask player.]^";
             #Endif; ! DEBUG
@@ -3939,6 +3950,50 @@ Constant SCORE__DIVISOR     = 20;
     rtrue;
 ];
 
+
+! ----------------------------------------------------------------------------
+!  MatchWord matches a word to the name of an object.  This is used to assume
+!  that an object simply named "key" is meant when the player types TAKE KEY
+!  rather than TAKE BRASS KEY.
+! ----------------------------------------------------------------------------
+
+[ MatchWord p_obj p_word_no       len_name len_input start_input i;
+
+    p_word_no--;
+
+    PrintToBuffer(StorageForShortName, SHORTNAMEBUF_LEN, p_obj);
+    len_name = StorageForShortName --> 0;
+
+    if(len_name > 9) {
+       for(i = 9 : i < len_name : i++)
+           if(StorageForShortName -> (WORDSIZE + i) == 32) rfalse;
+       len_name = 9;
+    }
+
+#Ifdef TARGET_ZCODE;
+    start_input = (parse + 2) -> (4 * p_word_no + 3);
+    len_input = (parse + 2) -> (4 * p_word_no + 2);
+    if(len_input > 9) len_input = 9;
+    if(len_name ~= len_input) rfalse;
+    for(i = 0 : i < len_name : i++) {
+       if(StorageForShortName -> (WORDSIZE + i) ~= buffer -> (start_input + i))
+           rfalse;
+    }
+#Ifnot;  ! TARGET_GLULX
+    start_input = parse --> (((p_word_no+1) * 3)) - 2;
+    len_input = parse --> ((p_word_no+1) * 3 - 1);
+    if(len_input > 9) len_input = 9;
+    if(len_name ~= len_input) rfalse;
+    for(i = 0 : i < len_name : i++) {
+       if(StorageForShortName -> (WORDSIZE + i) ~= buffer -> (start_input + i + 2))
+           rfalse;
+    }
+#Endif;  ! TARGET_
+
+    rtrue;
+];
+
+
 ! ----------------------------------------------------------------------------
 !  PrintCommand reconstructs the command as it presently reads, from
 !  the pattern which has been built up