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

Subversion Repositories raptor64

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 37 robfinch
// ============================================================================
2
// (C) 2012 Robert Finch
3
// All Rights Reserved.
4
// robfinch<remove>@opencores.org
5
//
6
// C64 - Raptor64 'C' derived language compiler
7
//  - 64 bit CPU
8
//
9
// This source file is free software: you can redistribute it and/or modify 
10
// it under the terms of the GNU Lesser General Public License as published 
11
// by the Free Software Foundation, either version 3 of the License, or     
12
// (at your option) any later version.                                      
13
//                                                                          
14
// This source file is distributed in the hope that it will be useful,      
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
17
// GNU General Public License for more details.                             
18
//                                                                          
19
// You should have received a copy of the GNU General Public License        
20
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
21
//                                                                          
22
// ============================================================================
23
//
24
#include <stdio.h> 
25
#include "c.h" 
26
#include "expr.h" 
27
#include "Statement.h"
28
#include "gen.h"
29
#include "cglbdec.h" 
30
 
31
extern TYP *head, *tail;
32
extern char *declid;
33
extern int catchdecl;
34
Statement *ParseStatement();   /* forward declararation */
35
Statement *ParseCatchStatement();
36
 
37
Statement *NewStatement(int typ, int gt) {
38
        Statement *s = (Statement *)xalloc(sizeof(Statement));
39
        s->stype = typ;
40
        if (gt) NextToken();
41
        return s;
42
};
43
 
44
 
45
int GetTypeHash(TYP *p)
46
{
47
        int n;
48
        TYP *p1;
49
 
50
        n = 0;
51
        do {
52
                if (p->type==bt_pointer)
53
                        n+=20000;
54
                p1 = p;
55
                p = p->btp;
56
        } while (p);
57
        n += p1->typeno;
58
        return n;
59
}
60
 
61
 
62
//struct snode    *interrupt_stmt()
63
//{       struct snode    *snp; 
64
//        SYM             *sp; 
65
//             TYP     *temp1;
66
//
67
//         NextToken(); 
68
//              if( lastst != id ) { 
69
//                      error(ERR_IDEXPECT); 
70
//                      return 0; 
71
//        } 
72
//        sp = allocSYM(); 
73
//        sp->name = litlate(lastid); 
74
//        sp->value.i = nextlabel++; 
75
//        sp->storage_class = sc_global;
76
//        sp->tp = temp1; 
77
//        temp1 = maketype(bt_long,0);
78
//        temp1->val_flag = 1;
79
//        insert(sp,&lsyms); 
80
//        NextToken();       /* get past label name */ 
81
//        needpunc( colon );
82
//              snp = (struct snode *)xalloc(sizeof(struct snode)); 
83
//        snp->stype = st_interrupt; 
84
//        snp->label = sp->name;
85
//        snp->next = 0; 
86
//              snp->s1 = statement(); 
87
//        return snp; 
88
//} 
89
//  
90
struct snode    *vortex_stmt()
91
{       struct snode    *snp;
92
        SYM             *sp;
93
               TYP     *temp1;
94
 
95
           NextToken();
96
                if( lastst != id ) {
97
                        error(ERR_IDEXPECT);
98
                        return 0;
99
        }
100
        temp1 = maketype(bt_long,0);
101
        temp1->val_flag = 1;
102
        sp = allocSYM();
103
        sp->name = litlate(lastid);
104
        sp->value.i = nextlabel++;
105
        sp->storage_class = sc_global;
106
        sp->tp = temp1;
107
        insert(sp,&lsyms);
108
        NextToken();       /* get past label name */
109
        needpunc( colon );
110
                snp = (struct snode *)xalloc(sizeof(struct snode));
111
        snp->stype = st_vortex;
112
        snp->label = sp->name;
113
        snp->next = 0;
114
                snp->s1 = ParseStatement();
115
        return snp;
116
}
117
 
118
Statement *ParseWhileStatement()
119
{
120
        Statement *snp;
121
 
122
    snp = NewStatement(st_while, TRUE);
123
    if( lastst != openpa )
124
        error(ERR_EXPREXPECT);
125
    else {
126
        NextToken();
127
        if( expression(&(snp->exp)) == 0 )
128
            error(ERR_EXPREXPECT);
129
        needpunc( closepa );
130
                if (lastst==kw_do)
131
                        NextToken();
132
        snp->s1 = ParseStatement();
133
    }
134
    return snp;
135
}
136
 
137
Statement *ParseUntilStatement()
138
{
139
        Statement *snp;
140
    snp = NewStatement(st_until, TRUE);
141
    if( lastst != openpa )
142
        error(ERR_EXPREXPECT);
143
    else {
144
        NextToken();
145
        if( expression(&(snp->exp)) == 0 )
146
            error(ERR_EXPREXPECT);
147
        needpunc( closepa );
148
        snp->s1 = ParseStatement();
149
    }
150
    return snp;
151
}
152
 
153
Statement *ParseDoStatement()
154
{
155
        Statement *snp;
156
    snp = NewStatement(st_do, TRUE);
157
    snp->s1 = ParseStatement();
158
        if (lastst == kw_until)
159
                snp->stype = st_dountil;
160
        else if (lastst== kw_loop)
161
                snp->stype = st_doloop;
162
    if( lastst != kw_while && lastst != kw_until && lastst != kw_loop )
163
        error(ERR_WHILEXPECT);
164
    else {
165
        NextToken();
166
                if (snp->stype!=st_doloop) {
167
        if( expression(&(snp->exp)) == 0 )
168
            error(ERR_EXPREXPECT);
169
                }
170
        if( lastst != end )
171
            needpunc( semicolon );
172
    }
173
    return snp;
174
}
175
 
176
Statement *ParseForStatement()
177
{
178
        Statement *snp;
179
    snp = NewStatement(st_for, TRUE);
180
    needpunc(openpa);
181
    if( expression(&(snp->initExpr)) == NULL )
182
        snp->initExpr = NULL;
183
    needpunc(semicolon);
184
    if( expression(&(snp->exp)) == NULL )
185
        snp->exp = NULL;
186
    needpunc(semicolon);
187
    if( expression(&(snp->incrExpr)) == NULL )
188
        snp->incrExpr = NULL;
189
    needpunc(closepa);
190
    snp->s1 = ParseStatement();
191
    return snp;
192
}
193
 
194
Statement *ParseForeverStatement()
195
{
196
        Statement *snp;
197
    snp = NewStatement(st_forever, TRUE);
198
    snp->stype = st_forever;
199
    snp->s1 = ParseStatement();
200
    return snp;
201
}
202
 
203
struct snode *ParseCriticalStatement()
204
{
205
        struct snode    *snp;
206
        SYM *sp;
207
    snp = (struct snode*)xalloc(sizeof(struct snode));
208
    NextToken();
209
        if (lastst==openpa)
210
                NextToken();
211
    if( lastst != id ) {
212
        error(ERR_IDEXPECT);
213
        return 0;
214
    }
215
    if( (sp = search(lastid,&gsyms[0])) == NULL ) {
216
            error( ERR_UNDEFINED );
217
                        return 0;
218
            }
219
        NextToken();
220
        if (lastst==closepa)
221
                NextToken();
222
    snp->stype = st_critical;
223
    snp->label = sp->name;
224
    snp->next = 0;
225
        snp->s1 = ParseStatement();
226
        return snp;
227
}
228
 
229
Statement *ParseSpinlockStatement()
230
{
231
        Statement *snp;
232
        SYM *sp;
233
 
234
        snp = NewStatement(st_spinlock, TRUE);
235
        if (lastst==openpa)
236
                NextToken();
237 51 robfinch
    if( NonCommaExpression(&(snp->exp)) == 0 )
238
        error(ERR_EXPREXPECT);
239
        snp->incrExpr = 1;
240
        snp->initExpr = 0;
241
        //if( lastst != id ) { 
242
 //       error(ERR_IDEXPECT); 
243
 //       return 0; 
244
 //   }
245
 //   if( (sp = search(lastid,&gsyms[0])) == NULL ) { 
246
 //           error( ERR_UNDEFINED ); 
247
        //              return 0;
248
 //           }
249
//      NextToken();
250 37 robfinch
        if (lastst==comma) {
251
                NextToken();
252 51 robfinch
                snp->incrExpr = GetIntegerExpression();
253
                if (snp->incrExpr < 1 || snp->incrExpr > 15)
254
                        error(ERR_SEMA_INCR);
255
                snp->incrExpr = (int)snp->incrExpr & 15;
256 37 robfinch
        }
257 51 robfinch
        if (lastst==comma) {
258
                NextToken();
259
                snp->initExpr = GetIntegerExpression();
260
        }
261 37 robfinch
        if (lastst==closepa)
262
                NextToken();
263 51 robfinch
//    snp->label = sp->name; 
264 37 robfinch
    snp->next = 0;
265
        snp->s1 = ParseStatement();
266
        if (lastst==kw_lockfail) {
267
                NextToken();
268
                snp->s2 = ParseStatement();
269
        }
270
        return snp;
271
}
272
 
273
Statement *ParseSpinunlockStatement()
274
{
275
        Statement *snp;
276
        SYM *sp;
277
 
278
    snp = NewStatement(st_spinunlock, TRUE);
279 51 robfinch
        snp->incrExpr = 1;
280 37 robfinch
        if (lastst==openpa)
281
                NextToken();
282 51 robfinch
    if( expression(&(snp->exp)) == 0 )
283
        error(ERR_EXPREXPECT);
284
        if (lastst==comma) {
285
                NextToken();
286
                snp->incrExpr = GetIntegerExpression();
287
                if (snp->incrExpr < 1 || snp->incrExpr > 15)
288
                        error(ERR_SEMA_INCR);
289
                snp->incrExpr = (int)snp->incrExpr & 15;
290
        }
291
    //if( lastst != id ) { 
292
    //    error(ERR_IDEXPECT); 
293
    //    return 0; 
294
    //}
295
  //  if( (sp = search(lastid,&gsyms[0])) == NULL ) { 
296
  //      error( ERR_UNDEFINED ); 
297
                //return 0;
298
  //  }
299 37 robfinch
        NextToken();
300
        if (lastst==closepa)
301
                NextToken();
302 51 robfinch
    //snp->label = sp->name; 
303 37 robfinch
    snp->next = 0;
304
        return snp;
305
}
306
 
307
Statement *ParseFirstcallStatement()
308
{
309
        Statement *snp;
310
    snp = NewStatement(st_firstcall, TRUE);
311
    snp->s1 = ParseStatement();
312
    return snp;
313
}
314
 
315
Statement *ParseIfStatement()
316
{
317
        Statement *snp;
318
 
319
    snp = NewStatement(st_if, TRUE);
320
    if( lastst != openpa )
321
        error(ERR_EXPREXPECT);
322
    else {
323
        NextToken();
324
        if( expression(&(snp->exp)) == 0 )
325
            error(ERR_EXPREXPECT);
326
        needpunc( closepa );
327
                if (lastst==kw_then)
328
                        NextToken();
329
        snp->s1 = ParseStatement();
330
        if( lastst == kw_else ) {
331
            NextToken();
332
            snp->s2 = ParseStatement();
333
        }
334
                else if (lastst == kw_elsif) {
335
            snp->s2 = ParseIfStatement();
336
                }
337
        else
338
            snp->s2 = 0;
339
    }
340
    return snp;
341
}
342
 
343
Statement *ParseCatchStatement()
344
{
345
        Statement *snp;
346
        SYM *sp;
347
        TYP *tp,*tp1,*tp2;
348
 
349
        snp = NewStatement(st_catch, TRUE);
350
        if (lastst != openpa) {
351
                snp->label = NULL;
352
                snp->s2 = 99999;
353
                snp->s1 = ParseStatement();
354
                return snp;
355
        }
356
    needpunc(openpa);
357
        tp = head;
358
        tp1 = tail;
359
        catchdecl = TRUE;
360
        ParseAutoDeclarations();
361
        catchdecl = FALSE;
362
        tp2 = head;
363
        head = tp;
364
        tail = tp1;
365
    needpunc(closepa);
366
 
367
        if( (sp = search(declid,&lsyms)) == NULL)
368
        sp = makeint(declid);
369
        snp->s1 = ParseStatement();
370
        snp->label = (char *)sp;        // save off symbol pointer
371
        if (sp->tp->typeno >= bt_last)
372
                error(ERR_CATCHSTRUCT);
373
        snp->s2 = GetTypeHash(sp->tp);
374
        return snp;
375
}
376
 
377
Statement *ParseCaseStatement()
378
{
379
        Statement *snp;
380
    Statement *head, *tail;
381
        int buf[256];
382
        int nn;
383
        int *bf;
384
 
385
    snp = NewStatement(st_case, FALSE);
386
        if (lastst == kw_fallthru)      // ignore "fallthru"
387
                NextToken();
388
    if( lastst == kw_case ) {
389
        NextToken();
390
        snp->s2 = 0;
391
                nn = 0;
392
                do {
393
                        buf[nn] = GetIntegerExpression();
394
                        nn++;
395
                        if (lastst != comma)
396
                                break;
397
                        NextToken();
398
                } while (nn < 256);
399
                if (nn==256)
400
                        error(ERR_TOOMANYCASECONSTANTS);
401
                bf = (int *)xalloc(sizeof(int)*(nn+1));
402
                bf[0] = nn;
403
                for (; nn > 0; nn--)
404
                        bf[nn]=buf[nn-1];
405
                snp->label = bf;
406
    }
407
    else if( lastst == kw_default) {
408
        NextToken();
409
        snp->s2 = 1;
410
                snp->stype = st_default;
411
    }
412
    else {
413
        error(ERR_NOCASE);
414
        return NULL;
415
    }
416
    needpunc(colon);
417
    head = NULL;
418
    while( lastst != end && lastst != kw_case && lastst != kw_default ) {
419
                if( head == NULL )
420
                        head = tail = ParseStatement();
421
                else {
422
                        tail->next = ParseStatement();
423
                        if( tail->next != NULL )
424
                                tail = tail->next;
425
                }
426
        tail->next = 0;
427
    }
428
    snp->s1 = head;
429
    return snp;
430
}
431
 
432
int CheckForDuplicateCases(Statement *head)
433
{
434
        Statement *top, *cur;
435
 
436
        cur = top = head;
437
        while( top != NULL )
438
        {
439
                cur = top->next;
440
                while( cur != NULL )
441
                {
442
                        if( (!(cur->s1 || cur->s2) && cur->label == top->label)
443
                                || (cur->s2 && top->s2) )
444
                        {
445
                                printf(" duplicate case value %d\n",cur->label);
446
                                return TRUE;
447
                        }
448
                        cur = cur->next;
449
                }
450
                top = top->next;
451
        }
452
        return FALSE;
453
}
454
 
455
Statement *ParseSwitchStatement()
456
{
457
        Statement *snp;
458
    Statement *head, *tail;
459
 
460
    snp = NewStatement(st_switch, TRUE);
461
    if( expression(&(snp->exp)) == NULL )
462
        error(ERR_EXPREXPECT);
463
    needpunc(begin);
464
    head = 0;
465
    while( lastst != end ) {
466
                if( head == NULL )
467
                        head = tail = ParseCaseStatement();
468
                else {
469
                        tail->next = ParseCaseStatement();
470
                        if( tail->next != NULL )
471
                                tail = tail->next;
472
                }
473
                if (tail==NULL) break;  // end of file in switch
474
        tail->next = NULL;
475
    }
476
    snp->s1 = head;
477
    NextToken();
478
    if( CheckForDuplicateCases(head) )
479
        error(ERR_DUPCASE);
480
    return snp;
481
}
482
 
483
Statement *ParseReturnStatement()
484
{
485
        Statement *snp;
486
 
487
        snp = NewStatement(st_return, TRUE);
488
    expression(&(snp->exp));
489
    if( lastst != end )
490
        needpunc( semicolon );
491
    return snp;
492
}
493
 
494
Statement *ParseThrowStatement()
495
{
496
        Statement *snp;
497
        TYP *tp;
498
 
499
        currentFn->DoesThrow = TRUE;
500
        snp = NewStatement(st_throw, TRUE);
501
    tp = expression(&(snp->exp));
502
        snp->label = GetTypeHash(tp);
503
    if( lastst != end )
504
        needpunc( semicolon );
505
    return snp;
506
}
507
 
508
Statement *ParseBreakStatement()
509
{
510
        Statement *snp;
511
 
512
        snp = NewStatement(st_break, TRUE);
513
    if( lastst != end )
514
        needpunc( semicolon );
515
    return snp;
516
}
517
 
518
Statement *ParseContinueStatement()
519
{
520
        Statement *snp;
521
 
522
    snp = NewStatement(st_continue, TRUE);
523
    if( lastst != end )
524
        needpunc( semicolon );
525
    return snp;
526
}
527
 
528
Statement *ParseIntoffStatement()
529
{
530
        Statement *snp;
531
    snp = NewStatement(st_intoff, TRUE);
532
    if( lastst != end )
533
        needpunc( semicolon );
534
    return snp;
535
}
536
 
537
Statement *ParseIntonStatement()
538
{
539
        Statement *snp;
540
 
541
    snp = NewStatement(st_inton, TRUE);
542
    if( lastst != end )
543
        needpunc( semicolon );
544
    return snp;
545
}
546
 
547
Statement *ParseStopStatement()
548
{
549
        Statement *snp;
550
 
551
        snp = NewStatement(st_stop, TRUE);
552
        if( lastst != end )
553
                needpunc( semicolon );
554
        return snp;
555
}
556
 
557
Statement *ParseAsmStatement()
558
{
559
        static char buf[2001];
560
        int nn;
561
 
562
        Statement *snp;
563
    snp = NewStatement(st_asm, FALSE);
564
    while( isspace(lastch) )
565
                getch();
566
    NextToken();
567
        if (lastst != begin)
568
                error(ERR_PUNCT);
569
        nn = 0;
570
        do {
571
                getch();
572
                if (lastch=='}')
573
                        break;
574
                buf[nn++] = lastch;
575
        }
576
        while(lastch!=-1 && nn < 2000);
577
        if (nn >= 2000)
578
                error(ERR_ASMTOOLONG);
579
        buf[nn] = '\0';
580
        snp->label = litlate(buf);
581
    return snp;
582
}
583
 
584
Statement *ParseTryStatement()
585
{
586
        Statement *snp;
587
        TYP *tp,*tp1,*tp2;
588
        SYM *sp;
589
        Statement *hd, *tl;
590
 
591
        hd = NULL;
592
        tl = NULL;
593
        snp = NewStatement(st_try, TRUE);
594
    snp->s1 = ParseStatement();
595
        if (lastst != kw_catch)
596
        error(ERR_CATCHEXPECT);
597
    while( lastst == kw_catch ) {
598
                if( hd == NULL )
599
                        hd = tl = ParseCatchStatement();
600
                else {
601
                        tl->next = ParseCatchStatement();
602
                        if( tl->next != NULL )
603
                                tl = tl->next;
604
                }
605
                if (tl==NULL) break;    // end of file in try
606
        tl->next = NULL;
607
    }
608
    snp->s2 = hd;
609
    return snp;
610
}
611
 
612
Statement *ParseExpressionStatement()
613
{
614
        Statement *snp;
615
    snp = NewStatement(st_expr, FALSE);
616
    if( expression(&(snp->exp)) == NULL ) {
617
        error(ERR_EXPREXPECT);
618
        NextToken();
619
    }
620
    if( lastst != end )
621
        needpunc( semicolon );
622
    return snp;
623
}
624
 
625
Statement *ParseCompoundStatement()
626
{
627
        Statement *head, *tail;
628
 
629
        head = 0;
630
        while( lastst != end ) {
631
                if( head == NULL )
632
                        head = tail = ParseStatement();
633
                else {
634
                        tail->next = ParseStatement();
635
                        if( tail->next != NULL )
636
                                tail = tail->next;
637
                }
638
        }
639
    NextToken();
640
    return head;
641
}
642
 
643
Statement *ParseLabelStatement()
644
{
645
        Statement *snp;
646
    SYM *sp;
647
 
648
    snp = NewStatement(st_label, FALSE);
649
    if( (sp = search(lastid,&lsyms)) == NULL ) {
650
        sp = allocSYM();
651
        sp->name = litlate(lastid);
652
        sp->storage_class = sc_label;
653
        sp->tp = 0;
654
        sp->value.i = nextlabel++;
655
        insert(sp,&lsyms);
656
    }
657
    else {
658
        if( sp->storage_class != sc_ulabel )
659
            error(ERR_LABEL);
660
        else
661
            sp->storage_class = sc_label;
662
    }
663
    NextToken();       /* get past id */
664
    needpunc(colon);
665
    if( sp->storage_class == sc_label ) {
666
        snp->label = sp->value.i;
667
        snp->next = NULL;
668
        return snp;
669
    }
670
    return 0;
671
}
672
 
673
Statement *ParseGotoStatement()
674
{
675
        Statement *snp;
676
    SYM *sp;
677
 
678
    NextToken();
679
    if( lastst != id ) {
680
        error(ERR_IDEXPECT);
681
        return NULL;
682
    }
683
    snp = NewStatement(st_goto, FALSE);
684
    if( (sp = search(lastid,&lsyms)) == NULL ) {
685
        sp = allocSYM();
686
        sp->name = litlate(lastid);
687
        sp->value.i = nextlabel++;
688
        sp->storage_class = sc_ulabel;
689
        sp->tp = 0;
690
        insert(sp,&lsyms);
691
    }
692
    NextToken();       /* get past label name */
693
    if( lastst != end )
694
        needpunc( semicolon );
695
    if( sp->storage_class != sc_label && sp->storage_class != sc_ulabel)
696
        error( ERR_LABEL );
697
    else {
698
        snp->stype = st_goto;
699
        snp->label = sp->value.i;
700
        snp->next = NULL;
701
        return snp;
702
    }
703
    return NULL;
704
}
705
 
706
Statement *ParseStatement()
707
{
708
        Statement *snp;
709
    switch( lastst ) {
710
    case semicolon:
711
        NextToken();
712
        snp = NULL;
713
        break;
714
    case begin:
715
                NextToken();
716
        snp = ParseCompoundStatement();
717
        return snp;
718
    case kw_if: snp = ParseIfStatement(); break;
719
    case kw_while: snp = ParseWhileStatement(); break;
720
    case kw_until: snp = ParseUntilStatement(); break;
721
    case kw_for:   snp = ParseForStatement();   break;
722
    case kw_forever: snp = ParseForeverStatement(); break;
723
    case kw_firstcall: snp = ParseFirstcallStatement(); break;
724
    case kw_return: snp = ParseReturnStatement(); break;
725
    case kw_break: snp = ParseBreakStatement(); break;
726
    case kw_goto: snp = ParseGotoStatement(); break;
727
    case kw_continue: snp = ParseContinueStatement(); break;
728
    case kw_do:
729
        case kw_loop: snp = ParseDoStatement(); break;
730
    case kw_switch: snp = ParseSwitchStatement(); break;
731
        case kw_try: snp = ParseTryStatement(); break;
732
        case kw_throw: snp = ParseThrowStatement(); break;
733
        case kw_vortex:
734
                        snp = vortex_stmt();
735
                        break;
736
        case kw_intoff: snp = ParseIntoffStatement(); break;
737
        case kw_inton: snp = ParseIntonStatement(); break;
738
        case kw_stop: snp = ParseStopStatement(); break;
739
        case kw_asm:
740
                snp = ParseAsmStatement(); break;
741
        case kw_critical: snp = ParseCriticalStatement(); break;
742
        case kw_spinlock: snp = ParseSpinlockStatement(); break;
743
        case kw_spinunlock: snp = ParseSpinunlockStatement(); break;
744
    case id:
745
                        SkipSpaces();
746
            if( lastch == ':' )
747
                return ParseLabelStatement();
748
            // else fall through to parse expression
749
    default:
750
            snp = ParseExpressionStatement();
751
            break;
752
    }
753
    if( snp != NULL )
754
        snp->next = NULL;
755
    return snp;
756
}

powered by: WebSVN 2.1.0

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