Changeset 163

Show
Ignore:
Timestamp:
05/02/07 20:18:44 (2 years ago)
Author:
JarrettBillingsley
Message:

--

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/benchmark/binarytrees.md

    r162 r163  
    2828     
    2929local args = [vararg]; 
    30 local n = 12
     30local n = 16
    3131 
    3232if(#args > 0) 
  • trunk/benchmark/chameneos.md

    r162 r163  
    22 
    33// n = 1_000_000, 15.816 sec (meh) 
     4// laptop: 10.398 
    45 
    56local args = [vararg]; 
  • trunk/benchmark/cheapconcurrency.md

    r162 r163  
    22 
    33// n = 3000, 3.566 sec (very good, and on my desktop at that!!) 
     4// on my laptop: 1.128 sec!! 
    45 
    56function link(n) 
     
    3940for(i : 0 .. n) 
    4041    count += cofunc(); 
    41      
     42 
    4243writefln(count); 
    4344 
  • trunk/benchmark/fannkuch.md

    r162 r163  
    33// n = 10, 79.13 sec 
    44// n = 11, 975 sec 
     5// laptop: n = 10, 57.29 sec 
    56 
    67function fannkuch(n) 
  • trunk/benchmark/nsieve.md

    r162 r163  
    22 
    33// n = 9, 13.79 sec 
     4// laptop: 7.718 sec (rather nice) 
    45 
    56function nsieve(m) 
  • trunk/benchmark/nsievebits.md

    r162 r163  
    22 
    33// n = 11, 155 sec 
    4  
    5 local BPC = 32; 
     4// laptop, 107.87 sec 
    65 
    76function primes(n) 
     
    109    local size = 10000 << n; 
    1110 
    12     local flags = array.new(size / BPC + 1, -1); 
     11    local flags = array.new(size / 32 + 1, -1); 
    1312 
    1413    for(prime : 2 .. size + 1) 
    1514    { 
    16         local offset = prime / BPC
    17         local mask = 1 << (prime % BPC); 
     15        local offset = prime / 32
     16        local mask = 1 << (prime % 32); 
    1817 
    1918        if((flags[offset] & mask) != 0) 
     
    2322            for(i : prime + prime .. size + 1, prime) 
    2423            { 
    25                 offset = i / BPC
    26                 mask = 1 << (i % BPC); 
     24                offset = i / 32
     25                mask = 1 << (i % 32); 
    2726                 
    2827                if((flags[offset] & mask) != 0) 
  • trunk/benchmark/partialsums.md

    r162 r163  
    22 
    33// n = 2,500,000, 21.74 sec 
     4// on laptop, 13.996 sec 
    45 
    56local args = [vararg]; 
  • trunk/benchmark/recursive.md

    r162 r163  
    22 
    33// n = 11, 345.122 sec 
     4// On laptop, 284.581 sec 
    45 
    56function ack(m, n) 
     
    4243local time = os.microTime(); 
    4344 
    44     //writefln("Ack(3, %d): %d", n, ack(3, n)); 
     45    writefln("Ack(3, %d): %d", n, ack(3, n)); 
    4546    writefln("Fib(%.1f): %.1f", n + 27.0, fib(n + 27.0)); 
    4647 
    4748    --n; 
    48     //writefln("Tak(%d, %d, %d): %d", 3 * n, 2 * n, n, tak(3 * n, 2 * n, n)); 
    49     //writefln("Fib(3): %d", fib(3)); 
    50     //writefln("Tak(3.0, 2.0, 1.0): %.1f", tak(3.0, 2.0, 1.0)); 
    51      
     49    writefln("Tak(%d, %d, %d): %d", 3 * n, 2 * n, n, tak(3 * n, 2 * n, n)); 
     50    writefln("Fib(3): %d", fib(3)); 
     51    writefln("Tak(3.0, 2.0, 1.0): %.1f", tak(3.0, 2.0, 1.0)); 
     52 
    5253time = os.microTime() - time; 
    5354writefln("Took ", time / 1000000.0, " sec"); 
  • trunk/mdcl.brf

    r161 r163  
    44-O 
    55-inline 
     6-g 
    67-op 
  • trunk/mdcl.d

    r162 r163  
    167167 
    168168            try 
    169             { 
    170                 def = compileStatement(s, "stdin", atEOF); 
    171             } 
     169                def = compileStatements(s, "stdin", atEOF); 
    172170            catch(MDCompileException e) 
    173171            { 
  • trunk/minid/baselib.d

    r162 r163  
    709709    } 
    710710     
     711    int require(MDState s, uint numParams) 
     712    { 
     713        MDGlobalState().importModule(s.getParam!(char[])(0)); 
     714        return 0; 
     715    } 
     716     
     717    int loadString(MDState s, uint numParams) 
     718    { 
     719        char[] name; 
     720         
     721        if(numParams > 1) 
     722            name = s.getParam!(char[])(1); 
     723        else 
     724            name = "<loaded by loadString>"; 
     725             
     726        scope MemoryStream data = new MemoryStream(s.getParam!(char[])(0)); 
     727        bool dummy; 
     728 
     729        MDFuncDef def = compileStatements(data, name, dummy); 
     730        s.push(new MDClosure(s.environment(1), def)); 
     731        return 1; 
     732    } 
     733     
     734    int eval(MDState s, uint numParams) 
     735    { 
     736        scope MemoryStream data = new MemoryStream(string.format("return %s;", s.getParam!(char[])(0))); 
     737        bool dummy; 
     738 
     739        MDFuncDef def = compileStatements(data, "<loaded by eval>", dummy); 
     740        MDNamespace env = s.environment(1); 
     741        s.easyCall(new MDClosure(env, def), 1, MDValue(env)); 
     742        return 1; 
     743    } 
     744     
     745    int loadJSON(MDState s, uint numParams) 
     746    { 
     747        scope MemoryStream data = new MemoryStream(s.getParam!(char[])(0)); 
     748        MDFuncDef def = compileJSON(data); 
     749        MDNamespace env = s.environment(1); 
     750        s.easyCall(new MDClosure(env, def), 1, MDValue(env)); 
     751        return 1; 
     752    } 
     753 
    711754    MDStringBufferClass stringBufferClass; 
    712755 
     
    11701213        setGlobal("currentThread"d, newClosure(&lib.currentThread,         "currentThread")); 
    11711214        setGlobal("curry"d,         newClosure(&lib.curry,                 "curry")); 
     1215        setGlobal("require"d,       newClosure(&lib.require,               "require")); 
     1216        setGlobal("loadString"d,    newClosure(&lib.loadString,            "loadString")); 
     1217        setGlobal("eval"d,          newClosure(&lib.eval,                  "eval")); 
     1218        setGlobal("loadJSON"d,      newClosure(&lib.loadJSON,              "loadJSON")); 
    11721219 
    11731220        MDNamespace namespace = MDNamespace.create 
  • trunk/minid/compiler.d

    r162 r163  
    5757} 
    5858 
    59 public MDFuncDef compileStatement(Stream source, char[] name, out bool atEOF) 
     59public MDFuncDef compileStatements(Stream source, char[] name, out bool atEOF) 
    6060{ 
    6161    Token* tokens = Lexer.lex(name, source); 
    62     Statement s; 
     62    List!(Statement) s; 
    6363    FuncState fs; 
    6464 
    6565    try 
    66         s = Statement.parse(tokens); 
     66    { 
     67        do 
     68            s.add(Statement.parse(tokens)); 
     69        while(tokens.type != Token.Type.EOF) 
     70    } 
    6771    catch(Object o) 
    6872    { 
     
    7276        throw o; 
    7377    } 
     78     
     79    Statement[] stmts = s.toArray(); 
    7480 
    7581    fs = new FuncState(Location(utf.toUTF32(name), 1, 1), utf.toUTF32(name)); 
    76     s = s.fold(); 
    77     s.codeGen(fs); 
    78     fs.codeI(s.mEndLocation.line, Op.Ret, 0, 1); 
     82    fs.mIsVararg = true; 
     83     
     84    foreach(stmt; stmts) 
     85        stmt.fold().codeGen(fs); 
     86 
     87    fs.codeI(stmts[$ - 1].mEndLocation.line, Op.Ret, 0, 1); 
     88 
     89    return fs.toFuncDef(); 
     90
     91 
     92public MDFuncDef compileJSON(Stream source) 
     93
     94    Token* tokens = Lexer.lex("JSON", source, true); 
     95 
     96    Expression e; 
     97 
     98    if(tokens.type == Token.Type.LBrace) 
     99        e = TableCtorExp.parseJSON(tokens); 
     100    else 
     101        e = ArrayCtorExp.parseJSON(tokens); 
     102 
     103    Statement s = new ReturnStatement(Location("JSON"), Location("JSON"), [e]); 
     104    FuncState fs = new FuncState(Location("JSON"), "JSON"); 
     105 
     106    s.fold().codeGen(fs); 
     107    fs.codeI(1, Op.Ret, 0, 1); 
    79108 
    80109    return fs.toFuncDef(); 
     
    397426    protected static dchar mLookaheadCharacter; 
    398427    protected static bool mHaveLookahead = false; 
    399      
     428    protected static bool mIsJSON = false; 
     429 
    400430    enum Encoding 
    401431    { 
     
    409439    protected static Encoding mEncoding; 
    410440 
    411     public static Token* lex(char[] name, Stream source
     441    public static Token* lex(char[] name, Stream source, bool isJSON = false
    412442    { 
    413443        if(!source.readable) 
     
    417447 
    418448        mSource = new BufferedStream(source); 
     449        mIsJSON = isJSON; 
    419450 
    420451        char firstChar = mSource.getc(); 
     
    428459                     
    429460                    if(c != 0xBB) 
    430                         throw new MDCompileException(mLoc, "Invalid input source text encoding"); 
     461                        throw new MDCompileException(mLoc, "Invalid source text encoding 1"); 
    431462                         
    432463                    c = mSource.getc(); 
    433464                     
    434465                    if(c != 0xBF) 
    435                         throw new MDCompileException(mLoc, "Invalid input source text encoding"); 
     466                        throw new MDCompileException(mLoc, "Invalid source text encoding 2"); 
    436467                         
    437468                    mEncoding = Encoding.UTF8; 
     
    443474                     
    444475                    if(c != 0xFF) 
    445                         throw new MDCompileException(mLoc, "Invalid input source text encoding"); 
     476                        throw new MDCompileException(mLoc, "Invalid source text encoding 3"); 
    446477                         
    447478                    mEncoding = Encoding.UTF16BE; 
     
    453484                     
    454485                    if(c != 0xFE) 
    455                         throw new MDCompileException(mLoc, "Invalid input source text encoding"); 
     486                        throw new MDCompileException(mLoc, "Invalid source text encoding 4"); 
    456487     
    457488                    c = mSource.getc(); 
     
    462493                         
    463494                        if(c != 0) 
    464                             throw new MDCompileException(mLoc, "Invalid input source text encoding"); 
     495                            throw new MDCompileException(mLoc, "Invalid source text encoding 5"); 
    465496 
    466497                        mEncoding = Encoding.UTF32LE; 
     
    487518                     
    488519                    if(c != 0) 
    489                         throw new MDCompileException(mLoc, "Invalid input source text encoding"); 
     520                        throw new MDCompileException(mLoc, "Invalid source text encoding 6"); 
    490521                         
    491522                    c = mSource.getc(); 
    492523     
    493524                    if(c != 0xFE) 
    494                         throw new MDCompileException(mLoc, "Invalid input source text encoding"); 
     525                        throw new MDCompileException(mLoc, "Invalid source text encoding 7"); 
    495526                         
    496527                    c = mSource.getc(); 
    497528     
    498529                    if(c != 0xFF) 
    499                         throw new MDCompileException(mLoc, "Invalid input source text encoding"); 
     530                        throw new MDCompileException(mLoc, "Invalid source text encoding 8"); 
    500531                         
    501532                    mEncoding = Encoding.UTF32BE; 
     
    10081039            case '\"': nextChar(); return '\"'; 
    10091040            case '\'': nextChar(); return '\''; 
     1041             
     1042            case '/': 
     1043                if(mIsJSON) 
     1044                { 
     1045                    nextChar(); 
     1046                    return '/'; 
     1047                } 
     1048 
     1049                goto default; 
    10101050 
    10111051            case 'x': 
     
    23552395 
    23562396            case ExpType.Const: 
    2357                 codeR(line, Op.Move, dest, src.index, 0); 
     2397                if(isLocalTag(dest)) 
     2398                    codeR(line, Op.LoadConst, dest, src.index, 0); 
     2399                else 
     2400                    codeR(line, Op.Move, dest, src.index, 0); 
    23582401                break; 
    23592402 
    23602403            case ExpType.Var: 
    23612404                if(dest != src.index) 
    2362                     codeR(line, Op.Move, dest, src.index, 0); 
     2405                { 
     2406                    if(isLocalTag(dest) && isLocalTag(src.index)) 
     2407                        codeR(line, Op.MoveLocal, dest, src.index, 0); 
     2408                    else 
     2409                        codeR(line, Op.Move, dest, src.index, 0); 
     2410                } 
    23632411                break; 
    23642412 
     
    24032451 
    24042452                if(dest != src.index2) 
    2405                     codeR(line, Op.Move, dest, src.index2, 0); 
    2406  
     2453                { 
     2454                    if(isLocalTag(dest) && isLocalTag(src.index2)) 
     2455                        codeR(line, Op.MoveLocal, dest, src.index2, 0); 
     2456                    else 
     2457                        codeR(line, Op.Move, dest, src.index2, 0); 
     2458                } 
     2459                 
    24072460                freeExpTempRegs(src); 
    24082461                break; 
     
    24142467            case ExpType.Src: 
    24152468                if(dest != src.index) 
    2416                     codeR(line, Op.Move, dest, src.index, 0); 
    2417  
     2469                { 
     2470                    if(isLocalTag(dest) && isLocalTag(src.index)) 
     2471                        codeR(line, Op.MoveLocal, dest, src.index, 0); 
     2472                    else 
     2473                        codeR(line, Op.Move, dest, src.index, 0); 
     2474                } 
     2475                 
    24182476                freeExpTempRegs(src); 
    24192477                break; 
     
    25102568            case ExpType.Var: 
    25112569                if(dest.index != srcReg) 
    2512                     codeR(line, Op.Move, dest.index, srcReg, 0); 
     2570                { 
     2571                    if(isLocalTag(dest.index)) 
     2572                        codeR(line, Op.MoveLocal, dest.index, srcReg, 0); 
     2573                    else 
     2574                        codeR(line, Op.Move, dest.index, srcReg, 0); 
     2575                } 
    25132576                break; 
    25142577                 
     
    78527915        return PostfixExp.parse(t, exp); 
    78537916    } 
     7917     
     7918    public static Expression parseJSON(inout Token* t) 
     7919    { 
     7920        Expression exp; 
     7921        Location location = t.location; 
     7922 
     7923        switch(t.type) 
     7924        { 
     7925            case Token.Type.Null: 
     7926                exp = NullExp.parse(t); 
     7927                break; 
     7928 
     7929            case Token.Type.True, Token.Type.False: 
     7930                exp = BoolExp.parse(t); 
     7931                break; 
     7932 
     7933            case Token.Type.IntLiteral: 
     7934                exp = IntExp.parse(t); 
     7935                break; 
     7936 
     7937            case Token.Type.FloatLiteral: 
     7938                exp = FloatExp.parse(t); 
     7939                break; 
     7940 
     7941            case Token.Type.StringLiteral: 
     7942                exp = StringExp.parse(t); 
     7943                break; 
     7944 
     7945            case Token.Type.LBrace: 
     7946                exp = TableCtorExp.parseJSON(t); 
     7947                break; 
     7948 
     7949            case Token.Type.LBracket: 
     7950                exp = ArrayCtorExp.parseJSON(t); 
     7951                break; 
     7952 
     7953            default: 
     7954                throw new MDCompileException(location, "Expression expected, not '%s'", t.toString()); 
     7955        } 
     7956 
     7957        return exp; 
     7958    } 
    78547959} 
    78557960 
     
    83858490        if(t.type != Token.Type.RBrace) 
    83868491        { 
    8387             int index = 0; 
    8388  
    83898492            bool lastWasFunc = false; 
    83908493 
     
    84518554    } 
    84528555 
     8556    public static TableCtorExp parseJSON(inout Token* t) 
     8557    { 
     8558        Location location = t.location; 
     8559 
     8560        t = t.expect(Token.Type.LBrace); 
     8561 
     8562        Expression[2][] fields = new Expression[2][2]; 
     8563        uint i = 0; 
     8564 
     8565        void addPair(Expression k, Expression v) 
     8566        { 
     8567            if(i >= fields.length) 
     8568                fields.length = fields.length * 2; 
     8569 
     8570            fields[i][0] = k; 
     8571            fields[i][1] = v; 
     8572            i++; 
     8573        } 
     8574 
     8575        if(t.type != Token.Type.RBrace) 
     8576        { 
     8577            void parseField() 
     8578            { 
     8579                Expression k = StringExp.parse(t); 
     8580                t = t.expect(Token.Type.Colon); 
     8581                Expression v = PrimaryExp.parseJSON(t); 
     8582 
     8583                addPair(k, v); 
     8584            } 
     8585 
     8586            parseField(); 
     8587 
     8588            while(t.type != Token.Type.RBrace) 
     8589            { 
     8590                t = t.expect(Token.Type.Comma); 
     8591                parseField(); 
     8592            } 
     8593        } 
     8594 
     8595        fields.length = i; 
     8596 
     8597        t.expect(Token.Type.RBrace); 
     8598        Location endLocation = t.location; 
     8599        t = t.nextToken; 
     8600 
     8601        return new TableCtorExp(location, endLocation, fields); 
     8602    } 
     8603 
    84538604    public override void codeGen(FuncState s) 
    84548605    { 
     
    85248675                t = t.expect(Token.Type.Comma); 
    85258676                fields.add(Expression.parse(t)); 
     8677            } 
     8678        } 
     8679 
     8680        t.expect(Token.Type.RBracket); 
     8681        Location endLocation = t.location; 
     8682        t = t.nextToken; 
     8683 
     8684        return new ArrayCtorExp(location, endLocation, fields.toArray()); 
     8685    } 
     8686     
     8687    public static ArrayCtorExp parseJSON(inout Token* t) 
     8688    { 
     8689        Location location = t.location; 
     8690        t = t.expect(Token.Type.LBracket); 
     8691        List!(Expression) fields; 
     8692 
     8693        if(t.type != Token.Type.RBracket) 
     8694        { 
     8695            fields.add(PrimaryExp.parseJSON(t)); 
     8696 
     8697            while(t.type != Token.Type.RBracket) 
     8698            { 
     8699                t = t.expect(Token.Type.Comma); 
     8700                fields.add(PrimaryExp.parseJSON(t)); 
    85268701            } 
    85278702        } 
  • trunk/minid/opcodes.d

    r162 r163  
    6666    Length, 
    6767    LoadBool, 
     68    LoadConst, 
    6869    LoadNull, 
    6970    LoadNulls, 
     
    7273    ModEq, 
    7374    Move, 
     75    MoveLocal, 
    7476    Mul, 
    7577    MulEq, 
     
    146148Length............R: dest, src, n/a 
    147149LoadBool..........R: dest, 1/0, n/a 
     150LoadConst.........R: dest local, src const, n/a 
    148151LoadNull..........I: dest, n/a 
    149152LoadNulls.........I: dest, num regs 
     
    152155ModEq.............R: dest, src, n/a 
    153156Move..............R: dest, src, n/a 
     157MoveLocal.........R: dest local, src local, n/a 
    154158Mul...............R: dest, src, src 
    155159MulEq.............R: dest, src, n/a 
     
    290294            case Op.Length:        return string.format("len %s, %s", cr(rd), cr(rs)); 
    291295            case Op.LoadBool:      return string.format("lb %s, %s", cr(rd), rs); 
     296            case Op.LoadConst:     return string.format("lc %s, %s", cr(rd), cr(rs)); 
    292297            case Op.LoadNull:      return string.format("lnull %s", cr(rd)); 
    293298            case Op.LoadNulls:     return string.format("lnulls r%s, %s", rd, uimm); 
     
    296301            case Op.ModEq:         return string.format("modeq %s, %s", cr(rd), cr(rs)); 
    297302            case Op.Move:          return string.format("mov %s, %s", cr(rd), cr(rs)); 
     303            case Op.MoveLocal:     return string.format("movl %s, %s", cr(rd), cr(rs)); 
    298304            case Op.Mul:           return string.format("mul %s, %s, %s", cr(rd), cr(rs), cr(rt)); 
    299305            case Op.MulEq:         return string.format("muleq %s, %s", cr(rd), cr(rs)); 
  • trunk/minid/regexplib.d

    r161 r163  
    8181        char[] pattern = s.getParam!(char[])(0); 
    8282        char[] src = s.getParam!(char[])(1); 
    83         char[] rep = s.getParam!(char[])(2); 
    84         char[] attributes = ""; 
    85          
     83        char[] attributes = ""; 
     84 
    8685        if(numParams > 3) 
    8786            attributes = s.getParam!(char[])(3); 
    8887 
    89         s.push(s.safeCode(RegExp(pattern, attributes).replace(src,rep))); 
     88        if(s.isParam!("string")(2)) 
     89        { 
     90            char[] rep = s.getParam!(char[])(2); 
     91            s.push(s.safeCode(RegExp(pattern, attributes).replace(src, rep))); 
     92        } 
     93        else 
     94        { 
     95            MDClosure rep = s.getParam!(MDClosure)(2); 
     96            scope MDRegexp temp = regexpClass.newInstance(); 
     97 
     98            s.push(s.safeCode(sub(src, pattern, (RegExp m) 
     99            { 
     100                temp.constructor(m); 
     101                 
     102                s.easyCall(rep, 1, s.getContext(), temp); 
     103                 
     104                return s.pop!(char[]); 
     105            }, attributes))); 
     106        } 
     107 
    90108        return 1; 
    91109    } 
  • trunk/minid/types.d

    r162 r163  
    233233        // Object types 
    234234        private MDObject mObj; 
     235        private MDString mString; 
     236        private MDTable mTable; 
     237        private MDArray mArray; 
     238        private MDClosure mFunction; 
     239        private MDClass mClass; 
     240        private MDInstance mInstance; 
     241        private MDNamespace mNamespace; 
     242        private MDState mThread; 
    235243    } 
    236244     
     
    555563 
    556564            static if(is(T == char[])) 
    557                 return mObj.asString.asUTF8(); 
     565                return mString.asUTF8(); 
    558566            else static if(is(T == wchar[])) 
    559                 return mObj.asString.asUTF16(); 
     567                return mString.asUTF16(); 
    560568            else 
    561                 return mObj.asString.asUTF32(); 
     569                return mString.asUTF32(); 
    562570        } 
    563571        else static if(is(T : MDString)) 
    564572        { 
    565573            assert(mType == Type.String, "MDValue as " ~ T.stringof); 
    566             return mObj.asString; 
     574            return mString; 
    567575        } 
    568576        else static if(is(T : MDTable)) 
    569577        { 
    570578            assert(mType == Type.Table, "MDValue as " ~ T.stringof); 
    571             return mObj.asTable; 
     579            return mTable; 
    572580        } 
    573581        else static if(is(T : MDArray)) 
    574582        { 
    575583            assert(mType == Type.Array, "MDValue as " ~ T.stringof); 
    576             return mObj.asArray; 
     584            return mArray; 
    577585        } 
    578586        else static if(is(T : MDClosure)) 
    579587        { 
    580588            assert(mType == Type.Function, "MDValue as " ~ T.stringof); 
    581             return mObj.asClosure
     589            return mFunction
    582590        } 
    583591        else static if(is(T : MDClass)) 
    584592        { 
    585593            assert(mType == Type.Class, "MDValue as " ~ T.stringof); 
    586             return mObj.asClass; 
     594            return mClass; 
    587595        } 
    588596        else static if(is(T : MDInstance)) 
     
    590598            assert(mType == Type.Instance, "MDValue as " ~ T.stringof); 
    591599 
    592             T ret = cast(T)mObj.asInstance; 
    593  
    594             if(ret is null) 
    595                 throw new MDException("Cannot convert '%s' to " ~ T.stringof, mObj.asInstance.classinfo.name); 
     600            static if(is(T == MDInstance)) 
     601                T ret = mInstance; 
     602            else 
     603            { 
     604                T ret = cast(T)mInstance; 
     605 
     606                if(ret is null) 
     607                    throw new MDException("Cannot convert '%s' to " ~ T.stringof, mInstance.classinfo.name); 
     608            } 
    596609 
    597610            return ret; 
     
    600613        { 
    601614            assert(mType == Type.Namespace, "MDValue as " ~ T.stringof); 
    602             return mObj.asNamespace; 
     615            return mNamespace; 
    603616        } 
    604617        else static if(is(T : MDState)) 
    605618        { 
    606619            assert(mType == Type.Thread, "MDValue as " ~ T.stringof); 
    607             return mObj.asThread; 
     620            return mThread; 
    608621        } 
    609622        else static if(is(T : MDObject)) 
     
    660673 
    661674            static if(is(T == char[])) 
    662                 return mObj.asString.asUTF8(); 
     675                return mString.asUTF8(); 
    663676            else static if(is(T == wchar[])) 
    664                 return mObj.asString.asUTF16(); 
     677                return mString.asUTF16(); 
    665678            else 
    666                 return mObj.asString.asUTF32(); 
     679                return mString.asUTF32(); 
    667680        } 
    668681        else static if(is(T : MDString)) 
     
    671684                throw new MDException("Cannot convert '%s' to " ~ T.stringof, typeString()); 
    672685                 
    673             return mObj.asString; 
     686            return mString; 
    674687        } 
    675688        else static if(is(T : MDTable)) 
     
    678691                throw new MDException("Cannot convert '%s' to " ~ T.stringof, typeString()); 
    679692                 
    680             return mObj.asTable; 
     693            return mTable; 
    681694        } 
    682695        else static if(is(T : MDArray)) 
     
    685698                throw new MDException("Cannot convert '%s' to " ~ T.stringof, typeString()); 
    686699                 
    687             return mObj.asArray; 
     700            return mArray; 
    688701        } 
    689702        else static if(is(T : MDClosure)) 
     
    692705                throw new MDException("Cannot convert '%s' to " ~ T.stringof, typeString()); 
    693706 
    694             return mObj.asClosure
     707            return mFunction
    695708        } 
    696709        else static if(is(T : MDClass)) 
     
    699712                throw new MDException("Cannot convert '%s' to " ~ T.stringof, typeString()); 
    700713                 
    701             return mObj.asClass; 
     714            return mClass; 
    702715        } 
    703716        else static if(is(T : MDInstance)) 
     
    706719                throw new MDException("Cannot convert '%s' to " ~ T.stringof, typeString()); 
    707720                 
    708             T ret = cast(T)mObj.asInstance; 
    709  
    710             if(ret is null) 
    711                 throw new MDException("Cannot convert '%s' to " ~ T.stringof, mObj.asInstance.classinfo.name); 
    712                  
     721            static if(is(T == MDInstance)) 
     722                T ret = mInstance; 
     723            else 
     724            { 
     725                T ret = cast(T)mInstance; 
     726     
     727                if(ret is null) 
     728                    throw new MDException("Cannot convert '%s' to " ~ T.stringof, mInstance.classinfo.name); 
     729            } 
     730             
    713731            return ret; 
    714732        } 
     
    718736                throw new MDException("Cannot convert '%s' to " ~ T.stringof, typeString()); 
    719737 
    720             return mObj.asNamespace; 
     738            return mNamespace; 
    721739        } 
    722740        else static if(is(T : MDState)) 
     
    725743                throw new MDException("Cannot convert '%s' to " ~ T.stringof, typeString()); 
    726744 
    727             return mObj.asThread; 
     745            return mThread; 
    728746        } 
    729747        else static if(is(T : MDObject)) 
     
    773791        { 
    774792            mType = Type.String; 
    775             mObj = new MDString(src); 
     793            mString = new MDString(src); 
     794        } 
     795        else static if(is(T : MDString)) 
     796        { 
     797            mType = Type.String; 
     798            mString = src;   
     799        } 
     800        else static if(is(T : MDTable)) 
     801        { 
     802            mType = src.mType; 
     803            mTable = src; 
     804        } 
     805        else static if(is(T : MDArray)) 
     806        { 
     807            mType = Type.Array; 
     808            mArray = src; 
     809        } 
     810        else static if(is(T : MDClosure)) 
     811        { 
     812            mType = Type.Function; 
     813            mFunction = src; 
     814        } 
     815        else static if(is(T : MDClass)) 
     816        { 
     817            mType = Type.Class; 
     818            mClass = src; 
     819        } 
     820        else static if(is(T : MDInstance)) 
     821        { 
     822            mType = Type.Instance; 
     823            mInstance = src; 
     824        } 
     825        else static if(is(T : MDNamespace)) 
     826        { 
     827            mType = Type.Namespace; 
     828            mNamespace = src; 
     829        } 
     830        else static if(is(T : MDState)) 
     831        { 
     832            mType = Type.Thread; 
     833            mThread = src; 
    776834        } 
    777835        else static if(is(T : MDObject)) 
     
    849907 
    850908            case Type.String: 
    851                 Serialize(s, mObj.asString.mData); 
     909                Serialize(s, mString.mData); 
    852910                break; 
    853911                 
     
    887945                dchar[] data; 
    888946                Deserialize(s, data); 
    889                 ret.mObj = new MDString(data); 
     947                ret.mString = new MDString(data); 
    890948                break; 
    891949                 
     
    900958abstract class MDObject 
    901959{ 
     960    public MDValue.Type mType; 
     961 
    902962    public uint length(); 
    903963 
    904     // avoiding RTTI downcasts for speed 
    905     public MDString asString() { return null; } 
    906     public MDClosure asClosure() { return null; } 
    907     public MDTable asTable() { return null; } 
    908     public MDArray asArray() { return null; } 
    909     public MDClass asClass() { return null; } 
    910     public MDInstance asInstance() { return null; } 
    911     public MDNamespace asNamespace() { return null; } 
    912     public MDState asThread() { return null; } 
    913     public MDValue.Type mType; 
    914      
    915964    public int opCmp(Object o) 
    916965    { 
     
    9751024    } 
    9761025     
    977     public override MDString asString() 
    978     { 
    979         return this; 
    980     } 
    981  
    9821026    public override uint length() 
    9831027    { 
     
    11