Changeset 14 for trunk/dlexer.d

Show
Ignore:
Timestamp:
01/12/05 04:48:37 (7 years ago)
Author:
Jaymz031602
Message:

--

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/dlexer.d

    r13 r14  
    1111import  std.string; 
    1212import  std.ctype; 
     13 
     14private import std.c.stdlib;    // for strtod and strtold 
    1315 
    1416alias std.ctype.isdigit isdigit; 
     
    289291 
    290292// A language token: 
    291 struct Token { 
     293class Token { 
    292294    // The kind of token: 
    293295    uint    value; 
     296    Token   next; 
    294297 
    295298    // The value for the token: 
    296299    union { 
    297300        // The identifier or value of the token: 
    298         Identifier*   ident; 
     301        Identifier    ident; 
    299302 
    300303        char[]      ustring; 
     
    311314 
    312315    char[] toString() { 
    313         return toktostr[token]; 
     316        return toktostr[value]; 
     317    }; 
     318 
     319    static char[] toChars(uint value) { 
     320        return toktostr[value]; 
    314321    }; 
    315322} 
     
    328335    if (!isdigit(x) || (x == '8') || (x == '9')) return 0; 
    329336    return -1; 
     337} 
     338 
     339class Loc { 
     340    public: 
     341        int linnum; 
     342 
     343        this() { 
     344        } 
    330345} 
    331346 
     
    443458    protected: 
    444459        Token               token; 
    445         Identifier*[char[]] identifiers; 
     460        Identifier[char[]]  identifiers; 
     461        Loc                 loc; 
    446462 
    447463    private: 
     
    472488 
    473489                    case 0x1A: 
    474                         error(format("unterminated string constant starting at %s", s)); 
     490                        error("unterminated string constant starting at %s", s); 
    475491                        return null; 
    476492 
     
    517533 
    518534                    case 0x1A: 
    519                         error(format("unterminated string constant starting at %s", s)); 
     535                        error("unterminated string constant starting at %s", s); 
    520536                        return null; 
    521537 
    522538                    case '"': 
    523539                        if (n & 1) { 
    524                             error(format("odd number (%d) of hex characters in hex string", n)); 
     540                            error("odd number (%d) of hex characters in hex string", n); 
    525541                            return null; 
    526542                        } 
     
    536552                            c -= 'A' - 10; 
    537553                        else 
    538                             error(format("non-hex character '%c'", c)); 
     554                            error("non-hex character '%c'", c); 
    539555                        if (n & 1) { 
    540556                            v = (v << 4) | c; 
     
    562578 
    563579        // Possible to buffer up errors until some limit n. 
    564         void error(char[] msg) { 
    565             throw new DLexerException(this, msg); 
     580        void error(char[] msg, ...) { 
     581            throw new DLexerException(this, format(msg, _arguments)); 
    566582        } 
    567583 
    568584        // This function consumes a full D language token and returns it in the structure Token: 
    569585        // null is returned if the end of the file is reached. 
    570         uint    nextToken() { 
     586        uint    scan(Token t) { 
    571587            uint    start; 
    572588 
    573             token.ident = null; 
    574             token.uns64value = 0; 
    575             token.value = TOKidentifier; 
     589            t.ident = null; 
     590            t.uns64value = 0; 
     591            t.value = TOKidentifier; 
    576592 
    577593            // Past the end of file? Return an EOF token: 
    578594            if (p >= file.length) { 
    579                 token.value = TOKeof; 
    580                 return token.value; 
     595                t.value = TOKeof; 
     596                return t.value; 
    581597            } 
    582598 
     
    595611                            if (file[p] == '.') { 
    596612                                ++p; 
    597                                 token.value = TOKdotdotdot; 
     613                                t.value = TOKdotdotdot; 
    598614                            } else 
    599                                 token.value = TOKslice; 
     615                                t.value = TOKslice; 
    600616                        } else 
    601                             token.value = TOKdot; 
    602                         return token.value; 
     617                            t.value = TOKdot; 
     618                        return t.value; 
    603619 
    604620                    case '&': 
     
    606622                        if (file[p] == '=') { 
    607623                            ++p; 
    608                             token.value = TOKandass; 
     624                            t.value = TOKandass; 
    609625                        } else if (file[p] == '&') { 
    610626                            ++p; 
    611                             token.value = TOKandand; 
     627                            t.value = TOKandand; 
    612628                        } else 
    613                             token.value = TOKand; 
    614                         return token.value; 
     629                            t.value = TOKand; 
     630                        return t.value; 
    615631 
    616632                    case '|': 
     
    618634                        if (file[p] == '=') { 
    619635                            ++p; 
    620                             token.value = TOKorass; 
     636                            t.value = TOKorass; 
    621637                        } else if (file[p] == '|') { 
    622638                            ++p; 
    623                             token.value = TOKoror; 
     639                            t.value = TOKoror; 
    624640                        } else 
    625                             token.value = TOKor; 
    626                         return token.value; 
     641                            t.value = TOKor; 
     642                        return t.value; 
    627643 
    628644                    case '-': 
     
    630646                        if (file[p] == '=') { 
    631647                            ++p; 
    632                             token.value = TOKminass; 
     648                            t.value = TOKminass; 
    633649                        } else if (file[p] == '-') { 
    634650                            ++p; 
    635                             token.value = TOKminusminus; 
     651                            t.value = TOKminusminus; 
    636652                        } else 
    637                             token.value = TOKmin; 
    638                         return token.value; 
     653                            t.value = TOKmin; 
     654                        return t.value; 
    639655 
    640656                    case '+': 
     
    642658                        if (file[p] == '=') { 
    643659                            ++p; 
    644                             token.value = TOKaddass; 
     660                            t.value = TOKaddass; 
    645661                        } else if (file[p] == '+') { 
    646662                            ++p; 
    647                             token.value = TOKplusplus; 
     663                            t.value = TOKplusplus; 
    648664                        } else 
    649                             token.value = TOKadd; 
    650                         return token.value; 
     665                            t.value = TOKadd; 
     666                        return t.value; 
    651667 
    652668                    case '=': 
     
    656672                            if (file[p] == '=') { 
    657673                                ++p; 
    658                                 token.value = TOKidentity; 
     674                                t.value = TOKidentity; 
    659675                            } else 
    660                                 token.value = TOKequal; 
     676                                t.value = TOKequal; 
    661677                        } else 
    662                             token.value = TOKassign; 
    663                         return token.value; 
     678                            t.value = TOKassign; 
     679                        return t.value; 
    664680 
    665681                    case '<': 
     
    667683                        if (file[p] == '=') { 
    668684                            ++p; 
    669                             token.value = TOKle;          // <= 
     685                            t.value = TOKle;          // <= 
    670686                        } else if (file[p] == '<') { 
    671687                            ++p; 
    672688                            if (file[p] == '=') { 
    673689                                ++p; 
    674                                 token.value = TOKshlass;      // <<= 
     690                                t.value = TOKshlass;      // <<= 
    675691                            } else 
    676                                 token.value = TOKshl;     // << 
     692                                t.value = TOKshl;     // << 
    677693                        } else if (file[p] == '>') { 
    678694                            ++p; 
    679695                            if (file[p] == '=') { 
    680696                                ++p; 
    681                                 token.value = TOKleg;     // <>= 
     697                                t.value = TOKleg;     // <>= 
    682698                            } else 
    683                                 token.value = TOKlg;      // <> 
     699                                t.value = TOKlg;      // <> 
    684700                        } else 
    685                             token.value = TOKlt;          // < 
    686                         return token.value; 
     701                            t.value = TOKlt;          // < 
     702                        return t.value; 
    687703 
    688704                    case '>': 
     
    690706                        if (file[p] == '=') { 
    691707                            ++p; 
    692                             token.value = TOKge;          // >= 
     708                            t.value = TOKge;          // >= 
    693709                        } else if (file[p] == '>') { 
    694710                            ++p; 
    695711                            if (file[p] == '=') { 
    696712                                ++p; 
    697                                 token.value = TOKshrass;      // >>= 
     713                                t.value = TOKshrass;      // >>= 
    698714                            } else if (file[p] == '>') { 
    699715                                ++p; 
    700716                                if (file[p] == '=') { 
    701717                                    ++p; 
    702                                     token.value = TOKushrass; // >>>= 
     718                                    t.value = TOKushrass; // >>>= 
    703719                                } else 
    704                                     token.value = TOKushr;        // >>> 
     720                                    t.value = TOKushr;        // >>> 
    705721                            } else 
    706                                 token.value = TOKshr;     // >> 
     722                                t.value = TOKshr;     // >> 
    707723                        } else 
    708                             token.value = TOKgt;          // > 
    709                         return token.value; 
     724                            t.value = TOKgt;          // > 
     725                        return t.value; 
    710726 
    711727                    case '!': 
     
    715731                            if (file[p] == '=') { 
    716732                                ++p; 
    717                                 token.value = TOKnotidentity; // !== 
     733                                t.value = TOKnotidentity; // !== 
    718734                            } else 
    719                                 token.value = TOKnotequal;        // != 
     735                                t.value = TOKnotequal;        // != 
    720736                        } else if (file[p] == '<') { 
    721737                            ++p; 
     
    724740                                if (file[p] == '=') { 
    725741                                    ++p; 
    726                                     token.value = TOKunord; // !<>= 
     742                                    t.value = TOKunord; // !<>= 
    727743                                } else 
    728                                     token.value = TOKue;  // !<> 
     744                                    t.value = TOKue;  // !<> 
    729745                            } else if (file[p] == '=') { 
    730746                                ++p; 
    731                                 token.value = TOKug;  // !<= 
     747                                t.value = TOKug;  // !<= 
    732748                            } else 
    733                                 token.value = TOKuge; // !< 
     749                                t.value = TOKuge; // !< 
    734750                        } else if (file[p] == '>') { 
    735751                            ++p; 
    736752                            if (file[p] == '=') { 
    737753                                ++p; 
    738                                 token.value = TOKul;  // !>= 
     754                                t.value = TOKul;  // !>= 
    739755                            } else 
    740                                 token.value = TOKule; // !> 
     756                                t.value = TOKule; // !> 
    741757                        } else 
    742                             token.value = TOKnot;     // ! 
    743                         return token.value; 
     758                            t.value = TOKnot;     // ! 
     759                        return t.value; 
    744760 
    745761                    case '*': 
     
    747763                        if (file[p] == '=') { 
    748764                            ++p; 
    749                             token.value = TOKmulass; 
     765                            t.value = TOKmulass; 
    750766                        } else 
    751                             token.value = TOKmul; 
    752                         return token.value; 
     767                            t.value = TOKmul; 
     768                        return t.value; 
    753769                    case '%': 
    754770                        ++p; 
    755771                        if (file[p] == '=') { 
    756772                            ++p; 
    757                             token.value = TOKmodass; 
     773                            t.value = TOKmodass; 
    758774                        } else 
    759                             token.value = TOKmod; 
    760                         return token.value; 
     775                            t.value = TOKmod; 
     776                        return t.value; 
    761777                    case '^': 
    762778                        ++p; 
    763779                        if (file[p] == '=') { 
    764780                            ++p; 
    765                             token.value = TOKxorass; 
     781                            t.value = TOKxorass; 
    766782                        } else 
    767                             token.value = TOKxor; 
    768                         return token.value; 
     783                            t.value = TOKxor; 
     784                        return t.value; 
    769785                    case '~': 
    770786                        ++p; 
    771787                        if (file[p] == '=') { 
    772788                            ++p; 
    773                             token.value = TOKcatass; 
     789                            t.value = TOKcatass; 
    774790                        } else 
    775                             token.value = TOKtilde; 
    776                         return token.value; 
    777  
    778                     case '(': ++p; token.value = TOKlparen; return token.value; 
    779                     case ')': ++p; token.value = TOKrparen; return token.value; 
     791                            t.value = TOKtilde; 
     792                        return t.value; 
     793 
     794                    case '(': ++p; t.value = TOKlparen; return t.value; 
     795                    case ')': ++p; t.value = TOKrparen; return t.value; 
    780796                    case '[': 
    781797                        ++p; 
    782798                        if (file[p] == ']') { 
    783799                            ++p; 
    784                             token.value = TOKarray; 
     800                            t.value = TOKarray; 
    785801                        } else 
    786                             token.value = TOKlbracket; 
    787                         return token.value; 
    788                     case ']': ++p; token.value = TOKrbracket; return token.value; 
    789                     case '{': ++p; token.value = TOKlcurly; return token.value; 
    790                     case '}': ++p; token.value = TOKrcurly; return token.value; 
    791                     case ':': ++p; token.value = TOKcolon; return token.value; 
    792                     case ';': ++p; token.value = TOKsemicolon; return token.value; 
    793                     case '?': ++p; token.value = TOKquestion; return token.value; 
    794                     case ',': ++p; token.value = TOKcomma; return token.value; 
     802                            t.value = TOKlbracket; 
     803                        return t.value; 
     804                    case ']': ++p; t.value = TOKrbracket; return t.value; 
     805                    case '{': ++p; t.value = TOKlcurly; return t.value; 
     806                    case '}': ++p; t.value = TOKrcurly; return t.value; 
     807                    case ':': ++p; t.value = TOKcolon; return t.value; 
     808                    case ';': ++p; t.value = TOKsemicolon; return t.value; 
     809                    case '?': ++p; t.value = TOKquestion; return t.value; 
     810                    case ',': ++p; t.value = TOKcomma; return t.value; 
    795811 
    796812                    case '/': 
     
    798814                        switch (file[p]) { 
    799815                            case '=': 
    800                                 token.value = TOKdivass; 
    801                                 return token.value; 
     816                                t.value = TOKdivass; 
     817                                return t.value; 
    802818 
    803819                            case '/': 
     
    856872 
    857873                            default: 
    858                                 token.value = TOKdiv; 
    859                                 return token.value; 
     874                                t.value = TOKdiv; 
     875                                return t.value; 
    860876                        } 
    861877                        break; 
     
    882898                                ++p; 
    883899                                ++p; 
    884                                 token.value = TOKcharv; 
    885                                 token.ustring = tok; 
    886                                 return token.value; 
     900                                t.value = TOKcharv; 
     901                                t.ustring = tok; 
     902                                return t.value; 
    887903                            } else { 
    888904                                tok.length = 1; 
     
    890906                                ++p; 
    891907                                ++p; 
    892                                 token.value = TOKcharv; 
    893                                 token.ustring = tok; 
    894                                 return token.value; 
     908                                t.value = TOKcharv; 
     909                                t.ustring = tok; 
     910                                return t.value; 
    895911                            } 
    896912                        } else { 
     
    906922                                ++p; 
    907923                            } 
    908                             token.ustring = file[start .. p]; 
    909                             token.value = TOKcharv; 
    910                             ++p; 
    911                             return token.value; 
     924                            t.ustring = file[start .. p]; 
     925                            t.value = TOKcharv; 
     926                            ++p; 
     927                            return t.value; 
    912928                        } 
    913929                    } 
     
    947963                                } 
    948964                            } 
    949                             token.value = TOKstring; 
     965                            t.value = TOKstring; 
    950966                            tok.length = l; 
    951                             token.ustring = tok; 
    952                             ++p; 
    953                             return token.value; 
     967                            t.ustring = tok; 
     968                            ++p; 
     969                            return t.value; 
    954970                        } else { 
    955971                            // Just copy over the escape strings: 
     
    964980                                ++p; 
    965981                            } 
    966                             token.value = TOKstring; 
    967                             token.ustring = file[start .. p]; 
    968                             ++p; 
    969                             return token.value; 
     982                            t.value = TOKstring; 
     983                            t.ustring = file[start .. p]; 
     984                            ++p; 
     985                            return t.value; 
    970986                        } 
    971987                    } 
     
    980996                        } 
    981997                    case '`': 
    982                         token.value = TOKstring; 
    983                         token.ustring = wysiwygString(file[p]); 
    984                         return token.value; 
     998                        t.value = TOKstring; 
     999                        t.ustring = wysiwygString(file[p]); 
     1000                        return t.value; 
    9851001 
    9861002                    case 'x': 
     
    9911007                            goto case_ident; 
    9921008                        } 
    993                         token.value = TOKstring; 
    994                         token.ustring = hexString(); 
    995                         return token.value; 
     1009                        t.value = TOKstring; 
     1010                        t.ustring = hexString(); 
     1011                        return t.value; 
    9961012 
    9971013                    // Identifier start with _ or a-z,A-Z: 
     
    10151031                        char[] tok = file[start .. p]; 
    10161032                        if (tok in keywords) { 
    1017                             token.value = keywords[tok]; 
     1033                            t.value = keywords[tok]; 
    10181034                        } else { 
    1019                             token.value = TOKidentifier; 
     1035                            t.value = TOKidentifier; 
    10201036                            // Check for the identifier in the list: 
    10211037                            if (tok in identifiers) { 
    10221038                                // Use that. 
    1023                                 token.ident = identifiers[tok]; 
     1039                                t.ident = identifiers[tok]; 
    10241040                            } else { 
    10251041                                // Make a new one. 
    1026                                 token.ident = new Identifier(tok, 0); 
    1027                                 identifiers[tok] = token.ident; 
     1042                                t.ident = new Identifier(tok, 0); 
     1043                                identifiers[tok] = t.ident; 
    10281044                            } 
    10291045                        } 
    1030                         return token.value; 
     1046                        return t.value; 
    10311047 
    10321048                    // Numeric literal: 
    10331049                    case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': { 
    1034                         number(); 
    1035                         return token.value; 
     1050                        return number(t); 
    10361051                    } 
    10371052 
     
    10451060 
    10461061        // Parse a real number: 
    1047         uint    inreal() { 
     1062        uint    inreal(Token t) { 
    10481063            printf("inreal\n"); 
    1049             return TOKfloat80v; 
     1064 
     1065            int     dblstate, i; 
     1066            char[]  s; 
     1067            char    c; 
     1068            char    hex;            // is this a hexadecimal-floating-constant? 
     1069            uint    result; 
     1070 
     1071            //printf("Lexer::inreal()\n"); 
     1072            i = 0; 
     1073            s.length = 16; 
     1074            dblstate = 0; 
     1075            hex = 0; 
     1076        Lnext: 
     1077            while (p < file.length) { 
     1078                // Get next char from input 
     1079                c = file[p++]; 
     1080                while (1) { 
     1081                    switch (dblstate) { 
     1082                        case 0:         // opening state 
     1083                            if (c == '0') 
     1084                                dblstate = 9; 
     1085                            else 
     1086                                dblstate = 1; 
     1087                            break; 
     1088                 
     1089                        case 9: 
     1090                            dblstate = 1; 
     1091                            if (c == 'X' || c == 'x') { 
     1092                                hex++; 
     1093                                break; 
     1094                            } 
     1095                        case 1:         // digits to left of . 
     1096                        case 3:         // digits to right of . 
     1097                        case 7:         // continuing exponent digits 
     1098                            if (!isdigit(c) && !(hex && isxdigit(c))) { 
     1099                                if (c == '_') 
     1100                                    goto Lnext; // ignore embedded '_' 
     1101                                dblstate++; 
     1102                                continue; 
     1103                            } 
     1104                            break; 
     1105                 
     1106                        case 2:         // no more digits to left of . 
     1107                            if (c == '.') { 
     1108                                dblstate++; 
     1109                                break; 
     1110                            } 
     1111                        case 4:         // no more digits to right of . 
     1112                            if ((c == 'E' || c == 'e') || hex && (c == 'P' || c == 'p')) { 
     1113                                dblstate = 5; 
     1114                                hex = 0;    // exponent is always decimal 
     1115                                break; 
     1116                            } 
     1117                            if (hex) 
     1118                                error("binary-exponent-part required"); 
     1119                            goto done; 
     1120                 
     1121                        case 5:         // looking immediately to right of E 
     1122                            dblstate++; 
     1123                            if (c == '-' || c == '+') 
     1124                                break; 
     1125                        case 6:         // 1st exponent digit expected 
     1126                            if (!isdigit(c)) 
     1127                                error("exponent expected"); 
     1128                            dblstate++; 
     1129                            break; 
     1130                 
     1131                        case 8:         // past end of exponent digits 
     1132                            goto done; 
     1133                    } 
     1134                    break; 
     1135                } 
     1136                if (i == s.length) s.length = s.length * 2; 
     1137                s[i++] = c; 
     1138            } 
     1139        done: 
     1140            p--; 
     1141            s.length = i; 
     1142 
     1143            setErrno(0); 
     1144 
     1145            switch (file[p]) { 
     1146                case 'F': 
     1147                case 'f': 
     1148                    t.float80value = strtod(s.ptr, null); 
     1149                    result = TOKfloat32v; 
     1150                    p++; 
     1151                    break; 
     1152 
     1153                default: 
     1154                    t.float80value = strtod(s.ptr, null); 
     1155                    result = TOKfloat64v; 
     1156                    break; 
     1157 
     1158                case 'L': 
     1159                case 'l': 
     1160                    t.float80value = strtold(s.ptr, null); 
     1161                    result = TOKfloat80v; 
     1162                    p++; 
     1163                    break; 
     1164            } 
     1165            // Imaginary value: 
     1166            if (file[p] == 'i' || file[p] == 'I') { 
     1167                p++; 
     1168                switch (result) 
     1169                { 
     1170                    case TOKfloat32v: 
     1171                        result = TOKimaginary32v; 
     1172                        break; 
     1173                    case TOKfloat64v: 
     1174                        result = TOKimaginary64v; 
     1175                        break; 
     1176                    case TOKfloat80v: 
     1177                        result = TOKimaginary80v; 
     1178                        break; 
     1179                } 
     1180            } 
     1181            // Standard C: 
     1182            if (getErrno() != 0)    // == ERANGE 
     1183                error("number is not representable"); 
     1184            return result; 
    10501185        } 
    10511186 
    10521187        // Parse a number and return the associated value: 
    1053         uint    number() { 
     1188        uint    number(Token t) { 
    10541189            // We use a state machine to collect numbers 
    10551190            enum : uint { STATE_initial, STATE_0, STATE_decimal, STATE_octal, STATE_octale, 
     
    11361271                        realnum:    // It's a real number. Back up and rescan as a real 
    11371272                                p = start; 
    1138                                 return inreal(); 
     1273                                return inreal(t); 
    11391274                            } 
    11401275                            goto done; 
     
    11541289                                goto realnum; 
    11551290                            if (state == STATE_hex0) 
    1156                                 error(format("Hex digit expected, not '%c'", c)); 
     1291                                error("Hex digit expected, not '%c'", c); 
    11571292                            goto done; 
    11581293                        } 
     
    12811416                case 0: 
    12821417                    if (n & 0x8000000000000000L) 
    1283                         token.value = TOKuns64v; 
     1418                        t.value = TOKuns64v; 
    12841419                    else if (n & 0xFFFFFFFF00000000L) 
    1285                         token.value = TOKint64v; 
     1420                        t.value = TOKint64v; 
    12861421                    else if (n & 0x80000000) 
    1287                         token.value = TOKuns32v; 
     1422                        t.value = TOKuns32v; 
    12881423                    else 
    1289                         token.value = TOKint32v; 
     1424                        t.value = TOKint32v; 
    12901425                    break; 
    12911426 
     
    12931428                    if (n & 0x8000000000000000L) { 
    12941429                        error("signed integer overflow"); 
    1295                         token.value = TOKuns64v; 
     1430                        t.value = TOKuns64v; 
    12961431                    } 
    12971432                    else if (n & 0xFFFFFFFF80000000L) 
    1298                         token.value = TOKint64v; 
     1433                        t.value = TOKint64v; 
    12991434                    else 
    1300                         token.value = TOKint32v; 
     1435                        t.value = TOKint32v; 
    13011436                    break; 
    13021437 
     
    13041439                case FLAGS_decimal | FLAGS_unsigned: 
    13051440                    if (n & 0xFFFFFFFF00000000L) 
    1306                         token.value = TOKuns64v; 
     1441                        t.value = TOKuns64v; 
    13071442                    else 
    1308                         token.value = TOKuns32v; 
     1443                        t.value = TOKuns32v; 
    13091444                    break; 
    13101445 
     
    13121447                    if (n & 0x8000000000000000L) { 
    13131448                        error("signed integer overflow"); 
    1314                         token.value = TOKuns64v; 
     1449                        t.value = TOKuns64v; 
    13151450                    } else 
    1316                         token.value = TOKint64v; 
     1451                        t.value = TOKint64v; 
    13171452                    break; 
    13181453 
    13191454                case FLAGS_long: 
    13201455                    if (n & 0x8000000000000000L) 
    1321                         token.value = TOKuns64v; 
     1456                        t.value = TOKuns64v; 
    13221457                    else 
    1323                         token.value = TOKint64v; 
     1458                        t.value = TOKint64v; 
    13241459                    break; 
    13251460 
    13261461                case FLAGS_unsigned | FLAGS_long: 
    13271462                case FLAGS_decimal | FLAGS_unsigned | FLAGS_long: 
    1328                     token.value = TOKuns64v; 
     1463                    t.value = TOKuns64v; 
    13291464                    break; 
    13301465 
     
    13331468            } 
    13341469 
    1335             token.uns64value = n; 
     1470            t.uns64value = n; 
     1471            return t.value; 
     1472        } 
     1473 
     1474        uint nextToken() { 
     1475            Token   t; 
     1476 
     1477            if (token.next) { 
     1478                t = token.next; 
     1479                token = t; 
     1480                t.next = null; 
     1481            } else 
     1482                scan(token); 
     1483 
    13361484            return token.value; 
    13371485        } 
    13381486 
    13391487        // Only peek at the next token, don't consume it: 
    1340         uint    peekToken() { 
    1341             uint    savep = p, saveline = line; 
    1342             uint    tok = nextToken(); 
    1343             p = savep; 
    1344             line = saveline; 
    1345  
    1346             return tok; 
     1488        Token peek(Token ct) { 
     1489            Token   t; 
     1490 
     1491            if (ct.next) { 
     1492                t = ct.next; 
     1493            } else { 
     1494                t = new Token(); 
     1495                scan(t); 
     1496                t.next = null; 
     1497                ct.next = t; 
     1498            } 
     1499 
     1500            return t; 
    13471501        } 
    13481502