Changeset 167

Show
Ignore:
Timestamp:
05/20/07 14:55:46 (2 years ago)
Author:
JarrettBillingsley
Message:

--

Files:

Legend:

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

    r163 r167  
    125125        else if(inputFile.length >= 4 && inputFile[$ - 4 .. $] == ".mdm") 
    126126            def = MDModuleDef.loadFromFile(inputFile); 
    127              
    128         MDClosure cl = MDGlobalState().initModule(def, false, state); 
    129  
    130         uint funcReg = state.push(cl); 
    131  
    132         state.push(cl.environment); 
    133  
    134         foreach(arg; scriptArgs) 
    135             state.push(arg); 
     127        else 
     128        { 
     129            char[] sourceName = inputFile ~ ".md"; 
     130            char[] moduleName = inputFile ~ ".mdm"; 
     131 
     132            if(file.exists(sourceName)) 
     133            { 
     134                if(file.exists(moduleName)) 
     135                { 
     136                    long sourceTime; 
     137                    long moduleTime; 
     138                    long dummy; 
     139 
     140                    file.getTimes(sourceName, dummy, dummy, sourceTime); 
     141                    file.getTimes(moduleName, dummy, dummy, moduleTime); 
     142 
     143                    if(sourceTime > moduleTime) 
     144                        def = compileModule(sourceName); 
     145                    else 
     146                        def = MDModuleDef.loadFromFile(moduleName); 
     147                } 
     148                else 
     149                    def = compileModule(sourceName); 
     150            } 
     151            else 
     152                def = MDModuleDef.loadFromFile(moduleName); 
     153        } 
     154 
     155        MDNamespace ns = MDGlobalState().registerModule(def, state); 
     156 
     157        MDValue[] params = new MDValue[scriptArgs.length]; 
     158         
     159        foreach(i, v; scriptArgs) 
     160            params[i] = v; 
    136161 
    137162        try 
    138             state.call(funcReg, scriptArgs.length + 1, 0); 
     163            MDGlobalState().staticInitModule(def, ns, state, params); 
    139164        catch(MDException e) 
    140165        { 
  • trunk/minid/baselib.d

    r163 r167  
    3939    MDValue[] output; 
    4040 
    41     void outputValue(inout MDValue val) 
     41    void outputValue(ref MDValue val) 
    4242    { 
    4343        output ~= val; 
     
    406406        MDValue[] ret = s.safeCode(baseUnFormat(s, s.getParam!(dchar[])(0), din)); 
    407407         
    408         foreach(inout v; ret) 
     408        foreach(ref v; ret) 
    409409            s.push(v); 
    410410             
     
    711711    int require(MDState s, uint numParams) 
    712712    { 
    713         MDGlobalState().importModule(s.getParam!(char[])(0)); 
     713        MDGlobalState().importModule(s.getParam!(dchar[])(0)); 
    714714        return 0; 
    715715    } 
     
    824824                        { 
    825825                            i.append(other); 
    826                             return 0
     826                            continue
    827827                        } 
    828828                    } 
     
    11391139            if(lo < 0 || lo > hi || hi >= mLength) 
    11401140                throw new MDException("Invalid indices: %d .. %d", lo, hi); 
    1141                  
     1141 
    11421142            return mBuffer[lo .. hi]; 
    11431143        } 
  • trunk/minid/compiler.d

    r163 r167  
     1 
    12/****************************************************************************** 
    23License: 
     
    157158        Cat, 
    158159        CatEq, 
     160        Cmp3, 
    159161        Mul, 
    160162        MulEq, 
     
    198200        Semicolon, 
    199201        Length, 
     202        Question, 
    200203 
    201204        Ident, 
     
    252255        Type.Cat: "~", 
    253256        Type.CatEq: "~=", 
     257        Type.Cmp3: "<=>", 
    254258        Type.Mul: "*", 
    255259        Type.MulEq: "*=", 
     
    293297        Type.Semicolon: ";", 
    294298        Type.Length: "#", 
     299        Type.Question: "?", 
    295300 
    296301        Type.Ident: "Identifier", 
     
    13941399                    { 
    13951400                        nextChar(); 
    1396                         token.type = Token.Type.LE; 
     1401 
     1402                        if(mCharacter == '>') 
     1403                        { 
     1404                            nextChar(); 
     1405                            token.type = Token.Type.Cmp3; 
     1406                        } 
     1407                        else 
     1408                            token.type = Token.Type.LE; 
    13971409                    } 
    13981410                    else if(mCharacter == '<') 
     
    15511563                case '?': 
    15521564                    nextChar(); 
    1553                      
    1554                     if(mCharacter != '=') 
    1555                         throw new MDCompileException(tokenLoc, "'?' expected to be followed by '='"); 
    1556                      
    1557                     nextChar(); 
    1558  
    1559                     token.type = Token.Type.DefaultEq; 
     1565 
     1566                    if(mCharacter == '=') 
     1567                    { 
     1568                        nextChar(); 
     1569                        token.type = Token.Type.DefaultEq; 
     1570                    } 
     1571                    else 
     1572                        token.type = Token.Type.Question; 
     1573 
    15601574                    return token; 
    15611575 
     
    16001614                        int ival; 
    16011615 
    1602                         bool type = readNumLiteral(false, fval, ival); 
    1603  
    1604                         if(type == false) 
     1616                        bool isInt = readNumLiteral(false, fval, ival); 
     1617 
     1618                        if(isInt == false) 
    16051619                        { 
    16061620                            token.floatValue = fval; 
     
    17031717    char[] toString() 
    17041718    { 
    1705         char[] typename; 
    1706          
    1707         switch(type) 
    1708         { 
    1709             case ExpType.Null: typename = "Null"; break; 
    1710             case ExpType.True: typename = "True"; break; 
    1711             case ExpType.False: typename = "False"; break; 
    1712             case ExpType.Const: typename = "Const"; break; 
    1713             case ExpType.Var: typename = "Var"; break; 
    1714             case ExpType.NewGlobal: typename = "NewGlobal"; break; 
    1715             case ExpType.Indexed: typename = "Indexed"; break; 
    1716             case ExpType.Sliced: typename = "Sliced"; break; 
    1717             case ExpType.Vararg: typename = "Vararg"; break; 
    1718             case ExpType.Closure: typename = "Closure"; break; 
    1719             case ExpType.Call: typename = "Call"; break; 
    1720             case ExpType.Yield: typename = "Yield"; break; 
    1721             case ExpType.NeedsDest: typename = "NeedsDest"; break; 
    1722             case ExpType.Src: typename = "Src"; break; 
    1723         } 
    1724          
    1725         return string.format("%s (%d, %d, %d) : (%s, %s, %s)", typename, index, index2, index3, isTempReg, isTempReg2, isTempReg3); 
     1719        static const char[][] typeNames =  
     1720        [ 
     1721            ExpType.Null: "Null", 
     1722            ExpType.True: "True", 
     1723            ExpType.False: "False", 
     1724            ExpType.Const: "Const", 
     1725            ExpType.Var: "Var", 
     1726            ExpType.NewGlobal: "NewGlobal", 
     1727            ExpType.Indexed: "Indexed", 
     1728            ExpType.Sliced: "Sliced", 
     1729            ExpType.Vararg: "Vararg", 
     1730            ExpType.Closure: "Closure", 
     1731            ExpType.Call: "Call", 
     1732            ExpType.Yield: "Yield", 
     1733            ExpType.NeedsDest: "NeedsDest", 
     1734            ExpType.Src: "Src" 
     1735        ]; 
     1736 
     1737        return string.format("%s (%d, %d, %d) : (%s, %s, %s)", typeNames[cast(uint)type], index, index2, index3, isTempReg, isTempReg2, isTempReg3); 
    17261738    } 
    17271739} 
     
    19321944        sd.switchPC = codeR(line, Op.Switch, 0, srcReg, 0); 
    19331945        sd.prev = mSwitch; 
    1934  
    19351946        mSwitch = sd; 
    19361947    } 
     
    19391950    { 
    19401951        SwitchDesc* desc = mSwitch; 
    1941         assert(desc, "endSwitch - no switch to end"); 
     1952        assert(desc !is null, "endSwitch - no switch to end"); 
    19421953        mSwitch = mSwitch.prev; 
    19431954 
     
    19461957    } 
    19471958 
    1948     public void addNullCase(Location location) 
    1949     { 
    1950         assert(mSwitch !is null, "adding case outside of a switch"); 
    1951         int* oldOffset = (MDValue.nullValue in mSwitch.offsets); 
    1952  
    1953         if(oldOffset !is null) 
    1954             throw new MDCompileException(location, "Duplicate case value 'null'"); 
    1955  
    1956         mSwitch.offsets[MDValue.nullValue] = mCode.length - mSwitch.switchPC - 1; 
    1957     } 
    1958      
    1959     public void addCase(T)(Location location, T v) 
     1959    public int* addCase(Location location, Expression v) 
    19601960    { 
    19611961        if(mSwitch is null) 
    19621962            throw new MDCompileException(location, "Case statements may not exist outside of a switch"); 
    19631963 
    1964         MDValue val = v; 
     1964        MDValue val; 
     1965 
     1966        if(v.isNull()) 
     1967            val.setNull(); 
     1968        else if(v.isBool()) 
     1969            val = v.asBool(); 
     1970        else if(v.isInt()) 
     1971            val = v.asInt(); 
     1972        else if(v.isFloat()) 
     1973            val = v.asFloat(); 
     1974        else if(v.isChar()) 
     1975            val = v.asChar(); 
     1976        else if(v.isString()) 
     1977            val = v.asString(); 
     1978        else 
     1979            assert(false, "addCase invalid type: " ~ v.toString()); 
    19651980 
    19661981        int* oldOffset = (val in mSwitch.offsets); 
    19671982 
    19681983        if(oldOffset !is null) 
    1969             throw new MDCompileException(location, "Duplicate case value '%s'", v); 
    1970  
    1971         mSwitch.offsets[val] = mCode.length - mSwitch.switchPC - 1; 
     1984            throw new MDCompileException(location, "Duplicate case value '%s'", val); 
     1985 
     1986        mSwitch.offsets[val] = 0; 
     1987        return (val in mSwitch.offsets); 
    19721988    } 
    19731989 
     
    24372453                codeI(line, Op.Closure, dest, src.index); 
    24382454 
    2439                 foreach(inout UpvalDesc ud; mInnerFuncs[src.index].mUpvals) 
    2440                 { 
    2441                     if(ud.isUpvalue) 
    2442                         codeR(line, Op.Move, 1, ud.index, 0); 
    2443                     else 
    2444                         codeR(line, Op.Move, 0, ud.index, 0); 
    2445                 } 
     2455                foreach(ref UpvalDesc ud; mInnerFuncs[src.index].mUpvals) 
     2456                    codeR(line, Op.Move, ud.isUpvalue ? 1 : 0, ud.index, 0); 
    24462457 
    24472458                break; 
     
    25102521    } 
    25112522     
    2512     public void popReflexOp(uint line, Op type, uint rd, uint rs
     2523    public void popReflexOp(uint line, Op type, uint rd, uint rs, uint rt = 0
    25132524    { 
    25142525        Exp* dest = pushExp(); 
    25152526        dest.type = ExpType.NeedsDest; 
    2516         dest.index = codeR(line, type, rd, rs, 0); 
     2527        dest.index = codeR(line, type, rd, rs, rt); 
    25172528 
    25182529        popAssign(line); 
     
    26832694                codeR(line, Op.Index, temp.index, e.index, e.index2); 
    26842695                break; 
    2685                  
     2696 
    26862697            case ExpType.Sliced: 
    26872698                if(cleanup) 
     
    27092720                codeI(line, Op.Closure, temp.index, e.index); 
    27102721 
    2711                 foreach(inout UpvalDesc ud; mInnerFuncs[e.index].mUpvals) 
    2712                 { 
    2713                     if(ud.isUpvalue) 
    2714                         codeR(line, Op.Move, 1, ud.index, 0); 
    2715                     else 
    2716                         codeR(line, Op.Move, 0, ud.index, 0); 
    2717                 } 
     2722                foreach(ref UpvalDesc ud; mInnerFuncs[e.index].mUpvals) 
     2723                    codeR(line, Op.Move, ud.isUpvalue ? 1 : 0, ud.index, 0); 
    27182724 
    27192725                temp.isTempReg = true; 
     
    27512757    { 
    27522758        mCode[src.pc].imm = mCode.length - src.pc - 1; 
     2759    } 
     2760     
     2761    public void patchSwitchJumpToHere(int* offset) 
     2762    { 
     2763        assert(mSwitch !is null); 
     2764        *offset = mCode.length - mSwitch.switchPC - 1; 
    27532765    } 
    27542766 
     
    30683080        } 
    30693081         
    3070         foreach(uint i, inout SwitchDesc* t; mSwitchTables) 
     3082        foreach(uint i, ref SwitchDesc* t; mSwitchTables) 
    30713083        { 
    30723084            writefln(string.repeat("\t", tab + 1), "Switch Table ", i); 
     
    32023214    } 
    32033215 
    3204     public static void parseBody(Location location, inout Token* t, out FuncDef[] oMethods, out Field[] oFields, out Location oEndLocation) 
     3216    public static void parseBody(Location location, ref Token* t, out FuncDef[] oMethods, out Field[] oFields, out Location oEndLocation) 
    32053217    { 
    32063218        t = t.expect(Token.Type.LBrace); 
     
    32923304    } 
    32933305 
    3294     public static Expression parseBaseClass(inout Token* t) 
     3306    public static Expression parseBaseClass(ref Token* t) 
    32953307    { 
    32963308        Expression baseClass; 
     
    33553367        mBaseClass = mBaseClass.fold(); 
    33563368         
    3357         foreach(inout field; mFields) 
     3369        foreach(ref field; mFields) 
    33583370            field.initializer = field.initializer.fold(); 
    33593371             
    3360         foreach(inout method; mMethods) 
     3372        foreach(ref method; mMethods) 
    33613373            method = method.fold(); 
    33623374         
     
    33963408    } 
    33973409 
    3398     public static FuncDef parseSimple(inout Token* t) 
     3410    public static FuncDef parseSimple(ref Token* t) 
    33993411    { 
    34003412        Location location = t.location; 
     
    34123424    } 
    34133425     
    3414     public static FuncDef parseLiteral(inout Token* t) 
     3426    public static FuncDef parseLiteral(ref Token* t) 
    34153427    { 
    34163428        Location location = t.location; 
     
    34383450    } 
    34393451 
    3440     public static Param[] parseParams(inout Token* t, out bool isVararg) 
     3452    public static Param[] parseParams(ref Token* t, out bool isVararg) 
    34413453    { 
    34423454        Param[] ret = new Param[1]; 
     
    35123524    public FuncDef fold() 
    35133525    { 
    3514         foreach(inout p; mParams) 
     3526        foreach(ref p; mParams) 
    35153527            if(p.defValue !is null) 
    35163528                p.defValue = p.defValue.fold(); 
     
    35263538    protected Location mEndLocation; 
    35273539    protected ModuleDeclaration mModDecl; 
    3528     protected dchar[][][] mImports; 
     3540    protected dchar[][] mImports; 
    35293541    protected Statement[] mStatements; 
    35303542 
    3531     public this(Location location, Location endLocation, ModuleDeclaration modDecl, dchar[][][] imports, Statement[] statements) 
     3543    public this(Location location, Location endLocation, ModuleDeclaration modDecl, dchar[][] imports, Statement[] statements) 
    35323544    { 
    35333545        mLocation = location; 
     
    35383550    } 
    35393551 
    3540     public static Module parse(inout Token* t) 
     3552    public static Module parse(ref Token* t) 
    35413553    { 
    35423554        Location location = t.location; 
     
    35453557        List!(Statement) statements; 
    35463558 
    3547         bool[dchar[][]] imports; 
     3559        bool[dchar[]] imports; 
    35483560 
    35493561        void addImport(ImportStatement imp) 
    35503562        { 
    3551             imports[Identifier.toStringArray(imp.mNames)] = true; 
     3563            imports[Identifier.toLongString(imp.mNames)] = true; 
    35523564            statements.add(imp); 
    35533565        } 
     
    35703582        MDModuleDef def = new MDModuleDef(); 
    35713583 
    3572         def.mName.length = mModDecl.mNames.length; 
    3573  
    3574         foreach(i, ident; mModDecl.mNames) 
    3575             def.mName[i] = ident.mName; 
    3576  
     3584        def.mName = Identifier.toLongString(mModDecl.mNames); 
    35773585        def.mImports = mImports; 
    35783586 
     
    35823590        try 
    35833591        { 
    3584             foreach(inout s; mStatements) 
     3592            foreach(ref s; mStatements) 
    35853593            { 
    35863594                s = s.fold(); 
     
    36083616 
    36093617        foreach(name; mImports) 
    3610             writefln("import %s", djoin(name, '.')); 
     3618            writefln("import %s", name); 
    36113619    } 
    36123620} 
     
    36213629    } 
    36223630 
    3623     public static ModuleDeclaration parse(inout Token* t) 
     3631    public static ModuleDeclaration parse(ref Token* t) 
    36243632    { 
    36253633        t = t.expect(Token.Type.Module); 
     
    36513659    } 
    36523660 
    3653     public static Statement parse(inout Token* t) 
     3661    public static Statement parse(ref Token* t) 
    36543662    { 
    36553663        Location location = t.location; 
     
    36933701                return SwitchStatement.parse(t); 
    36943702                 
    3695             case Token.Type.Case: 
    3696               return CaseStatement.parse(t); 
    3697  
    3698             case Token.Type.Default: 
    3699               return DefaultStatement.parse(t); 
     3703            //case Token.Type.Case: 
     3704            //    return CaseStatement.parse(t); 
     3705 
     3706            //case Token.Type.Default: 
     3707            //    return DefaultStatement.parse(t); 
    37003708 
    37013709            case Token.Type.Continue: 
     
    37463754    } 
    37473755 
    3748     public static ImportStatement parse(inout Token* t) 
     3756    public static ImportStatement parse(ref Token* t) 
    37493757    { 
    37503758        Location location = t.location; 
     
    38613869    } 
    38623870 
    3863     public static ExpressionStatement parse(inout Token* t) 
     3871    public static ExpressionStatement parse(ref Token* t) 
    38643872    { 
    38653873        Location location = t.location; 
     
    39003908    } 
    39013909 
    3902     public static DeclarationStatement parse(inout Token* t) 
     3910    public static DeclarationStatement parse(ref Token* t) 
    39033911    { 
    39043912        Location location = t.location; 
     
    39383946    } 
    39393947 
    3940     public static Declaration parse(inout Token* t) 
     3948    public static Declaration parse(ref Token* t) 
    39413949    { 
    39423950        Location location = t.location; 
     
    39893997    } 
    39903998 
    3991     public static ClassDecl parse(inout Token* t) 
     3999    public static ClassDecl parse(ref Token* t) 
    39924000    { 
    39934001        Location location = t.location; 
     
    40584066    } 
    40594067 
    4060     public static VarDecl parse(inout Token* t) 
     4068    public static VarDecl parse(ref Token* t) 
    40614069    { 
    40624070        Location location = t.location; 
     
    42044212    } 
    42054213 
    4206     public static FuncDecl parse(inout Token* t, bool simple = false) 
     4214    public static FuncDecl parse(ref Token* t, bool simple = false) 
    42074215    { 
    42084216        Location location = t.location; 
     
    42664274    } 
    42674275 
    4268     public static Identifier parse(inout Token* t) 
     4276    public static Identifier parse(ref Token* t) 
    42694277    { 
    42704278        t.expect(Token.Type.Ident); 
     
    43124320    } 
    43134321 
    4314     public static CompoundStatement parse(inout Token* t) 
     4322    public static CompoundStatement parse(ref Token* t) 
    43154323    { 
    43164324        Location location = t.location; 
     
    43384346    public override CompoundStatement fold() 
    43394347    { 
    4340         foreach(inout statement; mStatements) 
     4348        foreach(ref statement; mStatements) 
    43414349            statement = statement.fold(); 
    43424350             
     
    43604368    } 
    43614369 
    4362     public static IfStatement parse(inout Token* t) 
     4370    public static IfStatement parse(ref Token* t) 
    43634371    { 
    43644372        Location location = t.location; 
     
    44604468    } 
    44614469 
    4462     public static WhileStatement parse(inout Token* t) 
     4470    public static WhileStatement parse(ref Token* t) 
    44634471    { 
    44644472        Location location = t.location; 
     
    45434551    } 
    45444552 
    4545     public static DoWhileStatement parse(inout Token* t) 
     4553    public static DoWhileStatement parse(ref Token* t) 
    45464554    { 
    45474555        Location location = t.location; 
     
    46454653    } 
    46464654 
    4647     public static Statement parse(inout Token* t) 
     4655    public static Statement parse(ref Token* t) 
    46484656    { 
    46494657        Location location = t.location; 
     
    46754683 
    46764684                Identifier index = Identifier.parse(t); 
    4677                  
     4685 
    46784686                t = t.expect(Token.Type.Colon); 
    4679                  
     4687 
    46804688                Expression lo = Expression.parse(t); 
    46814689                t = t.expect(Token.Type.DotDot); 
     
    48024810    public override Statement fold() 
    48034811    { 
    4804         foreach(inout init; mInit) 
     4812        foreach(ref init; mInit) 
    48054813        { 
    48064814            if(init.isDecl) 
     
    48134821            mCondition = mCondition.fold(); 
    48144822 
    4815         foreach(inout inc; mIncrement) 
     4823        foreach(ref inc; mIncrement) 
    48164824            inc = inc.fold(); 
    48174825 
     
    49274935         
    49284936        if(mLo.isConstant) 
    4929         { 
    4930             IntExp val = cast(IntExp)mLo; 
    4931  
    4932             if(val is null) 
     4937            if(!mLo.isInt) 
    49334938                throw new MDCompileException(mLo.mLocation, "Low value of a numeric for loop must be an integer"); 
    4934         } 
    49354939 
    49364940        if(mHi.isConstant) 
    4937         { 
    4938             IntExp val = cast(IntExp)mHi; 
    4939  
    4940             if(val is null) 
     4941            if(!mHi.isInt) 
    49414942                throw new MDCompileException(mHi.mLocation, "High value of a numeric for loop must be an integer"); 
    4942         } 
    49434943 
    49444944        if(mStep.isConstant) 
    49454945        { 
    4946             IntExp val = cast(IntExp)mStep; 
    4947  
    4948             if(val is null) 
     4946            if(!mStep.isInt) 
    49494947                throw new MDCompileException(mStep.mLocation, "Step value of a numeric for loop must be an integer"); 
    4950                  
    4951             if(val.mValue == 0) 
     4948 
     4949            if(mStep.asInt() == 0) 
    49524950                throw new MDCompileException(mStep.mLocation, "Step value of a numeric for loop may not be 0"); 
    49534951        } 
     
    49784976    } 
    49794977 
    4980     public static ForeachStatement parse(inout Token* t) 
     4978    public static ForeachStatement parse(ref Token* t) 
    49814979    { 
    49824980        Location location = t.location; 
     
    51265124    public override Statement fold() 
    51275125    { 
    5128         foreach(inout c; mContainer) 
     5126        foreach(ref c; mContainer) 
    51295127            c = c.fold(); 
    51305128             
     
    51495147    } 
    51505148 
    5151     public static SwitchStatement parse(inout Token* t) 
     5149    public static SwitchStatement parse(ref Token* t) 
    51525150    { 
    51535151        Location location = t.location; 
     
    51605158        t = t.expect(Token.Type.RParen); 
    51615159        t = t.expect(Token.Type.LBrace); 
    5162          
     5160 
    51635161        List!(CaseStatement) cases; 
    51645162 
     
    51835181    public override void codeGen(FuncState s) 
    51845182    { 
     5183        struct Case 
     5184        { 
     5185            Expression expr; 
     5186            CaseStatement stmt; 
     5187        } 
     5188         
     5189        List!(Case) constCases; 
     5190        List!(Case) dynCases; 
     5191 
     5192        foreach(caseStmt; mCases) 
     5193        { 
     5194            foreach(cond; caseStmt.mConditions) 
     5195            { 
     5196                if(cond.isConstant) 
     5197                    constCases.add(Case(cond, caseStmt)); 
     5198                else 
     5199                    dynCases.add(Case(cond, caseStmt)); 
     5200            } 
     5201        } 
     5202 
    51855203        s.pushScope(); 
    51865204            s.setBreakable(); 
     
    51895207            Exp src; 
    51905208            s.popSource(mLocation.line, src); 
    5191  
     5209             
     5210            foreach(c; dynCases) 
     5211            { 
     5212                c.expr.codeGen(s); 
     5213                Exp cond; 
     5214                s.popSource(mLocation.line, cond); 
     5215 
     5216                s.codeR(mLocation.line, Op.SwitchCmp, 0, src.index, cond.index); 
     5217                c.stmt.addDynJump(s.makeJump(mLocation.line, Op.Je, true)); 
     5218                s.freeExpTempRegs(&cond); 
     5219            } 
     5220             
    51925221            s.beginSwitch(mLocation.line, src.index); 
    5193  
    51945222            s.freeExpTempRegs(&src); 
    5195  
    5196             foreach(CaseStatement c; mCases) 
     5223             
     5224            foreach(c; constCases) 
     5225                c.stmt.addConstJump(s.addCase(c.expr.mLocation, c.expr)); 
     5226 
     5227            foreach(c; mCases) 
    51975228                c.codeGen(s); 
    51985229 
     
    52105241        mCondition = mCondition.fold(); 
    52115242         
    5212         foreach(inout c; mCases) 
     5243        foreach(ref c; mCases) 
    52135244            c = c.fold(); 
    52145245             
     
    52225253class CaseStatement : Statement 
    52235254{ 
    5224     protected Expression mCondition
     5255    protected Expression[] mConditions
    52255256    protected Statement mBody; 
    5226  
    5227     public this(Location location, Location endLocation, Expression condition, Statement caseBody) 
     5257    protected List!(InstRef*) mDynJumps; 
     5258    protected List!(int*) mConstJumps; 
     5259 
     5260    public this(Location location, Location endLocation, Expression[] conditions, Statement caseBody) 
    52285261    { 
    52295262        super(location, endLocation); 
    5230         mCondition = condition
     5263        mConditions = conditions
    52315264        mBody = caseBody; 
    52325265    } 
    52335266 
    5234     public static CaseStatement parse(inout Token* t) 
     5267    public static CaseStatement parse(ref Token* t) 
    52355268    { 
    52365269        Location location = t.location; 
     
    52385271        t = t.expect(Token.Type.Case); 
    52395272 
    5240         List!(Expression) cases; 
    5241         cases.add(Expression.parse(t)); 
     5273        List!(Expression) conditions; 
     5274        conditions.add(Expression.parse(t)); 
    52425275 
    52435276        while(t.type == Token.Type.Comma) 
    52445277        { 
    52455278            t = t.nextToken; 
    5246             cases.add(Expression.parse(t)); 
    5247         } 
    5248          
     5279            conditions.add(Expression.parse(t)); 
     5280        } 
     5281 
    52495282        t = t.expect(Token.Type.Colon); 
    52505283 
     
    52565289        Location endLocation = t.location; 
    52575290 
    5258         Statement ret = new CompoundStatement(location, endLocation, statements.toArray()); 
    5259         ret = new ScopeStatement(location, endLocation, ret); 
    5260  
    5261         for(int i = cases.length - 1; i >= 0; i--) 
    5262             ret = new CaseStatement(location, endLocation, cases[i], ret); 
    5263  
    5264         return cast(CaseStatement)ret; 
     5291        Statement caseBody = new CompoundStatement(location, endLocation, statements.toArray()); 
     5292        caseBody = new ScopeStatement(location, endLocation, caseBody); 
     5293 
     5294        return new CaseStatement(location, endLocation, conditions.toArray(), caseBody); 
     5295    } 
     5296     
     5297    public void addDynJump(InstRef* i) 
     5298    { 
     5299        mDynJumps.add(i); 
     5300    } 
     5301     
     5302    public void addConstJump(int* i) 
     5303    { 
     5304        mConstJumps.add(i); 
    52655305    } 
    52665306 
    52675307    public override void codeGen(FuncState s) 
    52685308    { 
    5269         if(!mCondition.isConstant) 
    5270             throw new MDCompileException(mLocation, "Case value is not constant"); 
    5271  
    5272         IntExp intExp = cast(IntExp)mCondition; 
     5309        foreach(ref j; mDynJumps) 
     5310        { 
     5311            s.patchJumpToHere(j); 
     5312            delete j; 
     5313        } 
    52735314         
    5274         if(intExp) 
    5275             s.addCase(mLocation, intExp.mValue); 
    5276         else 
    5277         { 
    5278             StringExp stringExp = cast(StringExp)mCondition; 
    5279  
    5280             if(stringExp) 
    5281                 s.addCase(mLocation, stringExp.mValue); 
    5282             else 
    5283             { 
    5284                 CharExp charExp = cast(CharExp)mCondition; 
    5285                  
    5286                 if(charExp) 
    5287                     s.addCase(mLocation, charExp.mValue); 
    5288                 else 
    5289                 { 
    5290                     FloatExp floatExp = cast(FloatExp)mCondition; 
    5291                      
    5292                     if(floatExp) 
    5293                         s.addCase(mLocation, floatExp.mValue); 
    5294                     else 
    5295                     { 
    5296                         BoolExp boolExp = cast(BoolExp)mCondition; 
    5297                          
    5298                         if(boolExp) 
    5299                             s.addCase(mLocation, boolExp.mValue); 
    5300                         else 
    5301                         { 
    5302                             NullExp nullExp = cast(NullExp)mCondition; 
    5303  
    5304                             if(nullExp) 
    5305                                 s.addNullCase(mLocation); 
    5306                             else 
    5307                                 throw new MDCompileException(mLocation, "Invalid case value"); 
    5308                         } 
    5309                     } 
    5310                 } 
    5311             } 
     5315        foreach(ref j; mConstJumps) 
     5316        { 
     5317            s.patchSwitchJumpToHere(j); 
     5318            j = null;    
    53125319        } 
    53135320 
     
    53175324    public override CaseStatement fold() 
    53185325    { 
    5319         mCondition = mCondition.fold(); 
     5326        foreach(ref cond; mConditions) 
     5327            cond = cond.fold(); 
     5328 
    53205329        mBody = mBody.fold(); 
    53215330        return this; 
     
    53335342    } 
    53345343 
    5335     public static DefaultStatement parse(inout Token* t) 
     5344    public static DefaultStatement parse(ref Token* t) 
    53365345    { 
    53375346        Location location = t.location; 
     
    53725381    } 
    53735382 
    5374     public static ContinueStatement parse(inout Token* t) 
     5383    public static ContinueStatement parse(ref Token* t) 
    53755384    { 
    53765385        Location location = t.location; 
     
    53955404    } 
    53965405 
    5397     public static BreakStatement parse(inout Token* t) 
     5406    public static BreakStatement parse(ref Token* t) 
    53985407    { 
    53995408        Location location = t.location; 
     
    54275436    } 
    54285437 
    5429     public static ReturnStatement parse(inout Token* t) 
     5438    public static ReturnStatement parse(ref Token* t) 
    54305439    { 
    54315440        Location location = t.location; 
     
    54875496    public override Statement fold() 
    54885497    { 
    5489         foreach(inout exp; mExprs) 
     5498        foreach(ref exp; mExprs) 
    54905499            exp = exp.fold(); 
    54915500             
     
    55115520    } 
    55125521 
    5513     public static TryCatchStatement parse(inout Token* t) 
     5522    public static TryCatchStatement parse(ref Token* t) 
    55145523    { 
    55155524        Location location = t.location; 
     
    56615670    } 
    56625671 
    5663     public static ThrowStatement parse(inout Token* t) 
     5672    public static ThrowStatement parse(ref Token* t) 
    56645673    { 
    56655674        Location location = t.location; 
     
    57065715    } 
    57075716 
    5708     public static Expression parse(inout Token* t) 
    5709     { 
    5710         return BinaryExp.parse(t); 
    5711     } 
    5712      
    5713     public static Expression parseStatement(inout Token* t) 
     5717    public static Expression parse(ref Token* t) 
     5718    { 
     5719        return CondExp.parse(t); 
     5720    } 
     5721     
     5722    public static Expression parseStatement(ref Token* t) 
    57145723    { 
    57155724        Location location = t.location; 
     
    57535762    } 
    57545763     
    5755     public static Expression[] parseArguments(inout Token* t) 
     5764    public static Expression[] parseArguments(ref Token* t) 
    57565765    { 
    57575766        Expression[] args = new Expression[5]; 
     
    58525861    } 
    58535862     
     5863    public bool isNull() 
     5864    { 
     5865        return false; 
     5866    } 
     5867     
     5868    public bool isBool() 
     5869    { 
     5870        return false; 
     5871    } 
     5872