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

Subversion Repositories raptor64

[/] [raptor64/] [trunk/] [software/] [c64/] [source/] [ParseDeclarations.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 <string.h>
3
#include        "c.h"
4
#include        "expr.h"
5
#include "Statement.h"
6
#include        "gen.h"
7
#include        "cglbdec.h"
8
 
9
/*
10
 *      68000 C compiler
11
 *
12
 *      Copyright 1984, 1985, 1986 Matthew Brandt.
13
 *  all commercial rights reserved.
14
 *
15
 *      This compiler is intended as an instructive tool for personal use. Any
16
 *      use for profit without the written consent of the author is prohibited.
17
 *
18
 *      This compiler may be distributed freely for non-commercial use as long
19
 *      as this notice stays intact. Please forward any enhancements or questions
20
 *      to:
21
 *
22
 *              Matthew Brandt
23
 *              Box 920337
24
 *              Norcross, Ga 30092
25
 */
26
/*******************************************************
27
        Modified to support Raptor64 'C64' language
28
        by Robert Finch
29
        robfinch@opencores.org
30
*******************************************************/
31
 
32
TYP             *head = NULL;
33
TYP             *tail = NULL;
34
char            *declid = NULL;
35
TABLE           tagtable = {0,0};
36
TYP             stdconst = { bt_long, bt_long, 1, FALSE, FALSE, FALSE, 0, 0, 8, {0, 0}, 0, "stdconst"};
37
char *names[20];
38
int nparms = 0;
39
int funcdecl = FALSE;
40
int catchdecl = FALSE;
41
int isTypedef = FALSE;
42
int isUnion = FALSE;
43
int isUnsigned = FALSE;
44
 
45
/* variable for bit fields */
46
static int              bit_max;        // largest bitnumber
47
int bit_offset; /* the actual offset */
48
int      bit_width;     /* the actual width */
49
int bit_next;   /* offset for next variable */
50
 
51
int declbegin(int st);
52
void dodecl(int defclass);
53
void ParseDeclarationSuffix();
54
void declstruct(int ztype);
55
void structbody(TYP *tp, int ztype);
56
void ParseEnumDeclaration(TABLE *table);
57
void enumbody(TABLE *table);
58
 
59
int     imax(int i, int j)
60
{       return (i > j) ? i : j;
61
}
62
 
63
 
64
char *litlate(char *s)
65
{
66
        char    *p;
67
    p = xalloc(strlen(s) + 1);
68
    strcpy(p,s);
69
    return p;
70
}
71
 
72
TYP *maketype(int bt, int siz)
73
{
74
        TYP *tp;
75
    tp = allocTYP();
76
    tp->val_flag = 0;
77
    tp->size = siz;
78
    tp->type = bt;
79
        tp->typeno = bt;
80
    tp->sname = 0;
81
    tp->lst.head = 0;
82
    return tp;
83
}
84
 
85
void ParseSpecifier(TABLE *table)
86
{
87
        SYM *sp;
88
 
89
        isUnsigned = FALSE;
90
        for (;;) {
91
                switch (lastst) {
92
                        case kw_signed: // Ignore 'signed'
93
                                NextToken();
94
                                break;
95
                        case kw_typedef:
96
                                isTypedef = TRUE;
97
                                NextToken();
98
                                break;
99
                        case kw_nocall:
100
                                isNocall = TRUE;
101
                                head = tail = maketype(bt_oscall,8);
102
                                NextToken();
103
                                goto lxit;
104
                        case kw_oscall:
105
                                isOscall = TRUE;
106
                                head = tail = maketype(bt_oscall,8);
107
                                NextToken();
108
                                goto lxit;
109
                        case kw_interrupt:
110
                                isInterrupt = TRUE;
111
                                head = tail = maketype(bt_interrupt,8);
112
                                NextToken();
113
                                goto lxit;
114
                        case kw_pascal:
115
                                isPascal = TRUE;
116
                                head = tail = maketype(bt_pascal,8);
117
                                NextToken();
118
                                break;
119
                        case kw_byte:
120
                                head = tail = maketype(bt_byte,1);
121
                                NextToken();
122
                                head->isUnsigned = isUnsigned;
123
                                bit_max = 8;
124
                                goto lxit;
125
                        case kw_char:
126
                                head = tail = maketype(bt_char,2);
127
                                NextToken();
128
                                head->isUnsigned = isUnsigned;
129
                                bit_max = 16;
130
                                goto lxit;
131
                        case kw_short:
132
                                head = tail = maketype(bt_short,4);
133
                                bit_max = 32;
134
                                NextToken();
135
                                if( lastst == kw_int )
136
                                        NextToken();
137
                                head->isUnsigned = isUnsigned;
138
                                head->isShort = TRUE;
139
                                goto lxit;
140
                                break;
141
                        case kw_long:   // long, long int
142
                                if (lastst==kw_int) {
143
                                        NextToken();
144
                                }
145
                                if (lastst==kw_float)
146
                                        head = tail = maketype(bt_double,8);
147
                                else
148
                                        head = tail = maketype(bt_long,8);
149
                                NextToken();
150
                                if (lastst==kw_oscall) {
151
                                        isOscall = TRUE;
152
                                        NextToken();
153
                                }
154
                                if (lastst==kw_nocall) {
155
                                        isNocall = TRUE;
156
                                        NextToken();
157
                                }
158
                                head->isUnsigned = isUnsigned;
159
                                bit_max = 64;
160
                                goto lxit;
161
                                break;
162
                        case kw_int:
163
                                head = tail = maketype(bt_long,8);
164
                                head->isUnsigned = isUnsigned;
165
                                NextToken();
166
                                if (lastst==kw_oscall) {
167
                                        isOscall = TRUE;
168
                                        NextToken();
169
                                }
170
                                if (lastst==kw_nocall) {
171
                                        isNocall = TRUE;
172
                                        NextToken();
173
                                }
174
                                bit_max = 64;
175
                                goto lxit;
176
                                break;
177
                        case kw_unsigned:
178
                                NextToken();
179
                                isUnsigned = TRUE;
180
                                break;
181
                        case id:                /* no type ParseSpecifierarator */
182
                                sp = search(lastid,&gsyms[0]);
183
                                if (sp) {
184
                                        if (sp->storage_class==sc_typedef) {
185
                                                NextToken();
186
                                                head = tail = sp->tp;
187
                                        }
188
                                        else
189
                                                head = tail = sp->tp;
190
//                                      head = tail = maketype(bt_long,4);
191
                                }
192
                                else {
193
                                        head = tail = maketype(bt_long,8);
194
                                        bit_max = 64;
195
                                }
196
                                goto lxit;
197
                                break;
198
                        case kw_float:
199
                                head = tail = maketype(bt_float,4);
200
                                NextToken();
201
                                bit_max = 32;
202
                                goto lxit;
203
                        case kw_double:
204
                                head = tail = maketype(bt_double,8);
205
                                NextToken();
206
                                bit_max = 64;
207
                                goto lxit;
208
                        case kw_void:
209
                                head = tail = maketype(bt_void,0);
210
                                NextToken();
211
                                if (lastst==kw_interrupt) {
212
                                        isInterrupt = TRUE;
213
                                        NextToken();
214
                                }
215
                                if (lastst==kw_nocall) {
216
                                        isNocall = TRUE;
217
                                        NextToken();
218
                                }
219
                                bit_max = 0;
220
                                goto lxit;
221
                        case kw_enum:
222
                                NextToken();
223
                                ParseEnumDeclaration(table);
224
                                bit_max = 16;
225
                                goto lxit;
226
                        case kw_struct:
227
                                NextToken();
228
                                ParseStructDeclaration(bt_struct);
229
                                goto lxit;
230
                        case kw_union:
231
                                NextToken();
232
                                ParseStructDeclaration(bt_union);
233
                                goto lxit;
234
                        default:
235
                                goto lxit;
236
                        }
237
        }
238
lxit:;
239
}
240
 
241
void ParseDeclarationPrefix(char isUnion)
242
{
243
        TYP *temp1, *temp2, *temp3, *temp4;
244
 
245
        switch (lastst) {
246
        case id:
247
                declid = litlate(lastid);
248
                                if (funcdecl==1)
249
                                        names[nparms++] = declid;
250
                NextToken();
251
                                if (lastst == colon) {
252
                                        NextToken();
253
                                        bit_width = GetIntegerExpression();
254
                                        if (isUnion)
255
                                                bit_offset = 0;
256
                                        else
257
                                                bit_offset = bit_next;
258
                                        if (bit_width < 0 || bit_width > bit_max) {
259
                                                error(ERR_BITFIELD_WIDTH);
260
                                                bit_width = 1;
261
                                        }
262
                                        if (bit_width == 0 || bit_offset + bit_width > bit_max)
263
                                                bit_offset = 0;
264
                                        bit_next = bit_offset + bit_width;
265
                                        break;  // no ParseDeclarationSuffix()
266
                                }
267
                                ParseDeclarationSuffix();
268
                break;
269
        case star:
270
                temp1 = maketype(bt_pointer,8);
271
                temp1->btp = head;
272
                head = temp1;
273
                if(tail == NULL)
274
                        tail = head;
275
                NextToken();
276
                ParseDeclarationPrefix(isUnion);
277
                break;
278
        case openpa:
279
                NextToken();
280
                temp1 = head;
281
                temp2 = tail;
282
                head = tail = NULL;
283
                ParseDeclarationPrefix(isUnion);
284
                needpunc(closepa);
285
                temp3 = head;
286
                temp4 = tail;
287
                head = temp1;
288
                tail = temp2;
289
                ParseDeclarationSuffix();
290
                temp4->btp = head;
291
                if(temp4->type == bt_pointer && temp4->val_flag != 0 && head != NULL)
292
                    temp4->size *= head->size;
293
                head = temp3;
294
                break;
295
        default:
296
                ParseDeclarationSuffix();
297
                break;
298
        }
299
}
300
 
301
// Take care of the () or [] trailing part of a ParseSpecifieraration
302
//
303
void ParseDeclarationSuffix()
304
{
305
        TYP     *temp1;
306
    switch (lastst) {
307
    case openbr:
308
        NextToken();
309
        temp1 = maketype(bt_pointer,0);
310
        temp1->val_flag = 1;
311
        temp1->btp = head;
312
        if(lastst == closebr) {
313
                temp1->size = 0;
314
                NextToken();
315
                }
316
        else if(head != NULL) {
317
                temp1->size = GetIntegerExpression() * head->size;
318
                needpunc(closebr);
319
                }
320
        else {
321
                temp1->size = GetIntegerExpression();
322
                needpunc(closebr);
323
                }
324
        head = temp1;
325
        if( tail == NULL)
326
                tail = head;
327
        ParseDeclarationSuffix();
328
        break;
329
    case openpa:
330
        NextToken();
331
        temp1 = maketype(bt_func,0);
332
        temp1->val_flag = 1;
333
        temp1->btp = head;
334
        head = temp1;
335
        if( lastst == closepa) {
336
            NextToken();
337 51 robfinch
            temp1->type = bt_ifunc;                     // this line wasn't present
338 37 robfinch
            if(lastst == begin)
339
                temp1->type = bt_ifunc;
340
        }
341
        else
342
            temp1->type = bt_ifunc;
343
        break;
344
    }
345
}
346
 
347
int alignment(TYP *tp)
348
{
349
        switch(tp->type) {
350
        case bt_byte:                   return AL_BYTE;
351
    case bt_char:           return AL_CHAR;
352
    case bt_short:          return AL_SHORT;
353
    case bt_long:           return AL_LONG;
354
    case bt_enum:           return AL_CHAR;
355
    case bt_pointer:
356
            if(tp->val_flag)
357
                return alignment(tp->btp);
358
            else
359
                                return AL_POINTER;
360
    case bt_float:          return AL_FLOAT;
361
    case bt_double:         return AL_DOUBLE;
362
    case bt_struct:
363
    case bt_union:          return AL_STRUCT;
364
    default:                return AL_CHAR;
365
    }
366
}
367
 
368
/*
369
 *      process ParseSpecifierarations of the form:
370
 *
371
 *              <type>  <ParseSpecifier>, <ParseSpecifier>...;
372
 *
373
 *      leaves the ParseSpecifierarations in the symbol table pointed to by
374
 *      table and returns the number of bytes declared. al is the
375
 *      allocation type to assign, ilc is the initial location
376
 *      counter. if al is sc_member then no initialization will
377
 *      be processed. ztype should be bt_struct for normal and in
378
 *      structure ParseSpecifierarations and sc_union for in union ParseSpecifierarations.
379
 */
380
int declare(TABLE *table,int al,int ilc,int ztype)
381
{
382
        SYM *sp, *sp1, *sp2;
383
    TYP *dhead;
384 51 robfinch
        char stnm[200];
385 37 robfinch
 
386
    static long old_nbytes;
387
    int nbytes;
388
 
389
        nbytes = 0;
390
    ParseSpecifier(table);
391
    dhead = head;
392
    for(;;) {
393
        declid = 0;
394
                bit_width = -1;
395
        ParseDeclarationPrefix(ztype==bt_union);
396
        if( declid != 0) {      /* otherwise just struct tag... */
397
            sp = allocSYM();
398 51 robfinch
                        sp->name = declid;
399 37 robfinch
            sp->storage_class = al;
400
                        if (bit_width > 0 && bit_offset > 0) {
401
                                // share the storage word with the previously defined field
402
                                nbytes = old_nbytes - ilc;
403
                        }
404
                        old_nbytes = ilc + nbytes;
405
                        if (al != sc_member) {
406
//                                                      sp->isTypedef = isTypedef;
407
                                if (isTypedef)
408
                                        sp->storage_class = sc_typedef;
409
                                isTypedef = FALSE;
410
                        }
411
            while( (ilc + nbytes) % alignment(head)) {
412
                if( al != sc_member && al != sc_external && al != sc_auto) {
413
                                        dseg();
414
                                        GenerateByte(0);
415
                }
416
                ++nbytes;
417
            }
418 51 robfinch
                        if( al == sc_static) {
419 37 robfinch
                                sp->value.i = nextlabel++;
420 51 robfinch
                        }
421 37 robfinch
                        else if( ztype == bt_union)
422
                sp->value.i = ilc;
423
            else if( al != sc_auto )
424
                sp->value.i = ilc + nbytes;
425
            else
426
                sp->value.i = -(ilc + nbytes + head->size);
427
 
428
                        if (bit_width == -1)
429
                                sp->tp = head;
430
                        else {
431
                                sp->tp = allocTYP();
432
                                *(sp->tp) = *head;
433
                                sp->tp->type = bt_bitfield;
434
                                sp->tp->size = head->size;//tp_int.size;
435
                                sp->tp->bit_width = bit_width;
436
                                sp->tp->bit_offset = bit_offset;
437
                        }
438
 
439
            if(
440
                                (sp->tp->type == bt_func) &&
441
                    sp->storage_class == sc_global )
442
                    sp->storage_class = sc_external;
443
            if(ztype == bt_union)
444
                    nbytes = imax(nbytes,sp->tp->size);
445
            else if(al != sc_external)
446
                    nbytes += sp->tp->size;
447
            if( sp->tp->type == bt_ifunc && (sp1 = search(sp->name,table)) != 0 &&
448
                    sp1->tp->type == bt_func )
449
                    {
450
                    sp1->tp = sp->tp;
451
                    sp1->storage_class = sp->storage_class;
452
//                                sp1->value.i = sp->value.i;
453
                                        sp1->IsPrototype = sp->IsPrototype;
454
                    sp = sp1;
455
                    }
456
                        else {
457
                                sp2 = search(sp->name,table);
458
                                if (sp2 == NULL)
459
                                        insert(sp,table);
460
                                else {
461
                                        if (funcdecl==2)
462
                                                sp2->tp = sp->tp;
463
                                        //else if (!sp2->IsPrototype)
464
                                        //      insert(sp,table);
465
                                }
466
                        }
467
            if( sp->tp->type == bt_ifunc) { /* function body follows */
468
                ParseFunction(sp);
469
                return nbytes;
470
            }
471
            if( (al == sc_global || al == sc_static) &&
472
                    sp->tp->type != bt_func && sp->storage_class!=sc_typedef)
473
                    doinit(sp);
474
        }
475
                if (funcdecl==TRUE) {
476
                        if (lastst==comma || lastst==semicolon)
477
                                break;
478
                        if (lastst==closepa)
479
                                goto xit1;
480
                }
481
                else if (catchdecl==TRUE) {
482
                        if (lastst==closepa)
483
                                goto xit1;
484
                }
485
                else if (lastst == semicolon)
486
                        break;
487
 
488
        needpunc(comma);
489
        if(declbegin(lastst) == 0)
490
                break;
491
        head = dhead;
492
    }
493
    NextToken();
494
xit1:
495
    return nbytes;
496
}
497
 
498
int declbegin(int st)
499
{
500
        return st == star || st == id || st == openpa || st == openbr;
501
}
502
 
503
void ParseGlobalDeclarations()
504
{
505
        funcdecl = FALSE;
506
    for(;;) {
507
                switch(lastst) {
508
                case id:
509
                case kw_interrupt:
510
                case kw_pascal:
511
                case kw_nocall:
512
                case kw_oscall:
513
                case kw_typedef:
514
                case kw_byte: case kw_char: case kw_int: case kw_short: case kw_unsigned: case kw_signed:
515
        case kw_long: case kw_struct: case kw_union:
516
        case kw_enum: case kw_void:
517
        case kw_float: case kw_double:
518
                lc_static += declare(&gsyms,sc_global,lc_static,bt_struct);
519
                                break;
520
                case kw_register:
521
                                NextToken();
522
                error(ERR_ILLCLASS);
523
                lc_static += declare(&gsyms,sc_global,lc_static,bt_struct);
524
                                break;
525
                case kw_private:
526
        case kw_static:
527
                NextToken();
528
                                lc_static += declare(&gsyms,sc_static,lc_static,bt_struct);
529
                break;
530
        case kw_extern:
531
                NextToken();
532 51 robfinch
                                if (lastst==kw_pascal) {
533
                                        isPascal = TRUE;
534 37 robfinch
                                        NextToken();
535 51 robfinch
                                }
536
                                else if (lastst==kw_oscall || lastst==kw_interrupt || lastst==kw_nocall)
537
                                        NextToken();
538 37 robfinch
                ++global_flag;
539
                declare(&gsyms,sc_external,0,bt_struct);
540
                --global_flag;
541
                break;
542
        default:
543
                return;
544
                }
545
        }
546
}
547
 
548
void ParseParameterDeclarations(int fd)
549
{
550
        funcdecl = fd;
551
    for(;;) {
552
                switch(lastst) {
553
                case kw_interrupt:
554
                case kw_nocall:
555
                case kw_oscall:
556
                case kw_pascal:
557
                case kw_typedef:
558
                error(ERR_ILLCLASS);
559
                declare(&lsyms,sc_auto,0,bt_struct);
560
                                break;
561
                case id:
562
                case kw_byte: case kw_char: case kw_int: case kw_short: case kw_unsigned: case kw_signed:
563
        case kw_long: case kw_struct: case kw_union:
564
        case kw_enum: case kw_void:
565
        case kw_float: case kw_double:
566
                declare(&lsyms,sc_auto,0,bt_struct);
567
                    break;
568
        case kw_static:
569
                NextToken();
570
                error(ERR_ILLCLASS);
571
                                lc_static += declare(&gsyms,sc_static,lc_static,bt_struct);
572
                                break;
573
        case kw_extern:
574
                NextToken();
575
                error(ERR_ILLCLASS);
576
                                if (lastst==kw_oscall || lastst==kw_interrupt || lastst == kw_nocall)
577
                                        NextToken();
578
                ++global_flag;
579
                declare(&gsyms,sc_external,0,bt_struct);
580
                --global_flag;
581
                break;
582
        default:
583
                return;
584
                }
585
        }
586
}
587
 
588
 
589
void ParseAutoDeclarations()
590
{
591
        SYM *sp;
592
 
593
        funcdecl = FALSE;
594
    for(;;) {
595
                switch(lastst) {
596
                case kw_interrupt:
597
                case kw_nocall:
598
                case kw_oscall:
599
                case kw_pascal:
600
                case kw_typedef:
601
                error(ERR_ILLCLASS);
602
                    lc_auto += declare(&lsyms,sc_auto,lc_auto,bt_struct);
603
                                break;
604
                case id: //return;
605
                                sp = search(lastid,&gsyms[0]);
606
                                if (sp) {
607
                                        if (sp->storage_class==sc_typedef) {
608
                                    lc_auto += declare(&lsyms,sc_auto,lc_auto,bt_struct);
609
                                                break;
610
                                        }
611
                                }
612
                                return;
613
        case kw_register:
614
                NextToken();
615
                case kw_byte: case kw_char: case kw_int: case kw_short: case kw_unsigned: case kw_signed:
616
        case kw_long: case kw_struct: case kw_union:
617
        case kw_enum: case kw_void:
618
        case kw_float: case kw_double:
619
            lc_auto += declare(&lsyms,sc_auto,lc_auto,bt_struct);
620
            break;
621
        case kw_static:
622
                NextToken();
623
                                lc_static += declare(&lsyms,sc_static,lc_static,bt_struct);
624
                                break;
625
        case kw_extern:
626
                NextToken();
627
                                if (lastst==kw_oscall || lastst==kw_interrupt || lastst == kw_nocall)
628
                                        NextToken();
629
                ++global_flag;
630
                declare(&gsyms,sc_external,0,bt_struct);
631
                --global_flag;
632
                break;
633
        default:
634
                return;
635
                }
636
        }
637
}
638
 
639
/*
640
 *      main compiler routine. this routine parses all of the
641
 *      ParseSpecifierarations using declare which will call funcbody as
642
 *      functions are encountered.
643
 */
644
void compile()
645
{
646
        while(lastst != eof)
647
        {
648
        ParseGlobalDeclarations();
649
        if( lastst != eof)
650
            NextToken();
651
    }
652
    dumplits();
653
}
654
 

powered by: WebSVN 2.1.0

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