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
|
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
/*
* Defines TADS vocabulary (player command parser) functionality
*/
#ifndef GLK_TADS_TADS2_VOCABULARY
#define GLK_TADS_TADS2_VOCABULARY
#include "common/util.h"
#include "glk/tads/tads2/lib.h"
#include "glk/tads/tads2/object.h"
#include "glk/tads/tads2/property.h"
#include "glk/tads/tads2/run.h"
namespace Glk {
namespace TADS {
namespace TADS2 {
/*
* Cover macro for parser errors. Any parser error should be covered
* with this macro for documentation and search purposes. (The macro
* doesn't do anything - this is just something to search for when we're
* trying to enumerate parser error codes.)
*/
#define VOCERR(errcode) errcode
/* maximum number of objects matching an ambiguous word */
#define VOCMAXAMBIG 200
/* size of input buffer */
#define VOCBUFSIZ 128
/*
* Vocabulary relation structure - this structure relates a vocabulary
* word to an object and part of speech. A list of these structures is
* attached to each vocabulary word structure to provide the word's
* meanings.
*/
struct vocwdef {
uint vocwnxt; /* index of next vocwdef attached to the same word */
objnum vocwobj; /* object associated with the word */
uchar vocwtyp; /* property associated with the word (part of speech) */
uchar vocwflg; /* flags for the word */
#define VOCFCLASS 1 /* word is for a class object */
#define VOCFINH 2 /* word is inherited from a superclass */
#define VOCFNEW 4 /* word was added at run-time */
#define VOCFDEL 8 /* word has been deleted */
};
/* vocabulary word structure */
struct vocdef {
vocdef *vocnxt; /* next word at same hash value */
uchar voclen; /* length of the word */
uchar vocln2; /* length of second word (0 if no second word) */
uint vocwlst; /* head of list of vocwdef's attached to the word */
uchar voctxt[1]; /* text of the word */
};
/* vocabulary inheritance cell */
struct vocidef {
uchar vocinsc; /* # of superclasses (gives size of record) */
union {
struct {
uchar vociusflg; /* flags for entry */
#define VOCIFCLASS 1 /* entry refers to a class object (loc records only) */
#define VOCIFVOC 2 /* entry has vocabulary words defined */
#define VOCIFXLAT 4 /* superclasses must be translated from portable fmt */
#define VOCIFLOCNIL 8 /* location is explicitly set to nil */
#define VOCIFNEW 16 /* object was allocated at run-time with "new" */
objnum vociusloc; /* location of the object */
objnum vociusilc; /* inherited location */
objnum vociussc[1]; /* array of superclasses */
} vocius;
vocidef *vociunxt;
} vociu;
#define vociflg vociu.vocius.vociusflg
#define vociloc vociu.vocius.vociusloc
#define vociilc vociu.vocius.vociusilc
#define vocisc vociu.vocius.vociussc
#define vocinxt vociu.vociunxt
};
/* size of a page in a vocabulary pool */
#define VOCPGSIZ 8192
/* number of bytes in an inheritance cell page */
#define VOCISIZ 8192
/* maximum number of inheritance pages */
#define VOCIPGMAX 32
/* maximum number of inheritance pages (256 objects per page) */
#define VOCINHMAX 128
/* size of vocabulary hash table */
#define VOCHASHSIZ 256
/* size of a template structure */
#define VOCTPLSIZ 10
/* new-style template structure */
#define VOCTPL2SIZ 16
/*
* vocwdef's are fixed in size. They're allocated in a set of arrays
* (the voccxwp member of the voc context has the list of arrays). Each
* array is of a fixed number of vocwdef entries; a maximum number of
* vocwdef arrays is possible.
*/
#define VOCWPGSIZ 2000 /* number of vocwdef's per array */
#define VOCWPGMAX 16 /* maximum number of vocwdef arrays */
/*
* To find a vocwdef entry given its index, divide the index by the
* number of entries per array to find the array number, and use the
* remainder to find the index within that array.
*/
/*#define VOCW_IN_CACHE*/
#ifdef VOCW_IN_CACHE
vocwdef *vocwget(struct voccxdef *ctx, uint idx);
#else
#define vocwget(ctx, idx) \
((idx) == VOCCXW_NONE ? (vocwdef *)0 : \
((ctx)->voccxwp[(idx)/VOCWPGSIZ] + ((idx) % VOCWPGSIZ)))
#endif
/*
* Special values for vocdtim - these values indicate that the daemon
* does not have a normal turn-based expiration time.
*/
#define VOCDTIM_EACH_TURN 0xffff /* the daemon fires every turn */
/* daemon/fuse/alarm slot */
struct vocddef {
objnum vocdfn; /* object number of function to be invoked */
runsdef vocdarg; /* argument for daemon/fuse function */
prpnum vocdprp; /* property number (used only for alarms) */
uint vocdtim; /* time for fuses/alarms (0xffff -> each-turn alarm) */
};
/* vocabulary object list entry */
struct vocoldef {
objnum vocolobj; /* object matching the word */
const char *vocolfst; /* first word in cmd[] that identified object */
const char *vocollst; /* last word in cmd[] that identified object */
char *vocolhlst; /* hypothetical last word, if we trimmed a prep */
int vocolflg; /* special flags (ALL, etc) */
};
/* vocabulary context */
struct voccxdef {
errcxdef *voccxerr; /* error handling context */
tiocxdef *voccxtio; /* text i/o context */
runcxdef *voccxrun; /* execution context */
mcmcxdef *voccxmem; /* memory manager context */
objucxdef *voccxundo; /* undo context */
uchar *voccxpool; /* next free byte in vocdef pool */
vocdef *voccxfre; /* head of vocdef free list */
char *voccxcpp; /* pointer to compound word area */
int voccxcpl; /* length of compound word area */
char *voccxspp; /* pointer to special word area */
int voccxspl; /* length of special word area */
uint voccxrem; /* number of bytes remaining in vocdef pool */
vocidef **voccxinh[VOCINHMAX]; /* vocidef page table: 256 per page */
uchar *voccxip[VOCIPGMAX]; /* inheritance cell pool */
vocidef *voccxifr; /* head of inheritance cell free list */
uint voccxiplst; /* last inheritance cell page allocated */
uint voccxilst; /* next unused byte in last inheritance page */
int voccxredo; /* flag: redo command in buffer */
/*
* redo buffer - if voccxredo is set, and this buffer is not empty,
* we'll redo the command in this buffer rather than the one in our
* internal stack buffer
*/
char voccxredobuf[VOCBUFSIZ];
/*
* "again" buffer - when we save the last command for repeating via
* the "again" command, we'll save the direct and indirect object
* words here, so that they can be recovered if "again" is used
*/
char voccxagainbuf[VOCBUFSIZ];
vocdef *voccxhsh[VOCHASHSIZ]; /* hash table */
#ifdef VOCW_IN_CACHE
mcmon voccxwp[VOCWPGMAX]; /* list of pages of vocab records */
mcmon voccxwplck; /* locked page of vocab records */
vocwdef *voccxwpgptr; /* pointer to currently locked page */
#else
vocwdef *voccxwp[VOCWPGMAX]; /* vocabulary word pool */
#endif
uint voccxwalocnt; /* number of vocwdef's used so far */
uint voccxwfre; /* index of first vocwdef in free list */
#define VOCCXW_NONE ((uint)(-1)) /* index value indicating end of list */
vocddef *voccxdmn; /* array of daemon slots */
uint voccxdmc; /* number of slots in daemon array */
vocddef *voccxfus; /* array of fuse slots */
uint voccxfuc; /* number of slots in fuse array */
vocddef *voccxalm; /* array of alarm slots */
uint voccxalc; /* number of slots in alarm array */
char voccxtim[26]; /* game's timestamp (asctime value) */
objnum voccxvtk; /* object number of "take" deepverb */
objnum voccxme; /* object number of "Me" actor */
objnum voccxme_init; /* initial setting of "Me" */
objnum voccxstr; /* object number of "strObj" */
objnum voccxnum; /* object number of "numObj" */
objnum voccxit; /* last "it" value */
objnum voccxhim; /* last "him" value */
objnum voccxher; /* last "her" value */
objnum voccxthc; /* count of items in "them" list */
objnum voccxthm[VOCMAXAMBIG]; /* list of items in "them" */
objnum voccxprd; /* "pardon" function object number */
objnum voccxpre; /* "preparse" function object number */
objnum voccxppc; /* "preparseCmd" function object number */
objnum voccxpre2; /* "preparseExt" function object number */
objnum voccxvag; /* "again" verb object */
objnum voccxini; /* "init" function */
objnum voccxper; /* "parseError" function object number */
objnum voccxprom; /* "cmdPrompt" function object number */
objnum voccxpostprom; /* "cmdPostPrompt" function object number */
objnum voccxpdis; /* parseDisambig function */
objnum voccxper2; /* parseError2 function */
objnum voccxperp; /* parseErrorParam function */
objnum voccxpdef; /* parseDefault function */
objnum voccxpdef2; /* parseDefaultExt function */
objnum voccxpask; /* parseAskobj function */
objnum voccxpask2; /* parseAskobjActor function */
objnum voccxpask3; /* parseAskobjIndirect function */
objnum voccxinitrestore; /* "initRestore" function object number */
objnum voccxpuv; /* parseUnknownVerb function object number */
objnum voccxpnp; /* parseNounPhrase function object number */
objnum voccxpostact; /* postAction function object number */
objnum voccxprecmd; /* preCommand function object number */
objnum voccxendcmd; /* endCommand function object number */
/* current command word list values */
vocoldef *voccxdobj; /* current direct object word list */
vocoldef *voccxiobj; /* current indirect object word list */
/* current command objects */
objnum voccxactor; /* current actor */
objnum voccxverb; /* current command deepverb */
objnum voccxprep; /* current command preposition */
/* previous command values - used by "again" */
objnum voccxlsa; /* previous actor */
objnum voccxlsv; /* previous verb */
vocoldef voccxlsd; /* previous direct object */
vocoldef voccxlsi; /* previous indirect object */
objnum voccxlsp; /* preposition */
int voccxlssty; /* style (new/old) of last template */
uchar voccxlst[VOCTPL2SIZ]; /* template */
objnum voccxpreinit; /* preinit function */
/* special flags */
uchar voccxflg;
#define VOCCXFCLEAR 1 /* ignore remainder of command line (restore) */
#define VOCCXFVWARN 2 /* generate redundant verb warnings */
#define VOCCXFDBG 4 /* debug mode: show parsing information */
#define VOCCXAGAINDEL 8 /* "again" lost due to object deletion */
/* number of remaining unresolved unknown words in the command */
int voccxunknown;
/* total number of unresolved words in the last command */
int voccxlastunk;
/* parser stack area */
uchar *voc_stk_ptr;
uchar *voc_stk_cur;
uchar *voc_stk_end;
};
/* allocate and push a list, returning a pointer to the list's memory */
uchar *voc_push_list_siz(voccxdef *ctx, uint lstsiz);
/* push a list of objects from a vocoldef array */
void voc_push_vocoldef_list(voccxdef *ctx, vocoldef *objlist, int cnt);
/* push a list of objects from an objnum array */
void voc_push_objlist(voccxdef *ctx, objnum objlist[], int cnt);
/* change the player character ("Me") object */
void voc_set_me(voccxdef *ctx, objnum new_me);
/* add a vocabulary word */
void vocadd(voccxdef *ctx, prpnum p, objnum objn,
int classflag, char *wrdval);
/* internal addword - must already be split into two words and lengths */
void vocadd2(voccxdef *ctx, prpnum p, objnum objn, int classflg,
uchar *wrd1, int len1, uchar *wrd2, int len2);
/* delete vocabulary for a given object */
void vocdel(voccxdef *ctx, objnum objn);
/* lower-level vocabulary deletion routine */
void vocdel1(voccxdef *ctx, objnum objn, char *wrd, prpnum prp,
int really_delete, int revert, int keep_undo);
/* delete all inherited vocabulary */
void vocdelinh(voccxdef *ctx);
/* allocate space for an inheritance record if needed */
void vocialo(voccxdef *ctx, objnum obj);
/* add an inheritance/location record */
void vociadd(voccxdef *ctx, objnum obj, objnum loc,
int numsc, objnum *sc, int flags);
/* delete inheritance records for an object */
void vocidel(voccxdef *ctx, objnum chi);
/* renumber an object's inheritance records - used for 'modify' */
void vociren(voccxdef *ctx, objnum oldnum, objnum newnum);
/* caller-provided context structure for vocffw/vocfnw searches */
struct vocseadef {
vocdef *v;
vocwdef *vw;
const uchar *wrd1;
int len1;
const uchar *wrd2;
int len2;
};
/* find first word matching a given word */
vocwdef *vocffw(voccxdef *ctx, const char *wrd, int len, const char *wrd2, int len2,
int p, vocseadef *search_ctx);
/* find next word */
vocwdef *vocfnw(voccxdef *voccx, vocseadef *search_ctx);
/* read a line of input text */
int vocread(voccxdef *ctx, objnum actor, objnum verb,
char *buf, int bufl, int type);
#define VOCREAD_OK 0
#define VOCREAD_REDO 1
/* compute size of a vocoldef list */
int voclistlen(vocoldef *lst);
/* tokenize an input buffer */
int voctok(voccxdef *ctx, char *cmd, char *outbuf,
char **wrd, int lower, int cvt_ones, int show_errors);
/* get types for a word list */
int vocgtyp(voccxdef *ctx, char **cmd, int *types, char *orgbuf);
/* execute a player command */
int voccmd(voccxdef *ctx, char *cmd, uint cmdlen);
/* disambiguator */
int vocdisambig(voccxdef *ctx, vocoldef *outlist, vocoldef *inlist,
prpnum defprop, prpnum accprop, prpnum verprop,
char *cmd[], objnum otherobj, objnum cmdActor,
objnum cmdVerb, objnum cmdPrep, char *cmdbuf,
int silent);
/* display a multiple-object prefix */
void voc_multi_prefix(voccxdef *ctx, objnum objn,
int show_prefix, int multi_flags,
int cur_index, int count);
/* low-level executor */
int execmd(voccxdef *ctx, objnum actor, objnum prep,
char *vverb, char *vprep, vocoldef *dolist, vocoldef *iolist,
char **cmd, int *typelist,
char *cmdbuf, int wrdcnt, uchar **preparse_list, int *next_start);
/* recursive command execution */
int execmd_recurs(voccxdef *ctx, objnum actor, objnum verb,
objnum dobj, objnum prep, objnum iobj,
int validate_dobj, int validate_iobj);
/* try running preparseCmd user function */
int try_preparse_cmd(voccxdef *ctx, char **cmd, int wrdcnt,
uchar **preparse_list);
/*
* Handle an unknown verb or sentence structure. We'll call this when
* we encounter a sentence where we don't know the verb word, or we
* don't know the combination of verb and verb preposition, or we don't
* recognize the sentence structure (for example, an indirect object is
* present, but we don't have a template defined using an indirect
* object for the verb).
*
* 'wrdcnt' is the number of words in the cmd[] array. If wrdcnt is
* zero, we'll automatically count the array entries, with the end of
* the array indicated by a null pointer entry.
*
* If do_fuses is true, we'll execute the fuses and daemons if the
* function exists and doesn't throw an ABORT error, or any other
* run-time error other than EXIT.
*
* This function calls the game-defined function parseUnknownVerb, if it
* exists. If the function doesn't exist, we'll simply display the
* given error message, using the normal parseError mechanism. The
* function should use "abort" or "exit" if it wants to cancel further
* processing of the command.
*
* We'll return true if the function exists and executes successfully,
* in which case normal processing should continue with any remaining
* command on the command line. We'll return false if the function
* doesn't exist or throws an error other than EXIT, in which case the
* remainder of the command should be aborted.
*/
int try_unknown_verb(voccxdef *ctx, objnum actor,
char **cmd, int *typelist, int wrdcnt, int *next_start,
int do_fuses, int err, const char *msg, ...);
/* find a template */
int voctplfnd(voccxdef *ctx, objnum verb_in, objnum prep,
uchar *tplout, int *newstyle);
/* build a printable name for an object from the words in a command list */
void voc_make_obj_name(voccxdef *ctx, char *namebuf, char *cmd[],
int firstwrd, int lastwrd);
void voc_make_obj_name_from_list(voccxdef *ctx, char *namebuf,
char *cmd[], const char *firstwrd, const char *lastwrd);
/*
* check noun - determines whether the next set of words is a valid noun
* phrase. No complaint is issued if not; this check is generally made
* to figure out what type of sentence we're dealing with. This is
* simple; we just call vocgobj() with the complaint flag turned off.
*/
/* int vocchknoun(voccxdef *ctx, char **cmd, int *typelist, int cur,
int *next, vocoldef *nounlist, int chkact); */
#define vocchknoun(ctx, cmd, typelist, cur, next, nounlist, chkact) \
vocgobj(ctx, cmd, typelist, cur, next, FALSE, nounlist, TRUE, chkact, 0)
#define vocchknoun2(ctx, cmd, typlst, cur, next, nounlist, chkact, nomatch) \
vocgobj(ctx, cmd, typlst, cur, next, FALSE, nounlist, TRUE, chkact, nomatch)
/*
* get noun - reads an object list. We simply call vocgobj() with the
* complaint and multiple-noun flags turned on.
*/
/* int vocgetnoun(voccxdef *ctx, char **cmd, int *typelist, int cur,
int *next, vocoldef *nounlist); */
#define vocgetnoun(ctx, cmd, typelist, cur, next, nounlist) \
vocgobj(ctx, cmd, typelist, cur, next, TRUE, nounlist, TRUE, FALSE, 0)
/* get object */
int vocgobj(voccxdef *ctx, char **cmd, int *typelist, int cur,
int *next, int complain, vocoldef *nounlist,
int multi, int chkact, int *nomatch);
/* tokenize a string - TADS program code interface */
void voc_parse_tok(voccxdef *ctx);
/* get token types - TADS program code interface */
void voc_parse_types(voccxdef *ctx);
/* get objects matching all of the given words - TADS program code interface */
void voc_parse_dict_lookup(voccxdef *ctx);
/* parse a noun list - TADS program code interface */
void voc_parse_np(voccxdef *ctx);
/* disambiguate a noun list - TADS program code interface */
void voc_parse_disambig(voccxdef *ctx);
/* replace the current command - TADS program code interface */
void voc_parse_replace_cmd(voccxdef *ctx);
/* check access to an object */
int vocchkaccess(voccxdef *ctx, objnum obj, prpnum verprop,
int seqno, objnum actor, objnum verb);
/* check to see if an object is visible */
int vocchkvis(voccxdef *ctx, objnum obj, objnum cmdActor);
/* display an appropriate message for an unreachable object */
void vocnoreach(voccxdef *ctx, objnum *list1, int cnt,
objnum actor, objnum verb, objnum prep, prpnum defprop,
int show_multi_prefix, int multi_flags,
int multi_base_index, int multi_total_count);
/* set {numObj | strObj}.value, as appropriate */
void vocsetobj(voccxdef *ctx, objnum obj, dattyp typ, const void *val,
vocoldef *inobj, vocoldef *outobj);
/* macros to read values out of templates */
#define voctplpr(tpl) ((objnum)osrp2(((uchar *)tpl))) /* preposition */
#define voctplvi(tpl) ((prpnum)osrp2(((uchar *)tpl) + 2)) /* verIoVerb */
#define voctplio(tpl) ((prpnum)osrp2(((uchar *)tpl) + 4)) /* ioVerb */
#define voctplvd(tpl) ((prpnum)osrp2(((uchar *)tpl) + 6)) /* verDoVerb */
#define voctpldo(tpl) ((prpnum)osrp2(((uchar *)tpl) + 8)) /* doVerb */
#define voctplflg(tpl) (*(((uchar *)tpl) + 10)) /* flags */
/* flag values for the voctplflg */
#define VOCTPLFLG_DOBJ_FIRST 0x01 /* disambiguate direct object first */
/* word type flags */
#define VOCT_ARTICLE 1
#define VOCT_ADJ 2
#define VOCT_NOUN 4
#define VOCT_PREP 8
#define VOCT_VERB 16
#define VOCT_SPEC 32 /* special words - "of", ",", ".", etc. */
#define VOCT_PLURAL 64
#define VOCT_UNKNOWN 128 /* word is unknown */
/* special type flags */
#define VOCS_ALL 1 /* "all" */
#define VOCS_EXCEPT 2 /* "except" */
#define VOCS_IT 4 /* "it" */
#define VOCS_THEM 8 /* "them" */
#define VOCS_NUM 16 /* a number */
#define VOCS_COUNT 32 /* a number being used as a count */
#define VOCS_PLURAL 64 /* plural */
#define VOCS_ANY 128 /* "any" */
#define VOCS_HIM 256 /* "him" */
#define VOCS_HER 512 /* "her" */
#define VOCS_STR 1024 /* a quoted string */
#define VOCS_UNKNOWN 2048 /* noun phrase contains an unknown word */
#define VOCS_ENDADJ 4096 /* word matched adjective at end of phrase */
#define VOCS_TRUNC 8192 /* truncated match - word is leading substring */
#define VOCS_TRIMPREP 16384 /* trimmed prep phrase: assumed it was for verb */
/* special internally-defined one-character word flags */
#define VOCW_AND ','
#define VOCW_THEN '.'
#define VOCW_OF 'O'
#define VOCW_ALL 'A'
#define VOCW_BOTH 'B'
#define VOCW_IT 'I'
#define VOCW_HIM 'M'
#define VOCW_ONE 'N'
#define VOCW_ONES 'P'
#define VOCW_HER 'R'
#define VOCW_THEM 'T'
#define VOCW_BUT 'X'
#define VOCW_ANY 'Y'
/* structure for special internal word table */
struct vocspdef {
const char *vocspin;
char vocspout;
};
/* check if a word is a special word - true if word is given special word */
/* int vocspec(char *wordptr, int speccode); */
#define vocspec(w, s) (*(w) == (s))
/*
* Set a fuse/daemon/notifier.
*/
void vocsetfd(voccxdef *ctx, vocddef *what, objnum func, prpnum prop,
uint tm, runsdef *val, int err);
/* remove a fuse/daemon/notifier */
void vocremfd(voccxdef *ctx, vocddef *what, objnum func, prpnum prop,
runsdef *val, int err);
/* count a turn (down all fuse/notifier timers) */
void vocturn(voccxdef *ctx, int turncnt, int do_fuses);
/* initialize voc context */
void vocini(voccxdef *vocctx, errcxdef *errctx, mcmcxdef *memctx,
runcxdef *runctx, objucxdef *undoctx, int fuses,
int daemons, int notifiers);
/* clean up the voc context - frees memory allocated by vocini() */
void vocterm(voccxdef *vocctx);
/* allocate/free fuse/daemon/notifier array for voc ctx initialization */
void vocinialo(voccxdef *ctx, vocddef **what, int cnt);
void voctermfree(vocddef *what);
/* get a vocidef given an object number */
/* vocidef *vocinh(voccxdef *ctx, objnum obj); */
#define vocinh(ctx, obj) ((ctx)->voccxinh[(obj) >> 8][(obj) & 255])
/* revert all objects back to original state, using inheritance records */
void vocrevert(voccxdef *ctx);
/* clear all fuses/daemons/notifiers (useful for restarting) */
void vocdmnclr(voccxdef *ctx);
/* display a parser error message */
void vocerr(voccxdef *ctx, int err, const char *f, ...);
/*
* display a parser informational error message - this will display the
* message whether or not we're suppressing messages due to unknown
* words, and should be used when providing information, such as objects
* we're assuming by default
*/
void vocerr_info(voccxdef *ctx, int err, const char *f, ...);
/* client undo callback - undoes a daemon/fuse/notifier */
void vocdundo(void *ctx, uchar *data);
/* client undo size figuring callback - return size of client undo record */
ushort OS_LOADDS vocdusz(void *ctx, uchar *data);
/* save undo for object creation */
void vocdusave_newobj(voccxdef *ctx, objnum objn);
/* save undo for adding a word */
void vocdusave_addwrd(voccxdef *ctx, objnum objn, prpnum typ, int flags,
char *wrd);
/* save undo for deleting a word */
void vocdusave_delwrd(voccxdef *ctx, objnum objn, prpnum typ, int flags,
char *wrd);
/* save undo for object deletion */
void vocdusave_delobj(voccxdef *ctx, objnum objn);
/* save undo for changing the "Me" object */
void vocdusave_me(voccxdef *ctx, objnum old_me);
/* compute vocabulary word hash value */
uint vochsh(const uchar *t, int len);
/* TADS versions of isalpha, isspace, isdigit, etc */
#define vocisupper(c) ((uchar)(c) <= 127 && Common::isUpper((uchar)(c)))
#define vocislower(c) ((uchar)(c) <= 127 && Common::isLower((uchar)(c)))
#define vocisalpha(c) ((uchar)(c) > 127 || Common::isAlpha((uchar)(c)))
#define vocisspace(c) ((uchar)(c) <= 127 && Common::isSpace((uchar)(c)))
#define vocisdigit(c) ((uchar)(c) <= 127 && Common::isDigit((uchar)(c)))
/*
* Undo types for voc subsystem
*/
#define VOC_UNDO_DAEMON 1 /* fuse/daemon status change */
#define VOC_UNDO_NEWOBJ 2 /* object creation */
#define VOC_UNDO_DELOBJ 3 /* object deletion */
#define VOC_UNDO_ADDVOC 4 /* add vocabulary to an object */
#define VOC_UNDO_DELVOC 5 /* delete vocabulary from an object */
#define VOC_UNDO_SETME 6 /* set the "Me" object */
/*
* Our own stack. We need to allocate some fairly large structures
* (for the disambiguation lists, mostly) in a stack-like fashion, and
* we don't want to consume vast quantities of the real stack, because
* some machines have relatively restrictive limitations on stack usage.
* To provide some elbow room, we'll use a stack-like structure of our
* own: we'll allocate out of this structure as needed, and whenever we
* leave a C stack frame, we'll also leave our own stack frame.
*/
/* re-initialize the stack, allocating space for it if needed */
void voc_stk_ini(voccxdef *ctx, uint siz);
/* enter a stack frame, marking our current position */
#define voc_enter(ctx, marker) (*(marker) = (ctx)->voc_stk_cur)
/* leave a stack frame, restoring the entry position */
#define voc_leave(ctx, marker) ((ctx)->voc_stk_cur = marker)
/* return a value */
#define VOC_RETVAL(ctx, marker, retval) \
voc_leave(ctx, marker); return retval
/* allocate space from the stack */
void *voc_stk_alo(voccxdef *ctx, uint siz);
/* allocation cover macros */
#define VOC_STK_ARRAY(ctx, typ, var, cnt) \
(var = (typ *)voc_stk_alo(ctx, (uint)((cnt) * sizeof(typ))))
#define VOC_MAX_ARRAY(ctx, typ, var) \
VOC_STK_ARRAY(ctx, typ, var, VOCMAXAMBIG)
/*
* Stack size for the vocab stack. We'll scale our stack needs based
* on the size of the vocoldef structure, since this is the most common
* item to be allocated on the vocab stack. We'll also scale based on
* the defined VOCMAXAMBIG parameter, since it is the number of elements
* usually allocated. The actual amount of space needed depends on how
* the functions in vocab.c and execmd.c work, so this parameter may
* need to be adjusted for changes to the player command parser.
*/
#define VOC_STACK_SIZE (16 * VOCMAXAMBIG * sizeof(vocoldef))
/*
* Execute all fuses and daemons, then execute the endCommand user
* function. Returns zero on success, or ERR_ABORT if 'abort' was
* thrown during execution. This is a convenient cover single function
* to do all end-of-turn processing; this calls exefuse() and exedaem()
* as needed, trapping any 'abort' or 'exit' errors that occur.
*
* If 'do_fuses' is true, we'll run fuses and daemons. Otherwise,
*/
int exe_fuses_and_daemons(voccxdef *ctx, int err, int do_fuses,
objnum actor, objnum verb,
vocoldef *dobj_list, int do_cnt,
objnum prep, objnum iobj);
/*
* Execute any pending fuses. Return TRUE if any fuses were executed,
* FALSE otherwise.
*/
int exefuse(voccxdef *ctx, int do_run);
/*
* Execute daemons
*/
void exedaem(voccxdef *ctx);
/*
* Get the number and size of words defined for an object. The size
* returns the total byte count from all the words involved. Do not
* include deleted words in the count.
*/
void voc_count(voccxdef *ctx, objnum objn, prpnum prp, int *cnt, int *siz);
/*
* Iterate through all words for a particular object, calling a
* function with each vocwdef found. If objn == MCMONINV, we'll call
* the callback for every word.
*/
void voc_iterate(voccxdef *ctx, objnum objn,
void (*fn)(void *, vocdef *, vocwdef *), void *fnctx);
/* ------------------------------------------------------------------------ */
/*
* disambiguation status codes - used for disambigDobj and disambigIobj
* methods in the deepverb
*/
/* continue with disambiguation process (using possibly updated list) */
#define VOC_DISAMBIG_CONT 1
/* done - the list is fully resolved; return with (possibly updated) list */
#define VOC_DISAMBIG_DONE 2
/* error - abort the command */
#define VOC_DISAMBIG_ERROR 3
/* parse string returned in second element of list as interactive response */
#define VOC_DISAMBIG_PARSE_RESP 4
/* already asked for an interactive response, but didn't read it yet */
#define VOC_DISAMBIG_PROMPTED 5
/* ------------------------------------------------------------------------ */
/*
* parseNounPhrase status codes
*/
/* parse error occurred */
#define VOC_PNP_ERROR 1
/* use built-in default parser */
#define VOC_PNP_DEFAULT 2
/* successful parse */
#define VOC_PNP_SUCCESS 3
/* ------------------------------------------------------------------------ */
/*
* parserResolveObjects usage codes
*/
#define VOC_PRO_RESOLVE_DOBJ 1 /* direct object */
#define VOC_PRO_RESOLVE_IOBJ 2 /* indirect object */
#define VOC_PRO_RESOLVE_ACTOR 3 /* actor */
} // End of namespace TADS2
} // End of namespace TADS
} // End of namespace Glk
#endif
|