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

Subversion Repositories raptor64

[/] [raptor64/] [trunk/] [software/] [c64/] [source/] [ParseExpressions.c] - Blame information for rev 51

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 37 robfinch
#include        <stdio.h>
2
#include        "c.h"
3
#include        "expr.h"
4
#include "Statement.h"
5
#include        "gen.h"
6
#include        "cglbdec.h"
7
 
8
/*
9
 *      68000 C compiler
10
 *
11
 *      Copyright 1984, 1985, 1986 Matthew Brandt.
12
 *  all commercial rights reserved.
13
 *
14
 *      This compiler is intended as an instructive tool for personal use. Any
15
 *      use for profit without the written consent of the author is prohibited.
16
 *
17
 *      This compiler may be distributed freely for non-commercial use as long
18
 *      as this notice stays intact. Please forward any enhancements or questions
19
 *      to:
20
 *
21
 *              Matthew Brandt
22
 *              Box 920337
23
 *              Norcross, Ga 30092
24
 */
25
/*******************************************************
26
        Modified to support Raptor64 'C64' language
27
        by Robert Finch
28
        robfinch@opencores.org
29
*******************************************************/
30
 
31
TYP             stdint = { bt_long, bt_long, 0, FALSE, FALSE, FALSE, 0,0,8, {0, 0}, 0, 0 };
32
TYP             stduint = { bt_long, bt_long, 0, TRUE, FALSE, FALSE, 0,0,8, {0, 0}, 0, 0 };
33
TYP             stdlong = { bt_long, bt_long, 0, FALSE, FALSE, FALSE, 0,0,8, {0, 0}, 0, 0 };
34
TYP             stdulong = { bt_long, bt_long, 0, TRUE, FALSE, FALSE, 0,0,8, {0, 0}, 0, 0 };
35
TYP             stdshort = { bt_short, bt_short, 0, FALSE, FALSE, FALSE, 0,0,4, {0, 0}, 0, 0 };
36
TYP             stdushort = { bt_short, bt_short, 0, TRUE, FALSE, FALSE, 0,0,4, {0, 0}, 0, 0 };
37
TYP             stdchar = {bt_char, bt_char, 0, FALSE, FALSE, FALSE, 0,0,2, {0, 0}, 0, 0 };
38
TYP             stduchar = {bt_char, bt_char, 0, TRUE, FALSE, FALSE, 0,0,2, {0, 0}, 0, 0 };
39
TYP             stdbyte = {bt_byte, bt_byte, 0, FALSE, FALSE, FALSE, 0,0,1, {0, 0}, 0, 0 };
40
TYP             stdubyte = {bt_byte, bt_byte, 0, TRUE, FALSE, FALSE, 0,0,1, {0, 0}, 0, 0 };
41
TYP             stdstring = {bt_pointer, bt_pointer, 1, FALSE, FALSE, FALSE, 0,0,4, {0, 0}, &stdchar, 0};
42
TYP             stdfunc = {bt_func, bt_func, 1, FALSE, FALSE, FALSE, 0,0,0, {0, 0}, &stdint, 0};
43
extern TYP      *head;          /* shared with ParseSpecifier */
44
extern TYP      *tail;
45
 
46
/*
47
 *      expression evaluation
48
 *
49
 *      this set of routines builds a parse tree for an expression.
50
 *      no code is generated for the expressions during the build,
51
 *      this is the job of the codegen module. for most purposes
52
 *      expression() is the routine to call. it will allow all of
53
 *      the C operators. for the case where the comma operator is
54
 *      not valid (function parameters for instance) call NonCommaExpression().
55
 *
56
 *      each of the routines returns a pointer to a describing type
57
 *      structure. each routine also takes one parameter which is a
58
 *      pointer to an expression node by reference (address of pointer).
59
 *      the completed expression is returned in this pointer. all
60
 *      routines return either a pointer to a valid type or NULL if
61
 *      the hierarchy of the next operator is too low or the next
62
 *      symbol is not part of an expression.
63
 */
64
 
65
TYP     *expression();  /* forward ParseSpecifieraration */
66
TYP     *NonCommaExpression();      /* forward ParseSpecifieraration */
67
TYP     *ParseUnaryExpression();       /* forward ParseSpecifieraration */
68
 
69
/*
70
 *      build an expression node with a node type of nt and values
71
 *      v1 and v2.
72
 */
73
ENODE *makenode(int nt, ENODE *v1, ENODE *v2)
74
{
75
        ENODE *ep;
76
    ep = (ENODE *)xalloc(sizeof(ENODE));
77
    ep->nodetype = nt;
78
    ep->constflag = FALSE;
79
        ep->etype = bt_void;
80
        ep->esize = -1;
81
        ep->p[0] = v1;
82
        ep->p[1] = v2;
83
    return ep;
84
}
85
 
86
ENODE *makesnode(int nt, char *v1)
87
{
88
        ENODE *ep;
89
    ep = (ENODE *)xalloc(sizeof(ENODE));
90
    ep->nodetype = nt;
91
    ep->constflag = FALSE;
92
        ep->etype = bt_void;
93
        ep->esize = -1;
94
        ep->sp = v1;
95
    return ep;
96
}
97
 
98
ENODE *makenodei(int nt, ENODE *v1, __int64 i)
99
{
100
        ENODE *ep;
101
    ep = (ENODE *)xalloc(sizeof(ENODE));
102
    ep->nodetype = nt;
103
    ep->constflag = FALSE;
104
        ep->etype = bt_void;
105
        ep->esize = -1;
106
        ep->i = i;
107
        ep->p[0] = v1;
108
        ep->p[1] = NULL;
109
    return ep;
110
}
111
 
112
ENODE *makeinode(int nt, __int64 v1)
113
{
114
        ENODE *ep;
115
    ep = (ENODE *)xalloc(sizeof(ENODE));
116
    ep->nodetype = nt;
117
    ep->constflag = TRUE;
118
        ep->etype = bt_void;
119
        ep->esize = -1;
120
    ep->i = v1;
121
    return ep;
122
}
123
 
124
void PromoteConstFlag(ENODE *ep)
125
{
126
        ep->constflag = ep->p[0]->constflag && ep->p[1]->constflag;
127
}
128
 
129
/*
130
 *      build the proper dereference operation for a node using the
131
 *      type pointer tp.
132
 */
133
TYP *deref(ENODE **node, TYP *tp)
134
{
135
        switch( tp->type ) {
136
                case bt_byte:
137
                        if (tp->isUnsigned)
138
                                *node = makenode(en_ub_ref,*node,NULL);
139
                        else
140
                                *node = makenode(en_b_ref,*node,NULL);
141
                        (*node)->esize = tp->size;
142
                        (*node)->etype = tp->type;
143
            tp = &stdint;
144
            break;
145
                case bt_char:
146
        case bt_enum:
147
                        if (tp->isUnsigned)
148
                                *node = makenode(en_uc_ref,*node,NULL);
149
                        else
150
                                *node = makenode(en_c_ref,*node,NULL);
151
                        (*node)->esize = tp->size;
152
                        (*node)->etype = tp->type;
153
            tp = &stdchar;
154
            break;
155
        case bt_short:
156
            *node = makenode(en_h_ref,*node,NULL);
157
                        (*node)->esize = tp->size;
158
                        (*node)->etype = tp->type;
159
            tp = &stdint;
160
            break;
161
                case bt_long:
162
                case bt_pointer:
163
                case bt_unsigned:
164
                        (*node)->esize = tp->size;
165
                        (*node)->etype = tp->type;
166
            *node = makenode(en_w_ref,*node,NULL);
167
            break;
168
                case bt_bitfield:
169
                        if (tp->isUnsigned){
170
                                if (tp->size==1)
171
                                        *node = makenode(en_ubfieldref, *node, NULL);
172
                                else if (tp->size==2)
173
                                        *node = makenode(en_ucfieldref, *node, NULL);
174
                                else if (tp->size==4)
175
                                        *node = makenode(en_uhfieldref, *node, NULL);
176
                                else
177
                                        *node = makenode(en_wfieldref, *node, NULL);
178
                        }
179
                        else {
180
                                if (tp->size==1)
181
                                        *node = makenode(en_bfieldref, *node, NULL);
182
                                else if (tp->size==2)
183
                                        *node = makenode(en_cfieldref, *node, NULL);
184
                                else if (tp->size==4)
185
                                        *node = makenode(en_hfieldref, *node, NULL);
186
                                else
187
                                        *node = makenode(en_wfieldref, *node, NULL);
188
                        }
189
                        (*node)->bit_width = tp->bit_width;
190
                        (*node)->bit_offset = tp->bit_offset;
191
                        /*
192
                        * maybe it should be 'unsigned'
193
                        */
194
                        (*node)->etype = stdint.type;
195
                        (*node)->esize = tp->size;
196
                        tp = &stdint;
197
                        break;
198
                default:
199
                        error(ERR_DEREF);
200
                        break;
201
    }
202
    return tp;
203
}
204
 
205
/*
206
 *      nameref will build an expression tree that references an
207
 *      identifier. if the identifier is not in the global or
208
 *      local symbol table then a look-ahead to the next character
209
 *      is done and if it indicates a function call the identifier
210
 *      is coerced to an external function name. non-value references
211
 *      generate an additional level of indirection.
212
 */
213
TYP *nameref(ENODE **node)
214
{
215
        SYM             *sp;
216
    TYP             *tp;
217 51 robfinch
        char stnm[200];
218 37 robfinch
    sp = gsearch(lastid);
219
    if( sp == NULL ) {
220
        while( isspace(lastch) )
221
            getch();
222
        if( lastch == '(') {
223
            ++global_flag;
224
            sp = allocSYM();
225
            sp->tp = &stdfunc;
226
            sp->name = litlate(lastid);
227
            sp->storage_class = sc_external;
228
            insert(sp,&gsyms);
229
            --global_flag;
230
            tp = &stdfunc;
231
            *node = makesnode(en_nacon,sp->name);
232
            (*node)->constflag = TRUE;
233
        }
234
        else {
235
            tp = NULL;
236
            error(ERR_UNDEFINED);
237
        }
238
    }
239
    else    {
240
            if( (tp = sp->tp) == NULL ) {
241
                error(ERR_UNDEFINED);
242
                return NULL;       /* guard against untyped entries */
243
            }
244
            switch( sp->storage_class ) {
245
                    case sc_static:
246 51 robfinch
                                                if (sp->tp->type==bt_func || sp->tp->type==bt_ifunc) {
247
                                                                strcpy(stnm,GetNamespace());
248
                                                                strcat(stnm,"_");
249
                                                                strcat(stnm,sp->name);
250
                                                                *node = makesnode(en_nacon,litlate(stnm));
251
                                                                (*node)->constflag = TRUE;
252
                                                                //*node = makesnode(en_nacon,sp->name);
253
                                                                //(*node)->constflag = TRUE;
254
                                                        }
255
                                                        else {
256
                                                                *node = makeinode(en_labcon,sp->value.i);
257
                                                                (*node)->constflag = TRUE;
258
                                                        }
259 37 robfinch
                            break;
260
                    case sc_global:
261
                    case sc_external:
262
                            *node = makesnode(en_nacon,sp->name);
263
                            (*node)->constflag = TRUE;
264
                            break;
265
                    case sc_const:
266
                            *node = makeinode(en_icon,sp->value.i);
267
                            (*node)->constflag = TRUE;
268
                            break;
269
                    default:        /* auto and any errors */
270
                            if( sp->storage_class != sc_auto)
271
                                    error(ERR_ILLCLASS);
272
                            *node = makeinode(en_autocon,sp->value.i);
273
                            break;
274
                    }
275
            if( tp->val_flag == FALSE)
276
                    tp = deref(node,tp);
277
            }
278
    NextToken();
279
    return tp;
280
}
281
 
282
/*
283
 *      ArgumentList will build a list of parameter expressions in
284
 *      a function call and return a pointer to the last expression
285
 *      parsed. since parameters are generally pushed from right
286
 *      to left we get just what we asked for...
287
 */
288
ENODE *ArgumentList()
289
{
290
        struct ENODE    *ep1, *ep2;
291
    ep1 = 0;
292
    while( lastst != closepa)
293
        {
294
        NonCommaExpression(&ep2);          /* evaluate a parameter */
295
        ep1 = makenode(en_void,ep2,ep1);
296
        if( lastst != comma)
297
            break;
298
        NextToken();
299
    }
300
    return ep1;
301
}
302
 
303
/*
304
 *      return 1 if st in set of [ kw_char, kw_short, kw_long, kw_int,
305
 *      kw_float, kw_double, kw_struct, kw_union ]
306
 */
307
static int IsIntrinsicType(int st)
308
{
309
        return  st == kw_byte || st==kw_char || st == kw_short || st == kw_int || st==kw_void ||
310
                st == kw_long || st == kw_float || st == kw_double || st==kw_enum ||
311
                st == kw_struct || st == kw_union || st== kw_unsigned || st==kw_signed;
312
}
313
 
314
int IsBeginningOfTypecast(int st)
315
{
316
        SYM *sp;
317
        if (st==id) {
318
                sp = search(lastid,&gsyms[0]);
319
                if (sp)
320
                        return sp->storage_class==sc_typedef;
321
                return FALSE;
322
        }
323
        else
324
                return IsIntrinsicType(st);
325
}
326
 
327
/*
328
 *      primary will parse a primary expression and set the node pointer
329
 *      returning the type of the expression parsed. primary expressions
330
 *      are any of:
331
 *                      id
332
 *                      constant
333
 *                      string
334
 *                      ( expression )
335
 *                      primary[ expression ]
336
 *                      primary.id
337
 *                      primary->id
338
 *                      primary( parameter list )
339
 */
340
TYP *ParsePrimaryExpression(ENODE **node)
341
{
342 51 robfinch
        ENODE    *pnode, *qnode, *rnode, *snode, *rnode1, *pnode1, *qnode1, *qnode2;
343
        __int64 i ;
344
        int sza[10];
345
        int brcount;
346 37 robfinch
        SYM             *sp;
347
        TYP             *tptr;
348 51 robfinch
                brcount = 0;
349
                qnode1 = NULL;
350
                qnode2 = NULL;
351 37 robfinch
        switch( lastst ) {
352
 
353
                case id:
354
                        tptr = nameref(&pnode);
355
                        break;
356
                case iconst:
357
                        tptr = &stdint;
358
                        pnode = makeinode(en_icon,ival);
359
                        pnode->constflag = TRUE;
360
                        NextToken();
361
                        break;
362
                case sconst:
363
                        tptr = &stdstring;
364 51 robfinch
                        pnode = makenodei(en_labcon,NULL,stringlit(laststr));
365 37 robfinch
                        pnode->constflag = TRUE;
366
                        NextToken();
367
                        break;
368
 
369
                case openpa:
370
                        NextToken();
371
                        if( !IsBeginningOfTypecast(lastst) ) {
372
                            tptr = expression(&pnode);
373
                            needpunc(closepa);
374
                        }
375
                        else {                  /* cast operator */
376
                            ParseSpecifier(0); /* do cast ParseSpecifieraration */
377
                            ParseDeclarationPrefix(FALSE);
378
                            tptr = head;
379
                            needpunc(closepa);
380
                            if( ParseUnaryExpression(&pnode) == NULL ) {
381
                                error(ERR_IDEXPECT);
382
                                tptr = NULL;
383
                            }
384
                        }
385
                        break;
386
 
387
                default:
388
                        return NULL;
389
                }
390
        for(;;) {
391
                switch( lastst ) {
392
                        case openbr:    /* build a subscript reference */
393 51 robfinch
                                                        brcount++;
394 37 robfinch
                                                        if (tptr==NULL) {
395
                                                                error(ERR_UNDEFINED);
396
                                                                goto fini;
397
                                                        }
398
                                if( tptr->type != bt_pointer )
399
                                        error(ERR_NOPOINTER);
400
                                else
401
                                        tptr = tptr->btp;
402
                                NextToken();
403 51 robfinch
                                                                if (tptr->val_flag && (tptr->size==1 || tptr->size==2 || tptr->size==4 || tptr->size==8)) {
404
                                                                        expression(&rnode);
405
                                                                        pnode = makenode(en_add,rnode,pnode);
406
                                                                        pnode->constflag = rnode->constflag && pnode->p[1]->constflag;
407
                                                                        pnode->scale = tptr->size;
408
                                                                }
409
                                                                else {
410
                                                                        sza[brcount-1] = tptr->size;
411
                                                                        qnode = makeinode(en_icon,tptr->size);
412
                                                                        // swap sizes for array indexing
413
                                                                        if (brcount==3) {
414
                                                                                qnode->i = sza[0];
415
                                                                                qnode2->i = sza[1];
416
                                                                                qnode1->i = sza[2];
417
                                                                        }
418
                                                                        else if (brcount==2) {
419
                                                                                qnode->i = sza[0];
420
                                                                                qnode1->i = sza[1];
421
                                                                        }
422
                                                                        if (qnode1==NULL)
423
                                                                                qnode1 = qnode;
424
                                                                        else
425
                                                                                qnode2 = qnode;
426
                                                                        qnode->constflag = TRUE;
427
                                                                        expression(&rnode);
428
                                                                        needpunc(closebr);
429
        /*
430 37 robfinch
 *      we could check the type of the expression here...
431
 */
432 51 robfinch
                                                                        qnode = makenode(en_mulu,qnode,rnode);
433
                                                                        qnode->constflag = rnode->constflag && qnode->p[0]->constflag;
434
                                                                        pnode = makenode(en_add,qnode,pnode);
435
                                                                        pnode->constflag = qnode->constflag && pnode->p[1]->constflag;
436
                                                                        pnode->scale = 1;
437
                                                                        //if( tptr->val_flag == 0 )
438
                                                                        //      tptr = deref(&pnode,tptr);
439
                                                                }
440 37 robfinch
                                ////snode = makenode(en_mul,qnode,rnode);
441
                                ////snode->constflag = rnode->constflag && snode->p[0]->constflag;
442
                                ////pnode = makenode(en_add,snode,pnode);
443
                                ////pnode->constflag = snode->constflag && pnode->p[1]->constflag;
444
                                if( tptr->val_flag == FALSE )
445
                                    tptr = deref(&pnode,tptr);
446 51 robfinch
//                                needpunc(closebr);
447 37 robfinch
                                break;
448
 
449
                        case pointsto:
450
                                                        if (tptr==NULL) {
451
                                                                error(ERR_UNDEFINED);
452
                                                                goto fini;
453
                                                        }
454
                            if( tptr->type != bt_pointer )
455
                                error(ERR_NOPOINTER);
456
                            else
457
                                tptr = tptr->btp;
458
                            if( tptr->val_flag == FALSE )
459
                                pnode = makenode(en_w_ref,pnode,NULL);
460
/*
461
 *      fall through to dot operation
462
 */
463
                        case dot:
464
                                NextToken();       /* past -> or . */
465
                                if( lastst != id )
466
                                        error(ERR_IDEXPECT);
467
                                else    {
468
                                        sp = search(lastid,&tptr->lst);
469
                                        if( sp == NULL )
470
                                            error(ERR_NOMEMBER);
471
                                        else {
472
                                            tptr = sp->tp;
473
                                            qnode = makeinode(en_icon,sp->value.i);
474
                                            qnode->constflag = TRUE;
475
                                            pnode = makenode(en_add,pnode,qnode);
476
                                            pnode->constflag = pnode->p[0]->constflag;
477
                                            if( tptr->val_flag == FALSE )
478
                                                tptr = deref(&pnode,tptr);
479
                                        }
480
                                        NextToken();       /* past id */
481
                                        }
482
                                break;
483
 
484
                        case openpa:    /* function reference */
485
                                NextToken();
486
                                if( tptr->type != bt_func && tptr->type != bt_ifunc )
487
                                    error(ERR_NOFUNC);
488
                                else
489
                                    tptr = tptr->btp;
490
                                                                currentFn->IsLeaf = FALSE;
491
                                pnode = makenode(en_fcall,pnode,ArgumentList());
492
                                needpunc(closepa);
493
                                break;
494
 
495
                        default:
496
                                goto fini;
497
                        }
498
                }
499
fini:   *node = pnode;
500
        return tptr;
501
}
502
 
503
/*
504
 *      this function returns true if the node passed is an IsLValue.
505
 *      this can be qualified by the fact that an IsLValue must have
506
 *      one of the dereference operators as it's top node.
507
 */
508
int IsLValue(ENODE *node)
509
{
510
        switch( node->nodetype ) {
511
    case en_b_ref:
512
        case en_c_ref:
513
        case en_h_ref:
514
    case en_w_ref:
515
        case en_ub_ref:
516
        case en_uc_ref:
517
        case en_uh_ref:
518
    case en_uw_ref:
519
        case en_wfieldref:
520
        case en_uwfieldref:
521
        case en_bfieldref:
522
        case en_ubfieldref:
523
        case en_cfieldref:
524
        case en_ucfieldref:
525
        case en_hfieldref:
526
        case en_uhfieldref:
527
            return TRUE;
528
        case en_cbc:
529
        case en_cbh:
530
    case en_cbw:
531
        case en_cch:
532
        case en_ccw:
533
        case en_chw:
534
            return IsLValue(node->p[0]);
535
    }
536
    return FALSE;
537
}
538
 
539
/*
540
 *      ParseUnaryExpression evaluates unary expressions and returns the type of the
541
 *      expression evaluated. unary expressions are any of:
542
 *
543
 *                      primary
544
 *                      primary++
545
 *                      primary--
546
 *                      !unary
547
 *                      ~unary
548
 *                      ++unary
549
 *                      --unary
550
 *                      -unary
551
 *                      *unary
552
 *                      &unary
553
 *                      (typecast)unary
554
 *                      sizeof(typecast)
555
 *                      typenum(typecast)
556
 *
557
 */
558
TYP *ParseUnaryExpression(ENODE **node)
559
{
560
        TYP *tp, *tp1;
561
    ENODE *ep1, *ep2;
562
    int flag;
563
        __int64 i;
564
 
565
        flag = 0;
566
        switch( lastst ) {
567
                case autodec:
568
                        flag = 1;
569
                /* fall through to common increment */
570
                case autoinc:
571
                        NextToken();
572
                        tp = ParseUnaryExpression(&ep1);
573
                        if( tp == NULL ) {
574
                            error(ERR_IDEXPECT);
575
                            return NULL;
576
                        }
577
                        if( IsLValue(ep1)) {
578
                            if( tp->type == bt_pointer )
579
                                ep2 = makeinode(en_icon,tp->btp->size);
580
                            else
581
                                ep2 = makeinode(en_icon,1);
582
                            ep2->constflag = TRUE;
583
                            ep1 = makenode(flag ? en_assub : en_asadd,ep1,ep2);
584
                        }
585
                        else
586
                            error(ERR_LVALUE);
587
                        break;
588
 
589
                case minus:
590
                        NextToken();
591
                        tp = ParseUnaryExpression(&ep1);
592
                        if( tp == NULL ) {
593
                            error(ERR_IDEXPECT);
594
                            return NULL;
595
                        }
596
                        ep1 = makenode(en_uminus,ep1,NULL);
597
                        ep1->constflag = ep1->p[0]->constflag;
598
                        break;
599
 
600
                case not:
601
                        NextToken();
602
                        tp = ParseUnaryExpression(&ep1);
603
                        if( tp == NULL ) {
604
                            error(ERR_IDEXPECT);
605
                            return NULL;
606
                        }
607
                        ep1 = makenode(en_not,ep1,NULL);
608
                        ep1->constflag = ep1->p[0]->constflag;
609
                        break;
610
 
611
                case compl:
612
                        NextToken();
613
                        tp = ParseUnaryExpression(&ep1);
614
                        if( tp == NULL ) {
615
                            error(ERR_IDEXPECT);
616
                            return 0;
617
                        }
618
                        ep1 = makenode(en_compl,ep1,NULL);
619
                        ep1->constflag = ep1->p[0]->constflag;
620
                        break;
621
 
622
                case star:
623
                        NextToken();
624
                        tp = ParseUnaryExpression(&ep1);
625
                        if( tp == NULL ) {
626
                            error(ERR_IDEXPECT);
627
                            return NULL;
628
                        }
629
                        if( tp->btp == NULL )
630
                                                        error(ERR_DEREF);
631
                        else
632
                            tp = tp->btp;
633
                        if( tp->val_flag == FALSE )
634
                                                        tp = deref(&ep1,tp);
635
                        break;
636
 
637
                case and:
638
                        NextToken();
639
                        tp = ParseUnaryExpression(&ep1);
640
                        if( tp == NULL ) {
641
                            error(ERR_IDEXPECT);
642
                            return NULL;
643
                        }
644
                        if( IsLValue(ep1))
645
                                ep1 = ep1->p[0];
646
                        tp1 = allocTYP();
647
                        tp1->size = 8;
648
                        tp1->type = bt_pointer;
649
                        tp1->btp = tp;
650
                        tp1->val_flag = FALSE;
651
                        tp1->lst.head = NULL;
652
                        tp1->sname = NULL;
653
                        tp = tp1;
654
                        break;
655
 
656
                case kw_sizeof:
657
                        NextToken();
658
                        needpunc(openpa);
659
                                                tp = head;
660
                                                tp1 = tail;
661
                        ParseSpecifier(0);
662
                        ParseDeclarationPrefix(FALSE);
663
                        if( head != NULL )
664
                            ep1 = makeinode(en_icon,head->size);
665
                                                else {
666
                            error(ERR_IDEXPECT);
667
                            ep1 = makeinode(en_icon,1);
668
                        }
669
                                                head = tp;
670
                                                tail = tp1;
671
                        ep1->constflag = TRUE;
672
                        tp = &stdint;
673
                        needpunc(closepa);
674
                        break;
675
 
676
                case kw_typenum:
677
                        NextToken();
678
                        needpunc(openpa);
679
                                                tp = head;
680
                                                tp1 = tail;
681
                        ParseSpecifier(0);
682
                        ParseDeclarationPrefix(FALSE);
683
                        if( head != NULL )
684
                            ep1 = makeinode(en_icon,GetTypeHash(head));
685
                                                else {
686
                            error(ERR_IDEXPECT);
687
                            ep1 = makeinode(en_icon,1);
688
                        }
689
                                                head = tp;
690
                                                tail = tp1;
691
                        ep1->constflag = TRUE;
692
                        tp = &stdint;
693
                        needpunc(closepa);
694
                        break;
695
 
696
                default:
697
                        tp = ParsePrimaryExpression(&ep1);
698
                        if( tp != NULL ) {
699
                                if( tp->type == bt_pointer )
700
                                        i = tp->btp->size;
701
                                else
702
                                        i = 1;
703
                                if( lastst == autoinc) {
704 51 robfinch
                                                                        if( IsLValue(ep1) ) {
705
                                                                                if (tp->type == bt_pointer)
706
                                                                                        ep2 = makeinode(en_icon,tp->btp->size);
707
                                                                                else
708
                                                                                        ep2 = makeinode(en_icon,1);
709
                                                                                ep2->constflag = TRUE;
710
                                                                                ep1 = makenode(en_asadd,ep1,ep2);
711
//                                        ep1 = makenodei(en_ainc,ep1,i);
712
                                                                        }
713 37 robfinch
                                    else
714
                                        error(ERR_LVALUE);
715
                                    NextToken();
716
                                }
717
                                else if( lastst == autodec ) {
718 51 robfinch
                                                                        if( IsLValue(ep1) ) {
719
                                                                                if (tp->type == bt_pointer)
720
                                                                                        ep2 = makeinode(en_icon,tp->btp->size);
721
                                                                                else
722
                                                                                        ep2 = makeinode(en_icon,1);
723
                                                                                ep2->constflag = TRUE;
724
                                                                                ep1 = makenode(en_assub,ep1,ep2);
725
//                                                ep1 = makenodei(en_adec,ep1,i);
726
                                                                                }
727 37 robfinch
                                        else
728
                                                error(ERR_LVALUE);
729
                                        NextToken();
730
                                        }
731
                                }
732
                        break;
733
                }
734
        *node = ep1;
735
        return tp;
736
}
737
 
738
/*
739
 *      forcefit will coerce the nodes passed into compatable
740
 *      types and return the type of the resulting expression.
741
 */
742
TYP     *forcefit(ENODE **node1,TYP *tp1,ENODE **node2,TYP *tp2)
743
{
744
        switch( tp1->type ) {
745
                case bt_char:
746
                case bt_uchar:
747
                                        if (tp2->type == bt_long) {
748
                                                if (tp1->isUnsigned)
749
                                                        return &stdulong;
750
                                                else
751
                                                        return &stdlong;
752
                                        }
753
                                        if (tp2->type == bt_short) {
754
                                                if (tp1->isUnsigned)
755
                                                        return &stdushort;
756
                                                else
757
                                                        return &stdshort;
758
                                        }
759
                                        if (tp2->type == bt_pointer)
760
                                                return tp2;
761
                                        return tp1;     // char
762
                case bt_short:
763
                case bt_ushort:
764
                                        if (tp2->type == bt_long) {
765
                                                if (tp1->isUnsigned)
766
                                                        return &stdulong;
767
                                                else
768
                                                        return &stdlong;
769
                                        }
770
                                        if (tp2->type == bt_pointer)
771
                                                return tp2;
772
                                        return tp1;
773
                case bt_long:
774
                case bt_ulong:
775
                        if( tp2->type == bt_pointer     )
776
                                                        return tp2;
777
                                                return tp1;
778
                case bt_pointer:
779
                        if( isscalar(tp2) || tp2->type == bt_pointer)
780
                                return tp1;
781
                        break;
782
                case bt_unsigned:
783
                        if( tp2->type == bt_pointer )
784
                                return tp2;
785
                        else if( isscalar(tp2) )
786
                                return tp1;
787
                        break;
788
                }
789
        error( ERR_MISMATCH );
790
        return tp1;
791
}
792
 
793
/*
794
 *      this function returns true when the type of the argument is
795
 *      one of char, short, unsigned, or long.
796
 */
797
int     isscalar(TYP *tp)
798
{
799
        return
800
                        tp->type == bt_byte ||
801
                        tp->type == bt_char ||
802
            tp->type == bt_short ||
803
            tp->type == bt_long ||
804
                        tp->type == bt_uchar ||
805
            tp->type == bt_ushort ||
806
            tp->type == bt_ulong ||
807
            tp->type == bt_unsigned;
808
}
809
 
810
/*
811
 *      multops parses the multiply priority operators. the syntax of
812
 *      this group is:
813
 *
814
 *              unary
815
 *              multop * unary
816
 *              multop / unary
817
 *              multop % unary
818
 */
819
TYP *multops(struct ENODE **node)
820
{
821
        struct ENODE    *ep1, *ep2;
822
        TYP             *tp1, *tp2;
823
        int                   oper;
824
        tp1 = ParseUnaryExpression(&ep1);
825
        if( tp1 == 0 )
826
                return 0;
827
        while( lastst == star || lastst == divide || lastst == modop ) {
828
                oper = lastst;
829
                NextToken();       /* move on to next unary op */
830
                tp2 = ParseUnaryExpression(&ep2);
831
                if( tp2 == 0 ) {
832
                        error(ERR_IDEXPECT);
833
                        *node = ep1;
834
                        return tp1;
835
                        }
836
                tp1 = forcefit(&ep1,tp1,&ep2,tp2);
837
                switch( oper ) {
838
                        case star:
839
                                if( tp1->isUnsigned )
840
                                        ep1 = makenode(en_mulu,ep1,ep2);
841
                                else
842
                                        ep1 = makenode(en_mul,ep1,ep2);
843
                                break;
844
                        case divide:
845
                                if( tp1->isUnsigned )
846
                                        ep1 = makenode(en_udiv,ep1,ep2);
847
                                else
848
                                        ep1 = makenode(en_div,ep1,ep2);
849
                                break;
850
                        case modop:
851
                                if( tp1->isUnsigned )
852
                                        ep1 = makenode(en_umod,ep1,ep2);
853
                                else
854
                                        ep1 = makenode(en_mod,ep1,ep2);
855
                                break;
856
                        }
857
                PromoteConstFlag(ep1);
858
                }
859
        *node = ep1;
860
        return tp1;
861
}
862
 
863
/*
864
 *      addops handles the addition and subtraction operators.
865
 */
866
TYP     *addops(ENODE **node)
867
{
868
        ENODE    *ep1, *ep2, *ep3;
869
    TYP             *tp1, *tp2;
870
    int             oper;
871
 
872
        tp1 = multops(&ep1);
873
    if( tp1 == NULL )
874
        return NULL;
875
    while( lastst == plus || lastst == minus ) {
876
            oper = (lastst == plus);
877
            NextToken();
878
            tp2 = multops(&ep2);
879
            if( tp2 == 0 ) {
880
                    error(ERR_IDEXPECT);
881
                    *node = ep1;
882
                    return tp1;
883
                    }
884
            if( tp1->type == bt_pointer ) {
885
                    tp2 = forcefit(0,&stdint,&ep2,tp2);
886
                    ep3 = makeinode(en_icon,tp1->btp->size);
887
                    ep3->constflag = TRUE;
888
                    ep2 = makenode(en_mulu,ep3,ep2);
889
                    ep2->constflag = ep2->p[1]->constflag;
890
                    }
891
            else if( tp2->type == bt_pointer ) {
892
                    tp1 = forcefit(0,&stdint,&ep1,tp1);
893
                    ep3 = makeinode(en_icon,tp2->btp->size);
894
                    ep3->constflag = TRUE;
895
                    ep1 = makenode(en_mulu,ep3,ep1);
896
                    ep1->constflag = ep1->p[1]->constflag;
897
                    }
898
            tp1 = forcefit(&ep1,tp1,&ep2,tp2);
899
            ep1 = makenode( oper ? en_add : en_sub,ep1,ep2);
900
            PromoteConstFlag(ep1);
901
            }
902
    *node = ep1;
903
    return tp1;
904
}
905
 
906
/*
907
 *      shiftop handles the shift operators << and >>.
908
 */
909
TYP     *shiftop(ENODE **node)
910
{
911
        struct ENODE    *ep1, *ep2;
912
        TYP             *tp1, *tp2;
913
        int             oper;
914
        tp1 = addops(&ep1);
915
        if( tp1 == 0)
916
                return 0;
917
        while( lastst == lshift || lastst == rshift) {
918
                oper = (lastst == lshift);
919
                NextToken();
920
                tp2 = addops(&ep2);
921
                if( tp2 == 0 )
922
                        error(ERR_IDEXPECT);
923
                else    {
924
                        tp1 = forcefit(&ep1,tp1,&ep2,tp2);
925
                                                if (tp1->isUnsigned)
926
                                                        ep1 = makenode(oper ? en_shl : en_shru,ep1,ep2);
927
                                                else
928
                                                        ep1 = makenode(oper ? en_shl : en_shr,ep1,ep2);
929
                                PromoteConstFlag(ep1);
930
                        }
931
                }
932
        *node = ep1;
933
        return tp1;
934
}
935
 
936
/*
937
 *      relation handles the relational operators < <= > and >=.
938
 */
939
TYP     *relation(ENODE **node)
940
{       struct ENODE    *ep1, *ep2;
941
        TYP             *tp1, *tp2;
942
        int             nt;
943
        tp1 = shiftop(&ep1);
944
        if( tp1 == 0 )
945
                return 0;
946
        for(;;) {
947
                switch( lastst ) {
948
 
949
                        case lt:
950
                                if( tp1->isUnsigned )
951
                                        nt = en_ult;
952
                                else
953
                                        nt = en_lt;
954
                                break;
955
                        case gt:
956
                                if( tp1->isUnsigned )
957
                                        nt = en_ugt;
958
                                else
959
                                        nt = en_gt;
960
                                break;
961
                        case leq:
962
                                if( tp1->isUnsigned )
963
                                        nt = en_ule;
964
                                else
965
                                        nt = en_le;
966
                                break;
967
                        case geq:
968
                                if( tp1->isUnsigned )
969
                                        nt = en_uge;
970
                                else
971
                                        nt = en_ge;
972
                                break;
973
                        default:
974
                                goto fini;
975
                        }
976
                NextToken();
977
                tp2 = shiftop(&ep2);
978
                if( tp2 == 0 )
979
                        error(ERR_IDEXPECT);
980
                else    {
981
                        tp1 = forcefit(&ep1,tp1,&ep2,tp2);
982
                        ep1 = makenode(nt,ep1,ep2);
983
                                PromoteConstFlag(ep1);
984
                        }
985
                }
986
fini:   *node = ep1;
987
        return tp1;
988
}
989
 
990
/*
991
 *      equalops handles the equality and inequality operators.
992
 */
993
TYP     *equalops(ENODE **node)
994
{
995
        ENODE    *ep1, *ep2;
996
    TYP             *tp1, *tp2;
997
    int             oper;
998
    tp1 = relation(&ep1);
999
    if( tp1 == NULL )
1000
            return NULL;
1001
    while( lastst == eq || lastst == neq ) {
1002
        oper = (lastst == eq);
1003
        NextToken();
1004
        tp2 = relation(&ep2);
1005
        if( tp2 == NULL )
1006
                error(ERR_IDEXPECT);
1007
        else {
1008
            tp1 = forcefit(&ep1,tp1,&ep2,tp2);
1009
            ep1 = makenode( oper ? en_eq : en_ne,ep1,ep2);
1010
            PromoteConstFlag(ep1);
1011
        }
1012
        }
1013
    *node = ep1;
1014
    return tp1;
1015
}
1016
 
1017
/*
1018
 *      binop is a common routine to handle all of the legwork and
1019
 *      error checking for bitand, bitor, bitxor, andop, and orop.
1020
 */
1021
TYP *binop(ENODE **node, TYP *(*xfunc)(),int nt, int sy)
1022
{
1023
        ENODE    *ep1, *ep2;
1024
        TYP             *tp1, *tp2;
1025
        tp1 = (*xfunc)(&ep1);
1026
        if( tp1 == 0 )
1027
                return 0;
1028
        while( lastst == sy ) {
1029
                NextToken();
1030
                tp2 = (*xfunc)(&ep2);
1031
                if( tp2 == 0 )
1032
                        error(ERR_IDEXPECT);
1033
                else    {
1034
                        tp1 = forcefit(&ep1,tp1,&ep2,tp2);
1035
                        ep1 = makenode(nt,ep1,ep2);
1036
                                PromoteConstFlag(ep1);
1037
                        }
1038
                }
1039
        *node = ep1;
1040
        return tp1;
1041
}
1042
 
1043
TYP     *bitand(ENODE **node)
1044
/*
1045
 *      the bitwise and operator...
1046
 */
1047
{       return binop(node,equalops,en_and,and);
1048
}
1049
 
1050
TYP     *bitxor(ENODE **node)
1051
{       return binop(node,bitand,en_xor,uparrow);
1052
}
1053
 
1054
TYP     *bitor(ENODE **node)
1055
{       return binop(node,bitxor,en_or,or);
1056
}
1057
 
1058
TYP     *andop(ENODE **node)
1059
{       return binop(node,bitor,en_land,land);
1060
}
1061
 
1062
TYP *orop(ENODE **node)
1063
{
1064
        return binop(node,andop,en_lor,lor);
1065
}
1066
 
1067
/*
1068
 *      this routine processes the hook operator.
1069
 */
1070
TYP *conditional(ENODE **node)
1071
{
1072
        TYP             *tp1, *tp2, *tp3;
1073
    struct ENODE    *ep1, *ep2, *ep3;
1074
    tp1 = orop(&ep1);       /* get condition */
1075
    if( tp1 == NULL )
1076
            return NULL;
1077
    if( lastst == hook ) {
1078
            NextToken();
1079
            if( (tp2 = conditional(&ep2)) == NULL) {
1080
                    error(ERR_IDEXPECT);
1081
                    goto cexit;
1082
                    }
1083
            needpunc(colon);
1084
            if( (tp3 = conditional(&ep3)) == NULL) {
1085
                    error(ERR_IDEXPECT);
1086
                    goto cexit;
1087
                    }
1088
            tp1 = forcefit(&ep2,tp2,&ep3,tp3);
1089
            ep2 = makenode(en_void,ep2,ep3);
1090
            ep1 = makenode(en_cond,ep1,ep2);
1091
            }
1092
cexit:  *node = ep1;
1093
    return tp1;
1094
}
1095
 
1096
/*
1097
 *      asnop handles the assignment operators. currently only the
1098
 *      simple assignment is implemented.
1099
 */
1100
TYP *asnop(ENODE **node)
1101
{       struct ENODE    *ep1, *ep2, *ep3;
1102
        TYP             *tp1, *tp2;
1103
        int             op;
1104
        tp1 = conditional(&ep1);
1105
        if( tp1 == 0 )
1106
                return 0;
1107
        for(;;) {
1108
                switch( lastst ) {
1109
                        case assign:
1110
                                op = en_assign;
1111
ascomm:                         NextToken();
1112
                                tp2 = asnop(&ep2);
1113
ascomm2:                        if( tp2 == 0 || !IsLValue(ep1) )
1114
                                        error(ERR_LVALUE);
1115
                                else    {
1116
                                        tp1 = forcefit(&ep1,tp1,&ep2,tp2);
1117
                                        ep1 = makenode(op,ep1,ep2);
1118
                                        }
1119
                                break;
1120
                        case asplus:
1121
                                op = en_asadd;
1122
ascomm3:                        tp2 = asnop(&ep2);
1123
                                if( tp1->type == bt_pointer ) {
1124
                                        ep3 = makeinode(en_icon,tp1->btp->size);
1125
                                        ep2 = makenode(en_mul,ep2,ep3);
1126
                                        }
1127
                                goto ascomm;
1128
                        case asminus:
1129
                                op = en_assub;
1130
                                goto ascomm3;
1131
                        case astimes:
1132
                                op = en_asmul;
1133
                                goto ascomm;
1134
                        case asdivide:
1135
                                op = en_asdiv;
1136
                                goto ascomm;
1137
                        case asmodop:
1138
                                op = en_asmod;
1139
                                goto ascomm;
1140
                        case aslshift:
1141
                                op = en_aslsh;
1142
                                goto ascomm;
1143
                        case asrshift:
1144
                                op = en_asrsh;
1145
                                goto ascomm;
1146
                        case asand:
1147
                                op = en_asand;
1148
                                goto ascomm;
1149
                        case asor:
1150
                                op = en_asor;
1151
                                goto ascomm;
1152
                        default:
1153
                                goto asexit;
1154
                        }
1155
                }
1156
asexit: *node = ep1;
1157
        return tp1;
1158
}
1159
 
1160
/*
1161
 *      evaluate an expression where the comma operator is not legal.
1162
 */
1163
TYP *NonCommaExpression(ENODE **node)
1164
{
1165
        TYP *tp;
1166
    tp = asnop(node);
1167
    if( tp == NULL )
1168
        *node = NULL;
1169
    return tp;
1170
}
1171
 
1172
/*
1173
 *      evaluate the comma operator. comma operators are kept as
1174
 *      void nodes.
1175
 */
1176
TYP *commaop(ENODE **node)
1177
{
1178
        TYP             *tp1;
1179
        ENODE    *ep1, *ep2;
1180
        tp1 = asnop(&ep1);
1181
        if( tp1 == NULL )
1182
                return NULL;
1183
        if( lastst == comma ) {
1184
                tp1 = commaop(&ep2);
1185
                if( tp1 == NULL ) {
1186
                        error(ERR_IDEXPECT);
1187
                        goto coexit;
1188
                        }
1189
                ep1 = makenode(en_void,ep1,ep2);
1190
                }
1191
coexit: *node = ep1;
1192
        return tp1;
1193
}
1194
 
1195
/*
1196
 *      evaluate an expression where all operators are legal.
1197
 */
1198
TYP *expression(ENODE **node)
1199
{
1200
        TYP *tp;
1201
    tp = commaop(node);
1202
    if( tp == NULL )
1203
        *node = NULL;
1204
    return tp;
1205
}

powered by: WebSVN 2.1.0

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