xref: /AOO41X/main/soltools/cpp/_eval.c (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir #include "cpp.h"
2*cdf0e10cSrcweir 
3*cdf0e10cSrcweir #include <stdlib.h>
4*cdf0e10cSrcweir #include <string.h>
5*cdf0e10cSrcweir 
6*cdf0e10cSrcweir #define	NSTAK	32
7*cdf0e10cSrcweir #define	SGN	0
8*cdf0e10cSrcweir #define	UNS	1
9*cdf0e10cSrcweir #define	UND	2
10*cdf0e10cSrcweir 
11*cdf0e10cSrcweir #define	UNSMARK	0x1000
12*cdf0e10cSrcweir 
13*cdf0e10cSrcweir struct value
14*cdf0e10cSrcweir {
15*cdf0e10cSrcweir     long val;
16*cdf0e10cSrcweir     int type;
17*cdf0e10cSrcweir };
18*cdf0e10cSrcweir 
19*cdf0e10cSrcweir /* conversion types */
20*cdf0e10cSrcweir #define	RELAT	1
21*cdf0e10cSrcweir #define	ARITH	2
22*cdf0e10cSrcweir #define	LOGIC	3
23*cdf0e10cSrcweir #define	SPCL	4
24*cdf0e10cSrcweir #define	SHIFT	5
25*cdf0e10cSrcweir #define	UNARY	6
26*cdf0e10cSrcweir 
27*cdf0e10cSrcweir /* operator priority, arity, and conversion type, indexed by tokentype */
28*cdf0e10cSrcweir struct pri
29*cdf0e10cSrcweir {
30*cdf0e10cSrcweir     char pri;
31*cdf0e10cSrcweir     char arity;
32*cdf0e10cSrcweir     char ctype;
33*cdf0e10cSrcweir }   priority[] =
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir {
36*cdf0e10cSrcweir     {
37*cdf0e10cSrcweir         0, 0, 0
38*cdf0e10cSrcweir     },                                  /* END */
39*cdf0e10cSrcweir     {
40*cdf0e10cSrcweir         0, 0, 0
41*cdf0e10cSrcweir     },                                  /* UNCLASS */
42*cdf0e10cSrcweir     {
43*cdf0e10cSrcweir         0, 0, 0
44*cdf0e10cSrcweir     },                                  /* NAME */
45*cdf0e10cSrcweir     {
46*cdf0e10cSrcweir         0, 0, 0
47*cdf0e10cSrcweir     },                                  /* NUMBER */
48*cdf0e10cSrcweir     {
49*cdf0e10cSrcweir         0, 0, 0
50*cdf0e10cSrcweir     },                                  /* STRING */
51*cdf0e10cSrcweir     {
52*cdf0e10cSrcweir         0, 0, 0
53*cdf0e10cSrcweir     },                                  /* CCON */
54*cdf0e10cSrcweir     {
55*cdf0e10cSrcweir         0, 0, 0
56*cdf0e10cSrcweir     },                                  /* NL */
57*cdf0e10cSrcweir     {
58*cdf0e10cSrcweir         0, 0, 0
59*cdf0e10cSrcweir     },                                  /* WS */
60*cdf0e10cSrcweir     {
61*cdf0e10cSrcweir         0, 0, 0
62*cdf0e10cSrcweir     },                                  /* DSHARP */
63*cdf0e10cSrcweir     {
64*cdf0e10cSrcweir         11, 2, RELAT
65*cdf0e10cSrcweir     },                                  /* EQ */
66*cdf0e10cSrcweir     {
67*cdf0e10cSrcweir         11, 2, RELAT
68*cdf0e10cSrcweir     },                                  /* NEQ */
69*cdf0e10cSrcweir     {
70*cdf0e10cSrcweir         12, 2, RELAT
71*cdf0e10cSrcweir     },                                  /* LEQ */
72*cdf0e10cSrcweir     {
73*cdf0e10cSrcweir         12, 2, RELAT
74*cdf0e10cSrcweir     },                                  /* GEQ */
75*cdf0e10cSrcweir     {
76*cdf0e10cSrcweir         13, 2, SHIFT
77*cdf0e10cSrcweir     },                                  /* LSH */
78*cdf0e10cSrcweir     {
79*cdf0e10cSrcweir         13, 2, SHIFT
80*cdf0e10cSrcweir     },                                  /* RSH */
81*cdf0e10cSrcweir     {
82*cdf0e10cSrcweir         7, 2, LOGIC
83*cdf0e10cSrcweir     },                                  /* LAND */
84*cdf0e10cSrcweir     {
85*cdf0e10cSrcweir         6, 2, LOGIC
86*cdf0e10cSrcweir     },                                  /* LOR */
87*cdf0e10cSrcweir     {
88*cdf0e10cSrcweir         0, 0, 0
89*cdf0e10cSrcweir     },                                  /* PPLUS */
90*cdf0e10cSrcweir     {
91*cdf0e10cSrcweir         0, 0, 0
92*cdf0e10cSrcweir     },                                  /* MMINUS */
93*cdf0e10cSrcweir     {
94*cdf0e10cSrcweir         0, 0, 0
95*cdf0e10cSrcweir     },                                  /* ARROW */
96*cdf0e10cSrcweir     {
97*cdf0e10cSrcweir         0, 0, 0
98*cdf0e10cSrcweir     },                                  /* SBRA */
99*cdf0e10cSrcweir     {
100*cdf0e10cSrcweir         0, 0, 0
101*cdf0e10cSrcweir     },                                  /* SKET */
102*cdf0e10cSrcweir     {
103*cdf0e10cSrcweir         3, 0, 0
104*cdf0e10cSrcweir     },                                  /* LP */
105*cdf0e10cSrcweir     {
106*cdf0e10cSrcweir         3, 0, 0
107*cdf0e10cSrcweir     },                                  /* RP */
108*cdf0e10cSrcweir     {
109*cdf0e10cSrcweir         0, 0, 0
110*cdf0e10cSrcweir     },                                  /* DOT */
111*cdf0e10cSrcweir     {
112*cdf0e10cSrcweir         10, 2, ARITH
113*cdf0e10cSrcweir     },                                  /* AND */
114*cdf0e10cSrcweir     {
115*cdf0e10cSrcweir         15, 2, ARITH
116*cdf0e10cSrcweir     },                                  /* STAR */
117*cdf0e10cSrcweir     {
118*cdf0e10cSrcweir         14, 2, ARITH
119*cdf0e10cSrcweir     },                                  /* PLUS */
120*cdf0e10cSrcweir     {
121*cdf0e10cSrcweir         14, 2, ARITH
122*cdf0e10cSrcweir     },                                  /* MINUS */
123*cdf0e10cSrcweir     {
124*cdf0e10cSrcweir         16, 1, UNARY
125*cdf0e10cSrcweir     },                                  /* TILDE */
126*cdf0e10cSrcweir     {
127*cdf0e10cSrcweir         16, 1, UNARY
128*cdf0e10cSrcweir     },                                  /* NOT */
129*cdf0e10cSrcweir     {
130*cdf0e10cSrcweir         15, 2, ARITH
131*cdf0e10cSrcweir     },                                  /* SLASH */
132*cdf0e10cSrcweir     {
133*cdf0e10cSrcweir         15, 2, ARITH
134*cdf0e10cSrcweir     },                                  /* PCT */
135*cdf0e10cSrcweir     {
136*cdf0e10cSrcweir         12, 2, RELAT
137*cdf0e10cSrcweir     },                                  /* LT */
138*cdf0e10cSrcweir     {
139*cdf0e10cSrcweir         12, 2, RELAT
140*cdf0e10cSrcweir     },                                  /* GT */
141*cdf0e10cSrcweir     {
142*cdf0e10cSrcweir         9, 2, ARITH
143*cdf0e10cSrcweir     },                                  /* CIRC */
144*cdf0e10cSrcweir     {
145*cdf0e10cSrcweir         8, 2, ARITH
146*cdf0e10cSrcweir     },                                  /* OR */
147*cdf0e10cSrcweir     {
148*cdf0e10cSrcweir         5, 2, SPCL
149*cdf0e10cSrcweir     },                                  /* QUEST */
150*cdf0e10cSrcweir     {
151*cdf0e10cSrcweir         5, 2, SPCL
152*cdf0e10cSrcweir     },                                  /* COLON */
153*cdf0e10cSrcweir     {
154*cdf0e10cSrcweir         0, 0, 0
155*cdf0e10cSrcweir     },                                  /* ASGN */
156*cdf0e10cSrcweir     {
157*cdf0e10cSrcweir         4, 2, 0
158*cdf0e10cSrcweir     },                                  /* COMMA */
159*cdf0e10cSrcweir     {
160*cdf0e10cSrcweir         0, 0, 0
161*cdf0e10cSrcweir     },                                  /* SHARP */
162*cdf0e10cSrcweir     {
163*cdf0e10cSrcweir         0, 0, 0
164*cdf0e10cSrcweir     },                                  /* SEMIC */
165*cdf0e10cSrcweir     {
166*cdf0e10cSrcweir         0, 0, 0
167*cdf0e10cSrcweir     },                                  /* CBRA */
168*cdf0e10cSrcweir     {
169*cdf0e10cSrcweir         0, 0, 0
170*cdf0e10cSrcweir     },                                  /* CKET */
171*cdf0e10cSrcweir     {
172*cdf0e10cSrcweir         0, 0, 0
173*cdf0e10cSrcweir     },                                  /* ASPLUS */
174*cdf0e10cSrcweir     {
175*cdf0e10cSrcweir         0, 0, 0
176*cdf0e10cSrcweir     },                                  /* ASMINUS */
177*cdf0e10cSrcweir     {
178*cdf0e10cSrcweir         0, 0, 0
179*cdf0e10cSrcweir     },                                  /* ASSTAR */
180*cdf0e10cSrcweir     {
181*cdf0e10cSrcweir         0, 0, 0
182*cdf0e10cSrcweir     },                                  /* ASSLASH */
183*cdf0e10cSrcweir     {
184*cdf0e10cSrcweir         0, 0, 0
185*cdf0e10cSrcweir     },                                  /* ASPCT */
186*cdf0e10cSrcweir     {
187*cdf0e10cSrcweir         0, 0, 0
188*cdf0e10cSrcweir     },                                  /* ASCIRC */
189*cdf0e10cSrcweir     {
190*cdf0e10cSrcweir         0, 0, 0
191*cdf0e10cSrcweir     },                                  /* ASLSH */
192*cdf0e10cSrcweir     {
193*cdf0e10cSrcweir         0, 0, 0
194*cdf0e10cSrcweir     },                                  /* ASRSH */
195*cdf0e10cSrcweir     {
196*cdf0e10cSrcweir         0, 0, 0
197*cdf0e10cSrcweir     },                                  /* ASOR */
198*cdf0e10cSrcweir     {
199*cdf0e10cSrcweir         0, 0, 0
200*cdf0e10cSrcweir     },                                  /* ASAND */
201*cdf0e10cSrcweir     {
202*cdf0e10cSrcweir         0, 0, 0
203*cdf0e10cSrcweir     },                                  /* ELLIPS */
204*cdf0e10cSrcweir     {
205*cdf0e10cSrcweir         0, 0, 0
206*cdf0e10cSrcweir     },                                  /* DSHARP1 */
207*cdf0e10cSrcweir     {
208*cdf0e10cSrcweir         0, 0, 0
209*cdf0e10cSrcweir     },                                  /* NAME1 */
210*cdf0e10cSrcweir     {
211*cdf0e10cSrcweir         0, 0, 0
212*cdf0e10cSrcweir     },                                  /* NAME2 */
213*cdf0e10cSrcweir     {
214*cdf0e10cSrcweir         16, 1, UNARY
215*cdf0e10cSrcweir     },                                  /* DEFINED */
216*cdf0e10cSrcweir     {
217*cdf0e10cSrcweir         16, 0, UNARY
218*cdf0e10cSrcweir     },                                  /* UMINUS */
219*cdf0e10cSrcweir     {
220*cdf0e10cSrcweir         16, 1, UNARY
221*cdf0e10cSrcweir     },                                  /* ARCHITECTURE */
222*cdf0e10cSrcweir };
223*cdf0e10cSrcweir 
224*cdf0e10cSrcweir int evalop(struct pri);
225*cdf0e10cSrcweir struct value tokval(Token *);
226*cdf0e10cSrcweir struct value vals[NSTAK], *vp;
227*cdf0e10cSrcweir enum toktype ops[NSTAK], *op;
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir /*
230*cdf0e10cSrcweir  * Evaluate an #if #elif #ifdef #ifndef line.  trp->tp points to the keyword.
231*cdf0e10cSrcweir  */
232*cdf0e10cSrcweir long
233*cdf0e10cSrcweir     eval(Tokenrow * trp, int kw)
234*cdf0e10cSrcweir {
235*cdf0e10cSrcweir     Token *tp;
236*cdf0e10cSrcweir     Nlist *np;
237*cdf0e10cSrcweir     int ntok, rnd;
238*cdf0e10cSrcweir 
239*cdf0e10cSrcweir     trp->tp++;
240*cdf0e10cSrcweir     if (kw == KIFDEF || kw == KIFNDEF)
241*cdf0e10cSrcweir     {
242*cdf0e10cSrcweir         if (trp->lp - trp->bp != 4 || trp->tp->type != NAME)
243*cdf0e10cSrcweir         {
244*cdf0e10cSrcweir             error(ERROR, "Syntax error in #ifdef/#ifndef");
245*cdf0e10cSrcweir             return 0;
246*cdf0e10cSrcweir         }
247*cdf0e10cSrcweir         np = lookup(trp->tp, 0);
248*cdf0e10cSrcweir         return (kw == KIFDEF) == (np && np->flag & (ISDEFINED | ISMAC));
249*cdf0e10cSrcweir     }
250*cdf0e10cSrcweir     ntok = trp->tp - trp->bp;
251*cdf0e10cSrcweir     kwdefined->val = KDEFINED;          /* activate special meaning of
252*cdf0e10cSrcweir                                          * defined */
253*cdf0e10cSrcweir     expandrow(trp, "<if>");
254*cdf0e10cSrcweir     kwdefined->val = NAME;
255*cdf0e10cSrcweir     vp = vals;
256*cdf0e10cSrcweir     op = ops;
257*cdf0e10cSrcweir     *op++ = END;
258*cdf0e10cSrcweir     for (rnd = 0, tp = trp->bp + ntok; tp < trp->lp; tp++)
259*cdf0e10cSrcweir     {
260*cdf0e10cSrcweir         switch (tp->type)
261*cdf0e10cSrcweir         {
262*cdf0e10cSrcweir             case WS:
263*cdf0e10cSrcweir             case NL:
264*cdf0e10cSrcweir                 continue;
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir                 /* nilary */
267*cdf0e10cSrcweir             case NAME:
268*cdf0e10cSrcweir             case NAME1:
269*cdf0e10cSrcweir             case NAME2:
270*cdf0e10cSrcweir             case NUMBER:
271*cdf0e10cSrcweir             case CCON:
272*cdf0e10cSrcweir             case STRING:
273*cdf0e10cSrcweir                 if (rnd)
274*cdf0e10cSrcweir                     goto syntax;
275*cdf0e10cSrcweir                 *vp++ = tokval(tp);
276*cdf0e10cSrcweir                 rnd = 1;
277*cdf0e10cSrcweir                 continue;
278*cdf0e10cSrcweir 
279*cdf0e10cSrcweir                 /* unary */
280*cdf0e10cSrcweir             case DEFINED:
281*cdf0e10cSrcweir             case TILDE:
282*cdf0e10cSrcweir             case NOT:
283*cdf0e10cSrcweir                 if (rnd)
284*cdf0e10cSrcweir                     goto syntax;
285*cdf0e10cSrcweir                 *op++ = tp->type;
286*cdf0e10cSrcweir                 continue;
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir                 /* unary-binary */
289*cdf0e10cSrcweir             case PLUS:
290*cdf0e10cSrcweir             case MINUS:
291*cdf0e10cSrcweir             case STAR:
292*cdf0e10cSrcweir             case AND:
293*cdf0e10cSrcweir                 if (rnd == 0)
294*cdf0e10cSrcweir                 {
295*cdf0e10cSrcweir                     if (tp->type == MINUS)
296*cdf0e10cSrcweir                         *op++ = UMINUS;
297*cdf0e10cSrcweir                     if (tp->type == STAR || tp->type == AND)
298*cdf0e10cSrcweir                     {
299*cdf0e10cSrcweir                         error(ERROR, "Illegal operator * or & in #if/#elsif");
300*cdf0e10cSrcweir                         return 0;
301*cdf0e10cSrcweir                     }
302*cdf0e10cSrcweir                     continue;
303*cdf0e10cSrcweir                 }
304*cdf0e10cSrcweir                 /* flow through */
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir                 /* plain binary */
307*cdf0e10cSrcweir             case EQ:
308*cdf0e10cSrcweir             case NEQ:
309*cdf0e10cSrcweir             case LEQ:
310*cdf0e10cSrcweir             case GEQ:
311*cdf0e10cSrcweir             case LSH:
312*cdf0e10cSrcweir             case RSH:
313*cdf0e10cSrcweir             case LAND:
314*cdf0e10cSrcweir             case LOR:
315*cdf0e10cSrcweir             case SLASH:
316*cdf0e10cSrcweir             case PCT:
317*cdf0e10cSrcweir             case LT:
318*cdf0e10cSrcweir             case GT:
319*cdf0e10cSrcweir             case CIRC:
320*cdf0e10cSrcweir             case OR:
321*cdf0e10cSrcweir             case QUEST:
322*cdf0e10cSrcweir             case COLON:
323*cdf0e10cSrcweir             case COMMA:
324*cdf0e10cSrcweir                 if (rnd == 0)
325*cdf0e10cSrcweir                     goto syntax;
326*cdf0e10cSrcweir                 if (evalop(priority[tp->type]) != 0)
327*cdf0e10cSrcweir                     return 0;
328*cdf0e10cSrcweir                 *op++ = tp->type;
329*cdf0e10cSrcweir                 rnd = 0;
330*cdf0e10cSrcweir                 continue;
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir             case LP:
333*cdf0e10cSrcweir                 if (rnd)
334*cdf0e10cSrcweir                     goto syntax;
335*cdf0e10cSrcweir                 *op++ = LP;
336*cdf0e10cSrcweir                 continue;
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir             case RP:
339*cdf0e10cSrcweir                 if (!rnd)
340*cdf0e10cSrcweir                     goto syntax;
341*cdf0e10cSrcweir                 if (evalop(priority[RP]) != 0)
342*cdf0e10cSrcweir                     return 0;
343*cdf0e10cSrcweir                 if (op <= ops || op[-1] != LP)
344*cdf0e10cSrcweir                 {
345*cdf0e10cSrcweir                     goto syntax;
346*cdf0e10cSrcweir                 }
347*cdf0e10cSrcweir                 op--;
348*cdf0e10cSrcweir                 continue;
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir             case SHARP:
351*cdf0e10cSrcweir                 if ((tp + 1) < trp->lp)
352*cdf0e10cSrcweir                 {
353*cdf0e10cSrcweir                     np = lookup(tp + 1, 0);
354*cdf0e10cSrcweir                     if (np && (np->val == KMACHINE))
355*cdf0e10cSrcweir                     {
356*cdf0e10cSrcweir                         tp++;
357*cdf0e10cSrcweir                         if (rnd)
358*cdf0e10cSrcweir                             goto syntax;
359*cdf0e10cSrcweir                         *op++ = ARCHITECTURE;
360*cdf0e10cSrcweir                         continue;
361*cdf0e10cSrcweir                     }
362*cdf0e10cSrcweir                 }
363*cdf0e10cSrcweir                 /* fall through */
364*cdf0e10cSrcweir 
365*cdf0e10cSrcweir             default:
366*cdf0e10cSrcweir                 error(ERROR, "Bad operator (%t) in #if/#elsif", tp);
367*cdf0e10cSrcweir                 return 0;
368*cdf0e10cSrcweir         }
369*cdf0e10cSrcweir     }
370*cdf0e10cSrcweir     if (rnd == 0)
371*cdf0e10cSrcweir         goto syntax;
372*cdf0e10cSrcweir     if (evalop(priority[END]) != 0)
373*cdf0e10cSrcweir         return 0;
374*cdf0e10cSrcweir     if (op != &ops[1] || vp != &vals[1])
375*cdf0e10cSrcweir     {
376*cdf0e10cSrcweir         error(ERROR, "Botch in #if/#elsif");
377*cdf0e10cSrcweir         return 0;
378*cdf0e10cSrcweir     }
379*cdf0e10cSrcweir     if (vals[0].type == UND)
380*cdf0e10cSrcweir         error(ERROR, "Undefined expression value");
381*cdf0e10cSrcweir     return vals[0].val;
382*cdf0e10cSrcweir syntax:
383*cdf0e10cSrcweir     error(ERROR, "Syntax error in #if/#elsif");
384*cdf0e10cSrcweir     return 0;
385*cdf0e10cSrcweir }
386*cdf0e10cSrcweir 
387*cdf0e10cSrcweir int
388*cdf0e10cSrcweir     evalop(struct pri pri)
389*cdf0e10cSrcweir {
390*cdf0e10cSrcweir     struct value v1;
391*cdf0e10cSrcweir     struct value v2 = { 0, UND };
392*cdf0e10cSrcweir     long rv1, rv2;
393*cdf0e10cSrcweir     int rtype, oper;
394*cdf0e10cSrcweir 
395*cdf0e10cSrcweir     rv2 = 0;
396*cdf0e10cSrcweir     rtype = 0;
397*cdf0e10cSrcweir     while (pri.pri < priority[op[-1]].pri)
398*cdf0e10cSrcweir     {
399*cdf0e10cSrcweir         oper = *--op;
400*cdf0e10cSrcweir         if (priority[oper].arity == 2)
401*cdf0e10cSrcweir         {
402*cdf0e10cSrcweir             v2 = *--vp;
403*cdf0e10cSrcweir             rv2 = v2.val;
404*cdf0e10cSrcweir         }
405*cdf0e10cSrcweir         v1 = *--vp;
406*cdf0e10cSrcweir         rv1 = v1.val;
407*cdf0e10cSrcweir /*lint -e574 -e644 */
408*cdf0e10cSrcweir         switch (priority[oper].ctype)
409*cdf0e10cSrcweir         {
410*cdf0e10cSrcweir             case 0:
411*cdf0e10cSrcweir             default:
412*cdf0e10cSrcweir                 error(WARNING, "Syntax error in #if/#endif");
413*cdf0e10cSrcweir                 return 1;
414*cdf0e10cSrcweir             case ARITH:
415*cdf0e10cSrcweir             case RELAT:
416*cdf0e10cSrcweir                 if (v1.type == UNS || v2.type == UNS)
417*cdf0e10cSrcweir                     rtype = UNS;
418*cdf0e10cSrcweir                 else
419*cdf0e10cSrcweir                     rtype = SGN;
420*cdf0e10cSrcweir                 if (v1.type == UND || v2.type == UND)
421*cdf0e10cSrcweir                     rtype = UND;
422*cdf0e10cSrcweir                 if (priority[oper].ctype == RELAT && rtype == UNS)
423*cdf0e10cSrcweir                 {
424*cdf0e10cSrcweir                     oper |= UNSMARK;
425*cdf0e10cSrcweir                     rtype = SGN;
426*cdf0e10cSrcweir                 }
427*cdf0e10cSrcweir                 break;
428*cdf0e10cSrcweir             case SHIFT:
429*cdf0e10cSrcweir                 if (v1.type == UND || v2.type == UND)
430*cdf0e10cSrcweir                     rtype = UND;
431*cdf0e10cSrcweir                 else
432*cdf0e10cSrcweir                     rtype = v1.type;
433*cdf0e10cSrcweir                 if (rtype == UNS)
434*cdf0e10cSrcweir                     oper |= UNSMARK;
435*cdf0e10cSrcweir                 break;
436*cdf0e10cSrcweir             case UNARY:
437*cdf0e10cSrcweir                 rtype = v1.type;
438*cdf0e10cSrcweir                 break;
439*cdf0e10cSrcweir             case LOGIC:
440*cdf0e10cSrcweir             case SPCL:
441*cdf0e10cSrcweir                 break;
442*cdf0e10cSrcweir         }
443*cdf0e10cSrcweir         switch (oper)
444*cdf0e10cSrcweir         {
445*cdf0e10cSrcweir             case EQ:
446*cdf0e10cSrcweir             case EQ | UNSMARK:
447*cdf0e10cSrcweir                 rv1 = rv1 == rv2;
448*cdf0e10cSrcweir                 break;
449*cdf0e10cSrcweir             case NEQ:
450*cdf0e10cSrcweir             case NEQ | UNSMARK:
451*cdf0e10cSrcweir                 rv1 = rv1 != rv2;
452*cdf0e10cSrcweir                 break;
453*cdf0e10cSrcweir             case LEQ:
454*cdf0e10cSrcweir                 rv1 = rv1 <= rv2;
455*cdf0e10cSrcweir                 break;
456*cdf0e10cSrcweir             case GEQ:
457*cdf0e10cSrcweir                 rv1 = rv1 >= rv2;
458*cdf0e10cSrcweir                 break;
459*cdf0e10cSrcweir             case LT:
460*cdf0e10cSrcweir                 rv1 = rv1 < rv2;
461*cdf0e10cSrcweir                 break;
462*cdf0e10cSrcweir             case GT:
463*cdf0e10cSrcweir                 rv1 = rv1 > rv2;
464*cdf0e10cSrcweir                 break;
465*cdf0e10cSrcweir             case LEQ | UNSMARK:
466*cdf0e10cSrcweir                 rv1 = (unsigned long)rv1 <= (unsigned long)rv2;
467*cdf0e10cSrcweir                 break;
468*cdf0e10cSrcweir             case GEQ | UNSMARK:
469*cdf0e10cSrcweir                 rv1 = (unsigned long)rv1 >= (unsigned long)rv2;
470*cdf0e10cSrcweir                 break;
471*cdf0e10cSrcweir             case LT | UNSMARK:
472*cdf0e10cSrcweir                 rv1 = (unsigned long)rv1 < (unsigned long)rv2;
473*cdf0e10cSrcweir                 break;
474*cdf0e10cSrcweir             case GT | UNSMARK:
475*cdf0e10cSrcweir                 rv1 = (unsigned long)rv1 > (unsigned long)rv2;
476*cdf0e10cSrcweir                 break;
477*cdf0e10cSrcweir             case LSH:
478*cdf0e10cSrcweir                 rv1 <<= rv2;
479*cdf0e10cSrcweir                 break;
480*cdf0e10cSrcweir             case LSH | UNSMARK:
481*cdf0e10cSrcweir                 rv1 = (unsigned long) rv1 << rv2;
482*cdf0e10cSrcweir                 break;
483*cdf0e10cSrcweir             case RSH:
484*cdf0e10cSrcweir                 rv1 >>= rv2;
485*cdf0e10cSrcweir                 break;
486*cdf0e10cSrcweir             case RSH | UNSMARK:
487*cdf0e10cSrcweir                 rv1 = (unsigned long) rv1 >> rv2;
488*cdf0e10cSrcweir                 break;
489*cdf0e10cSrcweir             case LAND:
490*cdf0e10cSrcweir                 rtype = UND;
491*cdf0e10cSrcweir                 if (v1.type == UND)
492*cdf0e10cSrcweir                     break;
493*cdf0e10cSrcweir                 if (rv1 != 0)
494*cdf0e10cSrcweir                 {
495*cdf0e10cSrcweir                     if (v2.type == UND)
496*cdf0e10cSrcweir                         break;
497*cdf0e10cSrcweir                     rv1 = rv2 != 0;
498*cdf0e10cSrcweir                 }
499*cdf0e10cSrcweir                 else
500*cdf0e10cSrcweir                     rv1 = 0;
501*cdf0e10cSrcweir                 rtype = SGN;
502*cdf0e10cSrcweir                 break;
503*cdf0e10cSrcweir             case LOR:
504*cdf0e10cSrcweir                 rtype = UND;
505*cdf0e10cSrcweir                 if (v1.type == UND)
506*cdf0e10cSrcweir                     break;
507*cdf0e10cSrcweir                 if (rv1 == 0)
508*cdf0e10cSrcweir                 {
509*cdf0e10cSrcweir                     if (v2.type == UND)
510*cdf0e10cSrcweir                         break;
511*cdf0e10cSrcweir                     rv1 = rv2 != 0;
512*cdf0e10cSrcweir                 }
513*cdf0e10cSrcweir                 else
514*cdf0e10cSrcweir                     rv1 = 1;
515*cdf0e10cSrcweir                 rtype = SGN;
516*cdf0e10cSrcweir                 break;
517*cdf0e10cSrcweir             case AND:
518*cdf0e10cSrcweir                 rv1 &= rv2;
519*cdf0e10cSrcweir                 break;
520*cdf0e10cSrcweir             case STAR:
521*cdf0e10cSrcweir                 rv1 *= rv2;
522*cdf0e10cSrcweir                 break;
523*cdf0e10cSrcweir             case PLUS:
524*cdf0e10cSrcweir                 rv1 += rv2;
525*cdf0e10cSrcweir                 break;
526*cdf0e10cSrcweir             case MINUS:
527*cdf0e10cSrcweir                 rv1 -= rv2;
528*cdf0e10cSrcweir                 break;
529*cdf0e10cSrcweir             case UMINUS:
530*cdf0e10cSrcweir                 if (v1.type == UND)
531*cdf0e10cSrcweir                     rtype = UND;
532*cdf0e10cSrcweir                 rv1 = -rv1;
533*cdf0e10cSrcweir                 break;
534*cdf0e10cSrcweir             case OR:
535*cdf0e10cSrcweir                 rv1 |= rv2;
536*cdf0e10cSrcweir                 break;
537*cdf0e10cSrcweir             case CIRC:
538*cdf0e10cSrcweir                 rv1 ^= rv2;
539*cdf0e10cSrcweir                 break;
540*cdf0e10cSrcweir             case TILDE:
541*cdf0e10cSrcweir                 rv1 = ~rv1;
542*cdf0e10cSrcweir                 break;
543*cdf0e10cSrcweir             case NOT:
544*cdf0e10cSrcweir                 rv1 = !rv1;
545*cdf0e10cSrcweir                 if (rtype != UND)
546*cdf0e10cSrcweir                     rtype = SGN;
547*cdf0e10cSrcweir                 break;
548*cdf0e10cSrcweir             case SLASH:
549*cdf0e10cSrcweir                 if (rv2 == 0)
550*cdf0e10cSrcweir                 {
551*cdf0e10cSrcweir                     rtype = UND;
552*cdf0e10cSrcweir                     break;
553*cdf0e10cSrcweir                 }
554*cdf0e10cSrcweir                 if (rtype == UNS)
555*cdf0e10cSrcweir                     rv1 /= (unsigned long) rv2;
556*cdf0e10cSrcweir                 else
557*cdf0e10cSrcweir                     rv1 /= rv2;
558*cdf0e10cSrcweir                 break;
559*cdf0e10cSrcweir             case PCT:
560*cdf0e10cSrcweir                 if (rv2 == 0)
561*cdf0e10cSrcweir                 {
562*cdf0e10cSrcweir                     rtype = UND;
563*cdf0e10cSrcweir                     break;
564*cdf0e10cSrcweir                 }
565*cdf0e10cSrcweir                 if (rtype == UNS)
566*cdf0e10cSrcweir                     rv1 %= (unsigned long) rv2;
567*cdf0e10cSrcweir                 else
568*cdf0e10cSrcweir                     rv1 %= rv2;
569*cdf0e10cSrcweir                 break;
570*cdf0e10cSrcweir             case COLON:
571*cdf0e10cSrcweir                 if (op[-1] != QUEST)
572*cdf0e10cSrcweir                     error(ERROR, "Bad ?: in #if/endif");
573*cdf0e10cSrcweir                 else
574*cdf0e10cSrcweir                 {
575*cdf0e10cSrcweir                     op--;
576*cdf0e10cSrcweir                     if ((--vp)->val == 0)
577*cdf0e10cSrcweir                         v1 = v2;
578*cdf0e10cSrcweir                     rtype = v1.type;
579*cdf0e10cSrcweir                     rv1 = v1.val;
580*cdf0e10cSrcweir                 }
581*cdf0e10cSrcweir                 break;
582*cdf0e10cSrcweir 
583*cdf0e10cSrcweir             case DEFINED:
584*cdf0e10cSrcweir             case ARCHITECTURE:
585*cdf0e10cSrcweir                 break;
586*cdf0e10cSrcweir 
587*cdf0e10cSrcweir             default:
588*cdf0e10cSrcweir                 error(ERROR, "Eval botch (unknown operator)");
589*cdf0e10cSrcweir                 return 1;
590*cdf0e10cSrcweir         }
591*cdf0e10cSrcweir /*lint +e574 +e644 */
592*cdf0e10cSrcweir         v1.val = rv1;
593*cdf0e10cSrcweir         v1.type = rtype;
594*cdf0e10cSrcweir         *vp++ = v1;
595*cdf0e10cSrcweir     }
596*cdf0e10cSrcweir     return 0;
597*cdf0e10cSrcweir }
598*cdf0e10cSrcweir 
599*cdf0e10cSrcweir struct value
600*cdf0e10cSrcweir     tokval(Token * tp)
601*cdf0e10cSrcweir {
602*cdf0e10cSrcweir     struct value v;
603*cdf0e10cSrcweir     Nlist *np;
604*cdf0e10cSrcweir     int i, base;
605*cdf0e10cSrcweir     unsigned long n;
606*cdf0e10cSrcweir     uchar *p, c;
607*cdf0e10cSrcweir 
608*cdf0e10cSrcweir     v.type = SGN;
609*cdf0e10cSrcweir     v.val = 0;
610*cdf0e10cSrcweir     switch (tp->type)
611*cdf0e10cSrcweir     {
612*cdf0e10cSrcweir 
613*cdf0e10cSrcweir         case NAME:
614*cdf0e10cSrcweir             v.val = 0;
615*cdf0e10cSrcweir             break;
616*cdf0e10cSrcweir 
617*cdf0e10cSrcweir         case NAME1:
618*cdf0e10cSrcweir             if ((np = lookup(tp, 0)) != NULL && np->flag & (ISDEFINED | ISMAC))
619*cdf0e10cSrcweir                 v.val = 1;
620*cdf0e10cSrcweir             break;
621*cdf0e10cSrcweir 
622*cdf0e10cSrcweir         case NAME2:
623*cdf0e10cSrcweir             if ((np = lookup(tp, 0)) != NULL && np->flag & (ISARCHITECTURE))
624*cdf0e10cSrcweir                 v.val = 1;
625*cdf0e10cSrcweir             break;
626*cdf0e10cSrcweir 
627*cdf0e10cSrcweir         case NUMBER:
628*cdf0e10cSrcweir             n = 0;
629*cdf0e10cSrcweir             base = 10;
630*cdf0e10cSrcweir             p = tp->t;
631*cdf0e10cSrcweir             c = p[tp->len];
632*cdf0e10cSrcweir             p[tp->len] = '\0';
633*cdf0e10cSrcweir             if (*p == '0')
634*cdf0e10cSrcweir             {
635*cdf0e10cSrcweir                 base = 8;
636*cdf0e10cSrcweir                 if (p[1] == 'x' || p[1] == 'X')
637*cdf0e10cSrcweir                 {
638*cdf0e10cSrcweir                     base = 16;
639*cdf0e10cSrcweir                     p++;
640*cdf0e10cSrcweir                 }
641*cdf0e10cSrcweir                 p++;
642*cdf0e10cSrcweir             }
643*cdf0e10cSrcweir             for (;; p++)
644*cdf0e10cSrcweir             {
645*cdf0e10cSrcweir                 if ((i = digit(*p)) < 0)
646*cdf0e10cSrcweir                     break;
647*cdf0e10cSrcweir                 if (i >= base)
648*cdf0e10cSrcweir                     error(WARNING,
649*cdf0e10cSrcweir                           "Bad digit in number %t", tp);
650*cdf0e10cSrcweir                 n *= base;
651*cdf0e10cSrcweir                 n += i;
652*cdf0e10cSrcweir             }
653*cdf0e10cSrcweir             if (n >= 0x80000000 && base != 10)
654*cdf0e10cSrcweir                 v.type = UNS;
655*cdf0e10cSrcweir             for (; *p; p++)
656*cdf0e10cSrcweir             {
657*cdf0e10cSrcweir                 if (*p == 'u' || *p == 'U')
658*cdf0e10cSrcweir                     v.type = UNS;
659*cdf0e10cSrcweir                 else
660*cdf0e10cSrcweir                     if (*p == 'l' || *p == 'L')
661*cdf0e10cSrcweir                         ;
662*cdf0e10cSrcweir                     else
663*cdf0e10cSrcweir                     {
664*cdf0e10cSrcweir                         error(ERROR,
665*cdf0e10cSrcweir                               "Bad number %t in #if/#elsif", tp);
666*cdf0e10cSrcweir                         break;
667*cdf0e10cSrcweir                     }
668*cdf0e10cSrcweir             }
669*cdf0e10cSrcweir             v.val = n;
670*cdf0e10cSrcweir             tp->t[tp->len] = c;
671*cdf0e10cSrcweir             break;
672*cdf0e10cSrcweir 
673*cdf0e10cSrcweir         case CCON:
674*cdf0e10cSrcweir             n = 0;
675*cdf0e10cSrcweir             p = tp->t;
676*cdf0e10cSrcweir             if (*p == 'L')
677*cdf0e10cSrcweir             {
678*cdf0e10cSrcweir                 p += 1;
679*cdf0e10cSrcweir                 error(WARNING, "Wide char constant value undefined");
680*cdf0e10cSrcweir             }
681*cdf0e10cSrcweir             p += 1;
682*cdf0e10cSrcweir             if (*p == '\\')
683*cdf0e10cSrcweir             {
684*cdf0e10cSrcweir                 p += 1;
685*cdf0e10cSrcweir                 if ((i = digit(*p)) >= 0 && i <= 7)
686*cdf0e10cSrcweir                 {
687*cdf0e10cSrcweir                     n = i;
688*cdf0e10cSrcweir                     p += 1;
689*cdf0e10cSrcweir                     if ((i = digit(*p)) >= 0 && i <= 7)
690*cdf0e10cSrcweir                     {
691*cdf0e10cSrcweir                         p += 1;
692*cdf0e10cSrcweir                         n <<= 3;
693*cdf0e10cSrcweir                         n += i;
694*cdf0e10cSrcweir                         if ((i = digit(*p)) >= 0 && i <= 7)
695*cdf0e10cSrcweir                         {
696*cdf0e10cSrcweir                             p += 1;
697*cdf0e10cSrcweir                             n <<= 3;
698*cdf0e10cSrcweir                             n += i;
699*cdf0e10cSrcweir                         }
700*cdf0e10cSrcweir                     }
701*cdf0e10cSrcweir                 }
702*cdf0e10cSrcweir                 else
703*cdf0e10cSrcweir                     if (*p == 'x')
704*cdf0e10cSrcweir                     {
705*cdf0e10cSrcweir                         p += 1;
706*cdf0e10cSrcweir                         while ((i = digit(*p)) >= 0 && i <= 15)
707*cdf0e10cSrcweir                         {
708*cdf0e10cSrcweir                             p += 1;
709*cdf0e10cSrcweir                             n <<= 4;
710*cdf0e10cSrcweir                             n += i;
711*cdf0e10cSrcweir                         }
712*cdf0e10cSrcweir                     }
713*cdf0e10cSrcweir                     else
714*cdf0e10cSrcweir                     {
715*cdf0e10cSrcweir                         static char cvcon[] = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\";
716*cdf0e10cSrcweir                         static size_t cvlen = sizeof(cvcon) - 1;
717*cdf0e10cSrcweir 
718*cdf0e10cSrcweir                         size_t j;
719*cdf0e10cSrcweir                         for (j = 0; j < cvlen; j += 2)
720*cdf0e10cSrcweir                         {
721*cdf0e10cSrcweir                             if (*p == cvcon[j])
722*cdf0e10cSrcweir                             {
723*cdf0e10cSrcweir                                 n = cvcon[j + 1];
724*cdf0e10cSrcweir                                 break;
725*cdf0e10cSrcweir                             }
726*cdf0e10cSrcweir                         }
727*cdf0e10cSrcweir                         p += 1;
728*cdf0e10cSrcweir                         if (j >= cvlen)
729*cdf0e10cSrcweir                             error(WARNING,
730*cdf0e10cSrcweir                                "Undefined escape in character constant");
731*cdf0e10cSrcweir                     }
732*cdf0e10cSrcweir             }
733*cdf0e10cSrcweir             else
734*cdf0e10cSrcweir                 if (*p == '\'')
735*cdf0e10cSrcweir                     error(ERROR, "Empty character constant");
736*cdf0e10cSrcweir                 else
737*cdf0e10cSrcweir                     n = *p++;
738*cdf0e10cSrcweir             if (*p != '\'')
739*cdf0e10cSrcweir                 error(WARNING, "Multibyte character constant undefined");
740*cdf0e10cSrcweir             else
741*cdf0e10cSrcweir                 if (n > 127)
742*cdf0e10cSrcweir                     error(WARNING, "Character constant taken as not signed");
743*cdf0e10cSrcweir             v.val = n;
744*cdf0e10cSrcweir             break;
745*cdf0e10cSrcweir 
746*cdf0e10cSrcweir         case STRING:
747*cdf0e10cSrcweir             error(ERROR, "String in #if/#elsif");
748*cdf0e10cSrcweir             break;
749*cdf0e10cSrcweir     }
750*cdf0e10cSrcweir     return v;
751*cdf0e10cSrcweir }
752*cdf0e10cSrcweir 
753*cdf0e10cSrcweir int
754*cdf0e10cSrcweir     digit(int i)
755*cdf0e10cSrcweir {
756*cdf0e10cSrcweir     if ('0' <= i && i <= '9')
757*cdf0e10cSrcweir         i -= '0';
758*cdf0e10cSrcweir     else
759*cdf0e10cSrcweir         if ('a' <= i && i <= 'f')
760*cdf0e10cSrcweir             i -= 'a' - 10;
761*cdf0e10cSrcweir         else
762*cdf0e10cSrcweir             if ('A' <= i && i <= 'F')
763*cdf0e10cSrcweir                 i -= 'A' - 10;
764*cdf0e10cSrcweir             else
765*cdf0e10cSrcweir                 i = -1;
766*cdf0e10cSrcweir     return i;
767*cdf0e10cSrcweir }
768