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