1 /* 2 $Header: d:/cvsroot/tads/TADS2/PRS.H,v 1.3 1999/07/11 00:46:30 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 prs.h - parser definitions 14 Function 15 Definitions for the parser 16 Notes 17 None 18 Modified 19 08/30/91 MJRoberts - creation 20 */ 21 22 #ifndef PRS_INCLUDED 23 #define PRS_INCLUDED 24 25 #ifndef ERR_INCLUDED 26 #include "err.h" 27 #endif 28 #ifndef TOK_INCLUDED 29 #include "tok.h" 30 #endif 31 #ifndef PRP_INCLUDED 32 #include "prp.h" 33 #endif 34 #ifndef EMT_INCLUDED 35 #include "emt.h" 36 #endif 37 #ifndef VOC_INCLUDED 38 #include "voc.h" 39 #endif 40 41 /* expression parse tree node */ 42 typedef struct prsndef prsndef; 43 struct prsndef 44 { 45 int prsntyp; /* type of this node */ 46 int prsnnlf; /* number of leaves on this node */ 47 union 48 { 49 tokdef prsnvt; /* leaf node: token at leaf */ 50 prsndef *prsnvn[1]; /* non-leaf: one or more subnodes */ 51 } prsnv; 52 }; 53 54 /* 55 * Case table: the case table is a linked list of arrays of case 56 * records, each of which contains a value (in the form of a tokdef) and 57 * a label number. When additional case table entries are needed, 58 * another array is added to the list, providing essentially unlimited 59 * cases in a switch. Note that this is the parser's internal record of 60 * a case table as it's being parsed, and is converted to a different 61 * representation during code generation. 62 */ 63 #define PRSCTSIZE 50 /* number of case entries in one case array */ 64 typedef struct prsctdef prsctdef; 65 struct prsctdef 66 { 67 prsctdef *prsctnxt; /* next array in case table */ 68 struct 69 { 70 tokdef prscttok; /* value of this label */ 71 uint prsctofs; /* code position for this label */ 72 } prsctcase[PRSCTSIZE]; /* cases */ 73 }; 74 75 /* case table control block */ 76 struct prscsdef 77 { 78 struct prsctdef *prscstab; /* first case table */ 79 uint prscscnt; /* number of cases */ 80 uint prscsdflt; /* offset of 'default' code */ 81 }; 82 typedef struct prscsdef prscsdef; 83 84 /* parsing context */ 85 struct prscxdef 86 { 87 errcxdef *prscxerr; /* error handling context */ 88 tokcxdef *prscxtok; /* lexical analysis context */ 89 toktdef *prscxstab; /* table to which to add symbols */ 90 toktdef *prscxgtab; /* goto (label) symbol table */ 91 mcmcxdef *prscxmem; /* memory handling context */ 92 emtcxdef *prscxemt; /* emitter context */ 93 voccxdef *prscxvoc; /* vocabulary context */ 94 char *prscxcpp; /* pointer to compound word memory area */ 95 uint prscxcpf; /* offset of next free byte of compound words */ 96 size_t prscxcps; /* size of compound word memory area */ 97 uchar *prscxfsp; /* pointer to format string area */ 98 uint prscxfsf; /* offset of next free byte of format strings */ 99 size_t prscxfss; /* size of format string area */ 100 char *prscxspp; /* pointer to special word area */ 101 uint prscxspf; /* offset of next free byte of special words */ 102 size_t prscxsps; /* size of special word area */ 103 ushort prscxflg; /* parse flags */ 104 # define PRSCXFLIN 0x01 /* debug mode: generate inline line records */ 105 # define PRSCXFLCL 0x02 /* debug mode: generate inline local records */ 106 # define PRSCXFLST 0x04 /* parsing a list element - no indexing */ 107 # define PRSCXFARC 0x08 /* check argument counts in user fns */ 108 # define PRSCXFV1E 0x10 /* v1 'else' compat - ignore ';' after '}' */ 109 # define PRSCXFWTCH 0x20 /* compiling "watch" expression */ 110 # define PRSCXFFUNC 0x40 /* compiling function - no 'self' object */ 111 # define PRSCXFTPL1 0x80 /* use old-style templates */ 112 # define PRSCXFLIN2 0x100 /* generate new-style line records */ 113 uint prscxprp; /* maximum property number allocated so far */ 114 uint prscxext; /* count of external functions so far */ 115 uchar *prscxnode; /* next available node structure */ 116 uint prscxsofs; /* starting offset of current string */ 117 ushort prscxslen; /* length of current string */ 118 ushort prscxnsiz; /* bytes in node pool */ 119 ushort prscxnrem; /* remaining bytes in node pool */ 120 uchar *prscxnrst; /* value for resetting prscxnode */ 121 ushort prscxrrst; /* value for resetting prscxnrem */ 122 uchar *prscxplcl; /* pool for local variables */ 123 ushort prscxslcl; /* size of local pool */ 124 ushort prscxextc; /* count of external functions */ 125 osfildef *prscxstrfile; /* string capture file */ 126 uchar prscxpool[1]; /* pool for node allocation */ 127 }; 128 typedef struct prscxdef prscxdef; 129 130 /* parse function or object definition */ 131 void prscode(prscxdef *ctx, int markcomp); 132 133 /* parse a statement (or compound statement) */ 134 void prsstm(prscxdef *ctx, uint brk, uint cont, int parms, int locals, 135 uint entofs, prscsdef *swctl, uint curfr); 136 137 /* delete 'goto' labels belonging to current code block */ 138 void prsdelgoto(prscxdef *ctx); 139 140 /* parse an expression and generate code for it */ 141 void prsxgen(prscxdef *ctx); 142 143 /* 144 * Parse an expression and generate code for it, using speculative 145 * rules: we prohibit assignments, method calls, and function calls (in 146 * short, we prohibit anything that could change game state). This is 147 * meant to support the debugger's speculative evaluation mode (see 148 * dbgcompile() for information). Throws an error if a prohibited 149 * operation is found. 150 */ 151 void prsxgen_spec(prscxdef *ctx); 152 153 154 /* 155 * parse and generate an expression, checking for a possibly incorrect 156 * assignment if in C operator mode 157 */ 158 void prsxgen_pia(prscxdef *ctx); 159 160 /* string accumulation routines */ 161 ushort prsxsst(prscxdef *ctx); 162 void prsxsad(prscxdef *ctx, char *p, ushort len); 163 void prsxsend(prscxdef *ctx); 164 165 /* determine if a type is valid for logical operators */ 166 #define prsvlog(typ) \ 167 ((typ)==TOKTNUMBER || (typ)==TOKTNIL || (typ)==TOKTTRUE) 168 169 /* convert a value to a logical type, if it's a number */ 170 #define prs2log(typ, val) \ 171 ((typ)==TOKTNUMBER ? ((val) ? TOKTTRUE : TOKTNIL) : (typ)) 172 173 /* reset node pool */ 174 /* void prsrstn(prscxdef *ctx); */ 175 #define prsrstn(ctx) \ 176 ((ctx)->prscxnode = (ctx)->prscxnrst, \ 177 (ctx)->prscxnrem = (ctx)->prscxrrst) 178 179 /* maximum number of superclasses for a single object */ 180 #define PRSMAXSC 64 181 182 /* amount of space to allocate for a new object */ 183 #define PRSOBJSIZ 256 184 185 /* add a symbol to the symbol table */ 186 void prsdef(prscxdef *ctx, tokdef *tok, int typ); 187 188 /* define a symbol as an object or forward-reference object */ 189 void prsdefobj(prscxdef *ctx, tokdef *tok, int typ); 190 191 /* 192 * Require a property identifier, returning the property number. The 193 * token containing the property identifier is removed from the input 194 * stream. 195 */ 196 prpnum prsrqpr(prscxdef *ctx); 197 198 /* signal a "missing required token" error, finding token name */ 199 void prssigreq(prscxdef *ctx, int t); 200 201 /* generate code from a parse tree */ 202 void prsgexp(prscxdef *ctx, prsndef *n); 203 204 /* generate code for initializer */ 205 void prsgini(prscxdef *ctx, prsndef *node, uint curfr); 206 207 /* check for and skip a required token */ 208 void prsreq(prscxdef *ctx, int t); 209 210 /* get next token, require it to be a particular value, then skip it */ 211 void prsnreq(prscxdef *ctx, int t); 212 213 /* START parsing an expression - resets node pool */ 214 prsndef *prsexpr(prscxdef *ctx); 215 216 /* allocate space in the parse node area */ 217 uchar *prsbalo(prscxdef *ctx, uint siz); 218 219 /* build a quad operator node */ 220 prsndef *prsnew4(prscxdef *ctx, int t, prsndef *n1, prsndef *n2, 221 prsndef *n3, prsndef *n4); 222 223 /* build a tertiary operator node */ 224 prsndef *prsnew3(prscxdef *ctx, int t, prsndef *n1, prsndef *n2, 225 prsndef *n3); 226 227 /* build a binary operator node */ 228 prsndef *prsnew2(prscxdef *ctx, int t, prsndef *n1, 229 prsndef *n2); 230 231 /* build a unary operator node */ 232 prsndef *prsnew1(prscxdef *ctx, int t, prsndef *n); 233 234 /* build a new value node */ 235 prsndef *prsnew0(prscxdef *ctx, tokdef *tokp); 236 237 /* start parsing an initializer expression (resets node pool) */ 238 prsndef *prsxini(prscxdef *ctx); 239 240 241 #endif /* PRS_INCLUDED */ 242