X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=parser.h;h=c5b184a879a3de75e295ae521b4be04c138ccbe7;hb=refs%2Ftags%2Fv6.12.4;hp=d0b427ecd480f1f1951d63ddeec89b86af76765e;hpb=d94736d23b49e9b6653564cef67f96d028405c11;p=informlib.git diff --git a/parser.h b/parser.h index d0b427e..c5b184a 100644 --- a/parser.h +++ b/parser.h @@ -1,9 +1,9 @@ ! ============================================================================== ! PARSER: Front end to parser. ! -! Supplied for use with Inform 6 -- Release 6.12.2 -- Serial number 180520 +! Supplied for use with Inform 6 -- Release 6.12.4 -- Serial number 200718 ! -! Copyright Graham Nelson 1993-2004 and David Griffith 2012-2018 +! Copyright Graham Nelson 1993-2004 and David Griffith 2012-2020 ! ! This file is free software: you can redistribute it and/or modify ! it under the terms of the GNU Affero General Public License as @@ -15,13 +15,9 @@ ! 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 "verblib"; +! Include "berblib"; ! Include "grammar"; ! ! ------------------------------------------------------------------------------ @@ -70,13 +66,10 @@ System_file; ! ------------------------------------------------------------------------------ #Ifndef VN_1633; -Message fatalerror "*** Library 6.12.2 needs Inform v6.33 or later to work ***"; +Message fatalerror "*** Library 6.12.3 needs Inform v6.33 or later to work ***"; #Endif; ! VN_ -Constant LibSerial "180520"; -Constant LibRelease "6.12.2"; -Constant LIBRARY_VERSION 612; -Constant Grammar__Version 2; +Include "version"; Constant BEFORE_PARSER 10; Constant AFTER_PARSER 20; @@ -164,6 +157,7 @@ Fake_Action TheSame; Fake_Action PluralFound; Fake_Action ListMiscellany; Fake_Action Miscellany; +Fake_Action RunTimeError; Fake_Action Prompt; Fake_Action NotUnderstood; Fake_Action Going; @@ -326,6 +320,10 @@ Global inventory_stage = 1; ! 1 or 2 according to the context in which ! "invent" routines of objects are called Global inventory_style; ! List-writer style currently used while ! printing inventories + +Global objects_style; ! List-writer style currently used while +Global places_style; ! printing objects handled or places visited + ! ------------------------------------------------------------------------------ ! Menus and printing ! ------------------------------------------------------------------------------ @@ -376,6 +374,20 @@ Constant CLR_WHITE 9; Constant CLR_PURPLE 7; Constant CLR_AZURE 8; +#Ifdef TARGET_GLULX; +Array GlulxColourValues + --> (-2) + (-1) + $000000 + $EF0000 + $00D600 + $EFEF00 + $006BB5 + $FF00FF + $00EFEF + $FFFFFF; +#Endif; ! TARGET_GLULX + Constant WIN_ALL 0; Constant WIN_STATUS 1; Constant WIN_MAIN 2; @@ -804,7 +816,6 @@ Object thedark "(darkness object)" ! If you want to use the third-person of the narrative voice, you will ! need to replace this selfobj with your own. - Class SelfClass with name ',a' ',b' ',c' ',d' ',e', short_name YOURSELF__TX, @@ -815,7 +826,7 @@ Class SelfClass each_turn NULL, time_out NULL, describe NULL, - article "the", + article THE__TX, add_to_scope 0, capacity 100, parse_name 0, @@ -1444,7 +1455,7 @@ Object InformParser "(Inform Parser)" w2 = a_table-->(3*oops_from - 1); ! Length of word to go #Endif; ! TARGET_ -#IfDef OOPS_CHECK; +#Ifdef OOPS_CHECK; print "[~"; for (i=0 : i(i+w); print "~ --> ~"; @@ -1467,12 +1478,12 @@ Object InformParser "(Inform Parser)" for (i=0 : i(i+w) = buffer2->(i+x1); -#IfDef OOPS_CHECK; +#Ifdef OOPS_CHECK; print (char) buffer2->(i+x1); #Endif; } -#IfDef OOPS_CHECK; +#Ifdef OOPS_CHECK; print "~]^^"; #Endif; @@ -1743,14 +1754,14 @@ Object InformParser "(Inform Parser)" if (verb_word == 0 || ((verb_word->#dict_par1) & DICT_VERB) == 0) { - ! So is the first word an object contained in the special object "compass" + ! So is the first word an object contained in the special object "Compass" ! (i.e., a direction)? This needs use of NounDomain, a routine which ! does the object matching, returning the object number, or 0 if none found, ! or REPARSE_CODE if it has restructured the parse table so the whole parse ! must be begun again... wn = verb_wordnum; indef_mode = false; token_filter = 0; - l = NounDomain(compass, 0, NOUN_TOKEN); + l = NounDomain(Compass, 0, NOUN_TOKEN); if (l == REPARSE_CODE) jump ReParse; ! If it is a direction, send back the results: @@ -2370,7 +2381,13 @@ 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) { L__M(##Miscellany, 32, not_holding); oops_from=saved_oops; } + 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 == MULTI_PE) L__M(##Miscellany, 33); if (etype == MMULTI_PE) L__M(##Miscellany, 34); if (etype == VAGUE_PE) L__M(##Miscellany, 35, pronoun_word); @@ -2844,7 +2861,7 @@ Constant UNLIT_BIT = 32; #Endif; ! DEBUG l = NounDomain(actors_location, actor, token); if (l == REPARSE_CODE) return l; ! Reparse after Q&A - if (l ~= nothing && l ~= 1 && l notin actor && token == MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN) { + 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; @@ -2865,7 +2882,7 @@ Constant UNLIT_BIT = 32; wn = desc_wn; jump TryAgain2; } - if (etype ~=TOOFEW_PE && (multiflag || etype ~= MULTI_PE)) + if ((etype ~=TOOFEW_PE && etype ~= VAGUE_PE) && (multiflag || etype ~= MULTI_PE)) etype = CantSee(); jump FailToken; } ! Choose best error @@ -3054,6 +3071,7 @@ 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, "]^"; @@ -3162,7 +3180,7 @@ Constant UNLIT_BIT = 32; number_of_classes = 0; - if (match_length == 0 && indef_mode && indef_wanted ~= 100) + if (match_length == 0 && indef_mode && indef_wanted > 0 && indef_wanted < 100) number_matched = 0; ! ask question for 'take three' if (number_matched == 1) i = match_list-->0; if (number_matched > 1) { @@ -3775,9 +3793,9 @@ Constant SCORE__DIVISOR = 20; if (its_owner == actors_location) its_score = its_score + l_s; else { #Ifdef TRADITIONAL_TAKE_ALL; - if (its_owner ~= compass) its_score = its_score + SCORE__NOTCOMPASS; + if (its_owner ~= Compass) its_score = its_score + SCORE__NOTCOMPASS; #Ifnot; - if (its_owner ~= compass) + if (its_owner ~= Compass) if (take_all_rule && its_owner && its_owner has static or scenery && (its_owner has supporter || @@ -3871,7 +3889,7 @@ Constant SCORE__DIVISOR = 20; [ Identical o1 o2 p1 p2 n1 n2 i j flag; if (o1 == o2) rtrue; ! This should never happen, but to be on the safe side if (o1 == 0 || o2 == 0) rfalse; ! Similarly - if (parent(o1) == compass || parent(o2) == compass) rfalse; ! Saves time + if (parent(o1) == Compass || parent(o2) == Compass) rfalse; ! Saves time ! What complicates things is that o1 or o2 might have a parsing routine, ! so the parser can't know from here whether they are or aren't the same. @@ -3959,7 +3977,7 @@ Constant SCORE__DIVISOR = 20; if (i >= REPARSE_CODE) print (address) No__Dword(i-REPARSE_CODE); else - if (i in compass && LanguageVerbLikesAdverb(verb_word)) + if (i in Compass && LanguageVerbLikesAdverb(verb_word)) LanguageDirection (i.door_dir); ! the direction name as adverb else print (the) i; @@ -4261,7 +4279,7 @@ Constant SCORE__DIVISOR = 20; if (indef_mode==0 && domain==actors_location && scope_reason==PARSING_REASON && context~=CREATURE_TOKEN) - ScopeWithin(compass); + ScopeWithin(Compass); ! Look through the objects in the domain, avoiding "objectloop" in case ! movements occur, e.g. when trying each_turn. @@ -4789,7 +4807,6 @@ Constant MAX_DECIMAL_BASE 214748364; default: return GPR_FAIL; } if (digit >= base) return GPR_FAIL; - digit_count++; switch (base) { 16: if (digit_count > 2*WORDSIZE) return GPR_FAIL; 2: if (digit_count > 8*WORDSIZE) return GPR_FAIL; @@ -5145,7 +5162,7 @@ Object InformLibrary "(Inform Library)" } l = multiple_object-->k; PronounNotice(l); - print (name) l, (string) COLON__TX; + print (name) l, (string) COLON__TX, " "; if (inp1 == 0) { inp1 = l; switch (self.actor_act(actor, action, l, second)) { @@ -5315,13 +5332,17 @@ Object InformLibrary "(Inform Library)" if (lightflag == 0) location = thedark; if (j ~= 2) Banner(); -#ifndef NOINITIAL_LOOK; +#Ifndef NOINITIAL_LOOK; ; -#endif; +#Endif; before_first_turn = false; ]; [ GameEpilogue; + if (score ~= last_score) { + if (notify_mode == 1) NotifyTheScore(); + last_score = score; + } print "^^ "; #Ifdef TARGET_ZCODE; #IfV5; style bold; #Endif; ! V5 @@ -6287,46 +6308,36 @@ Object InformLibrary "(Inform Library)" ]; #Ifdef COLOUR; -[ SetColour f b window doclear i fwd bwd swin; - if (window) swin = 5-window; ! 4 for TextGrid, 3 for TextBuffer - - if (clr_on) { - fwd = MakeColourWord(f); - bwd = MakeColourWord(b); - for (i=0 : i<=10: i++) { - if (f == CLR_DEFAULT || b == CLR_DEFAULT) { ! remove style hints - glk_stylehint_clear(swin, i, 7); - glk_stylehint_clear(swin, i, 8); - } - else { - glk_stylehint_set(swin, i, 7, fwd); - glk_stylehint_set(swin, i, 8, bwd); - } - } - ! Now re-open the windows to apply the hints - if (gg_statuswin) glk_window_close(gg_statuswin, 0); - - if (doclear || ( window ~= 1 && (clr_fg ~= f || clr_bg ~= b) ) ) { - glk_window_close(gg_mainwin, 0); - gg_mainwin = glk_window_open(0, 0, 0, 3, GG_MAINWIN_ROCK); - if (gg_scriptstr ~= 0) - glk_window_set_echo_stream(gg_mainwin, gg_scriptstr); - } - - gg_statuswin = glk_window_open($12, gg_statuswin_cursize, - 4, GG_STATUSWIN_ROCK); - if (statuswin_current && gg_statuswin) - MoveCursor(); else MainWindow(); +[ SetColour f b window; + if (window == 0) { ! if setting both together, set reverse + clr_fgstatus = b; + clr_bgstatus = f; } - - if (window ~= 2) { + if (window == 1) { clr_fgstatus = f; clr_bgstatus = b; } - if (window ~= 1) { + if (window == 0 or 2) { clr_fg = f; clr_bg = b; } + if (clr_on) { + if (glk_gestalt(gestalt_GarglkText, 0)) { + if (f >= 0 && f < 10) { + f = GlulxColourValues-->f; + } + else { + f = -2; + } + if (b >= 0 && b < 10) { + b = GlulxColourValues-->b; + } + else { + b = -2; + } + garglk_set_zcolors(f, b); + } + } ]; #Endif; ! COLOUR #Endif; ! TARGET_ @@ -6429,7 +6440,7 @@ Object InformLibrary "(Inform Library)" #Endif; ! TARGET_ZCODE #Ifndef DrawStatusLine; -[ DrawStatusLine width posa posb; +[ DrawStatusLine width posa posb posc; #Ifdef TARGET_GLULX; ! If we have no status window, we must not try to redraw it. if (gg_statuswin == 0) @@ -6444,7 +6455,9 @@ Object InformLibrary "(Inform Library)" MoveCursor(1, 1); width = ScreenWidth(); - posa = width-26; posb = width-13; + posa = width-26; + posb = width-13; + posc = width-5; spaces width; MoveCursor(1, 2); @@ -6473,12 +6486,22 @@ Object InformLibrary "(Inform Library)" MoveCursor(1, posb); print (string) MOVES__TX, sline2; } - #Ifndef NO_SCORE; - if (width > 53 && width <= 66) { - MoveCursor(1, posb); - print sline1, "/", sline2; - } - #Endif; + if (width > 53 && width <= 66) { + MoveCursor(1, posb); + #Ifdef NO_SCORE; + print (string) MOVES__TX, sline2; + #Ifnot; + print sline1, "/", sline2; + #Endif; + } + if (width < 53) { + MoveCursor(1, posc); + #Ifdef NO_SCORE; + print (string) MOVES_S__TX, sline2; + #Ifnot; + print sline1, "/", sline2; + #Endif; + } } MainWindow(); ! set_window @@ -6629,10 +6652,8 @@ Object InformLibrary "(Inform Library)" gg_scriptstr = 0; gg_savestr = 0; gg_statuswin_cursize = 0; - #Ifdef DEBUG; gg_commandstr = 0; gg_command_reading = false; - #Endif; ! DEBUG ! Also tell the game to clear its object references. if (IdentifyGlkObject(0) == false) LibraryExtensions.RunWhile(ext_identifyglkobject, 0, 0); @@ -6641,12 +6662,10 @@ Object InformLibrary "(Inform Library)" switch (gg_arguments-->0) { GG_SAVESTR_ROCK: gg_savestr = id; GG_SCRIPTSTR_ROCK: gg_scriptstr = id; - #Ifdef DEBUG; GG_COMMANDWSTR_ROCK: gg_commandstr = id; gg_command_reading = false; GG_COMMANDRSTR_ROCK: gg_commandstr = id; gg_command_reading = true; - #Endif; ! DEBUG default: if (IdentifyGlkObject(1, 1, id, gg_arguments-->0) == false) LibraryExtensions.RunWhile(ext_identifyglkobject, false, 1, 1, id, gg_arguments-->0); } @@ -6910,7 +6929,7 @@ Array StorageForShortName -> WORDSIZE + SHORTNAMEBUF_LEN; PrintCapitalised(a, b, false, true, true); ]; -[ CapitRule str no_caps; +[ Cap str no_caps; if (no_caps) print (string) str; else PrintCapitalised(str,0,true); ]; @@ -6919,7 +6938,7 @@ Array StorageForShortName -> WORDSIZE + SHORTNAMEBUF_LEN; if (o provides articles) { artval=(o.&articles)-->(acode+short_name_case*LanguageCases); if (capitalise) - print (CapitRule) artval; + print (Cap) artval; else print (string) artval; if (pluralise) return; @@ -6969,7 +6988,7 @@ Array StorageForShortName -> WORDSIZE + SHORTNAMEBUF_LEN; } #Endif; ! TARGET_ - CapitRule (artform-->acode, ~~capitalise); ! print article + Cap (artform-->acode, ~~capitalise); ! print article if (pluralise) return; print (PSN__) o; ]; @@ -7244,6 +7263,8 @@ Object LibraryExtensions "(Library Extensions)" ext_printverb 0, ! [C2/R2] ext_timepasses 0, ! [C2/R1] ext_unknownverb 0, ! [C2/R2] + ext_aftersave 0, ! [C2/R2] + ext_afterrestore 0, ! [C2/R2] ! [C1] = Called in all cases ! [C2] = Called if EP is undefined, or returns false ! [C3] = called if EP is undefined, or returns -1