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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [lcc/] [src/] [lex.c.ORIG] - Rev 16

Go to most recent revision | Compare with Previous | Blame | View Log

#include "c.h"
#include <float.h>
#include <errno.h>

static char rcsid[] = "$Id: lex.c,v 1.1 2002/08/28 23:12:44 drh Exp $";

#define MAXTOKEN 32

enum { BLANK=01,  NEWLINE=02, LETTER=04,
       DIGIT=010, HEX=020,    OTHER=040 };

static unsigned char map[256] = { /* 000 nul */ 0,
                                   /* 001 soh */        0,
                                   /* 002 stx */        0,
                                   /* 003 etx */        0,
                                   /* 004 eot */        0,
                                   /* 005 enq */        0,
                                   /* 006 ack */        0,
                                   /* 007 bel */        0,
                                   /* 010 bs  */        0,
                                   /* 011 ht  */        BLANK,
                                   /* 012 nl  */        NEWLINE,
                                   /* 013 vt  */        BLANK,
                                   /* 014 ff  */        BLANK,
                                   /* 015 cr  */        0,
                                   /* 016 so  */        0,
                                   /* 017 si  */        0,
                                   /* 020 dle */        0,
                                   /* 021 dc1 */        0,
                                   /* 022 dc2 */        0,
                                   /* 023 dc3 */        0,
                                   /* 024 dc4 */        0,
                                   /* 025 nak */        0,
                                   /* 026 syn */        0,
                                   /* 027 etb */        0,
                                   /* 030 can */        0,
                                   /* 031 em  */        0,
                                   /* 032 sub */        0,
                                   /* 033 esc */        0,
                                   /* 034 fs  */        0,
                                   /* 035 gs  */        0,
                                   /* 036 rs  */        0,
                                   /* 037 us  */        0,
                                   /* 040 sp  */        BLANK,
                                   /* 041 !   */        OTHER,
                                   /* 042 "   */        OTHER,
                                   /* 043 #   */        OTHER,
                                   /* 044 $   */        0,
                                   /* 045 %   */        OTHER,
                                   /* 046 &   */        OTHER,
                                   /* 047 '   */        OTHER,
                                   /* 050 (   */        OTHER,
                                   /* 051 )   */        OTHER,
                                   /* 052 *   */        OTHER,
                                   /* 053 +   */        OTHER,
                                   /* 054 ,   */        OTHER,
                                   /* 055 -   */        OTHER,
                                   /* 056 .   */        OTHER,
                                   /* 057 /   */        OTHER,
                                   /* 060 0   */        DIGIT,
                                   /* 061 1   */        DIGIT,
                                   /* 062 2   */        DIGIT,
                                   /* 063 3   */        DIGIT,
                                   /* 064 4   */        DIGIT,
                                   /* 065 5   */        DIGIT,
                                   /* 066 6   */        DIGIT,
                                   /* 067 7   */        DIGIT,
                                   /* 070 8   */        DIGIT,
                                   /* 071 9   */        DIGIT,
                                   /* 072 :   */        OTHER,
                                   /* 073 ;   */        OTHER,
                                   /* 074 <   */        OTHER,
                                   /* 075 =   */        OTHER,
                                   /* 076 >   */        OTHER,
                                   /* 077 ?   */        OTHER,
                                   /* 100 @   */        0,
                                   /* 101 A   */        LETTER|HEX,
                                   /* 102 B   */        LETTER|HEX,
                                   /* 103 C   */        LETTER|HEX,
                                   /* 104 D   */        LETTER|HEX,
                                   /* 105 E   */        LETTER|HEX,
                                   /* 106 F   */        LETTER|HEX,
                                   /* 107 G   */        LETTER,
                                   /* 110 H   */        LETTER,
                                   /* 111 I   */        LETTER,
                                   /* 112 J   */        LETTER,
                                   /* 113 K   */        LETTER,
                                   /* 114 L   */        LETTER,
                                   /* 115 M   */        LETTER,
                                   /* 116 N   */        LETTER,
                                   /* 117 O   */        LETTER,
                                   /* 120 P   */        LETTER,
                                   /* 121 Q   */        LETTER,
                                   /* 122 R   */        LETTER,
                                   /* 123 S   */        LETTER,
                                   /* 124 T   */        LETTER,
                                   /* 125 U   */        LETTER,
                                   /* 126 V   */        LETTER,
                                   /* 127 W   */        LETTER,
                                   /* 130 X   */        LETTER,
                                   /* 131 Y   */        LETTER,
                                   /* 132 Z   */        LETTER,
                                   /* 133 [   */        OTHER,
                                   /* 134 \   */        OTHER,
                                   /* 135 ]   */        OTHER,
                                   /* 136 ^   */        OTHER,
                                   /* 137 _   */        LETTER,
                                   /* 140 `   */        0,
                                   /* 141 a   */        LETTER|HEX,
                                   /* 142 b   */        LETTER|HEX,
                                   /* 143 c   */        LETTER|HEX,
                                   /* 144 d   */        LETTER|HEX,
                                   /* 145 e   */        LETTER|HEX,
                                   /* 146 f   */        LETTER|HEX,
                                   /* 147 g   */        LETTER,
                                   /* 150 h   */        LETTER,
                                   /* 151 i   */        LETTER,
                                   /* 152 j   */        LETTER,
                                   /* 153 k   */        LETTER,
                                   /* 154 l   */        LETTER,
                                   /* 155 m   */        LETTER,
                                   /* 156 n   */        LETTER,
                                   /* 157 o   */        LETTER,
                                   /* 160 p   */        LETTER,
                                   /* 161 q   */        LETTER,
                                   /* 162 r   */        LETTER,
                                   /* 163 s   */        LETTER,
                                   /* 164 t   */        LETTER,
                                   /* 165 u   */        LETTER,
                                   /* 166 v   */        LETTER,
                                   /* 167 w   */        LETTER,
                                   /* 170 x   */        LETTER,
                                   /* 171 y   */        LETTER,
                                   /* 172 z   */        LETTER,
                                   /* 173 {   */        OTHER,
                                   /* 174 |   */        OTHER,
                                   /* 175 }   */        OTHER,
                                   /* 176 ~   */        OTHER, };
static struct symbol tval;
static char cbuf[BUFSIZE+1];
static unsigned int wcbuf[BUFSIZE+1];

Coordinate src;         /* current source coordinate */
int t;
char *token;            /* current token */
Symbol tsym;            /* symbol table entry for current token */

static void *cput(int c, void *cl);
static void *wcput(int c, void *cl);
static void *scon(int q, void *put(int c, void *cl), void *cl);
static int backslash(int q);
static Symbol fcon(void);
static Symbol icon(unsigned long, int, int);
static void ppnumber(char *);

int gettok(void) {
        for (;;) {
                register unsigned char *rcp = cp;
                while (map[*rcp]&BLANK)
                        rcp++;
                if (limit - rcp < MAXTOKEN) {
                        cp = rcp;
                        fillbuf();
                        rcp = cp;
                }
                src.file = file;
                src.x = (char *)rcp - line;
                src.y = lineno;
                cp = rcp + 1;
                switch (*rcp++) {
                case '/': if (*rcp == '*') {
                                int c = 0;
                                for (rcp++; *rcp != '/' || c != '*'; )
                                        if (map[*rcp]&NEWLINE) {
                                                if (rcp < limit)
                                                        c = *rcp;
                                                cp = rcp + 1;
                                                nextline();
                                                rcp = cp;
                                                if (rcp == limit)
                                                        break;
                                        } else
                                                c = *rcp++;
                                if (rcp < limit)
                                        rcp++;
                                else
                                        error("unclosed comment\n");
                                cp = rcp;
                                continue;
                          }
                          return '/';
                case '<':
                        if (*rcp == '=') return cp++, LEQ;
                        if (*rcp == '<') return cp++, LSHIFT;
                        return '<';
                case '>':
                        if (*rcp == '=') return cp++, GEQ;
                        if (*rcp == '>') return cp++, RSHIFT;
                        return '>';
                case '-':
                        if (*rcp == '>') return cp++, DEREF;
                        if (*rcp == '-') return cp++, DECR;
                        return '-';
                case '=': return *rcp == '=' ? cp++, EQL    : '=';
                case '!': return *rcp == '=' ? cp++, NEQ    : '!';
                case '|': return *rcp == '|' ? cp++, OROR   : '|';
                case '&': return *rcp == '&' ? cp++, ANDAND : '&';
                case '+': return *rcp == '+' ? cp++, INCR   : '+';
                case ';': case ',': case ':':
                case '*': case '~': case '%': case '^': case '?':
                case '[': case ']': case '{': case '}': case '(': case ')': 
                        return rcp[-1];
                case '\n': case '\v': case '\r': case '\f':
                        nextline();
                        if (cp == limit) {
                                tsym = NULL;
                                return EOI;
                        }
                        continue;

                case 'i':
                        if (rcp[0] == 'f'
                        && !(map[rcp[1]]&(DIGIT|LETTER))) {
                                cp = rcp + 1;
                                return IF;
                        }
                        if (rcp[0] == 'n'
                        &&  rcp[1] == 't'
                        && !(map[rcp[2]]&(DIGIT|LETTER))) {
                                cp = rcp + 2;
                                tsym = inttype->u.sym;
                                return INT;
                        }
                        goto id;
                case 'h': case 'j': case 'k': case 'm': case 'n': case 'o':
                case 'p': case 'q': case 'x': case 'y': case 'z':
                case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
                case 'G': case 'H': case 'I': case 'J': case 'K':
                case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
                case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
                case 'Y': case 'Z':
                id:
                        if (limit - rcp < MAXLINE) {
                                cp = rcp - 1;
                                fillbuf();
                                rcp = ++cp;
                        }
                        assert(cp == rcp);
                        token = (char *)rcp - 1;
                        while (map[*rcp]&(DIGIT|LETTER))
                                rcp++;
                        token = stringn(token, (char *)rcp - token);
                        tsym = lookup(token, identifiers);
                        cp = rcp;
                        return ID;
                case '0': case '1': case '2': case '3': case '4':
                case '5': case '6': case '7': case '8': case '9': {
                        unsigned long n = 0;
                        if (limit - rcp < MAXLINE) {
                                cp = rcp - 1;
                                fillbuf();
                                rcp = ++cp;
                        }
                        assert(cp == rcp);
                        token = (char *)rcp - 1;
                        if (*token == '0' && (*rcp == 'x' || *rcp == 'X')) {
                                int d, overflow = 0;
                                while (*++rcp) {
                                        if (map[*rcp]&DIGIT)
                                                d = *rcp - '0';
                                        else if (*rcp >= 'a' && *rcp <= 'f')
                                                d = *rcp - 'a' + 10;
                                        else if (*rcp >= 'A' && *rcp <= 'F')
                                                d = *rcp - 'A' + 10;
                                        else
                                                break;
                                        if (n&~(~0UL >> 4))
                                                overflow = 1;
                                        else
                                                n = (n<<4) + d;
                                }
                                if ((char *)rcp - token <= 2)
                                        error("invalid hexadecimal constant `%S'\n", token, (char *)rcp-token);
                                cp = rcp;
                                tsym = icon(n, overflow, 16);
                        } else if (*token == '0') {
                                int err = 0, overflow = 0;
                                for ( ; map[*rcp]&DIGIT; rcp++) {
                                        if (*rcp == '8' || *rcp == '9')
                                                err = 1;
                                        if (n&~(~0UL >> 3))
                                                overflow = 1;
                                        else
                                                n = (n<<3) + (*rcp - '0');
                                }
                                if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') {
                                        cp = rcp;
                                        tsym = fcon();
                                        return FCON;
                                }
                                cp = rcp;
                                tsym = icon(n, overflow, 8);
                                if (err)
                                        error("invalid octal constant `%S'\n", token, (char*)cp-token);
                        } else {
                                int overflow = 0;
                                for (n = *token - '0'; map[*rcp]&DIGIT; ) {
                                        int d = *rcp++ - '0';
                                        if (n > (ULONG_MAX - d)/10)
                                                overflow = 1;
                                        else
                                                n = 10*n + d;
                                }
                                if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') {
                                        cp = rcp;
                                        tsym = fcon();
                                        return FCON;
                                }
                                cp = rcp;
                                tsym = icon(n, overflow, 10);
                        }
                        return ICON;
                }
                case '.':
                        if (rcp[0] == '.' && rcp[1] == '.') {
                                cp += 2;
                                return ELLIPSIS;
                        }
                        if ((map[*rcp]&DIGIT) == 0)
                                return '.';
                        if (limit - rcp < MAXLINE) {
                                cp = rcp - 1;
                                fillbuf();
                                rcp = ++cp;
                        }
                        assert(cp == rcp);
                        cp = rcp - 1;
                        token = (char *)cp;
                        tsym = fcon();
                        return FCON;
                case 'L':
                        if (*rcp == '\'') {
                                unsigned int *s = scon(*cp, wcput, wcbuf);
                                if (s - wcbuf > 2)
                                        warning("excess characters in wide-character literal ignored\n");
                                tval.type = widechar;
                                tval.u.c.v.u = wcbuf[0];
                                tsym = &tval;
                                return ICON;
                        } else if (*rcp == '"') {
                                unsigned int *s = scon(*cp, wcput, wcbuf);
                                tval.type = array(widechar, s - wcbuf, 0);
                                tval.u.c.v.p = wcbuf;
                                tsym = &tval;
                                return SCON;
                        } else
                                goto id;
                case '\'': {
                        char *s = scon(*--cp, cput, cbuf);
                        if (s - cbuf > 2)
                                warning("excess characters in multibyte character literal ignored\n");
                        tval.type = inttype;
                        if (chartype->op == INT)
                                tval.u.c.v.i = extend(cbuf[0], chartype);
                        else
                                tval.u.c.v.i = cbuf[0]&0xFF;
                        tsym = &tval;
                        return ICON;
                        }
                case '"': {
                        char *s = scon(*--cp, cput, cbuf);
                        tval.type = array(chartype, s - cbuf, 0);
                        tval.u.c.v.p = cbuf;
                        tsym = &tval;
                        return SCON;
                        }
                case 'a':
                        if (rcp[0] == 'u'
                        &&  rcp[1] == 't'
                        &&  rcp[2] == 'o'
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
                                cp = rcp + 3;
                                return AUTO;
                        }
                        goto id;
                case 'b':
                        if (rcp[0] == 'r'
                        &&  rcp[1] == 'e'
                        &&  rcp[2] == 'a'
                        &&  rcp[3] == 'k'
                        && !(map[rcp[4]]&(DIGIT|LETTER))) {
                                cp = rcp + 4;
                                return BREAK;
                        }
                        goto id;
                case 'c':
                        if (rcp[0] == 'a'
                        &&  rcp[1] == 's'
                        &&  rcp[2] == 'e'
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
                                cp = rcp + 3;
                                return CASE;
                        }
                        if (rcp[0] == 'h'
                        &&  rcp[1] == 'a'
                        &&  rcp[2] == 'r'
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
                                cp = rcp + 3;
                                tsym = chartype->u.sym;
                                return CHAR;
                        }
                        if (rcp[0] == 'o'
                        &&  rcp[1] == 'n'
                        &&  rcp[2] == 's'
                        &&  rcp[3] == 't'
                        && !(map[rcp[4]]&(DIGIT|LETTER))) {
                                cp = rcp + 4;
                                return CONST;
                        }
                        if (rcp[0] == 'o'
                        &&  rcp[1] == 'n'
                        &&  rcp[2] == 't'
                        &&  rcp[3] == 'i'
                        &&  rcp[4] == 'n'
                        &&  rcp[5] == 'u'
                        &&  rcp[6] == 'e'
                        && !(map[rcp[7]]&(DIGIT|LETTER))) {
                                cp = rcp + 7;
                                return CONTINUE;
                        }
                        goto id;
                case 'd':
                        if (rcp[0] == 'e'
                        &&  rcp[1] == 'f'
                        &&  rcp[2] == 'a'
                        &&  rcp[3] == 'u'
                        &&  rcp[4] == 'l'
                        &&  rcp[5] == 't'
                        && !(map[rcp[6]]&(DIGIT|LETTER))) {
                                cp = rcp + 6;
                                return DEFAULT;
                        }
                        if (rcp[0] == 'o'
                        &&  rcp[1] == 'u'
                        &&  rcp[2] == 'b'
                        &&  rcp[3] == 'l'
                        &&  rcp[4] == 'e'
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
                                cp = rcp + 5;
                                tsym = doubletype->u.sym;
                                return DOUBLE;
                        }
                        if (rcp[0] == 'o'
                        && !(map[rcp[1]]&(DIGIT|LETTER))) {
                                cp = rcp + 1;
                                return DO;
                        }
                        goto id;
                case 'e':
                        if (rcp[0] == 'l'
                        &&  rcp[1] == 's'
                        &&  rcp[2] == 'e'
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
                                cp = rcp + 3;
                                return ELSE;
                        }
                        if (rcp[0] == 'n'
                        &&  rcp[1] == 'u'
                        &&  rcp[2] == 'm'
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
                                cp = rcp + 3;
                                return ENUM;
                        }
                        if (rcp[0] == 'x'
                        &&  rcp[1] == 't'
                        &&  rcp[2] == 'e'
                        &&  rcp[3] == 'r'
                        &&  rcp[4] == 'n'
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
                                cp = rcp + 5;
                                return EXTERN;
                        }
                        goto id;
                case 'f':
                        if (rcp[0] == 'l'
                        &&  rcp[1] == 'o'
                        &&  rcp[2] == 'a'
                        &&  rcp[3] == 't'
                        && !(map[rcp[4]]&(DIGIT|LETTER))) {
                                cp = rcp + 4;
                                tsym = floattype->u.sym;
                                return FLOAT;
                        }
                        if (rcp[0] == 'o'
                        &&  rcp[1] == 'r'
                        && !(map[rcp[2]]&(DIGIT|LETTER))) {
                                cp = rcp + 2;
                                return FOR;
                        }
                        goto id;
                case 'g':
                        if (rcp[0] == 'o'
                        &&  rcp[1] == 't'
                        &&  rcp[2] == 'o'
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
                                cp = rcp + 3;
                                return GOTO;
                        }
                        goto id;
                case 'l':
                        if (rcp[0] == 'o'
                        &&  rcp[1] == 'n'
                        &&  rcp[2] == 'g'
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
                                cp = rcp + 3;
                                return LONG;
                        }
                        goto id;
                case 'r':
                        if (rcp[0] == 'e'
                        &&  rcp[1] == 'g'
                        &&  rcp[2] == 'i'
                        &&  rcp[3] == 's'
                        &&  rcp[4] == 't'
                        &&  rcp[5] == 'e'
                        &&  rcp[6] == 'r'
                        && !(map[rcp[7]]&(DIGIT|LETTER))) {
                                cp = rcp + 7;
                                return REGISTER;
                        }
                        if (rcp[0] == 'e'
                        &&  rcp[1] == 't'
                        &&  rcp[2] == 'u'
                        &&  rcp[3] == 'r'
                        &&  rcp[4] == 'n'
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
                                cp = rcp + 5;
                                return RETURN;
                        }
                        goto id;
                case 's':
                        if (rcp[0] == 'h'
                        &&  rcp[1] == 'o'
                        &&  rcp[2] == 'r'
                        &&  rcp[3] == 't'
                        && !(map[rcp[4]]&(DIGIT|LETTER))) {
                                cp = rcp + 4;
                                return SHORT;
                        }
                        if (rcp[0] == 'i'
                        &&  rcp[1] == 'g'
                        &&  rcp[2] == 'n'
                        &&  rcp[3] == 'e'
                        &&  rcp[4] == 'd'
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
                                cp = rcp + 5;
                                return SIGNED;
                        }
                        if (rcp[0] == 'i'
                        &&  rcp[1] == 'z'
                        &&  rcp[2] == 'e'
                        &&  rcp[3] == 'o'
                        &&  rcp[4] == 'f'
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
                                cp = rcp + 5;
                                return SIZEOF;
                        }
                        if (rcp[0] == 't'
                        &&  rcp[1] == 'a'
                        &&  rcp[2] == 't'
                        &&  rcp[3] == 'i'
                        &&  rcp[4] == 'c'
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
                                cp = rcp + 5;
                                return STATIC;
                        }
                        if (rcp[0] == 't'
                        &&  rcp[1] == 'r'
                        &&  rcp[2] == 'u'
                        &&  rcp[3] == 'c'
                        &&  rcp[4] == 't'
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
                                cp = rcp + 5;
                                return STRUCT;
                        }
                        if (rcp[0] == 'w'
                        &&  rcp[1] == 'i'
                        &&  rcp[2] == 't'
                        &&  rcp[3] == 'c'
                        &&  rcp[4] == 'h'
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
                                cp = rcp + 5;
                                return SWITCH;
                        }
                        goto id;
                case 't':
                        if (rcp[0] == 'y'
                        &&  rcp[1] == 'p'
                        &&  rcp[2] == 'e'
                        &&  rcp[3] == 'd'
                        &&  rcp[4] == 'e'
                        &&  rcp[5] == 'f'
                        && !(map[rcp[6]]&(DIGIT|LETTER))) {
                                cp = rcp + 6;
                                return TYPEDEF;
                        }
                        goto id;
                case 'u':
                        if (rcp[0] == 'n'
                        &&  rcp[1] == 'i'
                        &&  rcp[2] == 'o'
                        &&  rcp[3] == 'n'
                        && !(map[rcp[4]]&(DIGIT|LETTER))) {
                                cp = rcp + 4;
                                return UNION;
                        }
                        if (rcp[0] == 'n'
                        &&  rcp[1] == 's'
                        &&  rcp[2] == 'i'
                        &&  rcp[3] == 'g'
                        &&  rcp[4] == 'n'
                        &&  rcp[5] == 'e'
                        &&  rcp[6] == 'd'
                        && !(map[rcp[7]]&(DIGIT|LETTER))) {
                                cp = rcp + 7;
                                return UNSIGNED;
                        }
                        goto id;
                case 'v':
                        if (rcp[0] == 'o'
                        &&  rcp[1] == 'i'
                        &&  rcp[2] == 'd'
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
                                cp = rcp + 3;
                                tsym = voidtype->u.sym;
                                return VOID;
                        }
                        if (rcp[0] == 'o'
                        &&  rcp[1] == 'l'
                        &&  rcp[2] == 'a'
                        &&  rcp[3] == 't'
                        &&  rcp[4] == 'i'
                        &&  rcp[5] == 'l'
                        &&  rcp[6] == 'e'
                        && !(map[rcp[7]]&(DIGIT|LETTER))) {
                                cp = rcp + 7;
                                return VOLATILE;
                        }
                        goto id;
                case 'w':
                        if (rcp[0] == 'h'
                        &&  rcp[1] == 'i'
                        &&  rcp[2] == 'l'
                        &&  rcp[3] == 'e'
                        && !(map[rcp[4]]&(DIGIT|LETTER))) {
                                cp = rcp + 4;
                                return WHILE;
                        }
                        goto id;
                case '_':
                        if (rcp[0] == '_'
                        &&  rcp[1] == 't'
                        &&  rcp[2] == 'y'
                        &&  rcp[3] == 'p'
                        &&  rcp[4] == 'e'
                        &&  rcp[5] == 'c'
                        &&  rcp[6] == 'o'
                        &&  rcp[7] == 'd'
                        &&  rcp[8] == 'e'
                        && !(map[rcp[9]]&(DIGIT|LETTER))) {
                                cp = rcp + 9;
                                return TYPECODE;
                        }
                        if (rcp[0] == '_'
                        &&  rcp[1] == 'f'
                        &&  rcp[2] == 'i'
                        &&  rcp[3] == 'r'
                        &&  rcp[4] == 's'
                        &&  rcp[5] == 't'
                        &&  rcp[6] == 'a'
                        &&  rcp[7] == 'r'
                        &&  rcp[8] == 'g'
                        && !(map[rcp[9]]&(DIGIT|LETTER))) {
                                cp = rcp + 9;
                                return FIRSTARG;
                        }
                        goto id;
                default:
                        if ((map[cp[-1]]&BLANK) == 0)
                                if (cp[-1] < ' ' || cp[-1] >= 0177)
                                        error("illegal character `\\0%o'\n", cp[-1]);
                                else
                                        error("illegal character `%c'\n", cp[-1]);
                }
        }
}
static Symbol icon(unsigned long n, int overflow, int base) {
        if ((*cp=='u'||*cp=='U') && (cp[1]=='l'||cp[1]=='L')
        ||  (*cp=='l'||*cp=='L') && (cp[1]=='u'||cp[1]=='U')) {
                tval.type = unsignedlong;
                cp += 2;
        } else if (*cp == 'u' || *cp == 'U') {
                if (overflow || n > unsignedtype->u.sym->u.limits.max.i)
                        tval.type = unsignedlong;
                else
                        tval.type = unsignedtype;
                cp += 1;
        } else if (*cp == 'l' || *cp == 'L') {
                if (overflow || n > longtype->u.sym->u.limits.max.i)
                        tval.type = unsignedlong;
                else
                        tval.type = longtype;
                cp += 1;
        } else if (overflow || n > longtype->u.sym->u.limits.max.i)
                tval.type = unsignedlong;
        else if (n > inttype->u.sym->u.limits.max.i)
                tval.type = longtype;
        else if (base != 10 && n > inttype->u.sym->u.limits.max.i)
                tval.type = unsignedtype;
        else
                tval.type = inttype;
        switch (tval.type->op) {
        case INT:
                if (overflow || n > tval.type->u.sym->u.limits.max.i) {
                        warning("overflow in constant `%S'\n", token,
                                (char*)cp - token);
                        tval.u.c.v.i = tval.type->u.sym->u.limits.max.i;
                } else
                        tval.u.c.v.i = n;
                break;
        case UNSIGNED:
                if (overflow || n > tval.type->u.sym->u.limits.max.u) {
                        warning("overflow in constant `%S'\n", token,
                                (char*)cp - token);
                        tval.u.c.v.u = tval.type->u.sym->u.limits.max.u;
                } else
                        tval.u.c.v.u = n;
                break;
        default: assert(0);
        }
        ppnumber("integer");
        return &tval;
}
static void ppnumber(char *which) {
        unsigned char *rcp = cp--;

        for ( ; (map[*cp]&(DIGIT|LETTER)) || *cp == '.'; cp++)
                if ((cp[0] == 'E' || cp[0] == 'e')
                &&  (cp[1] == '-' || cp[1] == '+'))
                        cp++;
        if (cp > rcp)
                error("`%S' is a preprocessing number but an invalid %s constant\n", token,

                        (char*)cp-token, which);
}
static Symbol fcon(void) {
        if (*cp == '.')
                do
                        cp++;
                while (map[*cp]&DIGIT);
        if (*cp == 'e' || *cp == 'E') {
                if (*++cp == '-' || *cp == '+')
                        cp++;
                if (map[*cp]&DIGIT)
                        do
                                cp++;
                        while (map[*cp]&DIGIT);
                else
                        error("invalid floating constant `%S'\n", token,
                                (char*)cp - token);
        }

        errno = 0;
        tval.u.c.v.d = strtod(token, NULL);
        if (errno == ERANGE)
                warning("overflow in floating constant `%S'\n", token,
                        (char*)cp - token);
        if (*cp == 'f' || *cp == 'F') {
                ++cp;
                if (tval.u.c.v.d > floattype->u.sym->u.limits.max.d)
                        warning("overflow in floating constant `%S'\n", token,
                                (char*)cp - token);
                tval.type = floattype;
        } else if (*cp == 'l' || *cp == 'L') {
                cp++;
                tval.type = longdouble;
        } else {
                if (tval.u.c.v.d > doubletype->u.sym->u.limits.max.d)
                        warning("overflow in floating constant `%S'\n", token,
                                (char*)cp - token);
                tval.type = doubletype;
        }
        ppnumber("floating");
        return &tval;
}

static void *cput(int c, void *cl) {
        char *s = cl;

        if (c < 0 || c > 255)
                warning("overflow in escape sequence with resulting value `%d'\n", c);
        *s++ = c;
        return s;
}

static void *wcput(int c, void *cl) {
        unsigned int *s = cl;

        *s++ = c;
        return s;
}

static void *scon(int q, void *put(int c, void *cl), void *cl) {
        int n = 0, nbad = 0;

        do {
                cp++;
                while (*cp != q) {
                        int c;
                        if (map[*cp]&NEWLINE) {
                                if (cp < limit)
                                        break;
                                cp++;
                                nextline();
                                if (cp == limit)
                                        break;
                                continue;
                        }
                        c = *cp++;
                        if (c == '\\') {
                                if (map[*cp]&NEWLINE) {
                                        if (cp++ < limit)
                                                continue;
                                        nextline();
                                }
                                if (limit - cp < MAXTOKEN)
                                        fillbuf();
                                c = backslash(q);
                        } else if (c < 0 || c > 255 || map[c] == 0)
                                nbad++;
                        if (n++ < BUFSIZE)
                                cl = put(c, cl);
                }
                if (*cp == q)
                        cp++;
                else
                        error("missing %c\n", q);
                if (q == '"' && put == wcput && getchr() == 'L') {
                        if (limit - cp < 2)
                                fillbuf();
                        if (cp[1] == '"')
                                cp++;
                }
        } while (q == '"' && getchr() == '"');
        cl = put(0, cl);
        if (n >= BUFSIZE)
                error("%s literal too long\n", q == '"' ? "string" : "character");
        if (Aflag >= 2 && q == '"' && n > 509)
                warning("more than 509 characters in a string literal\n");
        if (Aflag >= 2 && nbad > 0)
                warning("%s literal contains non-portable characters\n",
                        q == '"' ? "string" : "character");
        return cl;
}
int getchr(void) {
        for (;;) {
                while (map[*cp]&BLANK)
                        cp++;
                if (!(map[*cp]&NEWLINE))
                        return *cp;
                cp++;
                nextline();
                if (cp == limit)
                        return EOI;
        }
}
static int backslash(int q) {
        unsigned int c;

        switch (*cp++) {
        case 'a': return 7;
        case 'b': return '\b';
        case 'f': return '\f';
        case 'n': return '\n';
        case 'r': return '\r';
        case 't': return '\t';
        case 'v': return '\v';
        case '\'': case '"': case '\\': case '\?': break;
        case 'x': {
                int overflow = 0;
                if ((map[*cp]&(DIGIT|HEX)) == 0) {
                        if (*cp < ' ' || *cp == 0177)
                                error("ill-formed hexadecimal escape sequence\n");
                        else
                                error("ill-formed hexadecimal escape sequence `\\x%c'\n", *cp);
                        if (*cp != q)
                                cp++;
                        return 0;
                }
                for (c = 0; map[*cp]&(DIGIT|HEX); cp++) {
                        if (c >> (8*widechar->size - 4))
                                overflow = 1;
                        if (map[*cp]&DIGIT)
                                c = (c<<4) + *cp - '0';
                        else
                                c = (c<<4) + (*cp&~040) - 'A' + 10;
                }
                if (overflow)
                        warning("overflow in hexadecimal escape sequence\n");
                return c&ones(8*widechar->size);
                }
        case '0': case '1': case '2': case '3':
        case '4': case '5': case '6': case '7':
                c = *(cp-1) - '0';
                if (*cp >= '0' && *cp <= '7') {
                        c = (c<<3) + *cp++ - '0';
                        if (*cp >= '0' && *cp <= '7')
                                c = (c<<3) + *cp++ - '0';
                }
                return c;
        default:
                if (cp[-1] < ' ' || cp[-1] >= 0177)
                        warning("unrecognized character escape sequence\n");
                else
                        warning("unrecognized character escape sequence `\\%c'\n", cp[-1]);
        }
        return cp[-1];
}

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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