Changeset 14

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 
  • trunk/dparse.d

    r13 r14  
    1 // dtags - D module parser 
     1// dparse - D module parser 
    22// (C) Copyright 2004-2005 James Dunne 
    33 
     
    66// so, you may provide your modifications publicly, but you are not required to. 
    77 
    8 // TODO list: 
    9 // - correct parsing of type declarations in identifiers and functions 
    10 // - interface parsing 
    11 // - version {} blocks 
    12 // - correct extern (type) { } blocks, "extern (type):" and "extern (type) decl" work. 
    13 // - complete access modifiers on functions 
     8// A minimal parser that skips over actual code.  Only concerned with parsing for declarations. 
    149 
    1510module  dparse; 
     
    2015 
    2116import  dlexer; 
    22  
    23 class Type; 
    24 class Expression; 
    25 class Declaration; 
    26 class Statement; 
    27 class Import; 
    28 class Initializer; 
    29 class FuncDeclaration; 
    30 class CtorDeclaration; 
    31 class DtorDeclaration; 
    32 class StaticCtorDeclaration; 
    33 class StaticDtorDeclaration; 
    34 class InvariantDeclaration; 
    35 class UnitTestDeclaration; 
    36 class NewDeclaration; 
    37 class DeleteDeclaration; 
    38 class DebugCondition; 
    39 class VersionCondition; 
    40 class Module; 
    41 class ModuleDeclaration; 
    42 class TemplateDeclaration; 
    43 class TemplateInstance; 
    44 class StaticAssert; 
    45  
    46 class EnumDeclaration; 
    47 class Dsymbol; 
    48  
    49 // A dynamically growing array with some stack properties: 
    50 class Array { 
    51     void*[] p; 
    52     int     count; 
    53  
    54     this() { 
    55         count = 0; 
    56         p.length = 0; 
    57     } 
    58  
    59     int dim() { 
    60         return p.length; 
    61     } 
    62  
    63     void dim(int i) { 
    64         p.length = i; 
    65     } 
    66  
    67     void reserve(int i) { 
    68         if (p.length - count < i) 
    69             p.length = count + i; 
    70     } 
    71  
    72     void *pop() { 
    73         return p[--count]; 
    74     } 
    75  
    76     void push(void *s) { 
    77         reserve(1); 
    78         p[count++] = s; 
    79     } 
    80  
    81     void append(Array* a) { 
    82         p.length = count; 
    83         p ~= a; 
    84         count = p.length; 
    85     } 
    86 
     17import  dtypes; 
     18 
     19const int TRUE = 1; 
     20const int FALSE = 0; 
    8721 
    8822class DParse : DLexer { 
    89     public: 
    90         ModuleDeclaration*  md; 
    91  
    92         // Load up the module source code: 
    93         this(char[] filename, char[] src) { 
    94             // Load up the source for the lexer: 
    95             super(filename, src); 
    96             nextToken();            // start the scanner 
    97         } 
    98  
    9923    private: 
    100         // Is this token a basic type? 
    101         bool isType(uint value) { 
    102             switch (value) { 
    103                 case TOKwchar: case TOKdchar: 
    104                 case TOKbit: case TOKchar: 
    105                 case TOKint8: case TOKuns8: 
    106                 case TOKint16: case TOKuns16: 
    107                 case TOKint32: case TOKuns32: 
    108                 case TOKint64: case TOKuns64: 
    109                 case TOKfloat32: case TOKfloat64: case TOKfloat80: 
    110                 case TOKimaginary32: case TOKimaginary64: case TOKimaginary80: 
    111                 case TOKcomplex32: case TOKcomplex64: case TOKcomplex80: 
    112                 case TOKvoid: 
    113                     return true; 
    114                 default: 
    115                     return false; 
    116             } 
    117             return false; 
    118         } 
    119  
    12024        // Check for a certain token: 
    12125        void check(uint value) { 
     
    13135        } 
    13236 
     37        uint        linkage; 
     38 
    13339    public: 
     40        ArrayT!(Identifier)     moduleident; 
     41 
     42        // Load up the module source code: 
     43        this(char[] filename, char[] src) { 
     44            // Load up the source for the lexer: 
     45            super(filename, src); 
     46            linkage = LINKd; 
     47            nextToken();            // start the scanner 
     48        } 
    13449 
    13550        Array parseModule() { 
     
    14358                    goto Lerr; 
    14459                } else { 
    145                     Array a = null; 
    146                     Identifier *id; 
     60                    ArrayT!(Identifier) a = null; 
     61                    Identifier id; 
    14762 
    14863                    id = token.ident; 
    14964                    while (nextToken() == TOKdot) { 
    15065                        if (!a) 
    151                             a = new Array(); 
     66                            a = new ArrayT!(Identifier); 
    15267                        a.push(id); 
    15368                        nextToken(); 
     
    15974                    } 
    16075 
    161                     md = new ModuleDeclaration(a, id)
     76                    moduleident = a
    16277 
    16378                    if (token.value != TOKsemicolon) 
    164                         error("';' expected following module declaration instead of %s", token.toString()); 
     79                        error(format("';' expected following module declaration instead of %s", token.toString())); 
    16580                    nextToken(); 
    16681                } 
     
    18196        } 
    18297 
    183         Array parseDeclDefs(int once) 
    184         { 
    185             Dsymbol *s; 
     98        Array parseDeclDefs(int once) { 
     99            Dsymbol s; 
    186100            Array decldefs; 
    187101            Array a; 
     
    198112 
    199113                    case TOKstruct: 
     114                        s = parseAggregate(); 
     115                        break; 
     116 
    200117                    case TOKunion: 
     118                        s = parseAggregate(); 
     119                        break; 
     120 
    201121                    case TOKclass: 
     122                        s = parseAggregate(); 
     123                        break; 
     124 
    202125                    case TOKinterface: 
    203126                        s = parseAggregate(); 
     
    209132 
    210133                    case TOKtemplate: 
    211                         s = cast(Dsymbol *) parseTemplateDeclaration(); 
    212                         break; 
    213          
     134                        s = cast(Dsymbol) parseTemplateDeclaration(); 
     135                        break; 
     136 
    214137                    case TOKmixin: 
    215138                        s = parseMixin(); 
    216139                        break; 
    217          
     140 
    218141                    case TOKinstance:   // Deprecated 
    219                         if (isDeclaration(&token, 2, TOKreserved, null)) { 
     142                        if (isDeclaration(token, 2, TOKreserved, null)) { 
    220143                            //printf("it's a declaration\n"); 
    221144                            goto Ldeclaration; 
     
    227150                            //printf("it's an alias\n"); 
    228151                            ti = parseTemplateInstance(); 
    229                             s = cast(Dsymbol *) ti; 
     152                            s = cast(Dsymbol) ti; 
    230153                            if (ti) { 
    231154                                if (token.value == TOKidentifier) { 
    232                                     s = cast(Dsymbol *) new AliasDeclaration(loc, token.ident, ti); 
    233          
     155                                    s = new AliasDeclaration(loc, token.ident, ti); 
     156 
    234157                                    nextToken(); 
    235158                                } 
     
    239162                        } 
    240163                        break; 
    241          
     164 
    242165                    case TOKwchar: case TOKdchar: 
    243166                    case TOKbit: case TOKchar: 
     
    260183                        decldefs.append(a); 
    261184                        continue; 
    262          
     185 
    263186                    case TOKthis: 
    264187                        s = parseCtor(); 
    265188                        break; 
    266          
     189 
    267190                    case TOKtilde: 
    268191                        s = parseDtor(); 
    269192                        break; 
    270          
     193 
    271194                    case TOKinvariant: 
    272                         s = parseInvariant(); 
    273                         break; 
    274          
     195                        parseInvariant(); 
     196                        s = null; 
     197                        break; 
     198 
    275199                    case TOKunittest: 
    276                         s = parseUnitTest(); 
    277                         break; 
    278          
     200                        parseUnitTest(); 
     201                        s = null; 
     202                        break; 
     203 
    279204                    case TOKnew: 
    280205                        s = parseNew(); 
    281206                        break; 
    282          
     207 
    283208                    case TOKdelete: 
    284209                        s = parseDelete(); 
    285210                        break; 
    286          
     211 
    287212                    case TOKeof: 
    288213                    case TOKrcurly: 
    289214                        return decldefs; 
    290          
     215 
    291216                    case TOKstatic: 
    292217                        nextToken(); 
     
    302227                        } 
    303228                        break; 
    304          
     229 
    305230                    case TOKconst: 
    306231                        stc = STCconst; 
     
    324249                        stc = STCdeprecated; 
    325250                        goto Lstc; 
    326          
     251 
    327252                      Lstc: 
    328253                        nextToken(); 
     
    354279                        s = new StorageClassDeclaration(stc, a); 
    355280                        break; 
    356          
    357          
     281 
    358282                    case TOKprivate: 
    359283                        prot = PROTprivate; 
     
    371295                        prot = PROTexport; 
    372296                        goto Lprot; 
    373          
     297 
    374298                      Lprot: 
    375299                        nextToken(); 
     
    377301                        s = new ProtDeclaration(prot, a); 
    378302                        break; 
    379          
     303 
    380304                    case TOKalign: 
    381305                        { 
    382306                            uint n; 
    383          
     307 
    384308                            s = null; 
    385309                            nextToken(); 
     
    395319                                check(TOKrparen); 
    396320                            } else 
    397                                 n = global.structalign;   // default 
    398          
     321                                n = 4; //global.structalign;  // default 
     322 
    399323                            a = parseBlock(); 
    400324                            s = new AlignDeclaration(n, a); 
    401325                            break; 
    402326                        } 
    403          
     327 
    404328                    case TOKpragma: 
    405329                        { 
    406                             Identifier *ident; 
     330                            Identifier ident; 
    407331                            Array args = null; 
    408          
     332 
    409333                            nextToken(); 
    410334                            check(TOKlparen); 
     
    419343                            else 
    420344                                check(TOKrparen);   // pragma(identifier) 
    421          
     345 
    422346                            if (token.value == TOKsemicolon) 
    423347                                a = null; 
    424348                            else 
    425349                                a = parseBlock(); 
    426                             s = new PragmaDeclaration(ident, args, a); 
     350                            /+s = new PragmaDeclaration(ident, args, a);+/ 
     351                            s = null; 
    427352                            break; 
    428353                        } 
    429          
     354 
    430355                    case TOKextern: 
    431356                        { 
    432357                            uint link = LINKdefault; 
    433358                            uint linksave; 
    434          
     359 
    435360                            s = null; 
    436361                            nextToken(); 
     
    438363                                nextToken(); 
    439364                                if (token.value == TOKidentifier) { 
    440                                     Identifier *id = token.ident; 
     365                                    Identifier id = token.ident; 
    441366 
    442367                                    nextToken(); 
     
    473398                            break; 
    474399                        } 
    475          
     400 
    476401                    case TOKdebug: 
    477402                        { 
    478                             DebugCondition *condition; 
    479                             Array *aelse; 
    480          
     403                            DebugCondition condition; 
     404                            Array aelse; 
     405 
    481406                            nextToken(); 
    482407                            if (token.value == TOKassign) { 
     
    496421                                break; 
    497422                            } 
    498          
     423 
    499424                            if (token.value == TOKlparen) { 
    500425                                nextToken(); 
     
    502427                                check(TOKrparen); 
    503428                            } else 
    504                                 condition = new DebugCondition(mod, 1, null); 
     429                                condition = new DebugCondition(1, null); 
    505430                            a = parseBlock(); 
    506431                            aelse = null; 
     
    512437                            break; 
    513438                        } 
    514          
     439 
    515440                    case TOKversion: 
    516441                        { 
    517                             VersionCondition *condition; 
    518                             Array *aelse; 
    519          
     442                            VersionCondition condition; 
     443                            Array aelse; 
     444 
    520445                            nextToken(); 
    521446                            if (token.value == TOKassign) { 
     
    535460                                break; 
    536461                            } 
    537          
     462 
    538463                            if (token.value == TOKlparen) { 
    539464                                nextToken(); 
     
    553478                            break; 
    554479                        } 
    555          
     480 
    556481                    case TOKsemicolon:  // empty declaration 
    557482                        nextToken(); 
    558483                        continue; 
    559          
     484 
    560485                    default: 
    561486                        error("Declaration expected, not '%s'\n", token.toString()); 
     
    572497            return decldefs; 
    573498        } 
    574          
     499 
    575500        /******************************************** 
    576501         * Parse declarations after an align, protection, or extern decl. 
    577502         */ 
    578          
    579         Array * 
    580         parseBlock() 
    581         { 
    582             Array *a = null; 
    583             Dsymbol *s; 
    584          
     503 
     504        Array parseBlock() { 
     505            Array a = null; 
     506            Dsymbol s; 
     507 
    585508            //printf("parseBlock()\n"); 
    586509            switch (token.value) { 
     
    589512                    nextToken(); 
    590513                    break; 
    591          
     514 
    592515                case TOKlcurly: 
    593516                    nextToken(); 
     
    598521                        nextToken(); 
    599522                    break; 
    600          
     523 
    601524                case TOKcolon: 
    602525                    nextToken(); 
     
    606529        #endif+/ 
    607530                    break; 
    608          
     531 
    609532                default: 
    610533                    a = parseDeclDefs(1); 
     
    613536            return a; 
    614537        } 
    615          
     538 
    616539        /********************************** 
    617540         * Parse a static assertion. 
    618541         */ 
    619542 
    620         StaticAssert* parseStaticAssert() { 
     543        StaticAssert parseStaticAssert() { 
    621544            Loc loc = this.loc; 
    622             Expression *exp; 
    623          
     545            Expression exp; 
     546 
    624547            //printf("parseStaticAssert()\n"); 
    625548            nextToken(); 
     
    635558         */ 
    636559 
    637         DebugCondition * 
    638         parseDebugCondition() 
    639         { 
     560        DebugCondition parseDebugCondition() { 
    640561            uint level = 1; 
    641             Identifier *id = null; 
    642          
     562            Identifier id = null; 
     563 
    643564            if (token.value == TOKidentifier) 
    644565                id = token.ident; 
     
    648569                error("identifier or integer expected, not %s", token.toString()); 
    649570            nextToken(); 
    650          
    651             return new DebugCondition(mod, level, id); 
    652         } 
    653          
     571 
     572            return new DebugCondition(level, id); 
     573        } 
     574 
    654575        /************************************** 
    655576         * Parse a version conditional 
    656577         */ 
    657          
    658         VersionCondition *parseVersionCondition() 
    659         { 
     578 
     579        VersionCondition parseVersionCondition() { 
    660580            uint level = 1; 
    661             Identifier *id = null; 
    662          
     581            Identifier id = null; 
     582 
    663583            if (token.value == TOKidentifier) 
    664584                id = token.ident; 
     
    668588                error("identifier or integer expected, not %s", token.toString()); 
    669589            nextToken(); 
    670          
    671             return new VersionCondition(mod, level, id); 
    672         } 
    673          
     590 
     591            return new VersionCondition(level, id); 
     592        } 
     593 
    674594        /***************************************** 
    675595         * Parse a constructor definition: 
     
    677597         * Current token is 'this'. 
    678598         */ 
    679          
    680         CtorDeclaration *parseCtor() 
    681         { 
    682             CtorDeclaration *f; 
    683             Array *arguments; 
     599 
     600        CtorDeclaration parseCtor() { 
     601            CtorDeclaration f; 
     602            Array arguments; 
    684603            int varargs; 
    685604            Loc loc = this.loc; 
    686          
     605 
    687606            nextToken(); 
    688             arguments = parseParameters(&varargs); 
     607            arguments = parseParameters(varargs); 
    689608            f = new CtorDeclaration(loc, 0, arguments, varargs); 
    690609            parseContracts(f); 
    691610            return f; 
    692611        } 
    693          
     612 
    694613        /***************************************** 
    695614         * Parse a destructor definition: 
     
    697616         * Current token is '~'. 
    698617         */ 
    699          
    700         DtorDeclaration *parseDtor() 
    701         { 
    702             DtorDeclaration *f; 
     618 
     619        DtorDeclaration parseDtor() { 
     620            DtorDeclaration f; 
    703621            Loc loc = this.loc; 
    704          
     622 
    705623            nextToken(); 
    706624            check(TOKthis); 
    707625            check(TOKlparen); 
    708626            check(TOKrparen); 
    709          
     627 
    710628            f = new DtorDeclaration(loc, 0); 
    711629            parseContracts(f); 
    712630            return f; 
    713631        } 
    714          
     632 
    715633        /***************************************** 
    716634         * Parse a static constructor definition: 
     
    718636         * Current token is 'this'. 
    719637         */ 
    720          
    721         StaticCtorDeclaration * 
    722         parseStaticCtor() 
    723         { 
    724             StaticCtorDeclaration *f; 
     638 
     639        StaticCtorDeclaration parseStaticCtor() { 
     640            StaticCtorDeclaration f; 
    725641            Loc loc = this.loc; 
    726          
     642 
    727643            nextToken(); 
    728644            check(TOKlparen); 
    729645            check(TOKrparen); 
    730          
     646 
    731647            f = new StaticCtorDeclaration(loc, 0); 
    732648            parseContracts(f); 
    733649            return f; 
    734650        } 
    735          
     651 
    736652        /***************************************** 
    737653         * Parse a static destructor definition: 
     
    739655         * Current token is '~'. 
    740656         */ 
    741          
    742         StaticDtorDeclaration * 
    743         parseStaticDtor() 
    744         { 
    745             StaticDtorDeclaration *f; 
     657 
     658        StaticDtorDeclaration parseStaticDtor() { 
     659            StaticDtorDeclaration f; 
    746660            Loc loc = this.loc; 
    747          
     661 
    748662            nextToken(); 
    749663            check(TOKthis); 
    750664            check(TOKlparen); 
    751665            check(TOKrparen); 
    752          
     666 
    753667            f = new StaticDtorDeclaration(loc, 0); 
    754668            parseContracts(f); 
    755669            return f; 
    756670        } 
    757          
     671 
    758672        /***************************************** 
    759673         * Parse an invariant definition: 
     
    761675         * Current token is 'invariant'. 
    762676         */ 
    763          
    764         InvariantDeclaration * 
    765         parseInvariant() 
    766         { 
    767             InvariantDeclaration *f; 
     677 
     678        InvariantDeclaration parseInvariant() { 
     679            InvariantDeclaration f; 
    768680            Loc loc = this.loc; 
    769          
     681 
    770682            nextToken(); 
    771683            //check(TOKlparen);     // don't require () 
    772684            //check(TOKrparen); 
    773          
     685 
    774686            f = new InvariantDeclaration(loc, 0); 
    775687            f.fbody = parseStatement(PScurly); 
    776688            return f; 
    777689        } 
    778          
     690 
    779691        /***************************************** 
    780692         * Parse a unittest definition: 
     
    782694         * Current token is 'unittest'. 
    783695         */ 
    784          
    785         UnitTestDeclaration * 
    786         parseUnitTest() 
    787         { 
    788             UnitTestDeclaration *f; 
    789             Statement *sbody; 
     696 
     697        UnitTestDeclaration parseUnitTest() { 
     698            UnitTestDeclaration f; 
     699            Statement sbody; 
    790700            Loc loc = this.loc; 
    791          
     701 
    792702            nextToken(); 
    793          
     703 
    794704            sbody = parseStatement(PScurly); 
    795          
     705 
    796706            f = new UnitTestDeclaration(loc, this.loc); 
    797707            f.fbody = sbody; 
     
    805715         */ 
    806716         
    807         NewDeclaration * 
    808         parseNew() 
    809         { 
    810             NewDeclaration *f; 
    811             Array *arguments; 
     717        NewDeclaration parseNew() { 
     718            NewDeclaration f; 
     719            Array arguments; 
    812720            int varargs; 
    813721            Loc loc = this.loc; 
    814722         
    815723            nextToken(); 
    816             arguments = parseParameters(&varargs); 
     724            arguments = parseParameters(varargs); 
    817725            f = new NewDeclaration(loc, 0, arguments, varargs); 
    818726            parseContracts(f); 
     
    826734         */ 
    827735         
    828         DeleteDeclaration * 
    829         parseDelete() 
    830         { 
    831             DeleteDeclaration *f; 
    832             Array *arguments; 
     736        DeleteDeclaration parseDelete() { 
     737            DeleteDeclaration f; 
     738            Array arguments; 
    833739            int varargs; 
    834740            Loc loc = this.loc; 
    835741         
    836742            nextToken(); 
    837             arguments = parseParameters(&varargs); 
     743            arguments = parseParameters(varargs); 
    838744            if (varargs) 
    839745                error("... not allowed in delete function parameter list"); 
     
    842748            return f; 
    843749        } 
    844          
     750 
    845751        /********************************************** 
    846752         * Parse parameter list. 
    847753         */ 
    848          
    849         Array * 
    850         parseParameters(int *pvarargs) 
    851         { 
    852             Array *arguments = new Array; 
     754 
     755        Array parseParameters(out int pvarargs) { 
     756            Array arguments = new Array; 
    853757            int varargs = 0; 
    854758            int hasdefault = 0; 
    855          
     759 
    856760            check(TOKlparen); 
    857761            while (1) { 
    858                 Type *tb; 
    859                 Identifier *ai; 
    860                 Type *at; 
    861                 Argument *a; 
     762                Type tb; 
     763                Identifier ai; 
     764                Type at; 
     765                Argument a; 
    862766                uint inoutt; 
    863                 Expression *ae; 
    864          
     767                Expression ae; 
     768 
    865769                ai = null; 
    866770                inoutt = In;                // parameter is "in" by default 
     
    868772                    case TOKrparen: 
    869773                        break; 
    870          
     774 
    871775                    case TOKdotdotdot: 
    872776                        varargs = 1; 
    873777                        nextToken(); 
    874778                        break; 
    875          
     779 
    876780                    case TOKin: 
    877781                        inoutt = In; 
    878782                        nextToken(); 
    879783                        goto L1; 
    880          
     784 
    881785                    case TOKout: 
    882786                        inoutt = Out; 
    883787                        nextToken(); 
    884788                        goto L1; 
    885          
     789 
    886790                    case TOKinout: 
    887791                        inoutt = InOut; 
    888792                        nextToken(); 
    889793                        goto L1; 
    890          
     794 
    891795                    default: 
    892796                      L1: 
     
    914818            } 
    915819            check(TOKrparen); 
    916             *pvarargs = varargs; 
     820            pvarargs = varargs; 
    917821            return arguments; 
    918822        } 
    919          
     823 
    920824        /************************************* 
    921825         */ 
    922          
    923         EnumDeclaration * 
    924         parseEnum() 
    925         { 
    926             EnumDeclaration *e; 
    927             Identifier *id; 
    928             Type *t; 
    929          
     826 
     827        EnumDeclaration parseEnum() { 
     828            EnumDeclaration e; 
     829            Identifier id; 
     830            Type t; 
     831 
    930832            //printf("parseEnum()\n"); 
    931833            nextToken(); 
     
    935837            } else 
    936838                id = null; 
    937          
     839 
    938840            if (token.value == TOKcolon) { 
    939841                nextToken(); 
     
    941843            } else 
    942844                t = null; 
    943          
     845 
    944846            e = new EnumDeclaration(id, t); 
    945847            if (token.value == TOKsemicolon && id) 
     
    947849            else if (token.value == TOKlcurly) { 
    948850                //printf("enum definition\n"); 
    949                 e.members = new Array
     851                e.members = new ArrayT!(EnumMember)
    950852                nextToken(); 
    951853                while (token.value != TOKrcurly) { 
    952854                    if (token.value == TOKidentifier) { 
    953                         EnumMember *em; 
    954                         Expression *value; 
    955                         Identifier *ident; 
    956          
     855                        EnumMember em; 
     856                        Expression value; 
     857                        Identifier ident; 
     858 
    957859                        ident = token.ident; 
    958860                        value = null; 
     
    975877            } else 
    976878                error("enum declaration is invalid"); 
    977          
     879 
    978880            return e; 
    979881        } 
    980          
    981         Dsymbol * 
    982         parseAggregate() 
    983         { 
    984             AggregateDeclaration *a = null; 
     882 
     883        Dsymbol parseAggregate() { 
     884            AggregateDeclaration a = null; 
    985885            int anon = 0; 
    986886            uint tok; 
    987             Identifier *id; 
    988             Array *tpl = null; 
    989          
     887            Identifier id; 
     888            Array tpl = null; 
     889 
    990890            //printf("parseAggregate()\n"); 
    991891            tok = token.value; 
     
    996896                id = token.ident; 
    997897                nextToken(); 
    998          
     898 
    999899                if (token.value == TOKlparen) { // Class template declaration. 
    1000          
     900 
    1001901                    // Gather template parameter list 
    1002902                    tpl = parseTemplateParameterList(); 
    1003903                } 
    1004904            } 
    1005          
     905 
    1006906            switch (tok) { 
    1007907                case TOKclass: 
    1008908                case TOKinterface: 
    1009909                    { 
    1010                         Array *baseclasses = null; 
    1011                         BaseClass *b; 
    1012          
     910                        Array baseclasses = null; 
     911                        BaseClass b; 
     912 
    1013913                        if (!id) 
    1014914                            error("anonymous classes not allowed"); 
    1015          
     915 
    1016916                        // Collect base class(es) 
    1017917                        b = null; 
    1018918                        if (token.value == TOKcolon) { 
    1019919                            uint protection = PROTpublic; 
    1020          
     920 
    1021921                            baseclasses = new Array; 
    1022922                            while (1) { 
     
    1051951                                error("members expected"); 
    1052952                        } 
    1053          
     953 
    1054954                        if (tok == TOKclass) 
    1055955                            a = new ClassDeclaration(loc, id, baseclasses); 
     
    1058958                        break; 
    1059959                    } 
    1060          
     960 
    1061961                case TOKstruct: 
    1062962                    if (id) 
     
    1065965                        anon = 1; 
    1066966                    break; 
    1067          
     967 
    1068968                case TOKunion: 
    1069969                    if (id) 
     
    1072972                        anon = 2; 
    1073973                    break; 
    1074          
     974 
    1075975                default: 
    1076976                    assert(0); 
    1077977                    break; 
    1078978            } 
     979 
    1079980            if (a && token.value == TOKsemicolon) { 
    1080981                nextToken(); 
     
    1082983                //printf("aggregate definition\n"); 
    1083984                nextToken(); 
    1084                 Array *decl = parseDeclDefs(0); 
    1085          
     985                Array decl = parseDeclDefs(0); 
     986 
    1086987                if (token.value != TOKrcurly) 
    1087988                    error("struct member expected"); 
     
    1097998                a = new StructDeclaration(loc, null); 
    1098999            } 
    1099          
     1000 
    11001001            if (tpl) { 
    1101                 Array *decldefs; 
    1102                 TemplateDeclaration *tempdecl; 
    1103          
     1002                Array decldefs; 
     1003                TemplateDeclaration tempdecl; 
     1004 
    11041005                // Wrap a template around the aggregate declaration 
    11051006                decldefs = new Array; 
     
    11081009                return tempdecl; 
    11091010            } 
    1110          
     1011 
    11111012            return a; 
    11121013        } 
    1113          
     1014 
    11141015        /************************************** 
    11151016         * Parse a TemplateDeclaration. 
    11161017         */ 
    1117          
    1118         TemplateDeclaration * 
    1119         parseTemplateDeclaration() 
    1120         { 
    1121             TemplateDeclaration *tempdecl; 
    1122             Identifier *id; 
    1123             Array *tpl; 
    1124             Array *decldefs; 
     1018 
     1019        TemplateDeclaration parseTemplateDeclaration() { 
     1020            TemplateDeclaration tempdecl; 
     1021            Identifier id; 
     1022            Array tpl; 
     1023            Array decldefs; 
    11251024            Loc loc = this.loc; 
    1126          
     1025 
    11271026            nextToken(); 
    11281027            if (token.value != TOKidentifier) { 
     
    11351034            if (!tpl) 
    11361035                goto Lerr; 
    1137          
     1036 
    11381037            if (token.value != TOKlcurly) { 
    11391038                error("members of template declaration expected"); 
     
    11481047                nextToken(); 
    11491048            } 
    1150          
     1049 
    11511050            tempdecl = new TemplateDeclaration(loc, id, tpl, decldefs); 
    11521051            return tempdecl; 
    1153          
     1052 
    11541053          Lerr: 
    11551054            return null; 
    11561055        } 
    1157          
     1056 
    11581057        /****************************************** 
    11591058         * Parse template parameter list. 
    11601059         */ 
    1161          
    1162         Array * 
    1163         parseTemplateParameterList() 
    1164         { 
    1165             Array *tpl; 
    1166          
     1060 
     1061        Array parseTemplateParameterList() { 
     1062            Array tpl; 
     1063 
    11671064            if (token.value != TOKlparen) { 
    11681065                error("parenthesized TemplateParameterList expected following TemplateIdentifier"); 
     
    11711068            tpl = new Array; 
    11721069            nextToken(); 
    1173          
     1070 
    11741071            // Get TemplateParameterList 
    11751072            if (token.value != TOKrparen) { 
    11761073                while (1) { 
    1177                     TemplateParameter *tp; 
    1178                     Identifier *tp_ident = null
    1179                     Type *tp_spectype = null
    1180                     Type *tp_valtype = null
    1181                     Type *tp_defaulttype = null
    1182                     Expression *tp_specvalue = null
    1183                     Expression *tp_defaultvalue = null
    1184                     Token *t; 
    1185          
     1074                    TemplateParameter tp; 
     1075                    Identifier tp_ident
     1076                    Type tp_spectype
     1077                    Type tp_valtype
     1078                    Type tp_defaulttype
     1079                    Expression tp_specvalue
     1080                    Expression tp_defaultvalue
     1081                    Token t; 
     1082 
    11861083                    // Get TemplateParameter 
    1187          
     1084 
    11881085                    // First, look ahead to see if it is a TypeParameter or a ValueParameter 
    1189                     t = peek(&token); 
     1086                    t = peek(token); 
    11901087                    if (token.value == TOKalias) {  // AliasParameter 
    11911088                        nextToken(); 
     
    12501147            check(TOKrparen); 
    12511148            return tpl; 
    1252          
     1149 
    12531150          Lerr: 
    12541151            return null; 
    12551152        } 
    1256          
     1153 
    12571154        /************************************** 
    12581155         * Parse a TemplateInstance. 
    12591156         */ 
    1260          
    1261         TemplateInstance * 
    1262         parseTemplateInstance() 
    1263         { 
    1264             TemplateInstance *tempinst; 
    1265             Identifier *id; 
     1157 
     1158        TemplateInstance parseTemplateInstance() { 
     1159            TemplateInstance tempinst; 
     1160            Identifier id; 
    12661161 
    12671162            //printf("parseTemplateInstance()\n"); 
    12681163            nextToken(); 
    12691164            if (token.value == TOKdot) { 
    1270                 id = Idempty; 
     1165                id = Id.empty; 
    12711166            } else if (token.value == TOKidentifier) { 
    12721167                id = token.ident; 
     
    12871182                nextToken(); 
    12881183            } 
    1289             tempinst.tiargs = parseTemplateArgumentList(); 
    1290          
    1291             if (!global.params.useDeprecated) 
    1292               error("instance is deprecated, use %s", tempinst.toString()); 
     1184            /+tempinst.tiargs = +/parseTemplateArgumentList(); 
     1185 
     1186            //if (!global.params.useDeprecated) 
     1187            //    error("instance is deprecated, use %s", tempinst.toString()); 
    12931188            return tempinst; 
    1294          
     1189 
    12951190          Lerr: 
    12961191            return null; 
    12971192        } 
    1298          
     1193 
    12991194        /****************************************** 
    13001195         * Parse template mixin. 
     
    13041199         *  mixin Foo!(args) identifier; 
    13051200         */ 
    1306          
    1307         Dsymbol * 
    1308         parseMixin() 
    1309         { 
    1310             TemplateMixin *tm; 
    1311             Identifier *id; 
    1312             TypeTypeof *tqual; 
    1313             Array *tiargs; 
    1314             Array *idents; 
    1315          
     1201 
     1202        TemplateMixin parseMixin() { 
     1203            TemplateMixin tm; 
     1204            Identifier id; 
     1205            TypeTypeof tqual; 
     1206            Array tiargs; 
     1207            ArrayT!(Identifier) idents; 
     1208 
    13161209            //printf("parseMixin()\n"); 
    13171210            nextToken(); 
    1318          
     1211 
    13191212            tqual = null; 
    13201213            if (token.value == TOKdot) { 
    1321                 id = Idempty; 
     1214                id = Id.empty; 
    13221215            } else { 
    13231216                if (token.value == TOKtypeof) { 
    1324                     Expression *exp; 
    1325          
     1217                    Expression exp; 
     1218 
    13261219                    nextToken(); 
    13271220                    check(TOKlparen); 
     
    13371230                id = token.ident; 
    13381231            } 
    1339          
    1340             idents = new Array
     1232 
     1233            idents = new ArrayT!(Identifier)
    13411234            while (1) { 
    13421235                nextToken(); 
     
    13441237                if (token.value == TOKnot) { 
    13451238                    nextToken(); 
    1346                     tiargs = parseTemplateArgumentList(); 
    1347                 } 
    1348          
     1239                    /+tiargs = +/parseTemplateArgumentList(); 
     1240                } 
     1241 
    13491242                if (token.value != TOKdot) 
    13501243                    break; 
    1351          
     1244 
    13521245                if (tiargs) { 
    1353                     TemplateInstance *tempinst = new TemplateInstance(loc, id); 
     1246                    TemplateInstance tempinst = new TemplateInstance(loc, id); 
    13541247         
    13551248                    tempinst.tiargs = tiargs; 
    1356                     id = cast(Identifier *) tempinst; 
     1249                    id = cast(Identifier) tempinst; 
    13571250                    tiargs = null; 
    13581251                } 
    13591252                idents.push(id); 
    1360          
     1253 
    13611254                nextToken(); 
    13621255                if (token.value != TOKidentifier) { 
     
    13671260            } 
    13681261            idents.push(id); 
    1369          
     1262 
    13701263            if (token.value == TOKidentifier) { 
    13711264                id = token.ident; 
     
    13731266            } else 
    13741267                id = null; 
    1375          
     1268 
    13761269            tm = new TemplateMixin(loc, id, tqual, idents, tiargs); 
    13771270            if (token.value != TOKsemicolon) 
    13781271                error("';' expected after mixin"); 
    13791272            nextToken(); 
    1380          
     1273 
    13811274            return tm; 
    1382          
     1275 
    13831276          Lerr: 
    13841277            return null; 
    13851278        } 
    1386          
     1279 
    13871280        /****************************************** 
    13881281         * Parse template argument list. 
     
    13921285         *  current token is one after closing ')' 
    13931286         */ 
    1394          
    1395         Array * 
    1396         parseTemplateArgumentList() 
    1397         { 
    1398             Array *tiargs = new Array; 
    1399          
     1287 
     1288        void parseTemplateArgumentList() { 
     1289            /+ArrayT!(Object) tiargs = new Array;+/ 
     1290 
    14001291            if (token.value != TOKlparen) { 
    14011292                error("!(TemplateArgumentList) expected following TemplateIdentifier"); 
    1402                 return tiargs
     1293                return/+ tiargs+/
    14031294            } 
    14041295            nextToken(); 
    1405          
     1296 
    14061297            // Get TemplateArgumentList 
    14071298            if (token.value != TOKrparen) { 
    14081299                while (1) { 
    14091300                    // See if it is an Expression or a Type 
    1410                     if (isDeclaration(&token, 0, TOKreserved, null)) {    // Type 
    1411                         Type *ta; 
    1412          
     1301                    /+if (isDeclaration(&token, 0, TOKreserved, null)) {  // Type 
     1302                        Type ta; 
     1303 
    14131304                        // Get TemplateArgument 
    14141305                        ta = parseBasicType(); 
     
    14161307                        tiargs.push(ta); 
    14171308                    } else {            // Expression 
    1418                         Expression *ea; 
    1419          
     1309                        Expression ea; 
     1310 
    14201311                        ea = parseAssignExp(); 
    14211312                        tiargs.push(ea); 
    1422                     } 
     1313                    }+/ 
    14231314                    if (token.value != TOKcomma) 
    14241315                        break; 
     
    14271318            } 
    14281319            check(TOKrparen, "template argument list"); 
    1429             return tiargs; 
    1430         } 
    1431          
    1432         Import * 
    1433         parseImport(Array * decldefs) 
    1434         { 
    1435             Import *s; 
    1436             Identifier *id; 
    1437             Array *a; 
     1320            return/+ tiargs+/; 
     1321        } 
     1322 
     1323        Import parseImport(Array decldefs) { 
     1324            Import s; 
     1325            Identifier id; 
     1326            ArrayT!(Identifier) a; 
    14381327            Loc loc; 
    1439          
     1328 
    14401329            //printf("parseImport()\n"); 
    14411330            do { 
     
    14451334                    break; 
    14461335                } 
    1447          
     1336 
    14481337                loc = this.loc; 
    14491338                a = null; 
     
    14511340                while (nextToken() == TOKdot) { 
    14521341                    if (!a) 
    1453                         a = new Array
     1342                        a = new ArrayT!(Identifier)
    14541343                    a.push(id); 
    14551344                    nextToken(); 
     
    14601349                    id = token.ident; 
    14611350                } 
    1462          
     1351 
    14631352                s = new Import(loc, a, token.ident); 
    14641353                decldefs.push(s); 
    14651354            } while (token.value == TOKcomma); 
    1466          
     1355 
    14671356            if (token.value == TOKsemicolon) 
    14681357                nextToken(); 
     
    14711360                nextToken(); 
    14721361            } 
    1473          
     1362 
    14741363            return null; 
    14751364        } 
    1476          
    1477         Type *parseBasicType() 
    1478         { 
    1479             Type *t; 
    1480             Identifier *id; 
    1481             TypeQualified *tid; 
    1482             TemplateInstance *tempinst; 
     1365 
     1366        Type parseBasicType() { 
     1367            Type t; 
     1368            Identifier id; 
     1369            TypeQualified tid; 
     1370            TemplateInstance tempinst; 
    14831371 
    14841372            //printf("parseBasicType()\n"); 
     
    15091397                    nextToken(); 
    15101398                    break; 
    1511          
     1399 
    15121400                case TOKidentifier: 
    15131401                    id = token.ident; 
     
    15161404                        nextToken(); 
    15171405                        tempinst = new TemplateInstance(loc, id); 
    1518                         tempinst.tiargs = parseTemplateArgumentList(); 
     1406                        /+tempinst.tiargs = +/parseTemplateArgumentList(); 
    15191407                        tid = new TypeInstance(loc, tempinst); 
    15201408                        goto Lident2; 
     
    15341422                            nextToken(); 
    15351423                            tempinst = new TemplateInstance(loc, id); 
    1536                             tempinst.tiargs = parseTemplateArgumentList(); 
    1537                             tid.addIdent(cast(Identifier *) tempinst); 
     1424                            /+tempinst.tiargs = +/parseTemplateArgumentList(); 
     1425                            /+tid.addIdent(cast(Identifier) tempinst);+/ 
    15381426                        } else 
    1539                             tid.addIdent(id); 
     1427                            /+tid.addIdent(id);+/ { } 
    15401428                    } 
    15411429                    t = tid; 
    15421430                    break; 
    1543          
     1431 
    15441432                case TOKdot: 
    1545                     id = Idempty; 
     1433                    id = Id.empty; 
    15461434                    goto Lident; 
    1547          
     1435 
    15481436                case TOKinstance: 
    15491437                    {                   // Deprecated 
     
    15541442                            break; 
    15551443                        } 
    1556          
     1444 
    15571445                        tid = new TypeInstance(loc, tempinst); 
    15581446                        goto Lident2; 
    15591447                    } 
    1560          
     1448 
    15611449                case TOKtypeof: 
    15621450                    { 
    1563                         Expression *exp; 
    1564          
     1451                        Expression exp; 
     1452 
    15651453                        nextToken(); 
    15661454                        check(TOKlparen); 
     
    15701458                        goto Lident2; 
    15711459                    } 
    1572          
     1460 
    15731461                default: 
    15741462                    error("basic type expected, not %s", token.toString()); 
     
    15781466            return t; 
    15791467        } 
    1580          
    1581         Type * 
    1582         parseBasicType2(Type * t) 
    1583         { 
    1584             Expression *e; 
    1585             Type *ts; 
    1586             Type *ta; 
    1587          
     1468 
     1469        Type parseBasicType2(Type t) { 
     1470            Expression e; 
     1471            Type ts; 
     1472            Type ta; 
     1473 
    15881474            //printf("parseBasicType2()\n"); 
    15891475            while (1) { 
     
    16021488                            t = new TypeDArray(t);  // [] 
    16031489                            nextToken(); 
    1604                         } else if (isDeclaration(&token, 0, TOKrbracket, null)) { // It's an associative array declaration 
    1605                             Type *index; 
    1606          
     1490                        } else if (isDeclaration(token, 0, TOKrbracket, null)) {  // It's an associative array declaration 
     1491                            Type index; 
     1492 
    16071493                            //printf("it's an associative array\n"); 
    16081494                            index = parseBasicType(); 
     
    16171503                        } 
    16181504                        continue; 
    1619          
     1505 
    16201506                    case TOKdelegate: 
    16211507                    case TOKfunction: 
     
    16231509                            //  t delegate(parameter list) 
    16241510                            //  t function(parameter list) 
    1625                             Array *arguments; 
     1511                            Array arguments; 
    16261512                            int varargs; 
    16271513                            uint  save = token.value; 
    1628          
    1629                             nextToken(); 
    1630                             arguments = parseParameters(&varargs); 
     1514 
     1515                            nextToken(); 
     1516                            arguments = parseParameters(varargs); 
    16311517                            t = new TypeFunction(arguments, t, varargs, linkage); 
    16321518                            if (save == TOKdelegate) 
     
    16361522                            continue; 
    16371523                        } 
    1638          
     1524 
    16391525                    default: 
    16401526                        ts = t; 
     
    16451531            return ts; 
    16461532        } 
    1647          
    1648         Type * 
    1649         parseDeclarator(Type * t, Identifier ** pident) 
    1650         { 
    1651             Expression *e; 
    1652             Type *ts; 
    1653             Type *ta; 
    1654             Type **pt; 
    1655          
     1533 
     1534        Type parseDeclarator(Type t, Identifier *pident) { 
     1535            Expression e; 
     1536            Type ts; 
     1537            Type ta; 
     1538            Type *pt; 
     1539 
    16561540            //printf("parseDeclarator(t = %p)\n", t); 
    16571541            while (1) { 
     
    16701554                            t = new TypeDArray(t);  // [] 
    16711555                            nextToken(); 
    1672                         } else if (isDeclaration(&token, 0, TOKrbracket, null)) { // It's an associative array declaration 
    1673                             Type *index; 
    1674          
     1556                        } else if (isDeclaration(token, 0, TOKrbracket, null)) {  // It's an associative array declaration 
     1557                            Type index; 
     1558 
    16751559                            //printf("it's an associative array\n"); 
    16761560                            index = parseBasicType(); 
     
    16851569                        } 
    16861570                        continue; 
    1687          
     1571 
    16881572                    case TOKidentifier: 
    16891573                        if (pident) 
     
    16941578                        nextToken(); 
    16951579                        break; 
    1696          
     1580 
    16971581                    case TOKlparen: 
    16981582                        nextToken(); 
     
    17001584                        check(TOKrparen); 
    17011585                        break; 
    1702          
     1586 
    17031587                    case TOKdelegate: 
    17041588                    case TOKfunction: 
     
    17061590                            //  t delegate(parameter list) 
    17071591                            //  t function(parameter list) 
    1708                             Array *arguments; 
     1592                            Array arguments; 
    17091593                            int varargs; 
    17101594                            uint save = token.value; 
    1711          
    1712                             nextToken(); 
    1713                             arguments = parseParameters(&varargs); 
     1595 
     1596                            nextToken(); 
     1597                            arguments = parseParameters(varargs); 
    17141598                            t = new TypeFunction(arguments, t, varargs, linkage); 
    17151599                            if (save == TOKdelegate) 
     
    17251609                break; 
    17261610            } 
    1727          
     1611 
    17281612            while (1) { 
    17291613                switch (token.value) { 
     
    17351619                            ta = new TypeDArray(t); // [] 
    17361620                            nextToken(); 
    1737                         } else if (isDeclaration(&token, 0, TOKrbracket, null)) { // It's an associative array declaration 
    1738                             Type *index; 
    1739          
     1621                        } else if (isDeclaration(token, 0, TOKrbracket, null)) {  // It's an associative array declaration 
     1622                            Type index; 
     1623 
    17401624                            //printf("it's an associative array\n"); 
    17411625                            index = parseBasicType(); 
     
    17491633                            check(TOKrbracket); 
    17501634                        } 
    1751                         for (pt = &ts; *pt != t; pt = &(*pt).next) {} 
     1635                        for (pt = &ts; *pt != t; pt = &((*pt).next)) {} 
    17521636                        *pt = ta; 
    17531637                        continue; 
    17541638                    case TOKlparen: 
    17551639                        { 
    1756                             Array *arguments; 
     1640                            Array arguments; 
    17571641                            int varargs; 
    1758          
    1759                             arguments = parseParameters(&varargs); 
     1642 
     1643                            arguments = parseParameters(varargs); 
    17601644                            ta = new TypeFunction(arguments, t, varargs, linkage); 
    1761                             for (pt = &ts; *pt != t; pt = &(*pt).next) {} 
     1645                            for (pt = &ts; *pt != t; pt = &((*pt).next)) {} 
    17621646                            *pt = ta; 
    17631647                            continue; 
     
    17661650                break; 
    17671651            } 
    1768          
     1652 
    17691653            return ts; 
    17701654        } 
     
    17741658         */ 
    17751659         
    1776         Array * 
    1777         parseDeclaration() 
    1778         { 
     1660        Array parseDeclaration() { 
    17791661            uint storage_class; 
    17801662            uint sc; 
    1781             Type *ts; 
    1782             Type *t; 
    1783             Type *tfirst; 
    1784             Identifier *ident; 
    1785             Array *a; 
     1663            Type ts; 
     1664            Type t; 
     1665            Type tfirst; 
     1666            Identifier ident; 
     1667            Array a; 
    17861668            uint tok; 
    1787          
     1669 
    17881670            //printf("parseDeclaration()\n"); 
    17891671            switch (token.value) { 
     
    17931675                    nextToken(); 
    17941676                    break; 
    1795          
     1677 
    17961678                default: 
    17971679                    tok = TOKreserved; 
    17981680                    break; 
    17991681            } 
    1800          
     1682 
    18011683            storage_class = STCundefined; 
    18021684            while (1) { 
     
    18291711                        if (storage_class & sc) 
    18301712                            error("redundant storage class '%s'", token.toString()); 
    1831                         storage_class = cast(STC) (storage_class | sc); 
     1713                        storage_class = (storage_class | sc); 
    18321714                        nextToken(); 
    18331715                        continue; 
     
    18351717                break; 
    18361718            } 
    1837          
     1719 
    18381720            a = new Array; 
    18391721            ts = parseBasicType(); 
    18401722            ts = parseBasicType2(ts); 
    18411723            tfirst = null; 
    1842          
     1724 
    18431725            while (1) { 
    18441726                Loc loc = this.loc; 
    1845          
     1727 
    18461728                ident = null; 
    18471729                t = parseDeclarator(ts, &ident); 
     
    18531735                if (!ident) 
    18541736                    error("no identifier for declarator"); 
    1855          
     1737 
    18561738                if (tok == TOKtypedef || tok == TOKalias) { 
    1857                     Declaration *v; 
    1858                     Initializer *init; 
    1859          
     1739                    Declaration v; 
     1740                    Initializer init; 
     1741 
    18601742                    init = null; 
    18611743                    if (token.value == TOKassign) { 
     
    18761758                            nextToken(); 
    18771759                            break; 
    1878          
     1760 
    18791761                        case TOKcomma: 
    18801762                            nextToken(); 
    18811763                            continue; 
    1882          
     1764 
    18831765                        default: 
    18841766                            error("semicolon expected to close %s declaration", Token.toChars(tok)); 
     
    18861768                    } 
    18871769                } else if (t.ty == Tfunction) { 
    1888                     FuncDeclaration *f; 
    1889          
     1770                    FuncDeclaration f; 
     1771 
    18901772                    f = new FuncDeclaration(loc, 0, ident, storage_class, t); 
    18911773                    a.push(f); 
    18921774                    parseContracts(f); 
    18931775                } else { 
    1894                     VarDeclaration *v; 
    1895                     Initializer *init; 
    1896          
     1776                    VarDeclaration v; 
     1777                    Initializer init; 
     1778 
    18971779                    init = null; 
    18981780                    if (token.value == TOKassign) { 
     
    19071789                            nextToken(); 
    19081790                            break; 
    1909          
     1791 
    19101792                        case TOKcomma: 
    19111793                            nextToken(); 
    19121794                            continue; 
    1913          
     1795 
    19141796                        default: 
    19151797                            error("semicolon expected, not '%s'", token.toString()); 
     
    19211803            return a; 
    19221804        } 
    1923          
     1805 
    19241806        /***************************************** 
    19251807         * Parse contracts following function declaration. 
    19261808         */ 
    1927          
    1928         void 
    1929         parseContracts(FuncDeclaration * f) 
    1930         { 
    1931             Type *tb; 
     1809 
     1810        void parseContracts(FuncDeclaration f) { 
     1811            Type tb; 
    19321812            uint linksave = linkage; 
    1933          
     1813 
    19341814            // The following is irrelevant, as it is overridden by sc.linkage in 
    19351815            // TypeFunction.semantic 
     
    19411821                        error("missing body { ... } after in or out"); 
    19421822                    f.fbody = parseStatement(PSsemi); 
    1943                     f.endloc = endloc; 
     1823                    /+f.endloc = endloc;+/ 
    19441824                    break; 
    19451825         
     
    19471827                    nextToken(); 
    19481828                    f.fbody = parseStatement(PScurly); 
    1949                     f.endloc = endloc; 
     1829                    /+f.endloc = endloc;+/ 
    19501830                    break; 
    19511831         
     
    19891869         */ 
    19901870         
    1991         Initializer * 
    1992         parseInitializer() 
    1993         { 
    1994             StructInitializer *ist; 
    1995             ArrayInitializer *ia; 
    1996             ExpInitializer *ie; 
    1997             Expression *e; 
    1998             Identifier *id; 
    1999             Initializer *value; 
     1871        Initializer parseInitializer() { 
     1872            StructInitializer ist; 
     1873            ArrayInitializer ia; 
     1874            ExpInitializer ie; 
     1875            Expression e; 
     1876            Identifier id; 
     1877            Initializer value; 
    20001878            int comma; 
    20011879            Loc loc = this.loc; 
    2002             Token *t; 
     1880            Token t; 
    20031881         
    20041882            switch (token.value) { 
     
    20121890                                if (comma == 1) 
    20131891                                    error("comma expected separating field initializers"); 
    2014                                 t = peek(&token); 
     1892                                t = peek(token); 
    20151893                                if (t.value == TOKcolon) { 
    20161894                                    id = token.ident; 
     
    20971975                    } 
    20981976                    return ia; 
    2099          
     1977 
    21001978                default: 
    21011979                    e = parseAssignExp(); 
     
    21041982            } 
    21051983        } 
    2106          
    2107          
     1984 
     1985 
    21081986        /***************************************** 
    21091987         * Input: 
    21101988         *  flags   PSxxxx 
    21111989         */ 
    2112          
    2113         Statement* parseStatement(int flags) 
     1990 
     1991        Statement parseStatement(int flags) 
    21141992        { 
    2115             Statement *s; 
    2116             Token *t; 
     1993            Statement s; 
     1994            Token t; 
    21171995            Loc loc = this.loc; 
    2118          
     1996 
    21191997            //printf("parseStatement()\n"); 
    21201998         
     
    21252003                case TOKidentifier: 
    21262004                    // Need to look ahead to see if it is a declaration, label, or expression 
    2127                     t = peek(&token); 
     2005                    t = peek(token); 
    21282006                    if (t.value == TOKcolon) {  // It's a label 
    2129                         Identifier *ident; 
     2007                        Identifier ident; 
    21302008         
    21312009                        ident = token.ident; 
    21322010                        nextToken(); 
    21332011                        nextToken(); 
    2134                         s = parseStatement(PSsemi); 
    2135                         s = new LabelStatement(loc, ident, s); 
     2012                        /+s = +/parseStatement(PSsemi); 
     2013                        /+s = new LabelStatement(loc, ident, s);+/ 
     2014                        s = null; 
    21362015                        break; 
    21372016                    } 
     
    21392018                case TOKdot: 
    21402019                case TOKtypeof: 
    2141                     if (isDeclaration(&token, 2, TOKreserved, null)) 
     2020                    if (isDeclaration(token, 2, TOKreserved, null)) 
    21422021                        goto Ldeclaration; 
    21432022                    else 
     
    21792058                  Lexp: 
    21802059                    { 
    2181                         Expression *exp; 
     2060                        Expression exp; 
    21822061         
    21832062                        exp = parseExpression(); 
    21842063                        check(TOKsemicolon, "statement"); 
    2185                         s = new ExpStatement(loc, exp); 
     2064                        /+s = new ExpStatement(loc, exp);+/ 
    21862065                        break; 
    21872066                    } 
     
    21932072                     *  3) Expression 
    21942073                     */ 
    2195                     if (isDeclaration(&token, 2, TOKreserved, null)) { 
     2074                    if (isDeclaration(token, 2, TOKreserved, null)) { 
    21962075                        //printf("it's a declaration\n"); 
    21972076                        goto Ldeclaration; 
    21982077                    } else { 
    2199                         if (isTemplateInstance(&token, &t) && t.value == TOKidentifier) { // case 2 
    2200                             TemplateInstance *ti; 
    2201                             AliasDeclaration *a; 
     2078                        if (isTemplateInstance(token, &t) && t.value == TOKidentifier) {  // case 2 
     2079                            TemplateInstance ti; 
     2080                            AliasDeclaration a; 
    22022081         
    22032082                            ti = parseTemplateInstance(); 
     
    22172096                case TOKstatic: 
    22182097                    {                   // Look ahead to see if it's static assert() 
    2219                         Token *t; 
    2220          
    2221                         t = peek(&token); 
     2098                        Token t; 
     2099         
     2100                        t = peek(token); 
    22222101                        if (t.value == TOKassert) { 
    22232102                            nextToken(); 
    2224                             s = new StaticAssertStatement(parseStaticAssert()); 
     2103                            /+s = new StaticAssertStatement(parseStaticAssert());+/ 
     2104                            s = null; 
    22252105                            break; 
    22262106                        } 
     
    22462126                  Ldeclaration: 
    22472127                    { 
    2248                         Array *a; 
     2128                        Array a; 
    22492129 
    22502130                        a = parseDeclaration(); 
    22512131                        if (a.dim > 1) { 
    2252                             Array *as = new Array
     2132                            ArrayT!(Statement) as = new ArrayT!(Statement)()
    22532133 
    22542134                            as.reserve(a.dim); 
    22552135                            for (int i = 0; i < a.dim; i++) { 
    2256                                 Dsymbol *d = cast(Dsymbol *) a.data[i]; 
     2136                                Dsymbol d = cast(Dsymbol) a.data[i]; 
    22572137 
    22582138                                s = new DeclarationStatement(loc, d); 
     
    22612141                            s = new CompoundStatement(loc, as); 
    22622142                        } else if (a.dim == 1) { 
    2263                             Dsymbol *d = cast(Dsymbol *) a.data[0]; 
     2143                            Dsymbol d = cast(Dsymbol) a.data[0]; 
    22642144 
    22652145                            s = new DeclarationStatement(loc, d); 
    22662146                        } else 
    22672147                            assert(0); 
    2268                         if (flags & PSscope) 
    2269                             s = new ScopeStatement(loc, s); 
    22702148                        break; 
    22712149                    } 
     
    22762154                case TOKinterface: 
    22772155                    { 
    2278                         Dsymbol *d; 
     2156                        Dsymbol d; 
    22792157 
    22802158                        d = parseAggregate(); 
     
    22852163                case TOKenum: 
    22862164                    { 
    2287                         Dsymbol *d; 
     2165                        Dsymbol d; 
    22882166         
    22892167                        d = parseEnum(); 
     
    22942172                case TOKmixin: 
    22952173                    { 
    2296                         Dsymbol *d; 
     2174                        Dsymbol d; 
    22972175         
    22982176                        d = parseMixin(); 
     
    23032181                case TOKlcurly: 
    23042182                    { 
    2305                         Array *statements; 
    2306  
    2307                         nextToken(); 
    2308                         statements = new Array; 
     2183                        nextToken(); 
    23092184                        while (token.value != TOKrcurly) { 
    2310                             statements.push(parseStatement(PSsemi | PScurlyscope)); 
    2311                         } 
    2312                         endloc = this.loc; 
    2313                         s = new CompoundStatement(loc, statements); 
    2314                         if (flags & (PSscope | PScurlyscope)) 
    2315                             s = new ScopeStatement(loc, s); 
     2185                            parseStatement(PSsemi | PScurlyscope); 
     2186                        } 
    23162187                        nextToken(); 
    23172188                        break; 
     
    23202191                case TOKwhile: 
    23212192                    { 
    2322                         Expression *condition; 
    2323                         Statement *sbody; 
    2324  
    23252193                        nextToken(); 
    23262194                        check(TOKlparen); 
    2327                         condition = parseExpression(); 
     2195                        parseExpression(); 
    23282196                        check(TOKrparen); 
    2329                         sbody = parseStatement(PSscope); 
    2330                         s = new WhileStatement(loc, condition, sbody)
     2197                        parseStatement(PSscope); 
     2198                        s = null
    23312199                        break; 
    23322200                    } 
     
    23412209                case TOKdo: 
    23422210                    { 
    2343                         Statement *sbody; 
    2344                         Expression *condition; 
    2345  
    2346                         nextToken(); 
    2347                         sbody = parseStatement(PSscope); 
     2211                        nextToken(); 
     2212                        parseStatement(PSscope); 
    23482213                        check(TOKwhile); 
    23492214                        check(TOKlparen); 
    2350                         condition = parseExpression(); 
     2215                        parseExpression(); 
    23512216                        check(TOKrparen); 
    2352                         s = new DoStatement(loc, sbody, condition)
     2217                        s = null
    23532218                        break; 
    23542219                    } 
     
    23562221                case TOKfor: 
    23572222                    { 
    2358                         Statement *init; 
    2359                         Expression *condition; 
    2360                         Expression *increment; 
    2361                         Statement *sbody; 
    2362  
    23632223                        nextToken(); 
    23642224                        check(TOKlparen); 
    23652225                        if (token.value == TOKsemicolon) { 
    2366                             init = null; 
    23672226                            nextToken(); 
    23682227                        } else { 
    2369                             init = parseStatement(0); 
     2228                            parseStatement(0); 
    23702229                        } 
    23712230                        if (token.value == TOKsemicolon) { 
    2372                             condition = null; 
    23732231                            nextToken(); 
    23742232                        } else { 
    2375                             condition = parseExpression(); 
     2233                            parseExpression(); 
    23762234                            check(TOKsemicolon, "for condition"); 
    23772235                        } 
    23782236                        if (token.value == TOKrparen) { 
    2379                             increment = null; 
    23802237                            nextToken(); 
    23812238                        } else { 
    2382                             increment = parseExpression(); 
     2239                            parseExpression(); 
    23832240                            check(TOKrparen); 
    23842241                        } 
    2385                         sbody = parseStatement(0); 
    2386                         s = new ForStatement(loc, init, condition, increment, sbody)
     2242                        parseStatement(0); 
     2243                        s = null
    23872244                        break; 
    23882245                    } 
     
    23902247                case TOKforeach: 
    23912248                    { 
    2392                         Array *arguments; 
    2393          
    2394                         Statement *d; 
    2395                         Statement *sbody; 
    2396                         Expression *aggr; 
    2397          
    23982249                        nextToken(); 
    23992250                        check(TOKlparen); 
    24002251         
    2401                         arguments = new Array; 
    2402          
    24032252                        while (1) { 
    2404                             Type *tb; 
    2405                             Identifier *ai = null; 
    2406                             Type *at; 
     2253                            Type tb; 
     2254                            Identifier ai = null; 
     2255                            Type at; 
    24072256                            uint inoutt; 
    2408                             Argument *a; 
     2257                            Argument a; 
    24092258         
    24102259                            inoutt = In; 
     
    24172266                            if (!ai) 
    24182267                                error("no identifier for declarator"); 
    2419                             a = new Argument(inoutt, at, ai, null); 
    2420                             arguments.push(a); 
    24212268                            if (token.value == TOKcomma) { 
    24222269                                nextToken(); 
     
    24272274                        check(TOKsemicolon); 
    24282275         
    2429                         aggr = parseExpression(); 
     2276                        parseExpression(); 
    24302277                        check(TOKrparen); 
    2431                         sbody = parseStatement(0); 
    2432                         s = new ForeachStatement(loc, arguments, aggr, sbody)
     2278                        parseStatement(0); 
     2279                        s = null
    24332280                        break; 
    24342281                    } 
     
    24362283                case TOKif: 
    24372284                    { 
    2438                         Expression *condition; 
    2439                         Statement *ifbody; 
    2440                         Statement *elsebody; 
    2441          
    24422285                        nextToken(); 
    24432286                        check(TOKlparen); 
    2444                         condition = parseExpression(); 
     2287                        parseExpression(); 
    24452288                        check(TOKrparen); 
    2446                         ifbody = parseStatement(PSscope); 
     2289                        parseStatement(PSscope); 
    24472290                        if (token.value == TOKelse) { 
    24482291                            nextToken(); 
    2449                             elsebody = parseStatement(PSscope); 
    2450                         } else 
    2451                             elsebody = null; 
    2452                         s = new IfStatement(loc, condition, ifbody, elsebody); 
     2292                            parseStatement(PSscope); 
     2293                        } 
     2294                        s = null; 
    24532295                        break; 
    24542296                    } 
     
    24562298                case TOKdebug: 
    24572299                    { 
    2458                         Condition *condition; 
    2459                         Statement *ifbody; 
    2460                         Statement *elsebody; 
    2461          
    24622300                        nextToken(); 
    24632301                        if (token.value == TOKlparen) { 
    24642302                            nextToken(); 
    2465                             condition = parseDebugCondition(); 
     2303                            parseDebugCondition(); 
    24662304                            check(TOKrparen); 
    2467                         } else 
    2468                             condition = new DebugCondition(mod, 1, null); 
    2469                         ifbody = parseStatement(PSsemi); 
     2305                        } 
     2306                        parseStatement(PSsemi); 
    24702307                        if (token.value == TOKelse) { 
    24712308                            nextToken(); 
    2472                             elsebody = parseStatement(PSsemi); 
    2473                         } else 
    2474                             elsebody = null; 
    2475                         s = new ConditionalStatement(loc, condition, ifbody, elsebody); 
     2309                            parseStatement(PSsemi); 
     2310                        } 
     2311                        s = null; 
    24762312                        break; 
    24772313                    } 
     
    24792315                case TOKversion: 
    24802316                    { 
    2481                        Condition *condition; 
    2482                         Statement *ifbody; 
    2483                         Statement *elsebody; 
    2484        
     2317/+                     Condition condition; 
     2318                        Statement ifbody; 
     2319                        Statement elsebody; 
     2320+/     
    24852321                        nextToken(); 
    24862322                        if (token.value == TOKlparen) { 
    24872323                            nextToken(); 
    2488                             condition = parseVersionCondition(); 
     2324                            /+condition = +/parseVersionCondition(); 
    24892325                            check(TOKrparen); 
    24902326                        } else { 
    24912327                            error("(condition) expected after version"); 
    2492                             condition = null; 
    2493                         } 
    2494                         ifbody = parseStatement(PSsemi); 
     2328                            /+condition = null;+/ 
     2329                        } 
     2330                        /+ifbody = +/parseStatement(PSsemi); 
    24952331                        if (token.value == TOKelse) { 
    24962332                            nextToken(); 
    2497                             elsebody = parseStatement(PSsemi); 
    2498                         } else 
    2499                             elsebody = null; 
    2500                         s = new ConditionalStatement(loc, condition, ifbody, elsebody); 
     2333                            /+elsebody = +/parseStatement(PSsemi); 
     2334                        }/+ else 
     2335                            elsebody = null;+/ 
     2336                        /+s = new ConditionalStatement(loc, condition, ifbody, elsebody);+/ 
     2337                        s = null; 
    25012338                        break; 
    25022339                    } 
     
    25042341                case TOKpragma: 
    25052342                    { 
    2506                         Identifier *ident; 
    2507                         Array *args = null; 
    2508                         Statement *sbody; 
    2509          
    25102343                        nextToken(); 
    25112344                        check(TOKlparen); 
     
    25142347                            goto Lerror; 
    25152348                        } 
    2516                         ident = token.ident; 
    25172349                        nextToken(); 
    25182350                        if (token.value == TOKcomma) 
    2519                             args = parseArguments();  // pragma(identifier, args...); 
     2351                            parseArguments(); // pragma(identifier, args...); 
    25202352                        else 
    25212353                            check(TOKrparen);   // pragma(identifier); 
    2522                         sbody = parseStatement(PSsemi); 
    2523                         s = new PragmaStatement(loc, ident, args, sbody)
     2354                        parseStatement(PSsemi); 
     2355                        s = null
    25242356                        break; 
    25252357                    } 
     
    25272359                case TOKswitch: 
    25282360                    { 
    2529                         Expression *condition; 
    2530                         Statement *sbody; 
    25312361         
    25322362                        nextToken(); 
    25332363                        check(TOKlparen); 
    2534                         condition = parseExpression(); 
     2364                        parseExpression(); 
    25352365                        check(TOKrparen); 
    2536                         sbody = parseStatement(PSscope); 
    2537                         s = new SwitchStatement(loc, condition, sbody)
     2366                        parseStatement(PSscope); 
     2367                        s = null
    25382368                        break; 
    25392369                    } 
     
    25412371                case TOKcase: 
    25422372                    { 
    2543                         Expression *exp; 
    2544                         Array *statements; 
    2545                         Array cases;    // array of Expression's 
     2373                        Expression exp; 
     2374                        Array statements; 
    25462375         
    25472376                        while (1) { 
    25482377                            nextToken(); 
    25492378                            exp = parseAssignExp(); 
    2550                             cases.push(exp); 
    25512379                            if (token.value != TOKcomma) 
    25522380                                break; 
     
    25542382                        check(TOKcolon); 
    25552383         
    2556                         statements = new Array; 
    25572384                        while (token.value != TOKcase && token.value != TOKdefault && token.value != TOKrcurly) { 
    2558                             statements.push(parseStatement(PSsemi | PScurlyscope)); 
    2559                         } 
    2560                         s = new CompoundStatement(loc, statements); 
    2561                         s = new ScopeStatement(loc, s); 
    2562          
    2563                         // Keep cases in order by building the case statements backwards 
    2564                         for (int i = cases.dim; i; i--) { 
    2565                             exp = cast(Expression *) cases.data[i - 1]; 
    2566                             s = new CaseStatement(loc, exp, s); 
    2567                         } 
     2385                            parseStatement(PSsemi | PScurlyscope); 
     2386                        } 
     2387                        s = null; 
    25682388                        break; 
    25692389                    } 
     
    25712391                case TOKdefault: 
    25722392                    { 
    2573                         Array *statements; 
     2393                        Array statements; 
    25742394         
    25752395                        nextToken(); 
    25762396                        check(TOKcolon); 
    25772397         
    2578                         statements = new Array; 
    25792398                        while (token.value != TOKcase && token.value != TOKdefault && token.value != TOKrcurly) { 
    2580                             statements.push(parseStatement(PSsemi | PScurlyscope)); 
    2581                         } 
    2582                         s = new CompoundStatement(loc, statements); 
    2583                         s = new ScopeStatement(loc, s); 
    2584                         s = new DefaultStatement(loc, s); 
     2399                            parseStatement(PSsemi | PScurlyscope); 
     2400                        } 
     2401                        s = null; 
    25852402                        break; 
    25862403                    } 
     
    25882405                case TOKreturn: 
    25892406                    { 
    2590                         Expression *exp; 
     2407                        Expression exp; 
    25912408         
    25922409                        nextToken(); 
     
    25962413                            exp = parseExpression(); 
    25972414                        check(TOKsemicolon, "return statement"); 
    2598                         s = new ReturnStatement(loc, exp)
     2415                        s = null
    25992416                        break; 
    26002417                    } 
     
    26022419                case TOKbreak: 
    26032420                    { 
    2604                         Identifier *ident; 
     2421                        Identifier ident; 
    26052422         
    26062423                        nextToken(); 
     
    26112428                            ident = null; 
    26122429                        check(TOKsemicolon, "break statement"); 
    2613                         s = new BreakStatement(loc, ident)
     2430                        s = null
    26142431                        break; 
    26152432                    } 
     
    26172434                case TOKcontinue: 
    26182435                    { 
    2619                         Identifier *ident; 
     2436                        Identifier ident; 
    26202437         
    26212438                        nextToken(); 
     
    26262443                            ident = null; 
    26272444                        check(TOKsemicolon, "continue statement"); 
    2628                         s = new ContinueStatement(loc, ident)
     2445                        s = null
    26292446                        break; 
    26302447                    } 
     
    26322449                case TOKgoto: 
    26332450                    { 
    2634                         Identifier *ident; 
     2451                        Identifier ident; 
    26352452         
    26362453                        nextToken(); 
    26372454                        if (token.value == TOKdefault) { 
    26382455                            nextToken(); 
    2639                             s = new GotoDefaultStatement(loc)
     2456                            s = null
    26402457                        } else if (token.value == TOKcase) { 
    26412458                            Expression *exp = null; 
     
    26432460                            nextToken(); 
    26442461                            if (token.value != TOKsemicolon) 
    2645                                 exp = parseExpression(); 
    2646                             s = new GotoCaseStatement(loc, exp)
     2462                                parseExpression(); 
     2463                            s = null
    26472464                        } else { 
    26482465                            if (token.value != TOKidentifier) { 
    26492466                                error("Identifier expected following goto"); 
    2650                                 ident = null; 
    26512467                            } else { 
    2652                                 ident = token.ident; 
    26532468                                nextToken(); 
    26542469                            } 
    2655                             s = new GotoStatement(loc, ident)
     2470                            s = null
    26562471                        } 
    26572472                        check(TOKsemicolon, "goto statement"); 
     
    26612476                case TOKsynchronized: 
    26622477                    { 
    2663                         Expression *exp; 
    2664                         Statement *sbody; 
     2478                        Expression exp; 
     2479                        Statement sbody; 
    26652480         
    26662481                        nextToken(); 
    26672482                        if (token.value == TOKlparen) { 
    26682483                            nextToken(); 
    2669                             exp = parseExpression(); 
     2484                            parseExpression(); 
    26702485                            check(TOKrparen); 
    26712486                        } else 
    26722487                            exp = null; 
    2673                         sbody = parseStatement(PSscope); 
    2674                         s = new SynchronizedStatement(loc, exp, sbody)
     2488                        parseStatement(PSscope); 
     2489                        s = null
    26752490                        break; 
    26762491                    } 
     
    26782493                case TOKwith: 
    26792494                    { 
    2680                         Expression *exp; 
    2681                         Statement *sbody; 
    2682          
    26832495                        nextToken(); 
    26842496                        check(TOKlparen); 
    2685                         exp = parseExpression(); 
     2497                        parseExpression(); 
    26862498                        check(TOKrparen); 
    2687                         sbody = parseStatement(PSscope); 
    2688                         s = new WithStatement(loc, exp, sbody)
     2499                        parseStatement(PSscope); 
     2500                        s = null
    26892501                        break; 
    26902502                    } 
     
    26922504                case TOKtry: 
    26932505                    { 
    2694                         Statement *sbody; 
    2695                         Array *catches = null; 
    2696                         Statement *finalbody = null; 
    2697          
    2698                         nextToken(); 
    2699                         sbody = parseStatement(PSscope); 
     2506         
     2507                        nextToken(); 
     2508                        parseStatement(PSscope); 
    27002509                        while (token.value == TOKcatch) { 
    2701                             Statement *handler; 
    2702                             Catch *c; 
    2703                             Type *t; 
    2704                             Identifier *id; 
     2510                            Statement handler; 
     2511                            Type t; 
     2512                            Identifier id; 
    27052513         
    27062514                            nextToken(); 
     
    27152523                                check(TOKrparen); 
    27162524                            } 
    2717                             handler = parseStatement(0); 
    2718                             c = new Catch(loc, t, id, handler); 
    2719                             if (!catches) 
    2720                                 catches = new Array; 
    2721                             catches.push(c); 
     2525                            parseStatement(0); 
    27222526                        } 
    27232527         
    27242528                        if (token.value == TOKfinally) { 
    27252529                            nextToken(); 
    2726                             finalbody = parseStatement(0); 
    2727                         } 
    2728          
    2729                         s = sbody; 
    2730                         if (!catches && !finalbody) 
    2731                             error("catch or finally expected following try"); 
    2732                         else { 
    2733                             if (catches) 
    2734                                 s = new TryCatchStatement(loc, sbody, catches); 
    2735                             if (finalbody) 
    2736                                 s = new TryFinallyStatement(loc, s, finalbody); 
     2530                            parseStatement(0); 
    27372531                        } 
    27382532                        break; 
     
    27412535                case TOKthrow: 
    27422536                    { 
    2743                         Expression *exp; 
    2744          
    2745                         nextToken(); 
    2746                         exp = parseExpression(); 
     2537                        nextToken(); 
     2538                        parseExpression(); 
    27472539                        check(TOKsemicolon, "throw statement"); 
    2748                         s = new ThrowStatement(loc, exp)
     2540                        s = null
    27492541                        break; 
    27502542                    } 
     
    27522544                case TOKvolatile: 
    27532545                    nextToken(); 
    2754                     s = parseStatement(PSsemi | PSscope); 
    2755                     s = new VolatileStatement(loc, s)
     2546                    parseStatement(PSsemi | PSscope); 
     2547                    s = null
    27562548                    break; 
    27572549 
    27582550                case TOKasm: 
    27592551                    { 
    2760                         Array *statements; 
    2761                         Identifier *label; 
    2762                         Loc labelloc; 
    2763                         Token *toklist; 
    2764                         Token **ptoklist; 
    2765  
    27662552                        // Parse the asm block into a sequence of AsmStatements, 
    27672553                        // each AsmStatement is one instruction. 
     
    27712557                        nextToken(); 
    27722558                        check(TOKlcurly); 
    2773                         toklist = null; 
    2774                         ptoklist = &toklist; 
    2775                         label = null; 
    2776                         statements = new Array; 
    27772559                        while (1) { 
    27782560                            switch (token.value) { 
    27792561                                case TOKidentifier: 
    2780                                     if (!toklist) { 
    2781                                         // Look ahead to see if it is a label 
    2782                                         t = peek(&token); 
    2783                                         if (t.value == TOKcolon) {  // It's a label 
    2784                                             label = token.ident; 
    2785                                             labelloc = this.loc; 
    2786                                             nextToken(); 
    2787                                             nextToken(); 
    2788                                             continue; 
    2789                                         } 
     2562                                    // Look ahead to see if it is a label 
     2563                                    t = peek(token); 
     2564                                    if (t.value == TOKcolon) {  // It's a label 
     2565                                        nextToken(); 
     2566                                        nextToken(); 
     2567                                        continue; 
    27902568                                    } 
    27912569                                    goto Ldefault; 
    27922570 
    27932571                                case TOKrcurly: 
    2794                                     if (toklist || label) { 
    2795                                         error("asm statements must end in ';'"); 
    2796                                     } 
    27972572                                    break; 
    27982573 
    27992574                                case TOKsemicolon: 
    28002575                                    s = null; 
    2801                                     if (toklist || label) { // Create AsmStatement from list of tokens we've saved 
    2802                                         s = new AsmStatement(this.loc, toklist); 
    2803                                         toklist = null; 
    2804                                         ptoklist = &toklist; 
    2805                                         if (label) { 
    2806                                             s = new LabelStatement(labelloc, label, s); 
    2807                                             label = null; 
    2808                                         } 
    2809                                         statements.push(s); 
    2810                                     } 
    28112576                                    nextToken(); 
    28122577                                    continue; 
     
    28182583                                default: 
    28192584                                  Ldefault: 
    2820                                     *ptoklist = new Token(); 
    2821                                     memcpy(*ptoklist, &token, sizeof(Token)); 
    2822                                     ptoklist = &(*ptoklist).next; 
    2823                                     *ptoklist = null; 
    2824          
    28252585                                    nextToken(); 
    28262586                                    continue; 
     
    28282588                            break; 
    28292589                        } 
    2830                         s = new CompoundStatement(loc, statements)
     2590                        s = null
    28312591                        nextToken(); 
    28322592                        break; 
     
    28462606        } 
    28472607 
     2608        /************************************ 
     2609         * Determine if the scanner is sitting on the start of a declaration. 
     2610         * Input: 
     2611         *  needId  0   no identifier 
     2612         *      1   identifier optional 
     2613         *      2   must have identifier 
     2614         */ 
     2615 
     2616        bool isDeclaration(Token t, int needId, uint endtok, Token *pt) { 
     2617            bool haveId = 0; 
     2618 
     2619            if (!isBasicType(&t)) 
     2620                return false; 
     2621            if (!isDeclarator(&t, haveId, endtok)) 
     2622                return false; 
     2623            if ( needId == 1 || 
     2624            (needId == 0 && !haveId) || 
     2625            (needId == 2 &&  haveId)) 
     2626            {   if (pt) 
     2627                    *pt = t; 
     2628                return true; 
     2629            } 
     2630            else 
     2631                return false; 
     2632        } 
     2633 
     2634        int isBasicType(Token *pt) 
     2635        { 
     2636            // This code parallels parseBasicType() 
     2637            Token t = *pt; 
     2638            Token t2; 
     2639            int parens; 
     2640 
     2641            switch (t.value) { 
     2642                case TOKwchar: case TOKdchar: 
     2643                case TOKbit: case TOKchar: 
     2644                case TOKint8: case TOKuns8: 
     2645                case TOKint16: case TOKuns16: 
     2646                case TOKint32: case TOKuns32: 
     2647                case TOKint64: case TOKuns64: 
     2648                case TOKfloat32: case TOKfloat64: case TOKfloat80: 
     2649                case TOKimaginary32: case TOKimaginary64: case TOKimaginary80: 
     2650                case TOKcomplex32: case TOKcomplex64: case TOKcomplex80: 
     2651                case TOKvoid: 
     2652                t = peek(t); 
     2653                break; 
     2654 
     2655            case TOKidentifier: 
     2656                t = peek(t); 
     2657                if (t.value == TOKnot) 
     2658                { 
     2659                    goto L4; 
     2660                } 
     2661                goto L3; 
     2662                while (1) 
     2663                { 
     2664            L2: 
     2665                t = peek(t); 
     2666            L3: 
     2667                if (t.value == TOKdot) 
     2668                { 
     2669            Ldot: 
     2670  &nbs