This repository has been archived by the owner on Jul 9, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
/
parser.h
7262 lines (6206 loc) · 248 KB
/
parser.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
! ==============================================================================
! PARSER: Front end to parser.
!
! Supplied for use with Inform 6 -- Release 6.12.2 -- Serial number 180520
!
! Copyright Graham Nelson 1993-2004 and David Griffith 2012-2018
!
! This code is licensed under either the traditional Inform license as
! described by the DM4 or the Artistic License version 2.0. See the
! file COPYING in the distribution archive or at
! https://github.com/DavidGriffith/inform6lib/
!
! In your game file, Include three library files in this order:
! Include "Parser";
! Include "VerbLib";
! Include "Grammar";
!
! ------------------------------------------------------------------------------
! 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;
#Ifndef LIBRARY_STAGE; ! This file is the first one to define LIBRARY_STAGE.
! "This file already included" <=> "LIBRARY_STAGE exists"
! ------------------------------------------------------------------------------
#Ifndef VN_1633;
Message fatalerror "*** Library 6.12.2 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;
Constant BEFORE_PARSER 10;
Constant AFTER_PARSER 20;
Constant AFTER_VERBLIB 30;
Constant AFTER_GRAMMAR 40;
Constant LIBRARY_STAGE = BEFORE_PARSER;
Default COMMENT_CHARACTER '*';
#Ifdef INFIX;
Default DEBUG 0;
#Endif; ! INFIX
#Ifndef WORDSIZE; ! compiling with Z-code only compiler
Default TARGET_ZCODE 0;
Constant WORDSIZE 2;
#Endif; ! WORDSIZE
#Ifdef TARGET_ZCODE; ! offsets into Z-machine header
Constant HDR_ZCODEVERSION $00; ! byte
Constant HDR_TERPFLAGS $01; ! byte
Constant HDR_GAMERELEASE $02; ! word
Constant HDR_HIGHMEMORY $04; ! word
Constant HDR_INITIALPC $06; ! word
Constant HDR_DICTIONARY $08; ! word
Constant HDR_OBJECTS $0A; ! word
Constant HDR_GLOBALS $0C; ! word
Constant HDR_STATICMEMORY $0E; ! word
Constant HDR_GAMEFLAGS $10; ! word
Constant HDR_GAMESERIAL $12; ! six ASCII characters
Constant HDR_ABBREVIATIONS $18; ! word
Constant HDR_FILELENGTH $1A; ! word
Constant HDR_CHECKSUM $1C; ! word
Constant HDR_TERPNUMBER $1E; ! byte
Constant HDR_TERPVERSION $1F; ! byte
Constant HDR_SCREENHLINES $20; ! byte
Constant HDR_SCREENWCHARS $21; ! byte
Constant HDR_SCREENWUNITS $22; ! word
Constant HDR_SCREENHUNITS $24; ! word
Constant HDR_FONTWUNITS $26; ! byte
Constant HDR_FONTHUNITS $27; ! byte
Constant HDR_ROUTINEOFFSET $28; ! word
Constant HDR_STRINGOFFSET $2A; ! word
Constant HDR_BGCOLOUR $2C; ! byte
Constant HDR_FGCOLOUR $2D; ! byte
Constant HDR_TERMCHARS $2E; ! word
Constant HDR_PIXELSTO3 $30; ! word
Constant HDR_TERPSTANDARD $32; ! two bytes
Constant HDR_ALPHABET $34; ! word
Constant HDR_EXTENSION $36; ! word
Constant HDR_UNUSED $38; ! two words
Constant HDR_INFORMVERSION $3C; ! four ASCII characters
#Ifnot; ! TARGET_GLULX ! offsets into Glulx header and start of ROM
Constant HDR_MAGICNUMBER $00; ! long word
Constant HDR_GLULXVERSION $04; ! long word
Constant HDR_RAMSTART $08; ! long word
Constant HDR_EXTSTART $0C; ! long word
Constant HDR_ENDMEM $10; ! long word
Constant HDR_STACKSIZE $14; ! long word
Constant HDR_STARTFUNC $18; ! long word
Constant HDR_DECODINGTBL $1C; ! long word
Constant HDR_CHECKSUM $20; ! long word
Constant ROM_INFO $24; ! four ASCII characters
Constant ROM_MEMORYLAYOUT $28; ! long word
Constant ROM_INFORMVERSION $2C; ! four ASCII characters
Constant ROM_COMPVERSION $30; ! four ASCII characters
Constant ROM_GAMERELEASE $34; ! short word
Constant ROM_GAMESERIAL $36; ! six ASCII characters
Include "infglk";
#Endif; ! TARGET_
Include "linklpa";
Fake_Action LetGo;
Fake_Action Receive;
Fake_Action ThrownAt;
Fake_Action Order;
Fake_Action TheSame;
Fake_Action PluralFound;
Fake_Action ListMiscellany;
Fake_Action Miscellany;
Fake_Action Prompt;
Fake_Action NotUnderstood;
Fake_Action Going;
#Ifdef NO_PLACES;
Fake_Action Places;
Fake_Action Objects;
#Endif; ! NO_PLACES
! ------------------------------------------------------------------------------
[ Main; InformLibrary.play(); ];
! ------------------------------------------------------------------------------
#Ifdef COLOR;
Constant COLOUR;
#Endif;
#Ifdef COLOUR;
Global clr_on = 1;
#Ifnot;
Global clr_on = 0;
#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
! ------------------------------------------------------------------------------
#Ifdef TARGET_ZCODE;
Global top_object; ! Largest valid number of any tree object
! ### these globals are not meaningful... well, maybe standard_interpreter,
! but I'll decide that later (AP).
Constant INDIV_PROP_START 64; ! Equivalent of a Glulx constant
#Endif; ! TARGET_ZCODE
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 TARGET_ZCODE;
Global xcommsdir; ! true if command recording is on
#Endif; ! TARGET_ZCODE
#Ifdef TARGET_GLULX;
Constant GG_MAINWIN_ROCK 201;
Constant GG_STATUSWIN_ROCK 202;
Constant GG_QUOTEWIN_ROCK 203;
Constant GG_SAVESTR_ROCK 301;
Constant GG_SCRIPTSTR_ROCK 302;
Constant GG_COMMANDWSTR_ROCK 303;
Constant GG_COMMANDRSTR_ROCK 304;
Constant GG_SCRIPTFREF_ROCK 401;
Array gg_event --> 4;
#Ifdef VN_1630;
Array gg_arguments buffer 28;
#Ifnot;
Array gg_arguments --> 8;
#Endif; ! VN_
Global gg_mainwin = 0;
Global gg_statuswin = 0;
Global gg_quotewin = 0;
Global gg_scriptfref = 0;
Global gg_scriptstr = 0;
Global gg_savestr = 0;
Global gg_commandstr = 0;
Global gg_command_reading = 0; ! true if gg_commandstr is being replayed
#Endif; ! TARGET_GLULX
Global gg_statuswin_cursize = 0;
Global gg_statuswin_size = 1;
! ------------------------------------------------------------------------------
! Time and score
! (for linkage reasons, the task_* arrays are created not here but in verblib.h)
! ------------------------------------------------------------------------------
#Ifndef sys_statusline_flag;
Global sys_statusline_flag = 0; ! non-zero if status line displays time
#Endif;
#Ifndef START_MOVE;
Constant START_MOVE 0; ! Traditionally 0 for Infocom, 1 for Inform
#Endif;
Global turns = START_MOVE; ! 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; ! MAX_TIMERS
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 prev_location; ! The previous value of 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 = 2; ! 1=brief, 2=verbose, 3=superbrief
! room descriptions
Global print_player_flag; ! If set, print something like "(as Fred)"
! in room descriptions, to reveal whom the
! player 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()
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
Global lm_s;
#Ifdef DEBUG;
Constant DEBUG_MESSAGES $0001;
Constant DEBUG_ACTIONS $0002;
Constant DEBUG_TIMERS $0004;
Constant DEBUG_CHANGES $0008;
Constant DEBUG_VERBOSE $0080;
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
#Endif; ! DEBUG ! in scope
! five for colour control
! see http://www.inform-fiction.org/patches/L61007.html
! To enable colour define a constant or Global: COLOR or COLOUR
!Global clr_on; ! has colour been enabled by the player?
#Ifdef COLOUR;
Global clr_fg = 1; ! foreground colour
Global clr_bg = 1; ! background colour
Global clr_fgstatus = 1; ! foreground colour of statusline
Global clr_bgstatus = 1; ! background colour of statusline
#Endif; ! COLOUR
Global statuswin_current; ! if writing to top window
Constant CLR_CURRENT 0;
Constant CLR_DEFAULT 1;
Constant CLR_BLACK 2;
Constant CLR_RED 3;
Constant CLR_GREEN 4;
Constant CLR_YELLOW 5;
Constant CLR_BLUE 6;
Constant CLR_MAGENTA 7;
Constant CLR_CYAN 8;
Constant CLR_WHITE 9;
Constant CLR_PURPLE 7;
Constant CLR_AZURE 8;
Constant WIN_ALL 0;
Constant WIN_STATUS 1;
Constant WIN_MAIN 2;
! ------------------------------------------------------------------------------
! 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"
Global no_implicit_actions; ! Don't implicitly do things.
! ==============================================================================
! 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
Global parser_inflection_func; ! Programmer sets this to true when
! parser_infection is a function
! ------------------------------------------------------------------------------
! 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")
#Ifdef INFIX;
Global infix_verb; ! Verb is an Infix command
#Endif;
Array multiple_object --> 64; ! List of multiple parameters
Global multiflag; ! Multiple-object flag passed to actions
! Also used to prevent misleading MULTI_PE
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
Global asking_player; ! True during disambiguation question
! ------------------------------------------------------------------------------
! 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 no_infer_message = false; ! Use in ChooseObjects to suppress
! an inference message.
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
#Ifdef TARGET_ZCODE;
Constant REPARSE_CODE = 10000; ! Signals "reparse the text" as a reply
! from NounDomain
#Ifnot; ! TARGET_GLULX
Constant REPARSE_CODE = $40000000; ! The parser rather gunkily adds addresses
! to REPARSE_CODE for some purposes and
! expects the result to be greater than
! REPARSE_CODE (signed comparison).
! So Glulx Inform is limited to a single
! gigabyte of storage, for the moment.
#Endif; ! TARGET_
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)
Constant DICT_VERB $01;
Constant DICT_META $02;
Constant DICT_PLUR $04;
Constant DICT_PREP $08;
Constant DICT_X654 $70;
Constant DICT_NOUN $80;
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 = 64;
Array match_list --> MATCH_LIST_SIZE; ! An array of matched objects so far
Array match_classes --> MATCH_LIST_SIZE; ! An array of equivalence classes for them
Array match_scores --> MATCH_LIST_SIZE; ! 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 saved_ml;
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
! ------------------------------------------------------------------------------
#Ifdef TARGET_ZCODE;
! 'buffer' holds the input line as typed by the player
!
! buffer->0 INPUT_BUFFER_LEN - WORDSIZE
! buffer->1 Number of characters input by player
! buffer->2 ... buffer->121 The actual characters
! buffer->122 Spare byte to allow for 'terp bugs
!
! 'parse' holds the result of parsing that line into dictionary words
!
! parse->0 MAX_BUFFER_WORDS
! parse->1 Number of words input by player
!
! parse-->1 Dictionary addr of first input word
! parse->4 Number of characters in the word
! parse->5 Start position in 'buffer' of the word
!
! parse-->3 parse->8,9 Same data for second input word
! ...
! parse-->29 parse->60,61 Same data for MAX_BUFFER_WORDS input word
! parse->62,63,64 Spare bytes (not sure why)
Constant INPUT_BUFFER_LEN = WORDSIZE + 120; ! 120 is limit on input chars
Constant MAX_BUFFER_WORDS = 15; ! Limit on input words
Array buffer -> INPUT_BUFFER_LEN + 1; ! For main line of input
Array buffer2 -> INPUT_BUFFER_LEN + 1; ! For supplementary questions
Array buffer3 -> INPUT_BUFFER_LEN + 1; ! Retaining input for "AGAIN"
#Ifdef VN_1630;
Array parse buffer (MAX_BUFFER_WORDS * 4) + 3; ! Parsed data from 'buffer'
Array parse2 buffer (MAX_BUFFER_WORDS * 4) + 3; ! Parsed data from 'buffer2'
#Ifnot;
Array parse -> 2 + (MAX_BUFFER_WORDS * 4) + 3;
Array parse2 -> 2 + (MAX_BUFFER_WORDS * 4) + 3;
#Endif; ! VN_
#Ifnot; ! TARGET_GLULX
! 'buffer' holds the input line as typed by the player
!
! buffer-->0 Number of characters input by player
! buffer->4 ... buffer->259 The actual characters
!
! 'parse' holds the result of parsing that line into dictionary words
!
! parse-->0 Number of words input by player
!
! parse-->1 Dictionary addr of first input word
! parse-->2 Number of characters in the word
! parse-->3 Start position in 'buffer' of the word
!
! parse-->4,5,6 Same data for second input word
! ...
! parse-->58,59,60 Same data for MAX_BUFFER_WORDS input word
Constant INPUT_BUFFER_LEN = WORDSIZE + 256; ! 256 is limit on input chars
Constant MAX_BUFFER_WORDS = 20; ! Limit on input words
#Ifdef VN_1630;
Array buffer buffer (INPUT_BUFFER_LEN-WORDSIZE); ! For main line of input
Array buffer2 buffer (INPUT_BUFFER_LEN-WORDSIZE); ! For supplementary questions
Array buffer3 buffer (INPUT_BUFFER_LEN-WORDSIZE); ! Retaining input for "AGAIN"
#Ifnot;
Array buffer -> INPUT_BUFFER_LEN;
Array buffer2 -> INPUT_BUFFER_LEN;
Array buffer3 -> INPUT_BUFFER_LEN;
#Endif; ! VN_
Array parse --> 1 + (MAX_BUFFER_WORDS * 3); ! Parsed data from 'buffer'
Array parse2 --> 1 + (MAX_BUFFER_WORDS * 3); ! Parsed data from 'buffer2'
#Endif; ! TARGET_
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 num_desc; ! Number of descriptors 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
Constant OOPS_WORKSPACE_LEN 64; ! Used temporarily by "oops" routine
Array oops_workspace -> OOPS_WORKSPACE_LEN;
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".)
Global caps_mode; ! Keep track of (The) with 'proper' caps
Global print_anything_result; ! Return value from a PrintAny() routine
Global initial_lookmode; ! Default, or set in Initialise()
Global before_first_turn; ! True until after initial LOOK
! ----------------------------------------------------------------------------
Array PowersOfTwo_TB ! Used in converting case numbers to case
--> $$100000000000 ! 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;
Global dict_start;
Global dict_entry_size;
Global dict_end;
! ----------------------------------------------------------------------------
Include "language__"; ! The natural language definition, whose filename is taken from
! the ICL language_name variable
! ----------------------------------------------------------------------------
#Ifndef LanguageCases;
Constant LanguageCases = 1;
#Endif; ! LanguageCases
! ------------------------------------------------------------------------------
! 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; ! EnglishNaturalLanguage
! ============================================================================
! For present and past tenses
! ----------------------------------------------------------------------------
Constant PRESENT_TENSE 0;
Constant PAST_TENSE 1;
! ============================================================================
! For InformLibrary.actor_act() to control what happens when it aborts.
! ----------------------------------------------------------------------------
Constant ACTOR_ACT_OK 0;
Constant ACTOR_ACT_ABORT_NOTUNDERSTOOD 1;
Constant ACTOR_ACT_ABORT_ORDER 2;
! ============================================================================
! "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); ];
! 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,
description [; return L__M(##Miscellany, 19); ],
before NULL,
after NULL,
life NULL,
each_turn NULL,
time_out NULL,
describe NULL,
article "the",
add_to_scope 0,
capacity 100,
parse_name 0,
orders 0,
number 0,
narrative_voice 2,
narrative_tense PRESENT_TENSE,
nameless true,
posture 0,
before_implicit [;Take: return 2;],
has concealed animate proper transparent;
SelfClass selfobj "(self object)";
! ============================================================================
! The definition of the token-numbering system used by Inform.
! ----------------------------------------------------------------------------
Constant ILLEGAL_TT = 0; ! Types of grammar token: illegal
Constant ELEMENTARY_TT = 1; ! (one of those below)
Constant PREPOSITION_TT = 2; ! e.g. 'into'
Constant ROUTINE_FILTER_TT = 3; ! e.g. noun=CagedCreature
Constant ATTR_FILTER_TT = 4; ! e.g. edible
Constant SCOPE_TT = 5; ! e.g. scope=Spells
Constant GPR_TT = 6; ! a general parsing routine
Constant NOUN_TOKEN = 0; ! The elementary grammar tokens, and
Constant HELD_TOKEN = 1; ! the numbers compiled by Inform to
Constant MULTI_TOKEN = 2; ! encode them
Constant MULTIHELD_TOKEN = 3;
Constant MULTIEXCEPT_TOKEN = 4;
Constant MULTIINSIDE_TOKEN = 5;
Constant CREATURE_TOKEN = 6;
Constant SPECIAL_TOKEN = 7;
Constant NUMBER_TOKEN = 8;
Constant TOPIC_TOKEN = 9;
Constant GPR_FAIL = -1; ! Return values from General Parsing
Constant GPR_PREPOSITION = 0; ! Routines
Constant GPR_NUMBER = 1;
Constant GPR_MULTIPLE = 2;
Constant GPR_REPARSE = REPARSE_CODE;
Constant GPR_NOUN = $ff00;
Constant GPR_HELD = $ff01;
Constant GPR_MULTI = $ff02;
Constant GPR_MULTIHELD = $ff03;
Constant GPR_MULTIEXCEPT = $ff04;
Constant GPR_MULTIINSIDE = $ff05;
Constant GPR_CREATURE = $ff06;
Constant ENDIT_TOKEN = 15; ! Value used to mean "end of grammar line"
#Iftrue (Grammar__Version == 1);
[ AnalyseToken token m;
found_tdata = token;
if (token < 0) { found_ttype = ILLEGAL_TT; return; }
if (token <= 8) { found_ttype = ELEMENTARY_TT; return; }
if (token < 15) { found_ttype = ILLEGAL_TT; return; }
if (token == 15) { found_ttype = ELEMENTARY_TT; return; }
if (token < 48) { found_ttype = ROUTINE_FILTER_TT;
found_tdata = token - 16;
return;
}
if (token < 80) { found_ttype = GPR_TT;
found_tdata = #preactions_table-->(token-48);
return;
}
if (token < 128) { found_ttype = SCOPE_TT;
found_tdata = #preactions_table-->(token-80);
return;
}
if (token < 180) { found_ttype = ATTR_FILTER_TT;
found_tdata = token - 128;
return;
}
found_ttype = PREPOSITION_TT;
m = #adjectives_table;
for (::) {
if (token == m-->1) { found_tdata = m-->0; return; }
m = m+4;
}
m = #adjectives_table; RunTimeError(1);
found_tdata = m;
];
[ UnpackGrammarLine line_address i m;
for (i=0 : i<32 : i++) {
line_token-->i = ENDIT_TOKEN;
line_ttype-->i = ELEMENTARY_TT;
line_tdata-->i = ENDIT_TOKEN;
}
for (i=0 : i<=5 : i++) {
line_token-->i = line_address->(i+1);
AnalyseToken(line_token-->i);
if ((found_ttype == ELEMENTARY_TT) && (found_tdata == NOUN_TOKEN)
&& (m == line_address->0)) {
line_token-->i = ENDIT_TOKEN;
break;
}
line_ttype-->i = found_ttype;
line_tdata-->i = found_tdata;
if (found_ttype ~= PREPOSITION_TT) m++;
}
action_to_be = line_address->7;
action_reversed = false;
params_wanted = line_address->0;
return line_address + 8;
];
#Ifnot; ! Grammar__Version == 2
[ AnalyseToken token;
if (token == ENDIT_TOKEN) {
found_ttype = ELEMENTARY_TT;
found_tdata = ENDIT_TOKEN;
return;
}
found_ttype = (token->0) & $$1111;
found_tdata = (token+1)-->0;
];
#Ifdef TARGET_ZCODE;
[ UnpackGrammarLine line_address i;
for (i=0 : i<32 : i++) {
line_token-->i = ENDIT_TOKEN;
line_ttype-->i = ELEMENTARY_TT;
line_tdata-->i = ENDIT_TOKEN;
}
action_to_be = 256*(line_address->0) + line_address->1;
action_reversed = ((action_to_be & $400) ~= 0);
action_to_be = action_to_be & $3ff;
line_address--;
params_wanted = 0;
for (i=0 : : i++) {
line_address = line_address + 3;
if (line_address->0 == ENDIT_TOKEN) break;
line_token-->i = line_address;
AnalyseToken(line_address);
if (found_ttype ~= PREPOSITION_TT) params_wanted++;
line_ttype-->i = found_ttype;
line_tdata-->i = found_tdata;
}
return line_address + 1;
];
#Ifnot; ! TARGET_GLULX
[ UnpackGrammarLine line_address i;
for (i=0 : i<32 : i++) {
line_token-->i = ENDIT_TOKEN;
line_ttype-->i = ELEMENTARY_TT;
line_tdata-->i = ENDIT_TOKEN;
}
@aloads line_address 0 action_to_be;
action_reversed = (((line_address->2) & 1) ~= 0);
line_address = line_address - 2;
params_wanted = 0;
for (i=0 : : i++) {
line_address = line_address + 5;
if (line_address->0 == ENDIT_TOKEN) break;
line_token-->i = line_address;
AnalyseToken(line_address);
if (found_ttype ~= PREPOSITION_TT) params_wanted++;
line_ttype-->i = found_ttype;
line_tdata-->i = found_tdata;
}
return line_address + 1;
];
#Endif; ! TARGET_
#Endif; ! Grammar__Version
! To protect against a bug in early versions of the "Zip" interpreter:
! Of course, in Glulx, this routine actually performs work.
#Ifdef TARGET_ZCODE;
[ Tokenise__ b p; b->(2 + b->1) = 0; @tokenise b p; ];
#Ifnot; ! TARGET_GLULX
Array gg_tokenbuf -> DICT_WORD_SIZE;
[ GGWordCompare str1 str2 ix jx;
for (ix=0 : ix<DICT_WORD_SIZE : ix++) {
jx = (str1->ix) - (str2->ix);
if (jx ~= 0) return jx;