cfad47cfa3/tads2/voc.h

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
1
/*
2
$Header: d:/cvsroot/tads/TADS2/VOC.H,v 1.4 1999/07/11 00:46:31 MJRoberts Exp $
3
*/
4
5
/* 
6
 *   Copyright (c) 1991, 2002 Michael J. Roberts.  All Rights Reserved.
7
 *   
8
 *   Please see the accompanying license file, LICENSE.TXT, for information
9
 *   on using and copying this software.  
10
 */
11
/*
12
Name
13
  voc.h - vocabulary definitions
14
Function
15
  Defines TADS vocabulary (player command parser) functionality
16
Notes
17
  None
18
Modified
19
  11/07/91 MJRoberts     - creation
20
*/
21
22
#ifndef VOC_INCLUDED
23
#define VOC_INCLUDED
24
25
#ifndef ERR_INCLUDED
26
#include "err.h"
27
#endif
28
#ifndef OBJ_INCLUDED
29
#include "obj.h"
30
#endif
31
#ifndef PRP_INCLUDED
32
#include "prp.h"
33
#endif
34
#ifndef TIO_INCLUDED
35
#include "tio.h"
36
#endif
37
#ifndef RUN_INCLUDED
38
#include "run.h"
39
#endif
40
41
#include <time.h>
42
43
/*
44
 *   Cover macro for parser errors.  Any parser error should be covered
45
 *   with this macro for documentation and search purposes.  (The macro
46
 *   doesn't do anything - this is just something to search for when we're
47
 *   trying to enumerate parser error codes.) 
48
 */
49
#define VOCERR(errcode) errcode
50
51
/* maximum number of objects matching an ambiguous word */
52
#define VOCMAXAMBIG 200
53
54
/* size of input buffer */
55
#define VOCBUFSIZ 128
56
57
/*
58
 *   Vocabulary relation structure - this structure relates a vocabulary
59
 *   word to an object and part of speech.  A list of these structures is
60
 *   attached to each vocabulary word structure to provide the word's
61
 *   meanings.
62
 */
63
typedef struct vocwdef vocwdef;
64
struct vocwdef
65
{
66
    uint   vocwnxt;      /* index of next vocwdef attached to the same word */
67
    objnum vocwobj;                      /* object associated with the word */
68
    uchar  vocwtyp;   /* property associated with the word (part of speech) */
69
    uchar  vocwflg;                                   /* flags for the word */
70
#define VOCFCLASS  1                          /* word is for a class object */
71
#define VOCFINH    2                 /* word is inherited from a superclass */
72
#define VOCFNEW    4                          /* word was added at run-time */
73
#define VOCFDEL    8                               /* word has been deleted */
74
};
75
76
/* vocabulary word structure */
77
typedef struct vocdef vocdef;
78
struct vocdef
79
{
80
    vocdef *vocnxt;                         /* next word at same hash value */
81
    uchar   voclen;                                   /* length of the word */
82
    uchar   vocln2;          /* length of second word (0 if no second word) */
83
    uint    vocwlst;      /* head of list of vocwdef's attached to the word */
84
    uchar   voctxt[1];                                  /* text of the word */
85
};
86
87
/* vocabulary inheritance cell */
88
typedef struct vocidef vocidef;
89
struct vocidef
90
{
91
    uchar            vocinsc;   /* # of superclasses (gives size of record) */
92
    union
93
    {
94
        struct
95
        {
96
            uchar    vociusflg;                          /* flags for entry */
97
#define VOCIFCLASS  1  /* entry refers to a class object (loc records only) */
98
#define VOCIFVOC    2                 /* entry has vocabulary words defined */
99
#define VOCIFXLAT   4  /* superclasses must be translated from portable fmt */
100
#define VOCIFLOCNIL 8                  /* location is explicitly set to nil */
101
#define VOCIFNEW    16       /* object was allocated at run-time with "new" */
102
            objnum   vociusloc;                   /* location of the object */
103
            objnum   vociusilc;                       /* inherited location */
104
            objnum   vociussc[1];                  /* array of superclasses */
105
        } vocius;
106
        vocidef     *vociunxt;
107
    } vociu;
108
#   define   vociflg vociu.vocius.vociusflg
109
#   define   vociloc vociu.vocius.vociusloc
110
#   define   vociilc vociu.vocius.vociusilc
111
#   define   vocisc  vociu.vocius.vociussc
112
#   define   vocinxt vociu.vociunxt
113
};
114
115
/* size of a page in a vocabulary pool */
116
#define VOCPGSIZ  8192
117
118
/* number of bytes in an inheritance cell page */
119
#define VOCISIZ 8192
120
121
/* maximum number of inheritance pages */
122
#define VOCIPGMAX 32
123
124
/* maximum number of inheritance pages (256 objects per page) */
125
#define VOCINHMAX 128
126
127
/* size of vocabulary hash table */
128
#define VOCHASHSIZ  256
129
130
/* size of a template structure */
131
#define VOCTPLSIZ 10
132
133
/* new-style template structure */
134
#define VOCTPL2SIZ  16
135
136
137
/*
138
 *   vocwdef's are fixed in size.  They're allocated in a set of arrays
139
 *   (the voccxwp member of the voc context has the list of arrays).  Each
140
 *   array is of a fixed number of vocwdef entries; a maximum number of
141
 *   vocwdef arrays is possible. 
142
 */
143
#define VOCWPGSIZ   2000                   /* number of vocwdef's per array */
144
#define VOCWPGMAX   16                  /* maximum number of vocwdef arrays */
145
146
/*
147
 *   To find a vocwdef entry given its index, divide the index by the
148
 *   number of entries per array to find the array number, and use the
149
 *   remainder to find the index within that array. 
150
 */
151
/*#define VOCW_IN_CACHE*/
152
#ifdef VOCW_IN_CACHE
153
vocwdef *vocwget(struct voccxdef *ctx, uint idx);
154
#else
155
#define vocwget(ctx, idx) \
156
    ((idx) == VOCCXW_NONE ? (vocwdef *)0 : \
157
      ((ctx)->voccxwp[(idx)/VOCWPGSIZ] + ((idx) % VOCWPGSIZ)))
158
#endif
159
160
/*
161
 *   Special values for vocdtim - these values indicate that the daemon
162
 *   does not have a normal turn-based expiration time. 
163
 */
164
#define VOCDTIM_EACH_TURN  0xffff            /* the daemon fires every turn */
165
166
/* daemon/fuse/alarm slot */
167
struct vocddef
168
{
169
    objnum   vocdfn;             /* object number of function to be invoked */
170
    runsdef  vocdarg;                  /* argument for daemon/fuse function */
171
    prpnum   vocdprp;             /* property number (used only for alarms) */
172
    uint     vocdtim;  /* time for fuses/alarms (0xffff -> each-turn alarm) */
173
};
174
typedef struct vocddef vocddef;
175
176
/* vocabulary object list entry */
177
struct vocoldef
178
{
179
    objnum  vocolobj;                           /* object matching the word */
180
    char   *vocolfst;         /* first word in cmd[] that identified object */
181
    char   *vocollst;          /* last word in cmd[] that identified object */
182
    char   *vocolhlst;      /* hypothetical last word, if we trimmed a prep */
183
    int     vocolflg;                           /* special flags (ALL, etc) */
184
};
185
typedef struct vocoldef vocoldef;
186
187
/* vocabulary context */
188
struct voccxdef
189
{
190
    errcxdef  *voccxerr;                          /* error handling context */
191
    tiocxdef  *voccxtio;                                /* text i/o context */
192
    runcxdef  *voccxrun;                               /* execution context */
193
    mcmcxdef  *voccxmem;                          /* memory manager context */
194
    objucxdef *voccxundo;                                   /* undo context */
195
    uchar     *voccxpool;                  /* next free byte in vocdef pool */
196
    vocdef    *voccxfre;                        /* head of vocdef free list */
197
    char      *voccxcpp;                   /* pointer to compound word area */
198
    int        voccxcpl;                    /* length of compound word area */
199
    char      *voccxspp;                    /* pointer to special word area */
200
    int        voccxspl;                     /* length of special word area */
201
    uint       voccxrem;        /* number of bytes remaining in vocdef pool */
202
    vocidef  **voccxinh[VOCINHMAX];     /* vocidef page table: 256 per page */
203
    uchar     *voccxip[VOCIPGMAX];                 /* inheritance cell pool */
204
    vocidef   *voccxifr;              /* head of inheritance cell free list */
205
    uint       voccxiplst;          /* last inheritance cell page allocated */
206
    uint       voccxilst;      /* next unused byte in last inheritance page */
207
    int        voccxredo;                   /* flag: redo command in buffer */
208
209
    /* 
210
     *   redo buffer - if voccxredo is set, and this buffer is not empty,
211
     *   we'll redo the command in this buffer rather than the one in our
212
     *   internal stack buffer 
213
     */
214
    char       voccxredobuf[VOCBUFSIZ];
215
216
    /*
217
     *   "again" buffer - when we save the last command for repeating via
218
     *   the "again" command, we'll save the direct and indirect object
219
     *   words here, so that they can be recovered if "again" is used 
220
     */
221
    char       voccxagainbuf[VOCBUFSIZ];
222
223
    vocdef    *voccxhsh[VOCHASHSIZ];                          /* hash table */
224
225
#ifdef VOCW_IN_CACHE
226
    mcmon      voccxwp[VOCWPGMAX];        /* list of pages of vocab records */
227
    mcmon      voccxwplck;                  /* locked page of vocab records */
228
    vocwdef   *voccxwpgptr;             /* pointer to currently locked page */
229
#else
230
    vocwdef   *voccxwp[VOCWPGMAX];                  /* vocabulary word pool */
231
#endif
232
233
    uint       voccxwalocnt;             /* number of vocwdef's used so far */
234
    uint       voccxwfre;            /* index of first vocwdef in free list */
235
#define VOCCXW_NONE  ((uint)(-1))     /* index value indicating end of list */
236
237
    vocddef   *voccxdmn;                           /* array of daemon slots */
238
    uint       voccxdmc;                 /* number of slots in daemon array */
239
    vocddef   *voccxfus;                             /* array of fuse slots */
240
    uint       voccxfuc;                   /* number of slots in fuse array */
241
    vocddef   *voccxalm;                            /* array of alarm slots */
242
    uint       voccxalc;                  /* number of slots in alarm array */
243
    char       voccxtim[26];            /* game's timestamp (asctime value) */
244
    
245
    objnum     voccxvtk;                /* object number of "take" deepverb */
246
    objnum     voccxme;                      /* object number of "Me" actor */
247
    objnum     voccxme_init;                     /* initial setting of "Me" */
248
    objnum     voccxstr;                       /* object number of "strObj" */
249
    objnum     voccxnum;                       /* object number of "numObj" */
250
    objnum     voccxit;                                  /* last "it" value */
251
    objnum     voccxhim;                                /* last "him" value */
252
    objnum     voccxher;                                /* last "her" value */
253
    objnum     voccxthc;                   /* count of items in "them" list */
254
    objnum     voccxthm[VOCMAXAMBIG];            /* list of items in "them" */
255
    objnum     voccxprd;                 /* "pardon" function object number */
256
    objnum     voccxpre;               /* "preparse" function object number */
257
    objnum     voccxppc;            /* "preparseCmd" function object number */
258
    objnum     voccxpre2;           /* "preparseExt" function object number */
259
    objnum     voccxvag;                             /* "again" verb object */
260
    objnum     voccxini;                                 /* "init" function */
261
    objnum     voccxper;             /* "parseError" function object number */
262
    objnum     voccxprom;             /* "cmdPrompt" function object number */
263
    objnum     voccxpostprom;     /* "cmdPostPrompt" function object number */
264
    objnum     voccxpdis;                         /* parseDisambig function */
265
    objnum     voccxper2;                           /* parseError2 function */
266
    objnum     voccxperp;                       /* parseErrorParam function */
267
    objnum     voccxpdef;                          /* parseDefault function */
268
    objnum     voccxpdef2;                      /* parseDefaultExt function */
269
    objnum     voccxpask;                           /* parseAskobj function */
270
    objnum     voccxpask2;                     /* parseAskobjActor function */
271
    objnum     voccxpask3;                  /* parseAskobjIndirect function */
272
    objnum     voccxinitrestore;    /* "initRestore" function object number */
273
    objnum     voccxpuv;         /* parseUnknownVerb function object number */
274
    objnum     voccxpnp;          /* parseNounPhrase function object number */
275
    objnum     voccxpostact;           /* postAction function object number */
276
    objnum     voccxprecmd;            /* preCommand function object number */
277
    objnum     voccxendcmd;            /* endCommand function object number */
278
279
    /* current command word list values */
280
    vocoldef  *voccxdobj;                /* current direct object word list */
281
    vocoldef  *voccxiobj;              /* current indirect object word list */
282
283
    /* current command objects */
284
    objnum     voccxactor;                                 /* current actor */
285
    objnum     voccxverb;                       /* current command deepverb */
286
    objnum     voccxprep;                    /* current command preposition */
287
    
288
    /* previous command values - used by "again" */
289
    objnum     voccxlsa;                                  /* previous actor */
290
    objnum     voccxlsv;                                   /* previous verb */
291
    vocoldef   voccxlsd;                          /* previous direct object */
292
    vocoldef   voccxlsi;                        /* previous indirect object */
293
    objnum     voccxlsp;                                     /* preposition */
294
    int        voccxlssty;              /* style (new/old) of last template */
295
    uchar      voccxlst[VOCTPL2SIZ];                            /* template */
296
297
    objnum     voccxpreinit;                            /* preinit function */
298
299
    /* special flags */
300
    uchar      voccxflg;
301
#define VOCCXFCLEAR    1      /* ignore remainder of command line (restore) */
302
#define VOCCXFVWARN    2                /* generate redundant verb warnings */
303
#define VOCCXFDBG      4           /* debug mode:  show parsing information */
304
#define VOCCXAGAINDEL  8             /* "again" lost due to object deletion */
305
306
    /* number of remaining unresolved unknown words in the command */
307
    int        voccxunknown;
308
309
    /* total number of unresolved words in the last command */
310
    int        voccxlastunk;
311
312
    /* parser stack area */
313
    uchar *voc_stk_ptr;
314
    uchar *voc_stk_cur;
315
    uchar *voc_stk_end;
316
};
317
typedef struct voccxdef voccxdef;
318
319
/* allocate and push a list, returning a pointer to the list's memory */
320
uchar *voc_push_list_siz(voccxdef *ctx, uint lstsiz);
321
322
/* push a list of objects from a vocoldef array */
323
void voc_push_vocoldef_list(voccxdef *ctx, vocoldef *objlist, int cnt);
324
325
/* push a list of objects from an objnum array */
326
void voc_push_objlist(voccxdef *ctx, objnum objlist[], int cnt);
327
328
/* change the player character ("Me") object */
329
void voc_set_me(voccxdef *ctx, objnum new_me);
330
331
/* add a vocabulary word */
332
void vocadd(voccxdef *ctx, prpnum p, objnum objn,
333
            int classflag, char *wrdval);
334
335
/* internal addword - must already be split into two words and lengths */
336
void vocadd2(voccxdef *ctx, prpnum p, objnum objn, int classflg,
337
             uchar *wrd1, int len1, uchar *wrd2, int len2);
338
339
/* delete vocabulary for a given object */
340
void vocdel(voccxdef *ctx, objnum objn);
341
342
/* lower-level vocabulary deletion routine */
343
void vocdel1(voccxdef *ctx, objnum objn, char *wrd, prpnum prp,
344
             int really_delete, int revert, int keep_undo);
345
346
/* delete all inherited vocabulary */
347
void vocdelinh(voccxdef *ctx);
348
349
/* allocate space for an inheritance record if needed */
350
void vocialo(voccxdef *ctx, objnum obj);
351
352
/* add an inheritance/location record */
353
void vociadd(voccxdef *ctx, objnum obj, objnum loc,
354
             int numsc, objnum *sc, int flags);
355
356
/* delete inheritance records for an object */
357
void vocidel(voccxdef *ctx, objnum chi);
358
359
/* renumber an object's inheritance records - used for 'modify' */
360
void vociren(voccxdef *ctx, objnum oldnum, objnum newnum);
361
362
/* caller-provided context structure for vocffw/vocfnw searches */
363
typedef struct vocseadef vocseadef;
364
struct vocseadef
365
{
366
    vocdef  *v;
367
    vocwdef *vw;
368
    uchar   *wrd1;
369
    int      len1;
370
    uchar   *wrd2;
371
    int      len2;
372
};
373
374
/* find first word matching a given word */
375
vocwdef *vocffw(voccxdef *ctx, char *wrd, int len, char *wrd2, int len2,
376
                int p, vocseadef *search_ctx);
377
378
/* find next word */
379
vocwdef *vocfnw(voccxdef *voccx, vocseadef *search_ctx);
380
381
/* read a line of input text */
382
int vocread(voccxdef *ctx, objnum actor, objnum verb,
383
            char *buf, int bufl, int type);
384
#define VOCREAD_OK    0
385
#define VOCREAD_REDO  1
386
387
/* compute size of a vocoldef list */
388
int voclistlen(vocoldef *lst);
389
390
/* tokenize an input buffer */
391
int voctok(voccxdef *ctx, char *cmd, char *outbuf,
392
           char **wrd, int lower, int cvt_ones, int show_errors);
393
394
/* get types for a word list */
395
int vocgtyp(voccxdef *ctx, char **cmd, int *types, char *orgbuf);
396
397
/* execute a player command */
398
int voccmd(voccxdef *ctx, char *cmd, uint cmdlen);
399
400
/* disambiguator */
401
int vocdisambig(voccxdef *ctx, vocoldef *outlist, vocoldef *inlist,
402
                prpnum defprop, prpnum accprop, prpnum verprop,
403
                char *cmd[], objnum otherobj, objnum cmdActor,
404
                objnum cmdVerb, objnum cmdPrep, char *cmdbuf,
405
                int silent);
406
407
/* display a multiple-object prefix */
408
void voc_multi_prefix(voccxdef *ctx, objnum objn,
409
                      int show_prefix, int multi_flags,
410
                      int cur_index, int count);
411
412
/* low-level executor */
413
int execmd(voccxdef *ctx, objnum actor, objnum prep,
414
           char *vverb, char *vprep, vocoldef *dolist, vocoldef *iolist,
415
           char **cmd, int *typelist,
416
           char *cmdbuf, int wrdcnt, uchar **preparse_list, int *next_start);
417
418
/* recursive command execution */
419
int execmd_recurs(voccxdef *ctx, objnum actor, objnum verb,
420
                  objnum dobj, objnum prep, objnum iobj,
421
                  int validate_dobj, int validate_iobj);
422
423
/* try running preparseCmd user function */
424
int try_preparse_cmd(voccxdef *ctx, char **cmd, int wrdcnt,
425
                     uchar **preparse_list);
426
427
/*
428
 *   Handle an unknown verb or sentence structure.  We'll call this when
429
 *   we encounter a sentence where we don't know the verb word, or we
430
 *   don't know the combination of verb and verb preposition, or we don't
431
 *   recognize the sentence structure (for example, an indirect object is
432
 *   present, but we don't have a template defined using an indirect
433
 *   object for the verb).
434
 *   
435
 *   'wrdcnt' is the number of words in the cmd[] array.  If wrdcnt is
436
 *   zero, we'll automatically count the array entries, with the end of
437
 *   the array indicated by a null pointer entry.
438
 *   
439
 *   If do_fuses is true, we'll execute the fuses and daemons if the
440
 *   function exists and doesn't throw an ABORT error, or any other
441
 *   run-time error other than EXIT.
442
 *   
443
 *   This function calls the game-defined function parseUnknownVerb, if it
444
 *   exists.  If the function doesn't exist, we'll simply display the
445
 *   given error message, using the normal parseError mechanism.  The
446
 *   function should use "abort" or "exit" if it wants to cancel further
447
 *   processing of the command.
448
 *   
449
 *   We'll return true if the function exists and executes successfully,
450
 *   in which case normal processing should continue with any remaining
451
 *   command on the command line.  We'll return false if the function
452
 *   doesn't exist or throws an error other than EXIT, in which case the
453
 *   remainder of the command should be aborted.  
454
 */
455
int try_unknown_verb(voccxdef *ctx, objnum actor,
456
                     char **cmd, int *typelist, int wrdcnt, int *next_start,
457
                     int do_fuses, int err, char *msg, ...);
458
459
/* find a template */
460
int voctplfnd(voccxdef *ctx, objnum verb_in, objnum prep,
461
              uchar *tplout, int *newstyle);
462
463
/* build a printable name for an object from the words in a command list */
464
void voc_make_obj_name(voccxdef *ctx, char *namebuf, char *cmd[],
465
                       int firstwrd, int lastwrd);
466
void voc_make_obj_name_from_list(voccxdef *ctx, char *namebuf,
467
                                 char *cmd[], char *firstwrd, char *lastwrd);
468
469
/*
470
 *   check noun - determines whether the next set of words is a valid noun
471
 *   phrase.  No complaint is issued if not; this check is generally made
472
 *   to figure out what type of sentence we're dealing with.  This is
473
 *   simple; we just call vocgobj() with the complaint flag turned off.
474
 */
475
/* int vocchknoun(voccxdef *ctx, char **cmd, int *typelist, int cur,
476
                  int *next, vocoldef *nounlist, int chkact); */
477
#define vocchknoun(ctx, cmd, typelist, cur, next, nounlist, chkact) \
478
 vocgobj(ctx, cmd, typelist, cur, next, FALSE, nounlist, TRUE, chkact, 0)
479
#define vocchknoun2(ctx, cmd, typlst, cur, next, nounlist, chkact, nomatch) \
480
 vocgobj(ctx, cmd, typlst, cur, next, FALSE, nounlist, TRUE, chkact, nomatch)
481
482
/*
483
 *   get noun - reads an object list.  We simply call vocgobj() with the
484
 *   complaint and multiple-noun flags turned on.
485
 */
486
/* int vocgetnoun(voccxdef *ctx, char **cmd, int *typelist, int cur,
487
                  int *next, vocoldef *nounlist); */
488
#define vocgetnoun(ctx, cmd, typelist, cur, next, nounlist) \
489
 vocgobj(ctx, cmd, typelist, cur, next, TRUE, nounlist, TRUE, FALSE, 0)
490
491
/* get object */
492
int vocgobj(voccxdef *ctx, char **cmd, int *typelist, int cur,
493
            int *next, int complain, vocoldef *nounlist,
494
            int multi, int chkact, int *nomatch);
495
496
/* tokenize a string - TADS program code interface */
497
void voc_parse_tok(voccxdef *ctx);
498
499
/* get token types - TADS program code interface */
500
void voc_parse_types(voccxdef *ctx);
501
502
/* get objects matching all of the given words - TADS program code interface */
503
void voc_parse_dict_lookup(voccxdef *ctx);
504
505
/* parse a noun list - TADS program code interface */
506
void voc_parse_np(voccxdef *ctx);
507
508
/* disambiguate a noun list - TADS program code interface */
509
void voc_parse_disambig(voccxdef *ctx);
510
511
/* replace the current command - TADS program code interface */
512
void voc_parse_replace_cmd(voccxdef *ctx);
513
514
/* check access to an object */
515
int vocchkaccess(voccxdef *ctx, objnum obj, prpnum verprop,
516
                 int seqno, objnum actor, objnum verb);
517
518
/* check to see if an object is visible */
519
int vocchkvis(voccxdef *ctx, objnum obj, objnum cmdActor);
520
521
/* display an appropriate message for an unreachable object */
522
void vocnoreach(voccxdef *ctx, objnum *list1, int cnt,
523
                objnum actor, objnum verb, objnum prep, prpnum defprop,
524
                int show_multi_prefix, int multi_flags,
525
                int multi_base_index, int multi_total_count);
526
527
/* set {numObj | strObj}.value, as appropriate */
528
void vocsetobj(voccxdef *ctx, objnum obj, dattyp typ, void *val,
529
               vocoldef *inobj, vocoldef *outobj);
530
531
/* macros to read values out of templates */
532
#define voctplpr(tpl) ((objnum)osrp2(((uchar *)tpl)))        /* preposition */
533
#define voctplvi(tpl) ((prpnum)osrp2(((uchar *)tpl) + 2))      /* verIoVerb */
534
#define voctplio(tpl) ((prpnum)osrp2(((uchar *)tpl) + 4))         /* ioVerb */
535
#define voctplvd(tpl) ((prpnum)osrp2(((uchar *)tpl) + 6))      /* verDoVerb */
536
#define voctpldo(tpl) ((prpnum)osrp2(((uchar *)tpl) + 8))         /* doVerb */
537
#define voctplflg(tpl) (*(((uchar *)tpl) + 10))                    /* flags */
538
539
/* flag values for the voctplflg */
540
#define VOCTPLFLG_DOBJ_FIRST   0x01     /* disambiguate direct object first */
541
542
543
/* word type flags */
544
#define VOCT_ARTICLE  1
545
#define VOCT_ADJ      2
546
#define VOCT_NOUN     4
547
#define VOCT_PREP     8
548
#define VOCT_VERB     16
549
#define VOCT_SPEC     32            /* special words - "of", ",", ".", etc. */
550
#define VOCT_PLURAL   64
551
#define VOCT_UNKNOWN  128                                /* word is unknown */
552
553
/* special type flags */
554
#define VOCS_ALL     1                                             /* "all" */
555
#define VOCS_EXCEPT  2                                          /* "except" */
556
#define VOCS_IT      4                                              /* "it" */
557
#define VOCS_THEM    8                                            /* "them" */
558
#define VOCS_NUM     16                                         /* a number */
559
#define VOCS_COUNT   32                   /* a number being used as a count */
560
#define VOCS_PLURAL  64                                           /* plural */
561
#define VOCS_ANY     128                                           /* "any" */
562
#define VOCS_HIM     256                                           /* "him" */
563
#define VOCS_HER     512                                           /* "her" */
564
#define VOCS_STR     1024                                /* a quoted string */
565
#define VOCS_UNKNOWN 2048           /* noun phrase contains an unknown word */
566
#define VOCS_ENDADJ  4096        /* word matched adjective at end of phrase */
567
#define VOCS_TRUNC   8192    /* truncated match - word is leading substring */
568
#define VOCS_TRIMPREP 16384 /* trimmed prep phrase: assumed it was for verb */
569
570
/* special internally-defined one-character word flags */
571
#define VOCW_AND     ','
572
#define VOCW_THEN    '.'
573
#define VOCW_OF      'O'
574
#define VOCW_ALL     'A'
575
#define VOCW_BOTH    'B'
576
#define VOCW_IT      'I'
577
#define VOCW_HIM     'M'
578
#define VOCW_ONE     'N'
579
#define VOCW_ONES    'P'
580
#define VOCW_HER     'R'
581
#define VOCW_THEM    'T'
582
#define VOCW_BUT     'X'
583
#define VOCW_ANY     'Y'
584
585
/* structure for special internal word table */
586
struct vocspdef
587
{
588
    char *vocspin;
589
    char  vocspout;
590
};
591
typedef struct vocspdef vocspdef;
592
593
/* check if a word is a special word - true if word is given special word */
594
/* int vocspec(char *wordptr, int speccode); */
595
#define vocspec(w, s) (*(w) == (s))
596
597
/* 
598
 *   Set a fuse/daemon/notifier.
599
 */
600
void vocsetfd(voccxdef *ctx, vocddef *what, objnum func, prpnum prop,
601
              uint tm, runsdef *val, int err);
602
603
/* remove a fuse/daemon/notifier */
604
void vocremfd(voccxdef *ctx, vocddef *what, objnum func, prpnum prop,
605
              runsdef *val, int err);
606
607
/* count a turn (down all fuse/notifier timers) */
608
void vocturn(voccxdef *ctx, int turncnt, int do_fuses);
609
610
/* initialize voc context */
611
void vocini(voccxdef *vocctx, errcxdef *errctx, mcmcxdef *memctx,
612
            runcxdef *runctx, objucxdef *undoctx, int fuses,
613
            int daemons, int notifiers);
614
615
/* allocate fuse/daemon/notifier array for voc ctx initialization */
616
void vocinialo(voccxdef *ctx, vocddef **what, int cnt);
617
618
/* get a vocidef given an object number */
619
/* vocidef *vocinh(voccxdef *ctx, objnum obj); */
620
#define vocinh(ctx, obj) ((ctx)->voccxinh[(obj) >> 8][(obj) & 255])
621
622
/* revert all objects back to original state, using inheritance records */
623
void vocrevert(voccxdef *ctx);
624
625
/* clear all fuses/daemons/notifiers (useful for restarting) */
626
void vocdmnclr(voccxdef *ctx);
627
628
/* display a parser error message */
629
void vocerr(voccxdef *ctx, int err, char *f, ...);
630
631
/* 
632
 *   display a parser informational error message - this will display the
633
 *   message whether or not we're suppressing messages due to unknown
634
 *   words, and should be used when providing information, such as objects
635
 *   we're assuming by default 
636
 */
637
void vocerr_info(voccxdef *ctx, int err, char *f, ...);
638
639
/* client undo callback - undoes a daemon/fuse/notifier */
640
void vocdundo(void *ctx, uchar *data);
641
642
/* client undo size figuring callback - return size of client undo record */
643
ushort OS_LOADDS vocdusz(void *ctx, uchar *data);
644
645
/* save undo for object creation */
646
void vocdusave_newobj(voccxdef *ctx, objnum objn);
647
648
/* save undo for adding a word */
649
void vocdusave_addwrd(voccxdef *ctx, objnum objn, prpnum typ, int flags,
650
                      char *wrd);
651
652
/* save undo for deleting a word */
653
void vocdusave_delwrd(voccxdef *ctx, objnum objn, prpnum typ, int flags,
654
                      char *wrd);
655
656
/* save undo for object deletion */
657
void vocdusave_delobj(voccxdef *ctx, objnum objn);
658
659
/* save undo for changing the "Me" object */
660
void vocdusave_me(voccxdef *ctx, objnum old_me);
661
662
/* compute vocabulary word hash value */
663
uint vochsh(uchar *t, int len);
664
665
/* TADS versions of isalpha, isspace, isdigit, etc */
666
#define vocisupper(c) ((uchar)(c) <= 127 && isupper((uchar)(c)))
667
#define vocislower(c) ((uchar)(c) <= 127 && islower((uchar)(c)))
668
#define vocisalpha(c) ((uchar)(c) > 127 || isalpha((uchar)(c)))
669
#define vocisspace(c) ((uchar)(c) <= 127 && isspace((uchar)(c)))
670
#define vocisdigit(c) ((uchar)(c) <= 127 && isdigit((uchar)(c)))
671
672
673
/*
674
 *   Undo types for voc subsystem 
675
 */
676
#define VOC_UNDO_DAEMON   1                    /* fuse/daemon status change */
677
#define VOC_UNDO_NEWOBJ   2                              /* object creation */
678
#define VOC_UNDO_DELOBJ   3                              /* object deletion */
679
#define VOC_UNDO_ADDVOC   4                  /* add vocabulary to an object */
680
#define VOC_UNDO_DELVOC   5             /* delete vocabulary from an object */
681
#define VOC_UNDO_SETME    6                          /* set the "Me" object */
682
683
684
/*
685
 *   Our own stack.  We need to allocate some fairly large structures
686
 *   (for the disambiguation lists, mostly) in a stack-like fashion, and
687
 *   we don't want to consume vast quantities of the real stack, because
688
 *   some machines have relatively restrictive limitations on stack usage.
689
 *   To provide some elbow room, we'll use a stack-like structure of our
690
 *   own: we'll allocate out of this structure as needed, and whenever we
691
 *   leave a C stack frame, we'll also leave our own stack frame. 
692
 */
693
694
/* re-initialize the stack, allocating space for it if needed */
695
void  voc_stk_ini(voccxdef *ctx, uint siz);
696
697
/* enter a stack frame, marking our current position */
698
#define voc_enter(ctx, marker)  (*(marker) = (ctx)->voc_stk_cur)
699
700
/* leave a stack frame, restoring the entry position */
701
#define voc_leave(ctx, marker)  ((ctx)->voc_stk_cur = marker)
702
703
/* return a value */
704
#define VOC_RETVAL(ctx, marker, retval) \
705
       voc_leave(ctx, marker); return retval
706
707
/* allocate space from the stack */
708
void *voc_stk_alo(voccxdef *ctx, uint siz);
709
710
/* allocation cover macros */
711
#define VOC_STK_ARRAY(ctx, typ, var, cnt) \
712
    (var = (typ *)voc_stk_alo(ctx, (uint)((cnt) * sizeof(typ))))
713
714
#define VOC_MAX_ARRAY(ctx, typ, var) \
715
    VOC_STK_ARRAY(ctx, typ, var, VOCMAXAMBIG)
716
717
/*
718
 *   Stack size for the vocab stack.  We'll scale our stack needs based
719
 *   on the size of the vocoldef structure, since this is the most common
720
 *   item to be allocated on the vocab stack.  We'll also scale based on
721
 *   the defined VOCMAXAMBIG parameter, since it is the number of elements
722
 *   usually allocated.  The actual amount of space needed depends on how
723
 *   the functions in vocab.c and execmd.c work, so this parameter may
724
 *   need to be adjusted for changes to the player command parser. 
725
 */
726
#define VOC_STACK_SIZE  (16 * VOCMAXAMBIG * sizeof(vocoldef))
727
728
/*
729
 *   Execute all fuses and daemons, then execute the endCommand user
730
 *   function.  Returns zero on success, or ERR_ABORT if 'abort' was
731
 *   thrown during execution.  This is a convenient cover single function
732
 *   to do all end-of-turn processing; this calls exefuse() and exedaem()
733
 *   as needed, trapping any 'abort' or 'exit' errors that occur.
734
 *   
735
 *   If 'do_fuses' is true, we'll run fuses and daemons.  Otherwise, 
736
 */
737
int exe_fuses_and_daemons(voccxdef *ctx, int err, int do_fuses,
738
                          objnum actor, objnum verb,
739
                          vocoldef *dobj_list, int do_cnt,
740
                          objnum prep, objnum iobj);
741
742
/*
743
 *   Execute any pending fuses.  Return TRUE if any fuses were executed,
744
 *   FALSE otherwise.  
745
 */
746
int exefuse(voccxdef *ctx, int do_run);
747
748
/*
749
 *   Execute daemons 
750
 */
751
void exedaem(voccxdef *ctx);
752
753
/*
754
 *   Get the number and size of words defined for an object.  The size
755
 *   returns the total byte count from all the words involved.  Do not
756
 *   include deleted words in the count.  
757
 */
758
void voc_count(voccxdef *ctx, objnum objn, prpnum prp, int *cnt, int *siz);
759
760
/*
761
 *   Iterate through all words for a particular object, calling a
762
 *   function with each vocwdef found.  If objn == MCMONINV, we'll call
763
 *   the callback for every word.  
764
 */
765
void voc_iterate(voccxdef *ctx, objnum objn,
766
                 void (*fn)(void *, vocdef *, vocwdef *), void *fnctx);
767
768
/* ------------------------------------------------------------------------ */
769
/*
770
 *   disambiguation status codes - used for disambigDobj and disambigIobj
771
 *   methods in the deepverb
772
 */
773
774
/* continue with disambiguation process (using possibly updated list) */
775
#define VOC_DISAMBIG_CONT     1
776
777
/* done - the list is fully resolved; return with (possibly updated) list */
778
#define VOC_DISAMBIG_DONE     2
779
780
/* error - abort the command */
781
#define VOC_DISAMBIG_ERROR    3
782
783
/* parse string returned in second element of list as interactive response */
784
#define VOC_DISAMBIG_PARSE_RESP  4
785
786
/* already asked for an interactive response, but didn't read it yet */
787
#define VOC_DISAMBIG_PROMPTED 5
788
789
790
/* ------------------------------------------------------------------------ */
791
/*
792
 *   parseNounPhrase status codes 
793
 */
794
795
/* parse error occurred */
796
#define VOC_PNP_ERROR    1
797
798
/* use built-in default parser */
799
#define VOC_PNP_DEFAULT  2
800
801
/* successful parse */
802
#define VOC_PNP_SUCCESS  3
803
804
805
/* ------------------------------------------------------------------------ */
806
/*
807
 *   parserResolveObjects usage codes 
808
 */
809
#define VOC_PRO_RESOLVE_DOBJ  1                            /* direct object */
810
#define VOC_PRO_RESOLVE_IOBJ  2                          /* indirect object */
811
#define VOC_PRO_RESOLVE_ACTOR 3                                    /* actor */
812
813
814
#endif /* VOC_INCLUDED */
815