Changeset 14 for trunk/dparse.d

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

--

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/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                    t = peek(t); 
     2671                    if (t.value != TOKidentifier) 
     2672                        goto Lfalse; 
     2673                    t = peek(t); 
     2674                    if (t.value != TOKnot) 
     2675                        goto L3; 
     2676            L4: 
     2677                    t = peek(t); 
     2678                    if (t.value != TOKlparen) 
     2679                        goto Lfalse; 
     2680                    if (!skipParens(t, &t)) 
     2681                        goto Lfalse; 
     2682                } 
     2683                else 
     2684                    break; 
     2685                } 
     2686                break; 
     2687 
     2688            case TOKdot: 
     2689                goto Ldot; 
     2690 
     2691            case TOKinstance:   // Deprecated 
     2692                // Handle cases like: 
     2693                //  instance Foo(int).bar x; 
     2694                // But remember that: 
     2695                //  instance Foo(int) x; 
     2696                // is not a type, but is an AliasDeclaration declaration. 
     2697                if (!isTemplateInstance(t, &t)) 
     2698                    goto Lfalse;        // invalid syntax for template instance 
     2699                if (t.value == TOKdot) 
     2700                    goto Ldot; 
     2701                goto Lfalse; 
     2702 
     2703            case TOKtypeof: 
     2704                /* typeof(exp).identifier... 
     2705                 */ 
     2706                t = peek(t); 
     2707                if (t.value != TOKlparen) 
     2708                    goto Lfalse; 
     2709                if (!skipParens(t, &t)) 
     2710                    goto Lfalse; 
     2711                goto L2; 
     2712 
     2713            default: 
     2714                goto Lfalse; 
     2715            } 
     2716            *pt = t; 
     2717            return TRUE; 
     2718 
     2719        Lfalse: 
     2720            return FALSE; 
     2721        } 
     2722 
     2723        int isDeclarator(Token *pt, out bool haveId, uint endtok) 
     2724        {   // This code parallels parseDeclarator() 
     2725            Token t = *pt; 
     2726            int parens; 
     2727 
     2728            if (t.value == TOKassign) 
     2729                return FALSE; 
     2730 
     2731            while (1) { 
     2732                parens = FALSE; 
     2733                switch (t.value) 
     2734                { 
     2735                    case TOKmul: 
     2736                    case TOKand: 
     2737                        t = peek(t); 
     2738                        continue; 
     2739             
     2740                    case TOKlbracket: 
     2741                        t = peek(t); 
     2742                        if (t.value == TOKrbracket) 
     2743                        { 
     2744                            t = peek(t); 
     2745                        } 
     2746                        else if (isDeclaration(t, 0, TOKrbracket, &t)) 
     2747                        {   // It's an associative array declaration 
     2748                            t = peek(t); 
     2749                        } 
     2750                        else 
     2751                        { 
     2752                            // [ expression ] 
     2753                            if (!isExpression(&t)) 
     2754                                return FALSE; 
     2755                            if (t.value != TOKrbracket) 
     2756                                return FALSE; 
     2757                            t = peek(t); 
     2758                        } 
     2759                        continue; 
     2760             
     2761                    case TOKidentifier: 
     2762                        haveId = true; 
     2763                        t = peek(t); 
     2764                        break; 
     2765 
     2766                    case TOKlparen: 
     2767                        t = peek(t); 
     2768 
     2769                        if (t.value == TOKrparen) 
     2770                            return FALSE;       // () is not a declarator 
     2771 
     2772                        /* Regard ( identifier ) as not a declarator 
     2773                        * BUG: what about ( *identifier ) in 
     2774                        *   f(*p)(x); 
     2775                        * where f is a class instance with overloaded () ? 
     2776                        * Should we just disallow C-style function pointer declarations? 
     2777                        */ 
     2778                        if (t.value == TOKidentifier) 
     2779                        {   Token t2 = peek(t); 
     2780                            if (t2.value == TOKrparen) 
     2781                                return FALSE; 
     2782                        } 
     2783 
     2784 
     2785                        if (!isDeclarator(&t, haveId, TOKrparen)) 
     2786                            return FALSE; 
     2787                        t = peek(t); 
     2788                        parens = TRUE; 
     2789                        break; 
     2790 
     2791                    case TOKdelegate: 
     2792                    case TOKfunction: 
     2793                        t = peek(t); 
     2794                        if (!isParameters(&t)) 
     2795                            return FALSE; 
     2796                        continue; 
     2797                } 
     2798                break; 
     2799            } 
     2800 
     2801            while (1) { 
     2802                switch (t.value) 
     2803                { 
     2804    //      #if CARRAYDECL 
     2805                    case TOKlbracket: 
     2806                        parens = FALSE; 
     2807                        t = peek(t); 
     2808                        if (t.value == TOKrbracket) 
     2809                        { 
     2810                            t = peek(t); 
     2811                        } 
     2812                        else if (isDeclaration(t, 0, TOKrbracket, &t)) 
     2813                        {   // It's an associative array declaration 
     2814                            t = peek(t); 
     2815                        } 
     2816                        else 
     2817                        { 
     2818                            // [ expression ] 
     2819                            if (!isExpression(&t)) 
     2820                                return FALSE; 
     2821                            if (t.value != TOKrbracket) 
     2822                                return FALSE; 
     2823                            t = peek(t); 
     2824                        } 
     2825                        continue; 
     2826    //      #endif 
     2827             
     2828                    case TOKlparen: 
     2829                        parens = FALSE; 
     2830                        if (!isParameters(&t)) 
     2831                            return FALSE; 
     2832                        continue; 
     2833             
     2834                    // Valid tokens that follow a declaration 
     2835                    case TOKrparen: 
     2836                    case TOKrbracket: 
     2837                    case TOKassign: 
     2838                    case TOKcomma: 
     2839                    case TOKsemicolon: 
     2840                    case TOKlcurly: 
     2841                        // The !parens is to disallow unnecessary parentheses 
     2842                        if (!parens && (endtok == TOKreserved || endtok == t.value)) 
     2843                        {   *pt = t; 
     2844                            return TRUE; 
     2845                        } 
     2846                        return FALSE; 
     2847             
     2848                    default: 
     2849                        return FALSE; 
     2850                } 
     2851            } 
     2852        } 
     2853         
     2854         
     2855        int isParameters(Token *pt) 
     2856        {   // This code parallels parseParameters() 
     2857            Token t = *pt; 
     2858            bool tmp; 
     2859         
     2860            if (t.value != TOKlparen) 
     2861            return FALSE; 
     2862            t = peek(t); 
     2863            while (1) 
     2864            { 
     2865            switch (t.value) 
     2866            { 
     2867                case TOKrparen: 
     2868                break; 
     2869         
     2870                case TOKdotdotdot: 
     2871                t = peek(t); 
     2872                break; 
     2873         
     2874                case TOKin: 
     2875                case TOKout: 
     2876                case TOKinout: 
     2877                t = peek(t); 
     2878                default: 
     2879                if (!isBasicType(&t)) 
     2880                    return FALSE; 
     2881                tmp = FALSE; 
     2882                if (!isDeclarator(&t, tmp, TOKreserved)) 
     2883                    return FALSE; 
     2884                if (t.value == TOKcomma) 
     2885                {   t = peek(t); 
     2886                    continue; 
     2887                } 
     2888                break; 
     2889            } 
     2890            break; 
     2891            } 
     2892            if (t.value != TOKrparen) 
     2893            return FALSE; 
     2894            t = peek(t); 
     2895            *pt = t; 
     2896            return TRUE; 
     2897        } 
     2898         
     2899        int isExpression(Token *pt) 
     2900        { 
     2901            // This is supposed to determine if something is an expression. 
     2902            // What it actually does is scan until a closing right bracket 
     2903            // is found. 
     2904         
     2905            Token t = *pt; 
     2906            int nest = 0; 
     2907         
     2908            for (;; t = peek(t)) 
     2909            { 
     2910            switch (t.value) 
     2911            { 
     2912                case TOKlbracket: 
     2913                nest++; 
     2914                continue; 
     2915         
     2916                case TOKrbracket: 
     2917                if (--nest >= 0) 
     2918                    continue; 
     2919                break; 
     2920         
     2921                case TOKeof: 
     2922                return FALSE; 
     2923         
     2924                default: 
     2925                continue; 
     2926            } 
     2927            break; 
     2928            } 
     2929         
     2930            *pt = t; 
     2931            return TRUE; 
     2932        } 
     2933         
     2934        /********************************************** 
     2935         * Skip over 
     2936         *  instance foo.bar(parameters...) 
     2937         * Output: 
     2938         *  if (pt), *pt is set to the token following the closing ) 
     2939         * Returns: 
     2940         *  1   it's valid instance syntax 
     2941         *  0   invalid instance syntax 
     2942         */ 
     2943         
     2944        int isTemplateInstance(Token t, Token *pt) 
     2945        { 
     2946            t = peek(t); 
     2947            if (t.value != TOKdot) 
     2948            { 
     2949            if (t.value != TOKidentifier) 
     2950                goto Lfalse; 
     2951            t = peek(t); 
     2952            } 
     2953            while (t.value == TOKdot) 
     2954            { 
     2955            t = peek(t); 
     2956            if (t.value != TOKidentifier) 
     2957                goto Lfalse; 
     2958            t = peek(t); 
     2959            } 
     2960            if (t.value != TOKlparen) 
     2961            goto Lfalse; 
     2962         
     2963            // Skip over the template arguments 
     2964            while (1) 
     2965            { 
     2966            while (1) 
     2967            { 
     2968                t = peek(t); 
     2969                switch (t.value) 
     2970                { 
     2971                case TOKlparen: 
     2972                    if (!skipParens(t, &t)) 
     2973                    goto Lfalse; 
     2974                    continue; 
     2975                case TOKrparen: 
     2976                    break; 
     2977                case TOKcomma: 
     2978                    break; 
     2979                case TOKeof: 
     2980                case TOKsemicolon: 
     2981                    goto Lfalse; 
     2982                default: 
     2983                    continue; 
     2984                } 
     2985                break; 
     2986            } 
     2987         
     2988            if (t.value != TOKcomma) 
     2989                break; 
     2990            } 
     2991            if (t.value != TOKrparen) 
     2992            goto Lfalse; 
     2993            t = peek(t); 
     2994            if (pt) 
     2995            *pt = t; 
     2996            return 1; 
     2997         
     2998        Lfalse: 
     2999            return 0; 
     3000        } 
     3001         
     3002        /******************************************* 
     3003         * Skip parens, brackets. 
     3004         * Input: 
     3005         *  t is on opening ( 
     3006         * Output: 
     3007         *  *pt is set to closing token, which is ')' on success 
     3008         * Returns: 
     3009         *  !=0 successful 
     3010         *  0   some parsing error 
     3011         */ 
     3012         
     3013        int skipParens(Token t, Token *pt) 
     3014        { 
     3015            int parens = 0; 
     3016         
     3017            while (1) 
     3018            { 
     3019            switch (t.value) 
     3020            { 
     3021                case TOKlparen: 
     3022                parens++; 
     3023                break; 
     3024         
     3025                case TOKrparen: 
     3026                parens--; 
     3027                if (parens < 0) 
     3028                    goto Lfalse; 
     3029                if (parens == 0) 
     3030                    goto Ldone; 
     3031                break; 
     3032         
     3033                case TOKeof: 
     3034                case TOKsemicolon: 
     3035                goto Lfalse; 
     3036         
     3037                 default: 
     3038                break; 
     3039            } 
     3040            t = peek(t); 
     3041            } 
     3042         
     3043          Ldone: 
     3044            if (*pt) 
     3045            *pt = t; 
     3046            return 1; 
     3047         
     3048          Lfalse: 
     3049            return 0; 
     3050        } 
     3051         
     3052        /********************************* Expression Parser ***************************/ 
     3053         
     3054        Expression parsePrimaryExp() { 
     3055            Expression e; 
     3056            Type t; 
     3057            Identifier id; 
     3058            Loc loc = this.loc; 
     3059         
     3060            switch (token.value) { 
     3061                case TOKidentifier: 
     3062                    id = token.ident; 
     3063                    nextToken(); 
     3064                    if (token.value == TOKnot) { 
     3065                        // identifier!(template-argument-list) 
     3066                        TemplateInstance tempinst; 
     3067             
     3068                        tempinst = new TemplateInstance(loc, id); 
     3069                        nextToken(); 
     3070                        tempinst.tiargs = parseTemplateArgumentList(); 
     3071                        e = new ScopeExp(loc, tempinst); 
     3072                    } else 
     3073                        e = new IdentifierExp(loc, id); 
     3074                    break; 
     3075             
     3076                case TOKdot: 
     3077                    // Signal global scope '.' operator with "" identifier 
     3078                    e = new IdentifierExp(loc, Id.empty); 
     3079                    break; 
     3080             
     3081                case TOKthis: 
     3082                    e = new ThisExp(loc); 
     3083                    nextToken(); 
     3084                    break; 
     3085             
     3086                case TOKsuper: 
     3087                    e = new SuperExp(loc); 
     3088                    nextToken(); 
     3089                    break; 
     3090             
     3091                case TOKint32v: 
     3092                    e = new IntegerExp(loc, token.int32value, Type.tint32); 
     3093                    nextToken(); 
     3094                    break; 
     3095             
     3096                case TOKuns32v: 
     3097                    e = new IntegerExp(loc, token.uns32value, Type.tuns32); 
     3098                    nextToken(); 
     3099                    break; 
     3100             
     3101                case TOKint64v: 
     3102                    e = new IntegerExp(loc, token.int64value, Type.tint64); 
     3103                    nextToken(); 
     3104                    break; 
     3105             
     3106                case TOKuns64v: 
     3107                    e = new IntegerExp(loc, token.uns64value, Type.tuns64); 
     3108                    nextToken(); 
     3109                    break; 
     3110             
     3111                case TOKfloat32v: 
     3112                    e = new RealExp(loc, token.float80value, Type.tfloat32); 
     3113                    nextToken(); 
     3114                    break; 
     3115             
     3116                case TOKfloat64v: 
     3117                    e = new RealExp(loc, token.float80value, Type.tfloat64); 
     3118                    nextToken(); 
     3119                    break; 
     3120             
     3121                case TOKfloat80v: 
     3122                    e = new RealExp(loc, token.float80value, Type.tfloat80); 
     3123                    nextToken(); 
     3124                    break; 
     3125             
     3126                case TOKimaginary32v: 
     3127                    e = new ImaginaryExp(loc, token.float80value, Type.timaginary32); 
     3128                    nextToken(); 
     3129                    break; 
     3130             
     3131                case TOKimaginary64v: 
     3132                    e = new ImaginaryExp(loc, token.float80value, Type.timaginary64); 
     3133                    nextToken(); 
     3134                    break; 
     3135             
     3136                case TOKimaginary80v: 
     3137                    e = new ImaginaryExp(loc, token.float80value, Type.timaginary80); 
     3138                    nextToken(); 
     3139                    break; 
     3140             
     3141                case TOKnull: 
     3142                    e = new NullExp(loc); 
     3143                    nextToken(); 
     3144                    break; 
     3145             
     3146                case TOKtrue: 
     3147                    e = new IntegerExp(loc, 1, Type.tbit); 
     3148                    nextToken(); 
     3149                    break; 
     3150             
     3151                case TOKfalse: 
     3152                    e = new IntegerExp(loc, 0, Type.tbit); 
     3153                    nextToken(); 
     3154                    break; 
     3155             
     3156                case TOKcharv: 
     3157                    e = new IntegerExp(loc, token.uns32value, Type.tchar); 
     3158                    nextToken(); 
     3159                    break; 
     3160             
     3161                case TOKwcharv: 
     3162                    e = new IntegerExp(loc, token.uns32value, Type.twchar); 
     3163                    nextToken(); 
     3164                    break; 
     3165             
     3166                case TOKdcharv: 
     3167                    e = new IntegerExp(loc, token.uns32value, Type.tdchar); 
     3168                    nextToken(); 
     3169                    break; 
     3170             
     3171                case TOKstring: 
     3172                {   char[]  s; 
     3173     
     3174                    // cat adjacent strings 
     3175                    s = token.ustring; 
     3176                    while (1) { 
     3177                        nextToken(); 
     3178                        if (token.value == TOKstring) { 
     3179                            s ~= token.ustring; 
     3180                        } else 
     3181                            break; 
     3182                    } 
     3183                    e = new StringExp(loc, s, len); 
     3184                    break; 
     3185                } 
     3186             
     3187                    case TOKvoid:    t = Type.tvoid;  goto LabelX; 
     3188                    case TOKint8:    t = Type.tint8;  goto LabelX; 
     3189                    case TOKuns8:    t = Type.tuns8;  goto LabelX; 
     3190                    case TOKint16:   t = Type.tint16; goto LabelX; 
     3191                    case TOKuns16:   t = Type.tuns16; goto LabelX; 
     3192                    case TOKint32:   t = Type.tint32; goto LabelX; 
     3193                    case TOKuns32:   t = Type.tuns32; goto LabelX; 
     3194                    case TOKint64:   t = Type.tint64; goto LabelX; 
     3195                    case TOKuns64:   t = Type.tuns64; goto LabelX; 
     3196                    case TOKfloat32: t = Type.tfloat32; goto LabelX; 
     3197                    case TOKfloat64: t = Type.tfloat64; goto LabelX; 
     3198                    case TOKfloat80: t = Type.tfloat80; goto LabelX; 
     3199                    case TOKimaginary32: t = Type.timaginary32; goto LabelX; 
     3200                    case TOKimaginary64: t = Type.timaginary64; goto LabelX; 
     3201                    case TOKimaginary80: t = Type.timaginary80; goto LabelX; 
     3202                    case TOKcomplex32: t = Type.tcomplex32; goto LabelX; 
     3203                    case TOKcomplex64: t = Type.tcomplex64; goto LabelX; 
     3204                    case TOKcomplex80: t = Type.tcomplex80; goto LabelX; 
     3205                    case TOKbit:     t = Type.tbit;     goto LabelX; 
     3206                    case TOKchar:    t = Type.tchar;    goto LabelX; 
     3207                    case TOKwchar:   t = Type.twchar; goto LabelX; 
     3208                    case TOKdchar:   t = Type.tdchar; goto LabelX; 
     3209                    LabelX: 
     3210                        nextToken(); 
     3211                L1: 
     3212                    check(TOKdot, t.toString()); 
     3213                    if (token.value != TOKidentifier) 
     3214                    {   error("found '%s' when expecting identifier following '%s.'", token.toString(), t.toString()); 
     3215                    goto Lerr; 
     3216                    } 
     3217                    e = new TypeDotIdExp(loc, t, token.ident); 
     3218                    nextToken(); 
     3219                    break; 
     3220             
     3221                case TOKtypeof: 
     3222                {   Expression exp; 
     3223             
     3224                    nextToken(); 
     3225                    check(TOKlparen); 
     3226                    exp = parseExpression(); 
     3227                    check(TOKrparen); 
     3228                    t = new TypeTypeof(loc, exp); 
     3229                    goto L1; 
     3230                } 
     3231             
     3232                case TOKtypeid: 
     3233                {   Type t; 
     3234             
     3235                    nextToken(); 
     3236                    check(TOKlparen, "typeid"); 
     3237                    t = parseBasicType(); 
     3238                    t = parseDeclarator(t,NULL);    // ( type ) 
     3239                    check(TOKrparen); 
     3240                    e = new TypeidExp(loc, t); 
     3241                    break; 
     3242                } 
     3243             
     3244                case TOKassert: 
     3245                    nextToken(); 
     3246                    check(TOKlparen, "assert"); 
     3247                    e = parseAssignExp(); 
     3248                    check(TOKrparen); 
     3249                    e = new AssertExp(loc, e); 
     3250                    break; 
     3251             
     3252                case TOKinstance:   // Deprecated 
     3253                {   TemplateInstance tempinst; 
     3254             
     3255                    tempinst = parseTemplateInstance(); 
     3256                    if (!tempinst) 
     3257                    return NULL; 
     3258                    e = new ScopeExp(loc, tempinst); 
     3259                    break; 
     3260                } 
     3261             
     3262                case TOKfunction: 
     3263                case TOKdelegate: 
     3264                { 
     3265                    /* function type(parameters) { body } 
     3266                     * delegate type(parameters) { body } 
     3267                     */ 
     3268                    Array arguments; 
     3269                    int varargs; 
     3270                    FuncLiteralDeclaration fd; 
     3271                    Type t; 
     3272                    uint save = token.value; 
     3273             
     3274                    nextToken(); 
     3275                    if (token.value == TOKlcurly) 
     3276                    {   // default to void() 
     3277                        t = Type.tvoid; 
     3278                        varargs = 0; 
     3279                        arguments = new Array(); 
     3280                    } else { 
     3281                        if (token.value == TOKlparen) 
     3282                            t = Type.tvoid;     // default to void return type 
     3283                        else { 
     3284                            t = parseBasicType(); 
     3285                            t = parseBasicType2(t); // function return type 
     3286                        } 
     3287                        arguments = parseParameters(&varargs); 
     3288                    } 
     3289                    t = new TypeFunction(arguments, t, varargs, linkage); 
     3290                    fd = new FuncLiteralDeclaration(loc, 0, t, save, NULL); 
     3291                    parseContracts(fd); 
     3292                    e = new FuncExp(loc, fd); 
     3293                    break; 
     3294            } 
     3295         
     3296            default: 
     3297                error("expression expected, not '%s'", token.toString()); 
     3298            Lerr: 
     3299                // Anything for e, as long as it's not NULL 
     3300                e = new IntegerExp(loc, 0, Type.tint32); 
     3301                nextToken(); 
     3302                break; 
     3303            } 
     3304            return parsePostExp(e); 
     3305        } 
     3306         
     3307        Expression parsePostExp(Expression e) 
     3308        { 
     3309            Loc loc; 
     3310         
     3311            while (1) { 
     3312                loc = this.loc; 
     3313                switch (token.value) { 
     3314                    case TOKdot: 
     3315                        nextToken(); 
     3316                        if (token.value == TOKidentifier) 
     3317                        {   Identifier id = token.ident; 
     3318                 
     3319                            nextToken(); 
     3320                            if (token.value == TOKnot) 
     3321                            {   // identifier!(template-argument-list) 
     3322                            TemplateInstance tempinst; 
     3323                 
     3324                            tempinst = new TemplateInstance(loc, id); 
     3325                            nextToken(); 
     3326                            tempinst.tiargs = parseTemplateArgumentList(); 
     3327                            e = new DotTemplateInstanceExp(loc, e, tempinst); 
     3328                            } 
     3329                            else 
     3330                            e = new DotIdExp(loc, e, id); 
     3331                            continue; 
     3332                        } 
     3333                        else 
     3334                            error("identifier expected following '.', not '%s'", token.toString()); 
     3335                        break; 
     3336     
     3337                    case TOKplusplus: 
     3338                        e = new PostIncExp(loc, e); 
     3339                        break; 
     3340             
     3341                    case TOKminusminus: 
     3342                        e = new PostDecExp(loc, e); 
     3343                        break; 
     3344             
     3345                    case TOKlparen: 
     3346                        e = new CallExp(loc, e, parseArguments()); 
     3347                        continue; 
     3348             
     3349                    case TOKlbracket: 
     3350                    {   // array dereferences: 
     3351                    //  array[index] 
     3352                    //  array[] 
     3353                    //  array[lwr .. upr] 
     3354                    Expression index; 
     3355                    Expression upr; 
     3356             
     3357                    nextToken(); 
     3358                    if (token.value == TOKrbracket) 
     3359                    {   // array[] 
     3360                        e = new SliceExp(loc, e, NULL, NULL); 
     3361                        nextToken(); 
     3362                    } 
     3363                    else 
     3364                    { 
     3365                        index = parseAssignExp(); 
     3366                        if (token.value == TOKslice) 
     3367                        {   // array[lwr .. upr] 
     3368                        nextToken(); 
     3369                        upr = parseAssignExp(); 
     3370                        e = new SliceExp(loc, e, index, upr); 
     3371                        } 
     3372                        else 
     3373                        {   // array[index, i2, i3, i4, ...] 
     3374                        Array arguments = new Array(); 
     3375                        arguments.push(index); 
     3376                        if (token.value == TOKcomma) 
     3377                        { 
     3378                            nextToken(); 
     3379                            while (1) 
     3380                            {   Expression arg; 
     3381             
     3382                            arg = parseAssignExp(); 
     3383                            arguments.push(arg); 
     3384                            if (token.value == TOKrbracket) 
     3385                                break; 
     3386                            check(TOKcomma); 
     3387                            } 
     3388                        } 
     3389                        e = new ArrayExp(loc, e, arguments); 
     3390                        } 
     3391                        check(TOKrbracket); 
     3392                    } 
     3393                    continue; 
     3394                    } 
     3395             
     3396                    default: 
     3397                    return e; 
     3398                } 
     3399                nextToken(); 
     3400            } 
     3401        } 
     3402         
     3403        Expression parseUnaryExp() 
     3404        {   Expression e; 
     3405            Loc loc = this.loc; 
     3406         
     3407            switch (token.value) 
     3408            { 
     3409            case TOKand: 
     3410                nextToken(); 
     3411                e = parseUnaryExp(); 
     3412                e = new AddrExp(loc, e); 
     3413                break; 
     3414         
     3415            case TOKplusplus: 
     3416                nextToken(); 
     3417                e = parseUnaryExp(); 
     3418                e = new AddAssignExp(loc, e, new IntegerExp(loc, 1, Type.tint32)); 
     3419                break; 
     3420         
     3421            case TOKminusminus: 
     3422                nextToken(); 
     3423                e = parseUnaryExp(); 
     3424                e = new MinAssignExp(loc, e, new IntegerExp(loc, 1, Type.tint32)); 
     3425                break; 
     3426         
     3427            case TOKmul: 
     3428                nextToken(); 
     3429                e = parseUnaryExp(); 
     3430                e = new PtrExp(loc, e); 
     3431                break; 
     3432         
     3433            case TOKmin: 
     3434                nextToken(); 
     3435                e = parseUnaryExp(); 
     3436                e = new NegExp(loc, e); 
     3437                break; 
     3438         
     3439            case TOKadd: 
     3440                nextToken(); 
     3441                e = parseUnaryExp(); 
     3442                e = new UAddExp(loc, e); 
     3443                break; 
     3444 
     3445            case TOKnot: 
     3446                nextToken(); 
     3447                e = parseUnaryExp(); 
     3448                e = new NotExp(loc, e); 
     3449                break; 
     3450 
     3451            case TOKtilde: 
     3452                nextToken(); 
     3453                e = parseUnaryExp(); 
     3454                e = new ComExp(loc, e); 
     3455                break; 
     3456 
     3457            case TOKdelete: 
     3458                nextToken(); 
     3459                e = parseUnaryExp(); 
     3460                e = new DeleteExp(loc, e); 
     3461                break; 
     3462 
     3463            case TOKnew: 
     3464            {   Type t; 
     3465                Array newargs; 
     3466                Array arguments = NULL; 
     3467         
     3468                nextToken(); 
     3469                newargs = NULL; 
     3470                if (token.value == TOKlparen) { 
     3471                    newargs = parseArguments(); 
     3472                } 
     3473         
     3474//      #if LTORARRAYDECL 
     3475                t = parseBasicType(); 
     3476                t = parseBasicType2(t); 
     3477                if (t.ty == Taarray) 
     3478                { 
     3479                Type index = (cast(TypeAArray)t).index; 
     3480         
     3481                if (index.ty == Tident) 
     3482                { 
     3483                    TypeIdentifier ti = cast(TypeIdentifier)index; 
     3484                    int i; 
     3485                    Expression e; 
     3486                    Identifier id = ti.ident; 
     3487         
     3488                    e = new IdentifierExp(loc, id); 
     3489                    for (i = 0; i < ti.idents.dim; i++) 
     3490                    { 
     3491                    id = cast(Identifier)ti.idents.data[i]; 
     3492                    e = new DotIdExp(loc, e, id); 
     3493                    } 
     3494         
     3495                    arguments = new Array(); 
     3496                    arguments.push(e); 
     3497                    t = new TypeDArray(t.next); 
     3498                } 
     3499                else 
     3500                { 
     3501                    error("need size of rightmost array, not type %s", index.toString()); 
     3502                    return new NullExp(loc); 
     3503                } 
     3504                } 
     3505                else if (t.ty == Tsarray) 
     3506                { 
     3507                TypeSArray tsa = cast(TypeSArray)t; 
     3508                Expression e = tsa.dim; 
     3509         
     3510                arguments = new Array(); 
     3511                arguments.push(e); 
     3512                t = new TypeDArray(t.next); 
     3513                } 
     3514                else if (token.value == TOKlparen) 
     3515                { 
     3516                arguments = parseArguments(); 
     3517                } 
     3518/+      #else 
     3519                t = parseBasicType(); 
     3520                while (token.value == TOKmul) 
     3521                {   t = new TypePointer(t); 
     3522                nextToken(); 
     3523                } 
     3524                if (token.value == TOKlbracket) 
     3525                { 
     3526                Expression *e; 
     3527         
     3528                nextToken(); 
     3529                e = parseAssignExp(); 
     3530                arguments = new Array(); 
     3531                arguments.push(e); 
     3532                check(TOKrbracket); 
     3533                t = parseDeclarator(t, NULL); 
     3534                t = new TypeDArray(t); 
     3535                } 
     3536                else if (token.value == TOKlparen) 
     3537                arguments = parseArguments(); 
     3538        #endif 
     3539+/ 
     3540                e = new NewExp(loc, newargs, t, arguments); 
     3541                break; 
     3542            } 
     3543//      #if DCASTSYNTAX 
     3544            case TOKcast:               // cast(type) expression 
     3545            {   Type *t; 
     3546         
     3547                nextToken(); 
     3548                check(TOKlparen); 
     3549                t = parseBasicType(); 
     3550                t = parseDeclarator(t,NULL);    // ( type ) 
     3551                check(TOKrparen); 
     3552         
     3553                // if .identifier 
     3554                if (token.value == TOKdot) 
     3555                { 
     3556                nextToken(); 
     3557                if (token.value != TOKidentifier) 
     3558                {   error("Identifier expected following cast(type)."); 
     3559                    return NULL; 
     3560                } 
     3561                // cast(type).ident 
     3562                e = new TypeDotIdExp(loc, t, token.ident); 
     3563                nextToken(); 
     3564                } 
     3565                else 
     3566                { 
     3567                e = parseUnaryExp(); 
     3568                e = new CastExp(loc, e, t); 
     3569                } 
     3570