aboutsummaryrefslogtreecommitdiff
path: root/engines/glk/tads/tads2/vocabulary.h
diff options
context:
space:
mode:
authorPaul Gilbert2019-05-17 10:04:03 -1000
committerPaul Gilbert2019-05-24 18:21:06 -0700
commit0279143a62c2cdab635894103da03b43eba7cf9c (patch)
treefbc77cd007a4104204287825902601b6fb50bad1 /engines/glk/tads/tads2/vocabulary.h
parent54d240d81f8858f7ad694c690fcf738b3ec8b89d (diff)
downloadscummvm-rg350-0279143a62c2cdab635894103da03b43eba7cf9c.tar.gz
scummvm-rg350-0279143a62c2cdab635894103da03b43eba7cf9c.tar.bz2
scummvm-rg350-0279143a62c2cdab635894103da03b43eba7cf9c.zip
GLK: TADS2: Adding headers
Diffstat (limited to 'engines/glk/tads/tads2/vocabulary.h')
-rw-r--r--engines/glk/tads/tads2/vocabulary.h763
1 files changed, 759 insertions, 4 deletions
diff --git a/engines/glk/tads/tads2/vocabulary.h b/engines/glk/tads/tads2/vocabulary.h
index b4079932a5..5574675aa2 100644
--- a/engines/glk/tads/tads2/vocabulary.h
+++ b/engines/glk/tads/tads2/vocabulary.h
@@ -24,19 +24,774 @@
* Defines TADS vocabulary (player command parser) functionality
*/
-#ifndef GLK_TADS_TADS2_OS
-#define GLK_TADS_TADS2_OS
+#ifndef GLK_TADS_TADS2_VOCABULARY
+#define GLK_TADS_TADS2_VOCABULARY
-#include "glk/tads/tads2/types.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 {
-// TODO: Rest of vocabulary stuff
+/*
+ * 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 */
+ char *vocolfst; /* first word in cmd[] that identified object */
+ 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;
+ uchar *wrd1;
+ int len1;
+ uchar *wrd2;
+ int len2;
+};
+
+/* find first word matching a given word */
+vocwdef *vocffw(voccxdef *ctx, char *wrd, int len, 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, 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[], char *firstwrd, 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, 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 {
+ 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, 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, 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(uchar *t, int len);
+
+/* TADS versions of isalpha, isspace, isdigit, etc */
+#define vocisupper(c) ((uchar)(c) <= 127 && isupper((uchar)(c)))
+#define vocislower(c) ((uchar)(c) <= 127 && islower((uchar)(c)))
+#define vocisalpha(c) ((uchar)(c) > 127 || isalpha((uchar)(c)))
+#define vocisspace(c) ((uchar)(c) <= 127 && isspace((uchar)(c)))
+#define vocisdigit(c) ((uchar)(c) <= 127 && 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