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

Subversion Repositories raptor64

[/] [raptor64/] [trunk/] [software/] [c64/] [source/] [ParseDeclarations.c] - Blame information for rev 37

Go to most recent revision | 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
            if(lastst == begin)
338
                temp1->type = bt_ifunc;
339
        }
340
        else
341
            temp1->type = bt_ifunc;
342
        break;
343
    }
344
}
345
 
346
int alignment(TYP *tp)
347
{
348
        switch(tp->type) {
349
        case bt_byte:                   return AL_BYTE;
350
    case bt_char:           return AL_CHAR;
351
    case bt_short:          return AL_SHORT;
352
    case bt_long:           return AL_LONG;
353
    case bt_enum:           return AL_CHAR;
354
    case bt_pointer:
355
            if(tp->val_flag)
356
                return alignment(tp->btp);
357
            else
358
                                return AL_POINTER;
359
    case bt_float:          return AL_FLOAT;
360
    case bt_double:         return AL_DOUBLE;
361
    case bt_struct:
362
    case bt_union:          return AL_STRUCT;
363
    default:                return AL_CHAR;
364
    }
365
}
366
 
367
/*
368
 *      process ParseSpecifierarations of the form:
369
 *
370
 *              <type>  <ParseSpecifier>, <ParseSpecifier>...;
371
 *
372
 *      leaves the ParseSpecifierarations in the symbol table pointed to by
373
 *      table and returns the number of bytes declared. al is the
374
 *      allocation type to assign, ilc is the initial location
375
 *      counter. if al is sc_member then no initialization will
376
 *      be processed. ztype should be bt_struct for normal and in
377
 *      structure ParseSpecifierarations and sc_union for in union ParseSpecifierarations.
378
 */
379
int declare(TABLE *table,int al,int ilc,int ztype)
380
{
381
        SYM *sp, *sp1, *sp2;
382
    TYP *dhead;
383
 
384
    static long old_nbytes;
385
    int nbytes;
386
 
387
        nbytes = 0;
388
    ParseSpecifier(table);
389
    dhead = head;
390
    for(;;) {
391
        declid = 0;
392
                bit_width = -1;
393
        ParseDeclarationPrefix(ztype==bt_union);
394
        if( declid != 0) {      /* otherwise just struct tag... */
395
            sp = allocSYM();
396
            sp->name = declid;
397
            sp->storage_class = al;
398
                        if (bit_width > 0 && bit_offset > 0) {
399
                                // share the storage word with the previously defined field
400
                                nbytes = old_nbytes - ilc;
401
                        }
402
                        old_nbytes = ilc + nbytes;
403
                        if (al != sc_member) {
404
//                                                      sp->isTypedef = isTypedef;
405
                                if (isTypedef)
406
                                        sp->storage_class = sc_typedef;
407
                                isTypedef = FALSE;
408
                        }
409
            while( (ilc + nbytes) % alignment(head)) {
410
                if( al != sc_member && al != sc_external && al != sc_auto) {
411
                                        dseg();
412
                                        GenerateByte(0);
413
                }
414
                ++nbytes;
415
            }
416
            if( al == sc_static)
417
                                sp->value.i = nextlabel++;
418
                        else if( ztype == bt_union)
419
                sp->value.i = ilc;
420
            else if( al != sc_auto )
421
                sp->value.i = ilc + nbytes;
422
            else
423
                sp->value.i = -(ilc + nbytes + head->size);
424
 
425
                        if (bit_width == -1)
426
                                sp->tp = head;
427
                        else {
428
                                sp->tp = allocTYP();
429
                                *(sp->tp) = *head;
430
                                sp->tp->type = bt_bitfield;
431
                                sp->tp->size = head->size;//tp_int.size;
432
                                sp->tp->bit_width = bit_width;
433
                                sp->tp->bit_offset = bit_offset;
434
                        }
435
 
436
            if(
437
                                (sp->tp->type == bt_func) &&
438
                    sp->storage_class == sc_global )
439
                    sp->storage_class = sc_external;
440
            if(ztype == bt_union)
441
                    nbytes = imax(nbytes,sp->tp->size);
442
            else if(al != sc_external)
443
                    nbytes += sp->tp->size;
444
            if( sp->tp->type == bt_ifunc && (sp1 = search(sp->name,table)) != 0 &&
445
                    sp1->tp->type == bt_func )
446
                    {
447
                    sp1->tp = sp->tp;
448
                    sp1->storage_class = sp->storage_class;
449
//                                sp1->value.i = sp->value.i;
450
                                        sp1->IsPrototype = sp->IsPrototype;
451
                    sp = sp1;
452
                    }
453
                        else {
454
                                sp2 = search(sp->name,table);
455
                                if (sp2 == NULL)
456
                                        insert(sp,table);
457
                                else {
458
                                        if (funcdecl==2)
459
                                                sp2->tp = sp->tp;
460
                                        //else if (!sp2->IsPrototype)
461
                                        //      insert(sp,table);
462
                                }
463
                        }
464
            if( sp->tp->type == bt_ifunc) { /* function body follows */
465
                ParseFunction(sp);
466
                return nbytes;
467
            }
468
            if( (al == sc_global || al == sc_static) &&
469
                    sp->tp->type != bt_func && sp->storage_class!=sc_typedef)
470
                    doinit(sp);
471
        }
472
                if (funcdecl==TRUE) {
473
                        if (lastst==comma || lastst==semicolon)
474
                                break;
475
                        if (lastst==closepa)
476
                                goto xit1;
477
                }
478
                else if (catchdecl==TRUE) {
479
                        if (lastst==closepa)
480
                                goto xit1;
481
                }
482
                else if (lastst == semicolon)
483
                        break;
484
 
485
        needpunc(comma);
486
        if(declbegin(lastst) == 0)
487
                break;
488
        head = dhead;
489
    }
490
    NextToken();
491
xit1:
492
    return nbytes;
493
}
494
 
495
int declbegin(int st)
496
{
497
        return st == star || st == id || st == openpa || st == openbr;
498
}
499
 
500
void ParseGlobalDeclarations()
501
{
502
        funcdecl = FALSE;
503
    for(;;) {
504
                switch(lastst) {
505
                case id:
506
                case kw_interrupt:
507
                case kw_pascal:
508
                case kw_nocall:
509
                case kw_oscall:
510
                case kw_typedef:
511
                case kw_byte: case kw_char: case kw_int: case kw_short: case kw_unsigned: case kw_signed:
512
        case kw_long: case kw_struct: case kw_union:
513
        case kw_enum: case kw_void:
514
        case kw_float: case kw_double:
515
                lc_static += declare(&gsyms,sc_global,lc_static,bt_struct);
516
                                break;
517
                case kw_register:
518
                                NextToken();
519
                error(ERR_ILLCLASS);
520
                lc_static += declare(&gsyms,sc_global,lc_static,bt_struct);
521
                                break;
522
                case kw_private:
523
        case kw_static:
524
                NextToken();
525
                                lc_static += declare(&gsyms,sc_static,lc_static,bt_struct);
526
                break;
527
        case kw_extern:
528
                NextToken();
529
                                if (lastst==kw_oscall || lastst==kw_interrupt || lastst==kw_nocall)
530
                                        NextToken();
531
                ++global_flag;
532
                declare(&gsyms,sc_external,0,bt_struct);
533
                --global_flag;
534
                break;
535
        default:
536
                return;
537
                }
538
        }
539
}
540
 
541
void ParseParameterDeclarations(int fd)
542
{
543
        funcdecl = fd;
544
    for(;;) {
545
                switch(lastst) {
546
                case kw_interrupt:
547
                case kw_nocall:
548
                case kw_oscall:
549
                case kw_pascal:
550
                case kw_typedef:
551
                error(ERR_ILLCLASS);
552
                declare(&lsyms,sc_auto,0,bt_struct);
553
                                break;
554
                case id:
555
                case kw_byte: case kw_char: case kw_int: case kw_short: case kw_unsigned: case kw_signed:
556
        case kw_long: case kw_struct: case kw_union:
557
        case kw_enum: case kw_void:
558
        case kw_float: case kw_double:
559
                declare(&lsyms,sc_auto,0,bt_struct);
560
                    break;
561
        case kw_static:
562
                NextToken();
563
                error(ERR_ILLCLASS);
564
                                lc_static += declare(&gsyms,sc_static,lc_static,bt_struct);
565
                                break;
566
        case kw_extern:
567
                NextToken();
568
                error(ERR_ILLCLASS);
569
                                if (lastst==kw_oscall || lastst==kw_interrupt || lastst == kw_nocall)
570
                                        NextToken();
571
                ++global_flag;
572
                declare(&gsyms,sc_external,0,bt_struct);
573
                --global_flag;
574
                break;
575
        default:
576
                return;
577
                }
578
        }
579
}
580
 
581
 
582
void ParseAutoDeclarations()
583
{
584
        SYM *sp;
585
 
586
        funcdecl = FALSE;
587
    for(;;) {
588
                switch(lastst) {
589
                case kw_interrupt:
590
                case kw_nocall:
591
                case kw_oscall:
592
                case kw_pascal:
593
                case kw_typedef:
594
                error(ERR_ILLCLASS);
595
                    lc_auto += declare(&lsyms,sc_auto,lc_auto,bt_struct);
596
                                break;
597
                case id: //return;
598
                                sp = search(lastid,&gsyms[0]);
599
                                if (sp) {
600
                                        if (sp->storage_class==sc_typedef) {
601
                                    lc_auto += declare(&lsyms,sc_auto,lc_auto,bt_struct);
602
                                                break;
603
                                        }
604
                                }
605
                                return;
606
        case kw_register:
607
                NextToken();
608
                case kw_byte: case kw_char: case kw_int: case kw_short: case kw_unsigned: case kw_signed:
609
        case kw_long: case kw_struct: case kw_union:
610
        case kw_enum: case kw_void:
611
        case kw_float: case kw_double:
612
            lc_auto += declare(&lsyms,sc_auto,lc_auto,bt_struct);
613
            break;
614
        case kw_static:
615
                NextToken();
616
                                lc_static += declare(&lsyms,sc_static,lc_static,bt_struct);
617
                                break;
618
        case kw_extern:
619
                NextToken();
620
                                if (lastst==kw_oscall || lastst==kw_interrupt || lastst == kw_nocall)
621
                                        NextToken();
622
                ++global_flag;
623
                declare(&gsyms,sc_external,0,bt_struct);
624
                --global_flag;
625
                break;
626
        default:
627
                return;
628
                }
629
        }
630
}
631
 
632
/*
633
 *      main compiler routine. this routine parses all of the
634
 *      ParseSpecifierarations using declare which will call funcbody as
635
 *      functions are encountered.
636
 */
637
void compile()
638
{
639
        while(lastst != eof)
640
        {
641
        ParseGlobalDeclarations();
642
        if( lastst != eof)
643
            NextToken();
644
    }
645
    dumplits();
646
}
647
 

powered by: WebSVN 2.1.0

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