! ---------------------------------------------------------------------------- ! PARSERM: Core of parser. ! ! Supplied for use with Inform 6 Serial number 991113 ! Release 6/10 ! (c) Graham Nelson 1993, 1994, 1995, 1996, 1997, 1998, 1999 ! but freely usable (see manuals) ! ---------------------------------------------------------------------------- ! Inclusion of "linklpa" ! (which defines properties and attributes) ! Global variables, constants and arrays ! 1: outside of the parser ! 2: used within the parser ! Inclusion of natural language definition file ! (which creates a compass and direction-objects) ! Darkness and player objects ! Definition of grammar token numbering system used by Inform ! ! The InformParser object ! keyboard reading ! level 0: outer shell, conversation, errors ! 1: grammar lines ! 2: tokens ! 3: object lists ! 4: scope and ambiguity resolving ! 5: object comparisons ! 6: word comparisons ! 7: reading words and moving tables about ! pronoun management ! ! The InformLibrary object ! main game loop ! action processing ! end of turn sequence ! scope looping, before/after sequence, sending messages out ! timers, daemons, time of day, score notification ! light and darkness ! changing player personality ! tracing code (only present if DEBUG is set) ! ! Status line printing, menu display ! Printing object names with articles ! Miscellaneous utility routines ! Game banner, "version" verb, run-time errors ! ---------------------------------------------------------------------------- System_file; Constant NULL = $ffff; IFDEF MODULE_MODE; Constant DEBUG; Constant Grammar__Version 2; Include "linklpa"; ENDIF; ! ============================================================================ ! Global variables and their associated Constant and Array declarations ! ---------------------------------------------------------------------------- Global location = InformLibrary; ! Must be first global defined Global sline1; ! Must be second Global sline2; ! Must be third ! (for status line display) ! ------------------------------------------------------------------------------ ! Z-Machine and interpreter issues ! ------------------------------------------------------------------------------ Global top_object; ! Largest valid number of any tree object Global standard_interpreter; ! The version number of the Z-Machine ! Standard which the interpreter claims ! to support, in form (upper byte).(lower) Global undo_flag; ! Can the interpreter provide "undo"? Global just_undone; ! Can't have two successive UNDOs Global transcript_mode; ! true when game scripting is on IFDEF DEBUG; Global xcommsdir; ! true if command recording is on ENDIF; ! ------------------------------------------------------------------------------ ! Time and score ! (for linkage reasons, the task_* arrays are created not here but in verblib.h) ! ------------------------------------------------------------------------------ Global turns = 1; ! Number of turns of play so far Global the_time = NULL; ! Current time (in minutes since midnight) Global time_rate = 1; ! How often time is updated Global time_step; ! By how much #ifndef MAX_TIMERS; Constant MAX_TIMERS 32; ! Max number timers/daemons active at once #endif; Array the_timers --> MAX_TIMERS; Global active_timers; ! Number of timers/daemons actives Global score; ! The current score Global last_score; ! Score last turn (for testing for changes) Global notify_mode = true; ! Score notification Global places_score; ! Contribution to score made by visiting Global things_score; ! Contribution made by acquisition ! ------------------------------------------------------------------------------ ! The player ! ------------------------------------------------------------------------------ Global player; ! Which object the human is playing through Global deadflag; ! Normally 0, or false; 1 for dead; ! 2 for victorious, and higher numbers ! represent exotic forms of death ! ------------------------------------------------------------------------------ ! Light and room descriptions ! ------------------------------------------------------------------------------ Global lightflag = true; ! Is there currently light to see by? Global real_location; ! When in darkness, location = thedark ! and this holds the real location Global visibility_ceiling; ! Highest object in tree visible from ! the player's point of view (usually ! the room, sometimes darkness, sometimes ! a closed non-transparent container). Global lookmode = 1; ! 1=standard, 2=verbose, 3=brief room descs Global print_player_flag; ! If set, print something like "(as Fred)" ! in room descriptions, to reveal whom ! the human is playing through Global lastdesc; ! Value of location at time of most recent ! room description printed out ! ------------------------------------------------------------------------------ ! List writing (style bits are defined as Constants in "verblibm.h") ! ------------------------------------------------------------------------------ Global c_style; ! Current list-writer style Global lt_value; ! Common value of list_together Global listing_together; ! Object number of one member of a group ! being listed together Global listing_size; ! Size of such a group Global wlf_indent; ! Current level of indentation printed by ! WriteListFrom routine 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 ! ------------------------------------------------------------------------------ ! Menus and printing ! ------------------------------------------------------------------------------ Global pretty_flag = true; ! Use character graphics, or plain text? Global menu_nesting; ! Level of nesting (0 = root menu) Global menu_item; ! These are used in communicating Global item_width = 8; ! with the menu-creating routines Global item_name = "---"; Global lm_n; ! Parameters used by LibraryMessages Global lm_o; ! mechanism IFDEF DEBUG; Global debug_flag; ! Bitmap of flags for tracing actions, ! calls to object routines, etc. Global x_scope_count; ! Used in printing a list of everything ! in scope ENDIF; ! ------------------------------------------------------------------------------ ! Action processing ! ------------------------------------------------------------------------------ Global action; ! Action currently being asked to perform Global inp1; ! 0 (nothing), 1 (number) or first noun Global inp2; ! 0 (nothing), 1 (number) or second noun Global noun; ! First noun or numerical value Global second; ! Second noun or numerical value Global keep_silent; ! If true, attempt to perform the action ! silently (e.g. for implicit takes, ! implicit opening of unlocked doors) Global reason_code; ! Reason for calling a "life" rule ! (an action or fake such as ##Kiss) Global receive_action; ! Either ##PutOn or ##Insert, whichever ! is action being tried when an object's ! "before" rule is checking "Receive" ! ============================================================================== ! Parser variables: first, for communication to the parser ! ------------------------------------------------------------------------------ Global parser_trace = 0; ! Set this to 1 to make the parser trace ! tokens and lines Global parser_action; ! For the use of the parser when calling Global parser_one; ! user-supplied routines Global parser_two; ! Array inputobjs --> 16; ! For parser to write its results in Global parser_inflection; ! A property (usually "name") to find ! object names in ! ------------------------------------------------------------------------------ ! Parser output ! ------------------------------------------------------------------------------ Global actor; ! Person asked to do something Global actors_location; ! Like location, but for the actor Global meta; ! Verb is a meta-command (such as "save") Array multiple_object --> 64; ! List of multiple parameters Global multiflag; ! Multiple-object flag Global toomany_flag; ! Flag for "multiple match too large" ! (e.g. if "take all" took over 100 things) Global special_word; ! Dictionary address for "special" token Global special_number; ! Number typed for "special" token Global parsed_number; ! For user-supplied parsing routines Global consult_from; ! Word that a "consult" topic starts on Global consult_words; ! ...and number of words in topic ! ------------------------------------------------------------------------------ ! Implicit taking ! ------------------------------------------------------------------------------ Global notheld_mode; ! To do with implicit taking Global onotheld_mode; ! "old copy of notheld_mode", ditto Global not_holding; ! Object to be automatically taken as an ! implicit command Array kept_results --> 16; ! Delayed command (while the take happens) ! ------------------------------------------------------------------------------ ! Error numbers when parsing a grammar line ! ------------------------------------------------------------------------------ Global etype; ! Error number on current line Global best_etype; ! Preferred error number so far Global nextbest_etype; ! Preferred one, if ASKSCOPE_PE disallowed Constant STUCK_PE = 1; Constant UPTO_PE = 2; Constant NUMBER_PE = 3; Constant CANTSEE_PE = 4; Constant TOOLIT_PE = 5; Constant NOTHELD_PE = 6; Constant MULTI_PE = 7; Constant MMULTI_PE = 8; Constant VAGUE_PE = 9; Constant EXCEPT_PE = 10; Constant ANIMA_PE = 11; Constant VERB_PE = 12; Constant SCENERY_PE = 13; Constant ITGONE_PE = 14; Constant JUNKAFTER_PE = 15; Constant TOOFEW_PE = 16; Constant NOTHING_PE = 17; Constant ASKSCOPE_PE = 18; ! ------------------------------------------------------------------------------ ! Pattern-matching against a single grammar line ! ------------------------------------------------------------------------------ Array pattern --> 32; ! For the current pattern match Global pcount; ! and a marker within it Array pattern2 --> 32; ! And another, which stores the best match Global pcount2; ! so far Constant PATTERN_NULL = $ffff; ! Entry for a token producing no text Array line_ttype-->32; ! For storing an analysed grammar line Array line_tdata-->32; Array line_token-->32; Global parameters; ! Parameters (objects) entered so far Global nsns; ! Number of special_numbers entered so far Global special_number1; ! First number, if one was typed Global special_number2; ! Second number, if two were typed ! ------------------------------------------------------------------------------ ! Inferences and looking ahead ! ------------------------------------------------------------------------------ Global params_wanted; ! Number of parameters needed ! (which may change in parsing) Global inferfrom; ! The point from which the rest of the ! command must be inferred Global inferword; ! And the preposition inferred Global dont_infer; ! Another dull flag Global action_to_be; ! (If the current line were accepted.) Global action_reversed; ! (Parameters would be reversed in order.) Global advance_warning; ! What a later-named thing will be ! ------------------------------------------------------------------------------ ! At the level of individual tokens now ! ------------------------------------------------------------------------------ Global found_ttype; ! Used to break up tokens into type Global found_tdata; ! and data (by AnalyseToken) Global token_filter; ! For noun filtering by user routines Global length_of_noun; ! Set by NounDomain to no of words in noun Constant REPARSE_CODE = 10000; ! Signals "reparse the text" as a reply ! from NounDomain Global lookahead; ! The token after the one now being matched Global multi_mode; ! Multiple mode Global multi_wanted; ! Number of things needed in multitude Global multi_had; ! Number of things actually found Global multi_context; ! What token the multi-obj was accepted for Global indef_mode; ! "Indefinite" mode - ie, "take a brick" ! is in this mode Global indef_type; ! Bit-map holding types of specification Global indef_wanted; ! Number of items wanted (100 for all) Global indef_guess_p; ! Plural-guessing flag Global indef_owner; ! Object which must hold these items Global indef_cases; ! Possible gender and numbers of them Global indef_possambig; ! Has a possibly dangerous assumption ! been made about meaning of a descriptor? Global indef_nspec_at; ! Word at which a number like "two" was ! parsed (for backtracking) Global allow_plurals; ! Whether plurals presently allowed or not Global take_all_rule; ! Slightly different rules apply to ! "take all" than other uses of multiple ! objects, to make adjudication produce ! more pragmatically useful results ! (Not a flag: possible values 0, 1, 2) Global dict_flags_of_noun; ! Of the noun currently being parsed ! (a bitmap in #dict_par1 format) Global pronoun_word; ! Records which pronoun ("it", "them", ...) ! caused an error Global pronoun_obj; ! And what obj it was thought to refer to Global pronoun__word; ! Saved value Global pronoun__obj; ! Saved value ! ------------------------------------------------------------------------------ ! Searching through scope and parsing "scope=Routine" grammar tokens ! ------------------------------------------------------------------------------ Constant PARSING_REASON = 0; ! Possible reasons for searching scope Constant TALKING_REASON = 1; Constant EACH_TURN_REASON = 2; Constant REACT_BEFORE_REASON = 3; Constant REACT_AFTER_REASON = 4; Constant LOOPOVERSCOPE_REASON = 5; Constant TESTSCOPE_REASON = 6; Global scope_reason = PARSING_REASON; ! Current reason for searching scope Global scope_token; ! For "scope=Routine" grammar tokens Global scope_error; Global scope_stage; ! 1, 2 then 3 Global ats_flag = 0; ! For AddToScope routines Global ats_hls; ! Global placed_in_flag; ! To do with PlaceInScope ! ------------------------------------------------------------------------------ ! The match list of candidate objects for a given token ! ------------------------------------------------------------------------------ Constant MATCH_LIST_SIZE = 128; Array match_list --> 64; ! An array of matched objects so far Array match_classes --> 64; ! An array of equivalence classes for them Array match_scores --> 64; ! An array of match scores for them Global number_matched; ! How many items in it? (0 means none) Global number_of_classes; ! How many equivalence classes? Global match_length; ! How many words long are these matches? Global match_from; ! At what word of the input do they begin? Global bestguess_score; ! What did the best-guess object score? ! ------------------------------------------------------------------------------ ! Low level textual manipulation ! ------------------------------------------------------------------------------ Array buffer -> 121; ! Buffer for parsing main line of input Array parse -> 65; ! Parse table mirroring it Array buffer2 -> 121; ! Buffers for supplementary questions Array parse2 -> 65; ! Array buffer3 -> 121; ! Buffer retaining input for "again" Constant comma_word = 'comma,'; ! An "untypeable word" used to substitute ! for commas in parse buffers Global wn; ! Word number within "parse" (from 1) Global num_words; ! Number of words typed Global verb_word; ! Verb word (eg, take in "take all" or ! "dwarf, take all") - address in dict Global verb_wordnum; ! its number in typing order (eg, 1 or 3) 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 oops_from; ! The "first mistake" word number Global saved_oops; ! Used in working this out Array oops_workspace -> 64; ! Used temporarily by "oops" routine Global held_back_mode; ! Flag: is there some input from last time Global hb_wn; ! left over? (And a save value for wn.) ! (Used for full stops and "then".) ! ---------------------------------------------------------------------------- Array PowersOfTwo_TB ! Used in converting case numbers to --> $$100000000000 ! case bitmaps $$010000000000 $$001000000000 $$000100000000 $$000010000000 $$000001000000 $$000000100000 $$000000010000 $$000000001000 $$000000000100 $$000000000010 $$000000000001; ! ============================================================================ ! ============================================================================ ! Constants, and one variable, needed for the language definition file ! ---------------------------------------------------------------------------- Constant POSSESS_PK = $100; Constant DEFART_PK = $101; Constant INDEFART_PK = $102; Global short_name_case; ! ---------------------------------------------------------------------------- Include "language__"; ! The natural language definition, ! whose filename is taken from the ICL ! language_name variable ! ---------------------------------------------------------------------------- #ifndef LanguageCases; Constant LanguageCases = 1; #endif; ! ------------------------------------------------------------------------------ ! Pronouns support for the cruder (library 6/2 and earlier) version: ! only needed in English ! ------------------------------------------------------------------------------ #ifdef EnglishNaturalLanguage; Global itobj = NULL; ! The object which is currently "it" Global himobj = NULL; ! The object which is currently "him" Global herobj = NULL; ! The object which is currently "her" Global old_itobj = NULL; ! The object which is currently "it" Global old_himobj = NULL; ! The object which is currently "him" Global old_herobj = NULL; ! The object which is currently "her" #endif; ! ============================================================================ ! ============================================================================ ! "Darkness" is not really a place: but it has to be an object so that the ! location-name on the status line can be "Darkness". ! ---------------------------------------------------------------------------- Object thedark "(darkness object)" with initial 0, short_name DARKNESS__TX, description [; return L__M(##Miscellany, 17); ];