Files
scummvm-cursorfix/engines/glk/tads/tads2/vocabulary.h
2026-02-02 04:50:13 +01:00

800 lines
32 KiB
C++

/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
/*
* 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, size_t orgbuflen);
/* 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,
size_t cmdlen, 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, size_t cmdlen,
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