OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [lcc/] [cpp/] [eval.c] - Blame information for rev 112

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 hellwig
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
#include "cpp.h"
5
 
6
#define NSTAK   32
7
#define SGN     0
8
#define UNS     1
9
#define UND     2
10
 
11
#define UNSMARK 0x1000
12
 
13
struct value {
14
        long    val;
15
        int     type;
16
};
17
 
18
/* conversion types */
19
#define RELAT   1
20
#define ARITH   2
21
#define LOGIC   3
22
#define SPCL    4
23
#define SHIFT   5
24
#define UNARY   6
25
 
26
/* operator priority, arity, and conversion type, indexed by tokentype */
27
struct pri {
28
        char    pri;
29
        char    arity;
30
        char    ctype;
31
} priority[] = {
32
        { 0, 0, 0 },               /* END */
33
        { 0, 0, 0 },               /* UNCLASS */
34
        { 0, 0, 0 },               /* NAME */
35
        { 0, 0, 0 },               /* NUMBER */
36
        { 0, 0, 0 },               /* STRING */
37
        { 0, 0, 0 },               /* CCON */
38
        { 0, 0, 0 },               /* NL */
39
        { 0, 0, 0 },               /* WS */
40
        { 0, 0, 0 },               /* DSHARP */
41
        { 11, 2, RELAT },       /* EQ */
42
        { 11, 2, RELAT },       /* NEQ */
43
        { 12, 2, RELAT },       /* LEQ */
44
        { 12, 2, RELAT },       /* GEQ */
45
        { 13, 2, SHIFT },       /* LSH */
46
        { 13, 2, SHIFT },       /* RSH */
47
        { 7, 2, LOGIC },        /* LAND */
48
        { 6, 2, LOGIC },        /* LOR */
49
        { 0, 0, 0 },               /* PPLUS */
50
        { 0, 0, 0 },               /* MMINUS */
51
        { 0, 0, 0 },               /* ARROW */
52
        { 0, 0, 0 },               /* SBRA */
53
        { 0, 0, 0 },               /* SKET */
54
        { 3, 0, 0 },              /* LP */
55
        { 3, 0, 0 },              /* RP */
56
        { 0, 0, 0 },               /* DOT */
57
        { 10, 2, ARITH },       /* AND */
58
        { 15, 2, ARITH },       /* STAR */
59
        { 14, 2, ARITH },       /* PLUS */
60
        { 14, 2, ARITH },       /* MINUS */
61
        { 16, 1, UNARY },       /* TILDE */
62
        { 16, 1, UNARY },       /* NOT */
63
        { 15, 2, ARITH },       /* SLASH */
64
        { 15, 2, ARITH },       /* PCT */
65
        { 12, 2, RELAT },       /* LT */
66
        { 12, 2, RELAT },       /* GT */
67
        { 9, 2, ARITH },        /* CIRC */
68
        { 8, 2, ARITH },        /* OR */
69
        { 5, 2, SPCL },         /* QUEST */
70
        { 5, 2, SPCL },         /* COLON */
71
        { 0, 0, 0 },               /* ASGN */
72
        { 4, 2, 0 },             /* COMMA */
73
        { 0, 0, 0 },               /* SHARP */
74
        { 0, 0, 0 },               /* SEMIC */
75
        { 0, 0, 0 },               /* CBRA */
76
        { 0, 0, 0 },               /* CKET */
77
        { 0, 0, 0 },               /* ASPLUS */
78
        { 0, 0, 0 },               /* ASMINUS */
79
        { 0, 0, 0 },               /* ASSTAR */
80
        { 0, 0, 0 },               /* ASSLASH */
81
        { 0, 0, 0 },               /* ASPCT */
82
        { 0, 0, 0 },               /* ASCIRC */
83
        { 0, 0, 0 },               /* ASLSH */
84
        { 0, 0, 0 },               /* ASRSH */
85
        { 0, 0, 0 },               /* ASOR */
86
        { 0, 0, 0 },               /* ASAND */
87
        { 0, 0, 0 },               /* ELLIPS */
88
        { 0, 0, 0 },               /* DSHARP1 */
89
        { 0, 0, 0 },               /* NAME1 */
90
        { 16, 1, UNARY },       /* DEFINED */
91
        { 16, 0, UNARY },        /* UMINUS */
92
};
93
 
94
int     evalop(struct pri);
95
struct  value tokval(Token *);
96
struct value vals[NSTAK], *vp;
97
enum toktype ops[NSTAK], *op;
98
 
99
/*
100
 * Evaluate an #if #elif #ifdef #ifndef line.  trp->tp points to the keyword.
101
 */
102
long
103
eval(Tokenrow *trp, int kw)
104
{
105
        Token *tp;
106
        Nlist *np;
107
        int ntok, rand;
108
 
109
        trp->tp++;
110
        if (kw==KIFDEF || kw==KIFNDEF) {
111
                if (trp->lp - trp->bp != 4 || trp->tp->type!=NAME) {
112
                        error(ERROR, "Syntax error in #ifdef/#ifndef");
113
                        return 0;
114
                }
115
                np = lookup(trp->tp, 0);
116
                return (kw==KIFDEF) == (np && np->flag&(ISDEFINED|ISMAC));
117
        }
118
        ntok = trp->tp - trp->bp;
119
        kwdefined->val = KDEFINED;      /* activate special meaning of defined */
120
        expandrow(trp, "<if>");
121
        kwdefined->val = NAME;
122
        vp = vals;
123
        op = ops;
124
        *op++ = END;
125
        for (rand=0, tp = trp->bp+ntok; tp < trp->lp; tp++) {
126
                switch(tp->type) {
127
                case WS:
128
                case NL:
129
                        continue;
130
 
131
                /* nilary */
132
                case NAME:
133
                case NAME1:
134
                case NUMBER:
135
                case CCON:
136
                case STRING:
137
                        if (rand)
138
                                goto syntax;
139
                        if (vp == &vals[NSTAK]) {
140
                                error(ERROR, "Eval botch (stack overflow)");
141
                                return 0;
142
                        }
143
                        *vp++ = tokval(tp);
144
                        rand = 1;
145
                        continue;
146
 
147
                /* unary */
148
                case DEFINED:
149
                case TILDE:
150
                case NOT:
151
                        if (rand)
152
                                goto syntax;
153
                        *op++ = tp->type;
154
                        continue;
155
 
156
                /* unary-binary */
157
                case PLUS: case MINUS: case STAR: case AND:
158
                        if (rand==0) {
159
                                if (tp->type==MINUS)
160
                                        *op++ = UMINUS;
161
                                if (tp->type==STAR || tp->type==AND) {
162
                                        error(ERROR, "Illegal operator * or & in #if/#elsif");
163
                                        return 0;
164
                                }
165
                                continue;
166
                        }
167
                        /* flow through */
168
 
169
                /* plain binary */
170
                case EQ: case NEQ: case LEQ: case GEQ: case LSH: case RSH:
171
                case LAND: case LOR: case SLASH: case PCT:
172
                case LT: case GT: case CIRC: case OR: case QUEST:
173
                case COLON: case COMMA:
174
                        if (rand==0)
175
                                goto syntax;
176
                        if (evalop(priority[tp->type])!=0)
177
                                return 0;
178
                        *op++ = tp->type;
179
                        rand = 0;
180
                        continue;
181
 
182
                case LP:
183
                        if (rand)
184
                                goto syntax;
185
                        *op++ = LP;
186
                        continue;
187
 
188
                case RP:
189
                        if (!rand)
190
                                goto syntax;
191
                        if (evalop(priority[RP])!=0)
192
                                return 0;
193
                        if (op<=ops || op[-1]!=LP) {
194
                                goto syntax;
195
                        }
196
                        op--;
197
                        continue;
198
 
199
                default:
200
                        error(ERROR,"Bad operator (%t) in #if/#elsif", tp);
201
                        return 0;
202
                }
203
        }
204
        if (rand==0)
205
                goto syntax;
206
        if (evalop(priority[END])!=0)
207
                return 0;
208
        if (op!=&ops[1] || vp!=&vals[1]) {
209
                error(ERROR, "Botch in #if/#elsif");
210
                return 0;
211
        }
212
        if (vals[0].type==UND)
213
                error(ERROR, "Undefined expression value");
214
        return vals[0].val;
215
syntax:
216
        error(ERROR, "Syntax error in #if/#elsif");
217
        return 0;
218
}
219
 
220
int
221
evalop(struct pri pri)
222
{
223
        struct value v1, v2;
224
        long rv1, rv2;
225
        int rtype, oper;
226
 
227
        rv2=0;
228
        rtype=0;
229
        while (pri.pri < priority[op[-1]].pri) {
230
                oper = *--op;
231
                if (priority[oper].arity==2) {
232
                        v2 = *--vp;
233
                        rv2 = v2.val;
234
                }
235
                v1 = *--vp;
236
                rv1 = v1.val;
237
/*lint -e574 -e644 */
238
                switch (priority[oper].ctype) {
239
                case 0:
240
                default:
241
                        error(WARNING, "Syntax error in #if/#endif");
242
                        return 1;
243
                case ARITH:
244
                case RELAT:
245
                        if (v1.type==UNS || v2.type==UNS)
246
                                rtype = UNS;
247
                        else
248
                                rtype = SGN;
249
                        if (v1.type==UND || v2.type==UND)
250
                                rtype = UND;
251
                        if (priority[oper].ctype==RELAT && rtype==UNS) {
252
                                oper |= UNSMARK;
253
                                rtype = SGN;
254
                        }
255
                        break;
256
                case SHIFT:
257
                        if (v1.type==UND || v2.type==UND)
258
                                rtype = UND;
259
                        else
260
                                rtype = v1.type;
261
                        if (rtype==UNS)
262
                                oper |= UNSMARK;
263
                        break;
264
                case UNARY:
265
                        rtype = v1.type;
266
                        break;
267
                case LOGIC:
268
                case SPCL:
269
                        break;
270
                }
271
                switch (oper) {
272
                case EQ: case EQ|UNSMARK:
273
                        rv1 = rv1==rv2; break;
274
                case NEQ: case NEQ|UNSMARK:
275
                        rv1 = rv1!=rv2; break;
276
                case LEQ:
277
                        rv1 = rv1<=rv2; break;
278
                case GEQ:
279
                        rv1 = rv1>=rv2; break;
280
                case LT:
281
                        rv1 = rv1<rv2; break;
282
                case GT:
283
                        rv1 = rv1>rv2; break;
284
                case LEQ|UNSMARK:
285
                        rv1 = (unsigned long)rv1<=rv2; break;
286
                case GEQ|UNSMARK:
287
                        rv1 = (unsigned long)rv1>=rv2; break;
288
                case LT|UNSMARK:
289
                        rv1 = (unsigned long)rv1<rv2; break;
290
                case GT|UNSMARK:
291
                        rv1 = (unsigned long)rv1>rv2; break;
292
                case LSH:
293
                        rv1 <<= rv2; break;
294
                case LSH|UNSMARK:
295
                        rv1 = (unsigned long)rv1<<rv2; break;
296
                case RSH:
297
                        rv1 >>= rv2; break;
298
                case RSH|UNSMARK:
299
                        rv1 = (unsigned long)rv1>>rv2; break;
300
                case LAND:
301
                        rtype = UND;
302
                        if (v1.type==UND)
303
                                break;
304
                        if (rv1!=0) {
305
                                if (v2.type==UND)
306
                                        break;
307
                                rv1 = rv2!=0;
308
                        } else
309
                                rv1 = 0;
310
                        rtype = SGN;
311
                        break;
312
                case LOR:
313
                        rtype = UND;
314
                        if (v1.type==UND)
315
                                break;
316
                        if (rv1==0) {
317
                                if (v2.type==UND)
318
                                        break;
319
                                rv1 = rv2!=0;
320
                        } else
321
                                rv1 = 1;
322
                        rtype = SGN;
323
                        break;
324
                case AND:
325
                        rv1 &= rv2; break;
326
                case STAR:
327
                        rv1 *= rv2; break;
328
                case PLUS:
329
                        rv1 += rv2; break;
330
                case MINUS:
331
                        rv1 -= rv2; break;
332
                case UMINUS:
333
                        if (v1.type==UND)
334
                                rtype = UND;
335
                        rv1 = -rv1; break;
336
                case OR:
337
                        rv1 |= rv2; break;
338
                case CIRC:
339
                        rv1 ^= rv2; break;
340
                case TILDE:
341
                        rv1 = ~rv1; break;
342
                case NOT:
343
                        rv1 = !rv1; if (rtype!=UND) rtype = SGN; break;
344
                case SLASH:
345
                        if (rv2==0) {
346
                                rtype = UND;
347
                                break;
348
                        }
349
                        if (rtype==UNS)
350
                                rv1 /= (unsigned long)rv2;
351
                        else
352
                                rv1 /= rv2;
353
                        break;
354
                case PCT:
355
                        if (rv2==0) {
356
                                rtype = UND;
357
                                break;
358
                        }
359
                        if (rtype==UNS)
360
                                rv1 %= (unsigned long)rv2;
361
                        else
362
                                rv1 %= rv2;
363
                        break;
364
                case COLON:
365
                        if (op[-1] != QUEST)
366
                                error(ERROR, "Bad ?: in #if/endif");
367
                        else {
368
                                op--;
369
                                if ((--vp)->val==0)
370
                                        v1 = v2;
371
                                rtype = v1.type;
372
                                rv1 = v1.val;
373
                        }
374
                        break;
375
                case DEFINED:
376
                        break;
377
                default:
378
                        error(ERROR, "Eval botch (unknown operator)");
379
                        return 1;
380
                }
381
/*lint +e574 +e644 */
382
                v1.val = rv1;
383
                v1.type = rtype;
384
                if (vp == &vals[NSTAK]) {
385
                        error(ERROR, "Eval botch (stack overflow)");
386
                        return 0;
387
                }
388
                *vp++ = v1;
389
        }
390
        return 0;
391
}
392
 
393
struct value
394
tokval(Token *tp)
395
{
396
        struct value v;
397
        Nlist *np;
398
        int i, base, c;
399
        unsigned long n;
400
        uchar *p;
401
 
402
        v.type = SGN;
403
        v.val = 0;
404
        switch (tp->type) {
405
 
406
        case NAME:
407
                v.val = 0;
408
                break;
409
 
410
        case NAME1:
411
                if ((np = lookup(tp, 0)) != NULL && np->flag&(ISDEFINED|ISMAC))
412
                        v.val = 1;
413
                break;
414
 
415
        case NUMBER:
416
                n = 0;
417
                base = 10;
418
                p = tp->t;
419
                c = p[tp->len];
420
                p[tp->len] = '\0';
421
                if (*p=='0') {
422
                        base = 8;
423
                        if (p[1]=='x' || p[1]=='X') {
424
                                base = 16;
425
                                p++;
426
                        }
427
                        p++;
428
                }
429
                for (;; p++) {
430
                        if ((i = digit(*p)) < 0)
431
                                break;
432
                        if (i>=base)
433
                                error(WARNING,
434
                                  "Bad digit in number %t", tp);
435
                        n *= base;
436
                        n += i;
437
                }
438
                if (n>=0x80000000 && base!=10)
439
                        v.type = UNS;
440
                for (; *p; p++) {
441
                        if (*p=='u' || *p=='U')
442
                                v.type = UNS;
443
                        else if (*p=='l' || *p=='L')
444
                                ;
445
                        else {
446
                                error(ERROR,
447
                                  "Bad number %t in #if/#elsif", tp);
448
                                break;
449
                        }
450
                }
451
                v.val = n;
452
                tp->t[tp->len] = c;
453
                break;
454
 
455
        case CCON:
456
                n = 0;
457
                p = tp->t;
458
                if (*p=='L') {
459
                        p += 1;
460
                        error(WARNING, "Wide char constant value undefined");
461
                }
462
                p += 1;
463
                if (*p=='\\') {
464
                        p += 1;
465
                        if ((i = digit(*p))>=0 && i<=7) {
466
                                n = i;
467
                                p += 1;
468
                                if ((i = digit(*p))>=0 && i<=7) {
469
                                        p += 1;
470
                                        n <<= 3;
471
                                        n += i;
472
                                        if ((i = digit(*p))>=0 && i<=7) {
473
                                                p += 1;
474
                                                n <<= 3;
475
                                                n += i;
476
                                        }
477
                                }
478
                        } else if (*p=='x') {
479
                                p += 1;
480
                                while ((i = digit(*p))>=0 && i<=15) {
481
                                        p += 1;
482
                                        n <<= 4;
483
                                        n += i;
484
                                }
485
                        } else {
486
                                static char cvcon[]
487
                                  = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\";
488
                                for (i=0; i<sizeof(cvcon); i+=2) {
489
                                        if (*p == cvcon[i]) {
490
                                                n = cvcon[i+1];
491
                                                break;
492
                                        }
493
                                }
494
                                p += 1;
495
                                if (i>=sizeof(cvcon))
496
                                        error(WARNING,
497
                                         "Undefined escape in character constant");
498
                        }
499
                } else if (*p=='\'')
500
                        error(ERROR, "Empty character constant");
501
                else
502
                        n = *p++;
503
                if (*p!='\'')
504
                        error(WARNING, "Multibyte character constant undefined");
505
                else if (n>127)
506
                        error(WARNING, "Character constant taken as not signed");
507
                v.val = n;
508
                break;
509
 
510
        case STRING:
511
                error(ERROR, "String in #if/#elsif");
512
                break;
513
        }
514
        return v;
515
}
516
 
517
int
518
digit(int i)
519
{
520
        if ('0'<=i && i<='9')
521
                i -= '0';
522
        else if ('a'<=i && i<='f')
523
                i -= 'a'-10;
524
        else if ('A'<=i && i<='F')
525
                i -= 'A'-10;
526
        else
527
                i = -1;
528
        return i;
529
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.