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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [software/] [CC64/] [source/] [NextToken.cpp] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2012-2017  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
// C64 - 'C' derived language compiler
9
//  - 64 bit CPU
10
//
11
// This source file is free software: you can redistribute it and/or modify 
12
// it under the terms of the GNU Lesser General Public License as published 
13
// by the Free Software Foundation, either version 3 of the License, or     
14
// (at your option) any later version.                                      
15
//                                                                          
16
// This source file is distributed in the hope that it will be useful,      
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
19
// GNU General Public License for more details.                             
20
//                                                                          
21
// You should have received a copy of the GNU General Public License        
22
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
23
//                                                                          
24
// ============================================================================
25
//
26
#include "stdafx.h"
27
 
28
/*
29
 *      68000 C compiler
30
 *
31
 *      Copyright 1984, 1985, 1986 Matthew Brandt.
32
 *  all commercial rights reserved.
33
 *
34
 *      This compiler is intended as an instructive tool for personal use. Any
35
 *      use for profit without the written consent of the author is prohibited.
36
 *
37
 *      This compiler may be distributed freely for non-commercial use as long
38
 *      as this notice stays intact. Please forward any enhancements or questions
39
 *      to:
40
 *
41
 *              Matthew Brandt
42
 *              Box 920337
43
 *              Norcross, Ga 30092
44
 */
45
/*******************************************************
46
        Modified to support Raptor64 'C64' language
47
        by Robert Finch
48
        robfinch@opencores.org
49
*******************************************************/
50
extern char *errtext(int);
51
 
52
int inComment = FALSE;
53
int      my_errno[80];
54
int      numerrs;
55
char     inpline[520];
56
int             total_errors = 0;
57
extern char     *lptr;          /* shared with preproc */
58
extern std::ifstream *inclfile[10];  /* shared with preproc */
59
extern int      inclline[10];   /* shared with preproc */
60
extern int      incldepth;      /* shared with preproc */
61
char            *linstack[20];  /* stack for substitutions */
62
char            chstack[20];    /* place to save lastch */
63
int             lstackptr = 0;  /* substitution stack pointer */
64
static char numstr[100];
65
static char *numstrptr;
66
static char backup_token = 0;
67
 
68
int isalnum(char c)
69
{       return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
70
                (c >= '0' && c <= '9');
71
}
72
 
73
int isidch(char c) { return isalnum(c) || c == '_' || c == '$'; }
74
int my_isspace(char c) { return c == ' ' || c == '\t' || c == '\n' || c=='\r'; }
75
int isdigit(char c) { return (c >= '0' && c <= '9'); }
76
 
77
void initsym()
78
{
79
        lptr = inpline;
80
  inpline[0] = 0;
81
  numerrs = 0;
82
  total_errors = 0;
83
  lineno = 0;
84
}
85
 
86
int getline(int listflag)
87
{
88
        int rv;
89
 
90
    if(lineno > 0 && listflag) {
91
        lfs.printf("%6d\t%s",lineno,inpline);
92
                while(numerrs) {
93
                        numerrs--;
94
                        if (numerrs < 80)
95
                                lfs.printf(" *** error %d: %s\n",my_errno[numerrs],errtext(my_errno[numerrs]));
96
                }
97
        numerrs = 0;
98
    }
99
    ++lineno;
100
        memset(inpline, 0, sizeof(inpline));
101
    ifs->getline(inpline,512);
102
        strcat_s(inpline,sizeof(inpline),"\n");
103
        rv = ifs->gcount()==0;
104
        //printf("line:%.60s\r\n", inpline);
105
    if( rv && incldepth > 0 ) {
106
        ifs->close();
107
        ifs = inclfile[--incldepth];
108
        lineno = inclline[incldepth];
109
        return getline(0);
110
    }
111
    if( rv )
112
        return 1;
113
    lptr = inpline;
114
    if(inpline[0] == '#' && !inComment)
115
        return preprocess();
116
    return 0;
117
}
118
 
119
/*
120
 *      getch - basic get character routine.
121
 */
122
int getch()
123
{
124
 
125
        while( (lastch = *lptr++) == '\0') {
126
        if( lstackptr > 0 ) {
127
            lptr = linstack[--lstackptr];
128
            lastch = chstack[lstackptr];
129
            goto j1;
130
        }
131
        if(getline(incldepth == 0))
132
            return lastch = -1;
133
    }
134
 j1:
135
    if (numstrptr >= &numstr[0] && numstrptr < &numstr[98]) {
136
       *numstrptr = lastch;
137
       numstrptr++;
138
    }
139
    return lastch;
140
}
141
 
142
//
143
// getid - get an identifier.
144
//
145
// identifiers are any isidch conglomerate
146
// that doesn't start with a numeric character.
147
// this set INCLUDES keywords.
148
//
149
void getid()
150
{
151
        int    i;
152
    i = 0;
153
    lastid[0] = '_';
154
    while(isidch(lastch)) {
155
                if(i < 120) {
156
                        lastkw[i] = lastch;
157
                        i++;
158
                        lastid[i] = lastch;
159
        }
160
                getch();
161
    }
162
    lastkw[i] = '\0';
163
    lastid[i+1] = '\0';
164
    lastst = id;
165
}
166
 
167
/*
168
 *      getsch - get a character in a quoted string.
169
 *
170
 *      this routine handles all of the escape mechanisms
171
 *      for characters in strings and character constants.
172
 */
173
int     getsch()        /* return an in-quote character */
174
{       register int    i, j;
175
        if(lastch == '\n')
176
                return -1;
177
        if(lastch != '\\' || !parseEsc) {
178
                i = lastch;
179
                getch();
180
                return i;
181
                }
182
        getch();        /* get an escaped character */
183
        if(isdigit(lastch)) {
184
                i = 0;
185
                for(j = i = 0;j < 3;++j) {
186
                        if(lastch <= '7' && lastch >= '0')
187
                                i = (i << 3) + lastch - '0';
188
                        else
189
                                break;
190
                        getch();
191
                        }
192
                return i;
193
                }
194
        i = lastch;
195
        getch();
196
        switch(i) {
197
                case '\n':
198
                        getch();
199
                        return getsch();
200
                case 'b':
201
                        return '\b';
202
                case 'f':
203
                        return '\f';
204
                case 'n':
205
                        return '\n';
206
                case 'r':
207
                        return '\r';
208
                                case 't':
209
                                                return '\t';
210
                default:
211
                        return i;
212
                }
213
}
214
 
215
void getFilename()
216
{
217
        int i;
218
        char j;
219
 
220
    for(i = 0;i < MAX_STRLEN;++i) {
221
            if(lastch == '>')
222
                    break;
223
            if((j = getsch()) == -1)
224
                    break;
225
            else
226
                    laststr[i] = j;
227
            }
228
    laststr[i] = 0;
229
    lastst = sconst;
230
    if(lastch != '>')
231
            error(ERR_SYNTAX);
232
    else
233
            getch();
234
}
235
 
236
int64_t radix36(char c)
237
{
238
        if(isdigit(c))
239
            return c - '0';
240
    if(c >= 'a' && c <= 'z')
241
            return c - 'a' + 10;
242
    if(c >= 'A' && c <= 'Z')
243
            return c - 'A' + 10;
244
    return -1;
245
}
246
 
247
/*
248
 *      getbase - get an integer in any base.
249
 */
250
void getbase(int64_t b)
251
{
252
        register int64_t i0, i1, i2;
253
        register int64_t i, j;
254
        int k;
255
 
256
        i = 0;
257
        i0 = 0;
258
        i1 = 0;
259
        while(isalnum(lastch)) {
260
                if((j = radix36(lastch)) < b) {
261
                        i = i * b + j;
262
                        i2 = i0;
263
                        for (k = 0; k < b; k++) {
264
                            i0 = i0 + i2;
265
                            if (i0 & 0x1000000000000000LL) {
266
                               i0 = i0 - 0x1000000000000000LL;
267
                               i1 = i1 + 1;
268
                            }
269
                        }
270
                        i0 = i0 + j;
271
                        if (i0 & 0x1000000000000000LL) {
272
                            i0 = i0 - 0x1000000000000000LL;
273
                            i1 = i1 + 1;
274
                        }
275
                        getch();
276
                        }
277
                else break;
278
                }
279
                if (lastch=='L' || lastch=='U') // ignore a 'L'ong suffix and 'U'nsigned
280
                        getch();
281
        ival = i;
282
/*
283
        rval.exp = 0x804E;
284
        rval.man1 = (i1 >> 32) & 0xffffL;
285
        rval.man2 = (i1 >> 16) & 0xffffL;
286
        rval.man3 = i1 & 0xffffL;
287
        rval.man4 = (i0 >> 16) & 0ffffL;
288
        rval.man5 = i0 & 0xffffL;
289
        // normalize the number
290
        while (!(rval.man1 & 0x8000)) {
291
             rval.exp--;
292
             rval.man1 = (rval.man1 << 1) | (rval.man2 & 0x8000) ? 1 : 0;
293
             rval.man2 = (rval.man2 << 1) | (rval.man3 & 0x8000) ? 1 : 0;
294
             rval.man3 = (rval.man3 << 1) | (rval.man4 & 0x8000) ? 1 : 0;
295
             rval.man4 = (rval.man4 << 1) | (rval.man5 & 0x8000) ? 1 : 0;
296
             rval.man5 = (rval.man5 << 1);
297
        }
298
*/
299
        lastst = iconst;
300
}
301
 
302
//
303
//      getfrac - get fraction part of a floating number.
304
//
305
void getfrac()
306
{
307
        Float128 frmul128,tmp,ch128,fract128;
308
        double frmul;
309
        double fract = 0.0;
310
        Float128::Assign(&frmul128,Float128::One());
311
    frmul = 1.0;
312
    while(isdigit(lastch)) {
313
                Float128::IntToFloat(&ch128,lastch-'0');
314
                Float128::Mul(&tmp,&fract128,Float128::Ten());
315
                Float128::Add(&fract128,&ch128,&tmp);
316
 
317
        fract = fract * 10.0 + (lastch - '0');
318
        getch();
319
        frmul *= 10.0;
320
                Float128::Mul(&frmul128,&frmul128,Float128::Ten());
321
    }
322
        fract = fract / frmul;
323
        rval += fract;
324
        Float128::Div(&fract128,&fract128,&frmul128);
325
        Float128::Add(&rval128,&rval128,&fract128);
326
}
327
 
328
/*
329
 *      getexp - get exponent part of floating number.
330
 *
331
 *      this algorithm is primative but usefull.  Floating
332
 *      exponents are limited to +/-255 but most hardware
333
 *      won't support more anyway.
334
 */
335
void getexp()
336
{
337
                double  expo, exmul;
338
                Float128 exp128, exmul128;
339
 
340
                Float128::Assign(&exp128,Float128::One());
341
        expo = 1.0;
342
        if(lastst != rconst)
343
                rval = (double)ival;
344
        if(lastch == '-') {
345
                        Float128::Assign(&exmul128,Float128::OneTenth());
346
                exmul = 0.1;
347
                getch();
348
                }
349
                else if (lastch=='+') {
350
                        getch();
351
                        Float128::Assign(&exmul128,Float128::Ten());
352
                exmul = 10.0;
353
                }
354
        else {
355
                        Float128::Assign(&exmul128,Float128::Ten());
356
                exmul = 10.0;
357
                }
358
        getbase(10);
359
        if(ival > 32767)
360
                error(ERR_FPCON);
361
        else
362
                while(ival--) {
363
                                        Float128::Mul(&exp128,&exp128,&exmul128);
364
                        expo *= exmul;
365
                                }
366
                Float128::Mul(&rval128,&rval128,&exp128);
367
        rval *= expo;
368
}
369
 
370
/*
371
 *      getnum - get a number from input.
372
 *
373
 *      getnum handles all of the numeric input. it accepts
374
 *      decimal, octal, hexidecimal, and floating point numbers.
375
 */
376
void getnum()
377
{       register int    i;
378
        i = 0;
379
 
380
        ival = 0;
381
        rval = 0.0;
382
                Float128::Assign(&rval128,Float128::Zero());
383
        numstrptr = &numstr[0];
384
         *numstrptr = lastch;
385
         numstrptr++;
386
        if(lastch == '0') {
387
                getch();
388
                if (lastch=='.')
389
                     goto j1;
390
                if(lastch == 'x' || lastch == 'X') {
391
                        getch();
392
                        getbase(16);
393
                        }
394
                else getbase(8);
395
                }
396
        else    {
397
                getbase(10);
398
j1:
399
                if(lastch == '.') {
400
                        getch();
401
                        rval = (double)ival;    /* float the integer part */
402
                                                Float128::IntToFloat(&rval128, (__int64)ival);
403
                        getfrac();      /* add the fractional part */
404
                        lastst = rconst;
405
                        }
406
                if(lastch == 'e' || lastch == 'E') {
407
                        getch();
408
                        getexp();       /* get the exponent */
409
                                                // This must be reset because getting the exponent
410
                                                // calls getbase() which will set lastst=iconst
411
                                                lastst = rconst;
412
                        }
413
 
414
                                if (lastst==rconst && (lastch=='Q' || lastch=='q' ||
415
                                        lastch=='D' || lastch=='d' || lastch=='s' || lastch=='S' || lastch=='T' || lastch=='t')) {
416
                                                float_precision = tolower(lastch);
417
                                                getch();
418
                                }
419
                                else
420
                                        float_precision = 'd';
421
 
422
                                // Ignore 'U' unsigned suffix
423
                                if (lastch=='U' || lastch=='u') {
424
                                        getch();
425
                                }
426
                                }
427
    numstrptr[-1]='\0';
428
    numstrptr = NULL;
429
//    dd_real::read(numstr,rval);
430
//    printf("leave getnum=%s\r\n", numstr);
431
 
432
}
433
 
434
void SkipSpaces()
435
{
436
    while( my_isspace(lastch) ) {
437
        getch();
438
    }
439
}
440
/*
441
 *      NextToken - get next symbol from input stream.
442
 *
443
 *      NextToken is the basic lexical analyzer.  It builds
444
 *      basic tokens out of the characters on the input
445
 *      stream and sets the following global variables:
446
 *
447
 *      lastch:         A look behind buffer.
448
 *      lastst:         type of last symbol read.
449
 *      laststr:        last string constant read.
450
 *      lastid:         last identifier read.
451
 *      ival:           last integer constant read.
452
 *      rval:           last real constant read.
453
 *
454
 *      NextToken should be called for all your input needs...
455
 */
456
void NextToken()
457
{
458
  int i, j;
459
  SYM *sp;
460
  int tch;
461
restart:        /* we come back here after comments */
462
  if (backup_token) {
463
     backup_token = 0;
464
     lastch = '(';
465
     lastst = openpa;
466
     return;
467
  }
468
        SkipSpaces();
469
  if( lastch == -1) {
470
    lastst = my_eof;
471
    dfs.printf("Returning EOF from NextToken.\n");
472
  }
473
  else if(isdigit(lastch)) {
474
    getnum();
475
  }
476
  else if(isidch(lastch)) {
477
    getid();
478
 
479
                if( (sp = defsyms.Find(lastid,false)) != NULL) {
480
                        tch = lastch;
481
                        if (!(lastch==')' && sp->value.s[0]=='(')) {
482
                                if (lstackptr < 19) {
483
                                        linstack[lstackptr] = lptr;
484
                                        chstack[lstackptr++] = tch;
485
                                        lptr = sp->value.s;
486
                        }
487
                                getch();
488
                                goto restart;
489
                        }
490
                }
491
 
492
  }
493
  else {
494
  switch(lastch) {
495
  case '+':
496
    getch();
497
    if(lastch == '+') {
498
            getch();
499
            lastst = autoinc;
500
            }
501
    else if(lastch == '=') {
502
            getch();
503
            lastst = asplus;
504
            }
505
    else
506
                lastst = plus;
507
    break;
508
                case '-':
509
                        getch();
510
                        if(lastch == '-') {
511
                                getch();
512
                                lastst = autodec;
513
                                }
514
                        else if(lastch == '=') {
515
                                getch();
516
                                lastst = asminus;
517
                                }
518
                        else if(lastch == '>') {
519
                                getch();
520
                                lastst = pointsto;
521
                                }
522
                        else
523
                                                        lastst = minus;
524
                        break;
525
                case '*':
526
                        getch();
527
                        if(lastch == '=') {
528
                                getch();
529
                                lastst = astimes;
530
                                }
531
                        else lastst = star;
532
                        break;
533
                case '/':
534
                        getch();
535
                        if(lastch == '=') {
536
                          getch();
537
                          lastst = asdivide;
538
                        }
539
                        else if(lastch == '*') {
540
                          inComment = TRUE;
541
                          getch();
542
                                for(;;) {
543
                                        if(lastch == '*') {
544
                                                getch();
545
                                                if(lastch == '/') {
546
                                                        getch();
547
                                                                                                                inComment = FALSE;
548
                                                        goto restart;
549
                                                        }
550
                                                }
551
                                        else
552
                                                getch();
553
                                        }
554
                                }
555
                                                else if (lastch == '/') {
556
 
557
                                                        inComment = TRUE;
558
                                                        for(;;) {
559
                                                                getch();
560
                                                                if (lastch=='\n' || lastch==-1) {
561
                                                                        //getch();
562
                                                                        inComment = FALSE;
563
                                                                        goto restart;
564
                                                                }
565
                                                        }
566
 
567
                                                }
568
                        else lastst = divide;
569
                        break;
570
                case '^':
571
                        getch();
572
                        if( lastch == '=') {
573
                                                        lastst = asxor;
574
                                                        getch();
575
                        }
576
                                                else
577
                                                        lastst = uparrow;
578
                        break;
579
                case ';':
580
                        getch();
581
                        lastst = semicolon;
582
                        break;
583
                case ':':
584
                        getch();
585
                                                if (lastch==':') {
586
                                                        lastst = double_colon;
587
                                                        getch();
588
                                                }
589
                                                else
590
                                                        lastst = colon;
591
                        break;
592
                case '=':
593
                        getch();
594
                        if(lastch == '=') {
595
                                getch();
596
                                lastst = eq;
597
                                }
598
                        else lastst = assign;
599
                        break;
600
                case '>':
601
                        getch();
602
                        if(lastch == '=') {
603
                            getch();
604
                            lastst = geq;
605
                        }
606
                        else if(lastch == '>') {
607
                            getch();
608
                            if(lastch == '=') {
609
                                getch();
610
                                lastst = asrshift;
611
                            }
612
                                                        else if (lastch=='>') {
613
                                                                getch();
614
                                                                if (lastch=='=') {
615
                                                                        getch();
616
                                                                        lastst = asrrot;
617
                                                                }
618
                                                                else
619
                                                                        lastst = rrot;
620
                                                        }
621
                            else lastst = rshift;
622
                        }
623
                        else lastst = gt;
624
                        break;
625
                case '<':
626
                        getch();
627
                        if(lastch == '=') {
628
                                getch();
629
                                lastst = leq;
630
                                }
631
                        else if(lastch == '<') {
632
                                getch();
633
                                if(lastch == '=') {
634
                                    getch();
635
                                    lastst = aslshift;
636
                                }
637
                                                                else if (lastch=='<') {
638
                                                                        getch();
639
                                                                        if (lastch=='=') {
640
                                                                                getch();
641
                                                                                lastst = aslrot;
642
                                                                        }
643
                                                                        else
644
                                                                                lastst = lrot;
645
                                                                }
646
                                                                else
647
                                                                        lastst = lshift;
648
                                                }
649
                                                else if (lastch == '>') {
650
                                                        getch();
651
                                                        lastst = neq;
652
                                                }
653
                        else lastst = lt;
654
                        break;
655
                case '\'':
656
                        getch();
657
                        ival = getsch();        /* get a string char */
658
                        if(lastch != '\'')
659
                                error(ERR_SYNTAX);
660
                        else
661
                                getch();
662
                        lastst = cconst;
663
                        break;
664
                case '\"':
665
                        getch();
666
                        for(i = 0;i < MAX_STRLEN;++i) {
667
                                if(lastch == '\"')
668
                                        break;
669
                                if((j = getsch()) == -1)
670
                                        break;
671
                                else
672
                                        laststr[i] = j;
673
                                }
674
                        laststr[i] = 0;
675
                        lastst = sconst;
676
                        if(lastch != '\"')
677
                                error(ERR_SYNTAX);
678
                        else
679
                                getch();
680
                        break;
681
                case '!':
682
                        getch();
683
                        if(lastch == '=') {
684
                                getch();
685
                                lastst = neq;
686
                                }
687
                        else lastst = nott;
688
                        break;
689
                case '%':
690
                        getch();
691
                        if(lastch == '=') {
692
                                getch();
693
                                lastst = asmodop;
694
                                }
695
                        else lastst = modop;
696
                        break;
697
                case '~':
698
                        getch();
699
                        lastst = cmpl;
700
                        break;
701
                case '.':
702
                        getch();
703
                        lastst = dot;
704
                                                if (lastch=='.') {
705
                                                        getch();
706
                                                        if (lastch=='.') {
707
                                                                getch();
708
                                                                lastst = ellipsis;
709
                                                                strcpy_s(lastid, sizeof(lastid), "...");
710
                                                        }
711
                                                }
712
                        break;
713
                case ',':
714
                        getch();
715
                        lastst = comma;
716
                        break;
717
                case '&':
718
                        getch();
719
                        if( lastch == '&') {
720
                                lastst = land;
721
                                getch();
722
                                }
723
                        else if( lastch == '=') {
724
                                lastst = asand;
725
                                getch();
726
                                }
727
                        else
728
                                lastst = bitandd;
729
                        break;
730
                case '|':
731
                        getch();
732
                        if(lastch == '|') {
733
                                lastst = lor;
734
                                getch();
735
                                }
736
                        else if( lastch == '=') {
737
                                lastst = asor;
738
                                getch();
739
                                }
740
                        else
741
                                lastst = bitorr;
742
                        break;
743
                case '(':
744
                        getch();
745
                        lastst = openpa;
746
                        break;
747
                case ')':
748
                        getch();
749
                        lastst = closepa;
750
                        break;
751
                case '[':
752
                        getch();
753
                        lastst = openbr;
754
                        break;
755
                case ']':
756
                        getch();
757
                        lastst = closebr;
758
                        break;
759
                case '{':
760
                        getch();
761
                        lastst = begin;
762
                        break;
763
                case '}':
764
                        getch();
765
                        lastst = end;
766
                        break;
767
                case '?':
768
                        getch();
769
                        lastst = hook;
770
                        break;
771
                case '\\':
772
                        getch();
773
                        goto restart;
774
                default:
775
                        getch();
776
                        error(ERR_ILLCHAR);
777
                        goto restart;   /* get a real token */
778
                }
779
              }
780
  if(lastst == id)
781
    IdentifyKeyword();
782
//      printf("token: %d",lastst);
783
//      if (lastst==id)
784
//              printf("lastid=%s| ", lastid);
785
}
786
 
787
void needpunc(enum e_sym p,int clue)
788
{
789
        if( lastst == p)
790
        NextToken();
791
        else {
792
                //printf("%d %s\r\n", lineno, inpline);
793
                printf("*************clue:%d************\r\n",clue);
794
        error(ERR_PUNCT);
795
        }
796
}
797
 
798
void backup() {
799
    backup_token = 1;
800
}

powered by: WebSVN 2.1.0

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