Changeset 209

Show
Ignore:
Timestamp:
10/08/07 11:22:17 (1 year ago)
Author:
JarrettBillingsley
Message:

--

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/lib.brf

    r176 r209  
    11minid/arraylib.d 
     2minid/bind.d 
    23minid/baselib.d 
    34minid/charlib.d 
     5minid/commandline.d 
    46minid/compiler.d 
    57minid/iolib.d 
  • trunk/mdcl.brf

    r176 r209  
    22-clean 
    33-release 
     4-op 
    45-O 
    5 -op 
  • trunk/minid/baselib.d

    r205 r209  
    480480 
    481481        baseFormat(s, s.getAllParams(), &sink); 
    482         Cout()
     482        Stdout.flush
    483483        return 0; 
    484484    } 
     
    486486    int writeln(MDState s, uint numParams) 
    487487    { 
     488        char[256] buffer = void; 
     489        char[] buf = buffer; 
     490 
    488491        for(uint i = 0; i < numParams; i++) 
    489             Stdout.format("{}", s.valueToString(s.getParam(i)).mData); 
     492        { 
     493            buf = utf.toUtf8(s.valueToString(s.getParam(i)).mData, buf); 
     494            Stdout(buf); 
     495        } 
    490496 
    491497        Stdout.newline; 
     
    495501    int write(MDState s, uint numParams) 
    496502    { 
     503        char[256] buffer = void; 
     504        char[] buf = buffer; 
     505 
    497506        for(uint i = 0; i < numParams; i++) 
    498             Stdout.format("{}", s.valueToString(s.getParam(i)).mData); 
    499  
    500         Cout(); 
     507        { 
     508            buf = utf.toUtf8(s.valueToString(s.getParam(i)).mData, buf); 
     509            Stdout(buf); 
     510        } 
     511 
     512        Stdout.flush; 
    501513        return 0; 
    502514    } 
  • trunk/minid/compiler.d

    r200 r209  
    126126    else 
    127127        fs.codeI(stmts[$ - 1].mEndLocation.line, Op.Ret, 0, 1); 
     128         
     129    //fs.showMe(); Stdout.flush; 
    128130 
    129131    return fs.toFuncDef(); 
     
    31863188    public void codeGen(FuncState s) 
    31873189    { 
    3188         mBaseClass.codeGen(s); 
    3189         Exp base; 
    3190         s.popSource(mLocation.line, base); 
    3191         s.freeExpTempRegs(&base); 
    3192  
    3193         uint destReg = s.pushRegister(); 
    3194         uint nameConst = s.tagConst(s.codeStringConst(mName.mName)); 
    3195         s.codeR(mLocation.line, Op.Class, destReg, nameConst, base.index); 
    3196          
    3197         FuncState.enterClass(this); 
    3198  
    3199         foreach(Field field; mFields) 
    3200         { 
    3201             uint index = s.tagConst(s.codeStringConst(field.name)); 
    3202  
    3203             field.initializer.codeGen(s); 
    3204             Exp val; 
    3205             s.popSource(field.initializer.mEndLocation.line, val); 
    3206  
    3207             s.codeR(field.initializer.mEndLocation.line, Op.IndexAssign, destReg, index, val.index); 
    3208  
    3209             s.freeExpTempRegs(&val); 
    3210         } 
    3211  
    3212         foreach(FuncDef method; mMethods) 
    3213         { 
    3214             uint index = s.tagConst(s.codeStringConst(method.mName.mName)); 
    3215  
    3216             method.codeGen(s, true); 
    3217             Exp val; 
    3218             s.popSource(method.mEndLocation.line, val); 
    3219  
    3220             s.codeR(method.mEndLocation.line, Op.IndexAssign, destReg, index, val.index); 
    3221  
    3222             s.freeExpTempRegs(&val); 
    3223         } 
    3224          
    3225         FuncState.leaveClass(); 
    3226  
    3227         s.pushTempReg(destReg); 
     3190        /* 
     3191        A class declaration/literal actually gets rewritten as a call to a function literal.  This allows 
     3192        super calls to work correctly within the methods, by making this class available as an upvalue to those 
     3193        methods. 
     3194         
     3195        class A : B 
     3196        { 
     3197            this() { super(); } 
     3198            function fork() { super.fork(); } 
     3199        } 
     3200         
     3201        is rewritten as: 
     3202         
     3203        (function <class A>() 
     3204        { 
     3205            local __class; 
     3206             
     3207            __class = class A : B 
     3208            { 
     3209                this() { __class.super.constructor(with this); } 
     3210                function fork() { __class.super.fork(with this); } 
     3211            }; 
     3212             
     3213            return __class; 
     3214        })(); 
     3215        */ 
     3216         
     3217        Expression classExp = new class Expression 
     3218        { 
     3219            this() 
     3220            { 
     3221                super(mLocation, mEndLocation); 
     3222            } 
     3223 
     3224            override void codeGen(FuncState s) 
     3225            { 
     3226                mBaseClass.codeGen(s); 
     3227                Exp base; 
     3228                s.popSource(mLocation.line, base); 
     3229                s.freeExpTempRegs(&base); 
     3230         
     3231                uint destReg = s.pushRegister(); 
     3232                uint nameConst = s.tagConst(s.codeStringConst(mName.mName)); 
     3233                s.codeR(mLocation.line, Op.Class, destReg, nameConst, base.index); 
     3234                 
     3235                FuncState.enterClass(this.outer); 
     3236         
     3237                foreach(Field field; mFields) 
     3238                { 
     3239                    uint index = s.tagConst(s.codeStringConst(field.name)); 
     3240         
     3241                    field.initializer.codeGen(s); 
     3242                    Exp val; 
     3243                    s.popSource(field.initializer.mEndLocation.line, val); 
     3244         
     3245                    s.codeR(field.initializer.mEndLocation.line, Op.IndexAssign, destReg, index, val.index); 
     3246         
     3247                    s.freeExpTempRegs(&val); 
     3248                } 
     3249         
     3250                foreach(FuncDef method; mMethods) 
     3251                { 
     3252                    uint index = s.tagConst(s.codeStringConst(method.mName.mName)); 
     3253         
     3254                    method.codeGen(s, true); 
     3255                    Exp val; 
     3256                    s.popSource(method.mEndLocation.line, val); 
     3257         
     3258                    s.codeR(method.mEndLocation.line, Op.IndexAssign, destReg, index, val.index); 
     3259         
     3260                    s.freeExpTempRegs(&val); 
     3261                } 
     3262                 
     3263                FuncState.leaveClass(); 
     3264         
     3265                s.pushTempReg(destReg);  
     3266            } 
     3267        }; 
     3268 
     3269        Identifier __class = new Identifier("__class", mLocation); 
     3270        Expression __classExp = new IdentExp(mLocation, __class); 
     3271 
     3272        CompoundStatement funcBody = new CompoundStatement(mLocation, mEndLocation, 
     3273        [ 
     3274            cast(Statement)new DeclarationStatement(mLocation, mLocation, new VarDecl(mLocation, mLocation, Declaration.Protection.Local, [new Identifier("__class", mLocation)], null)), 
     3275            new ExpressionStatement(mLocation, mEndLocation, new Assignment(mLocation, mEndLocation, [__classExp], classExp)), 
     3276            new ReturnStatement(__classExp) 
     3277        ]); 
     3278         
     3279        FuncLiteralExp func = new FuncLiteralExp(mLocation, mEndLocation, new FuncDef(mLocation, mEndLocation, null, false, funcBody, mName)); 
     3280         
     3281        (new CallExp(mLocation, mEndLocation, func, null, null)).codeGen(s); 
    32283282    } 
    32293283 
     
    69286982                cmpVal = 0; 
    69296983            else if(mOp1.isInt && mOp2.isInt) 
    6930                 cmpVal = mOp1.asInt() - mOp2.asInt(); 
     6984                cmpVal = Compare3(mOp1.asInt(), mOp2.asInt()); 
    69316985            else if((mOp1.isInt || mOp1.isFloat) && (mOp2.isInt || mOp2.isFloat)) 
    6932             { 
    6933                 if(mOp1.asFloat() < mOp2.asFloat()) 
    6934                     cmpVal = -1; 
    6935                 else if(mOp1.asFloat() > mOp2.asFloat()) 
    6936                     cmpVal = 1; 
    6937                 else 
    6938                     cmpVal = 0; 
    6939             } 
     6986                cmpVal = Compare3(mOp1.asFloat(), mOp2.asFloat()); 
    69406987            else if(mOp1.isChar && mOp2.isChar) 
    6941                 cmpVal = mOp1.asChar() - mOp2.asChar(); 
     6988                cmpVal = Compare3(mOp1.asChar, mOp2.asChar); 
    69426989            else if(mOp1.isString && mOp2.isString) 
    69436990                cmpVal = dcmp(mOp1.asString(), mOp2.asString()); 
     
    69917038    { 
    69927039        super(location, endLocation, Op.Cmp3, left, right); 
     7040    } 
     7041     
     7042    public override Expression fold() 
     7043    { 
     7044        mOp1 = mOp1.fold(); 
     7045        mOp2 = mOp2.fold(); 
     7046         
     7047        if(mOp1.isConstant && mOp2.isConstant) 
     7048        { 
     7049            int cmpVal = 0; 
     7050 
     7051            if(mOp1.isNull && mOp2.isNull) 
     7052                cmpVal = 0; 
     7053            else if(mOp1.isInt && mOp2.isInt) 
     7054                cmpVal = Compare3(mOp1.asInt(), mOp2.asInt()); 
     7055            else if((mOp1.isInt || mOp1.isFloat) && (mOp2.isInt || mOp2.isFloat)) 
     7056                cmpVal = Compare3(mOp1.asFloat(), mOp2.asFloat()); 
     7057            else if(mOp1.isChar && mOp2.isChar) 
     7058                cmpVal = Compare3(mOp1.asChar(), mOp2.asChar()); 
     7059            else if(mOp1.isString && mOp2.isString) 
     7060                cmpVal = dcmp(mOp1.asString(), mOp2.asString()); 
     7061            else 
     7062                throw new MDCompileException(mLocation, "Invalid compile-time comparison"); 
     7063 
     7064            return new IntExp(mLocation, cmpVal); 
     7065        } 
     7066 
     7067 
     7068        return this; 
    69937069    } 
    69947070} 
     
    91569232 
    91579233        // rewrite super(1, 2, 3) as super.constructor(1, 2, 3) 
    9158         // rewrite super.method(1, 2, 3) as (this.super).method(with this, 1, 2, 3); 
     9234        // rewrite super.method(1, 2, 3) as __class.super.method(with this, 1, 2, 3); 
    91599235 
    91609236        ThisExp _this = new ThisExp(mLocation); 
    9161         DotSuperExp sup = new DotSuperExp(mLocation, mEndLocation, _this); 
     9237        IdentExp _class = new IdentExp(mLocation, new Identifier("__class", mLocation)); 
     9238        DotSuperExp sup = new DotSuperExp(mLocation, mEndLocation, _class); 
    91629239        DotExp dot = new DotExp(mLocation, mEndLocation, sup, method); 
    91639240        CallExp call = new CallExp(mLocation, mEndLocation, dot, _this, mArgs); 
  • trunk/minid/iolib.d

    r183 r209  
    423423            mLines = new LineIterator!(char)(mInput); 
    424424        } 
    425          
     425 
    426426        public T readVal(T)() 
    427427        { 
  • trunk/minid/types.d

    r204 r209  
    365365            case Type.Null: 
    366366                return true; 
    367                  
     367 
    368368            case Type.Bool: 
    369369                return this.mBool == other.mBool; 
     
    402402 
    403403            case Type.Int: 
    404                 return this.mInt - other.mInt
     404                return Compare3(this.mInt, other.mInt)
    405405 
    406406            case Type.Float: 
    407                 if(this.mFloat < other.mFloat) 
    408                     return -1; 
    409                 else if(this.mFloat > other.mFloat) 
    410                     return 1; 
    411                 else 
    412                     return 0; 
     407                return Compare3(this.mFloat, other.mFloat); 
    413408 
    414409            case Type.Char: 
    415                 return this.mChar - other.mChar
     410                return Compare3(this.mChar, other.mChar)
    416411 
    417412            default: 
     
    446441            case Type.Int: 
    447442                if(other.mType == Type.Float) 
    448                 { 
    449                     mdfloat val = mInt; 
    450  
    451                     if(val < other.mFloat) 
    452                         return -1; 
    453                     else if(val > other.mFloat) 
    454                         return 1; 
    455                     else 
    456                         return 0; 
    457                 } 
     443                    return Compare3(cast(mdfloat)this.mInt, other.mFloat); 
    458444                else 
    459                     return this.mInt - other.mInt
     445                    return Compare3(this.mInt, other.mInt)
    460446 
    461447            case Type.Float: 
    462448                if(other.mType == Type.Int) 
    463                 { 
    464                     mdfloat val = other.mInt; 
    465                      
    466                     if(this.mFloat < val) 
    467                         return -1; 
    468                     else if(this.mFloat > val) 
    469                         return 1; 
    470                     else 
    471                         return 0; 
    472                 } 
     449                    return Compare3(this.mFloat, cast(mdfloat)other.mInt); 
    473450                else 
    474                 { 
    475                     if(this.mFloat < other.mFloat) 
    476                         return -1; 
    477                     else if(this.mFloat > other.mFloat) 
    478                         return 1; 
    479                     else 
    480                         return 0; 
    481                 } 
     451                    return Compare3(this.mFloat, other.mFloat); 
    482452 
    483453            case Type.Char: 
    484                 return this.mChar - other.mChar
     454                return this.mChar < other.mChar ? -1 : this.mChar > other.mChar ? 1 : 0
    485455 
    486456            default: 
     
    14631433        for(uint i = 0; i < values.length; i++) 
    14641434        { 
    1465             if(values[i].isString()
    1466                 l += values[i].as!(MDString).length; 
    1467             else if(values[i].isChar()
     1435            if(values[i].mType == MDValue.Type.String
     1436                l += values[i].mString.length; 
     1437            else if(values[i].mType == MDValue.Type.Char
    14681438                l += 1; 
    14691439            else 
     
    14731443            } 
    14741444        } 
    1475          
     1445 
    14761446        dchar[] result = new dchar[l]; 
    1477          
     1447 
    14781448        uint i = 0; 
    1479          
     1449 
    14801450        foreach(MDValue v; values) 
    14811451        { 
    1482             if(v.isString()
     1452            if(v.mType == MDValue.Type.String
    14831453            { 
    1484                 MDString s = v.as!(MDString)
     1454                MDString s = v.mString
    14851455                result[i .. i + s.length] = s.mData[]; 
    14861456                i += s.length; 
     
    14881458            else 
    14891459            { 
    1490                 result[i] = v.as!(dchar)
     1460                result[i] = v.mChar
    14911461                i++; 
    14921462            } 
     
    17931763    public MDValue* opIndex(ref MDValue index) 
    17941764    { 
    1795         if(index.isNull()
     1765        if(index.mType == MDValue.Type.Null
    17961766            throw new MDException("Cannot index a table with null"); 
    17971767 
     
    18101780    public void opIndexAssign(ref MDValue value, ref MDValue index) 
    18111781    { 
    1812         if(index.isNull()
     1782        if(index.mType == MDValue.Type.Null
    18131783            throw new MDException("Cannot index assign a table with null"); 
    18141784 
    1815         if(value.isNull()
     1785        if(value.mType == MDValue.Type.Null
    18161786        { 
    18171787            if(index in mData) 
     
    21822152    private static MDArray concat(MDValue[] values) 
    21832153    { 
    2184         if(values.length == 2 && values[0].isArray()
    2185         { 
    2186             if(values[1].isArray()
    2187                 return values[0].as!(MDArray) ~ values[1].as!(MDArray)
     2154        if(values.length == 2 && values[0].mType == MDValue.Type.Array
     2155        { 
     2156            if(values[1].mType == MDValue.Type.Array
     2157                return values[0].mArray ~ values[1].mArray
    21882158            else 
    2189                 return values[0].as!(MDArray) ~ values[1]; 
     2159                return values[0].mArray ~ values[1]; 
    21902160        } 
    21912161 
     
    21942164        foreach(uint i, MDValue v; values) 
    21952165        { 
    2196             if(v.isArray()
    2197                 l += v.as!(MDArray).length; 
     2166            if(v.mType == MDValue.Type.Array
     2167                l += v.mArray.length; 
    21982168            else 
    21992169                l += 1; 
     
    22062176        foreach(MDValue v; values) 
    22072177        { 
    2208             if(v.isArray()
     2178            if(v.mType == MDValue.Type.Array
    22092179            { 
    2210                 MDArray a = v.as!(MDArray)
     2180                MDArray a = v.mArray
    22112181                result.mData[i .. i + a.length] = a.mData[]; 
    22122182                i += a.length; 
     
    22262196        foreach(uint i, ref MDValue v; values) 
    22272197        { 
    2228             if(v.isArray()
    2229                 dest ~= v.as!(MDArray)
     2198            if(v.mType == MDValue.Type.Array
     2199                dest ~= v.mArray
    22302200            else 
    22312201                dest ~= v; 
     
    23602330    public void opIndexAssign(ref MDValue value, MDString index) 
    23612331    { 
    2362         if(value.isFunction()
     2332        if(value.mType == MDValue.Type.Function
    23632333            mMethods[index] = value; 
    23642334        else 
     
    24352405{ 
    24362406    protected MDClass mClass; 
     2407    protected MDNamespace mMethods; 
    24372408    protected MDNamespace mFields; 
    2438     protected MDNamespace mMethods; 
    24392409 
    24402410    private this(MDClass _class) 
     
    24422412        mType = MDValue.Type.Instance; 
    24432413        mClass = _class; 
     2414        mMethods = mClass.mMethods; 
    24442415        mFields = mClass.mFields.dup; 
    2445         mMethods = mClass.mMethods; 
    24462416    } 
    24472417 
     
    24882458    public void opIndexAssign(ref MDValue value, MDString index) 
    24892459    { 
    2490         if(value.isFunction()
     2460        if(value.mType == MDValue.Type.Function
    24912461            throw new MDException("Attempting to change a method of an instance of '{}'", mClass.toUtf8()); 
    24922462        else if(auto member = index in mFields) 
     
    25522522    } 
    25532523} 
     2524 
     2525import tango.stdc.stdlib: cmalloc = malloc, cfree = free; 
     2526import tango.core.Exception; 
     2527import tango.core.Memory; 
    25542528 
    25552529/** 
     
    32413215    package static MDModuleDef function(FilePath, char[][]) tryPath; 
    32423216    version(MDDynLibs) package static char[] function(char[], char[][]) tryDynLibPath; 
    3243  
     3217     
    32443218    private Location[] mTraceback; 
    32453219    private MDState mMainThread; 
     
    35813555            else 
    35823556            { 
    3583                 if(v.isNamespace()
    3584                     put = v.as!(MDNamespace)
     3557                if(v.mType == MDValue.Type.Namespace
     3558                    put = v.mNamespace
    35853559                else 
    35863560                    throw new MDException("Error loading module \"{}\": conflicts with {}", name, join(packages[0 .. i + 1], "."d)); 
     
    35933567        if(v !is null) 
    35943568        { 
    3595             if(!v.isNamespace()
     3569            if(v.mType != MDValue.Type.Namespace
    35963570                throw new MDException("Error loading module \"{}\": a global of the same name already exists", name); 
    35973571 
    3598             modNS = v.as!(MDNamespace)
     3572            modNS = v.mNamespace
    35993573        } 
    36003574        else 
     
    39453919 
    39463920            if(numReturns == -1) 
    3947                 return mStackIndex - basedIndexToAbs(funcSlot); 
     3921                return mStackIndex - (mCurrentAR.base + funcSlot); 
    39483922            else 
    39493923            { 
    3950                 mStackIndex = basedIndexToAbs(funcSlot) + numReturns; 
     3924                mStackIndex = mCurrentAR.base + funcSlot + numReturns; 
    39513925                return numReturns; 
    39523926            } 
     
    40284002 
    40294003    // 4. Make the call. 
    4030     s.call(funcIdx, 2, 1); 
     4004    s.call(funcIdx, 3, 1); 
    40314005 
    40324006    // 5. Pop any return values. 
     
    40514025             
    40524026        if(numReturns == -1) 
    4053             return mStackIndex - basedIndexToAbs(slot); 
     4027            return mStackIndex - (mCurrentAR.base + slot); 
    40544028        else 
    40554029        { 
    4056             mStackIndex = basedIndexToAbs(slot) + numReturns; 
     4030            mStackIndex = mCurrentAR.base + slot + numReturns; 
    40574031            return numReturns; 
    40584032        } 
     
    41224096    public final bool isParam(char[] type)(uint index) 
    41234097    { 
    4124         if(index >= (getBasedStackIndex() - 1)) 
     4098        if(index >= (mStackIndex - mCurrentAR.base - 1)) 
    41254099            badParamError(index, "not enough parameters"); 
    41264100 
    4127         static if(type == "null")           return getBasedStack(index + 1).isNull()
    4128         else static if(type == "bool")      return getBasedStack(index + 1).isBool()
    4129         else static if(type == "int")       return getBasedStack(index + 1).isInt()
    4130         else static if(type == "float")     return getBasedStack(index + 1).isFloat()
    4131         else static if(type == "char")      return getBasedStack(index + 1).isChar()
    4132         else static if(type == "string")    return getBasedStack(index + 1).isString()
    4133         else static if(type == "table")     return getBasedStack(index + 1).isTable()
    4134         else static if(type == "array")     return getBasedStack(index + 1).isArray()
    4135         else static if(type == "function")  return getBasedStack(index + 1).isFunction()
    4136         else static if(type == "class")     return getBasedStack(index + 1).isClass()
    4137         else static if(type == "instance")  return getBasedStack(index + 1).isInstance()
    4138         else static if(type == "namespace") return getBasedStack(index + 1).isNamespace()
    4139         else static if(type == "thread")    return getBasedStack(index + 1).isThread()
     4101        static if(type == "null")           return mStack[mCurrentAR.base + index + 1].mType == MDValue.Type.Null
     4102        else static if(type == "bool")      return mStack[mCurrentAR.base + index + 1].mType == MDValue.Type.Bool
     4103        else static if(type == "int")       return mStack[mCurrentAR.base + index + 1].mType == MDValue.Type.Int
     4104        else static if(type == "float")     return mStack[mCurrentAR.base + index + 1].mType == MDValue.Type.Float
     4105        else static if(type == "char")      return mStack[mCurrentAR.base + index + 1].mType == MDValue.Type.Char
     4106        else static if(type == "string")    return mStack[mCurrentAR.base + index + 1].mType == MDValue.Type.String
     4107        else static if(type == "table")     return mStack[mCurrentAR.base + index + 1].mType == MDValue.Type.Table
     4108        else static if(type == "array")     return mStack[mCurrentAR.base + index + 1].mType == MDValue.Type.Array
     4109        else static if(type == "function")  return mStack[mCurrentAR.base + index + 1].mType == MDValue.Type.Function
     4110        else static if(type == "class")     return mStack[mCurrentAR.base + index + 1].mType == MDValue.Type.Class
     4111        else static if(type == "instance")  return mStack[mCurrentAR.base + index + 1].mType == MDValue.Type.Instance
     4112        else static if(type == "namespace") return mStack[mCurrentAR.base + index + 1].mType == MDValue.Type.Namespace
     4113        else static if(type == "thread")    return mStack[mCurrentAR.base + index + 1].mType == MDValue.Type.Thread
    41404114        else 
    41414115        { 
     
    41574131    public final T getParam(T = MDValue)(uint index) 
    41584132    { 
    4159         if(index >= (getBasedStackIndex() - 1)) 
     4133        if(index >= (mStackIndex - mCurrentAR.base - 1)) 
    41604134            badParamError(index, "not enough parameters"); 
    41614135 
     
    42054179    public final MDValue[] getParams(int lo, int hi) 
    42064180    { 
    4207         int numParams = getBasedStackIndex()
     4181        int numParams = mStackIndex - mCurrentAR.base
    42084182 
    42094183        if(lo < 0) 
     
    42274201    public final MDValue[] getAllParams() 
    42284202    { 
    4229         if(getBasedStackIndex() == 1) 
     4203        if(mStackIndex - mCurrentAR.base == 1) 
    42304204            return null; 
    42314205 
     
    43364310    public final MDString valueToString(ref MDValue value) 
    43374311    { 
    4338         if(value.isString()
    4339             return value.as!(MDString)
     4312        if(value.mType == MDValue.Type.String
     4313            return value.mString
    43404314 
    43414315        MDValue* method = getMM(value, MM.ToString); 
    43424316         
    4343         if(!method.isFunction()
     4317        if(method.mType != MDValue.Type.Function
    43444318            return new MDString(value.toUtf8()); 
    43454319 
    43464320        mNativeCallDepth++; 
    4347          
     4321 
    43484322        scope(exit) 
    43494323            mNativeCallDepth--; 
    43504324 
    4351         easyCall(method.as!(MDClosure), 1, value); 
     4325        easyCall(method.mFunction, 1, value); 
    43524326        MDValue ret = pop(); 
    43534327 
    4354         if(!ret.isString()
     4328        if(ret.mType != MDValue.Type.String
    43554329            throwRuntimeException("MDState.valueToString() - '{}' method did not return a string", MetaNames[MM.ToString]); 
    4356              
    4357         return ret.as!(MDString)
     4330 
     4331        return ret.mString
    43584332    } 
    43594333 
     
    44454419        return binOp(MM.Mod, &a, &b); 
    44464420    } 
    4447  
     4421     
    44484422    /** 
    44494423    Negates the argument.  Calls metamethods. 
     
    44614435        reflOp(MM.AddEq, &a, &b); 
    44624436    } 
    4463  
     4437     
    44644438    /// ditto 
    44654439    public final void subeq(ref MDValue a, ref MDValue b) 
     
    44674441        reflOp(MM.SubEq, &a, &b); 
    44684442    } 
    4469  
     4443     
    44704444    /// ditto 
    44714445    public final void muleq(ref MDValue a, ref MDValue b) 
     
    45394513        binaryReflOp(MM.AndEq, &a, &b); 
    45404514    } 
    4541  
     4515     
    45424516    /// ditto 
    45434517    public final void oreq(ref MDValue a, ref MDValue b) 
     
    45684542    { 
    45694543        binaryReflOp(MM.UShrEq, &a, &b); 
     4544    } 
     4545     
     4546    /** 
     4547    Concatenates the list of values (which must be at least two items long) into a single value and 
     4548    returns it.  Calls metamethods. 
     4549    */ 
     4550    public final MDValue cat(MDValue[] vals) 
     4551    { 
     4552        if(vals.length < 2) 
     4553            throwRuntimeException("MDState.cat() - Must have at least two values to concatenate"); 
     4554 
     4555        return operatorCat(vals); 
     4556    } 
     4557 
     4558    /** 
     4559    Appends the list of values (which must have at least one item) to the end of the value held in dest. 
     4560    Calls metamethods. 
     4561    */ 
     4562    public final void cateq(ref MDValue dest, MDValue[] vals) 
     4563    { 
     4564        if(vals.length < 1) 
     4565            throwRuntimeException("MDState.cateq() - Must have at least one value to append"); 
     4566 
     4567        operatorCatAssign(&dest, vals); 
    45704568    } 
    45714569 
     
    46884686        assert(numParams >= 0, "negative num params in callPrologue"); 
    46894687 
    4690         MDValue* func = getAbsStack(slot)
     4688        MDValue* func = &mStack[slot]
    46914689         
    46924690        switch(func.type()) 
    46934691        { 
    46944692            case MDValue.Type.Function: 
    4695                 closure = func.as!(MDClosure)
     4693                closure = func.mFunction
    46964694                paramSlot = slot + 1; 
    46974695                break; 
    46984696 
    46994697            case MDValue.Type.Class: 
    4700                 MDClass cls = func.as!(MDClass)
     4698                MDClass cls = func.mClass
    47014699                MDInstance n = cls.newInstance(); 
    47024700                MDValue* ctor = cls.getCtor(); 
    47034701 
    4704                 if(ctor !is null && ctor.isFunction()
     4702                if(ctor !is null && ctor.mType == MDValue.Type.Function
    47054703                { 
    47064704                    uint thisSlot = slot + 1; 
     
    47094707                    try 
    47104708                    { 
    4711                         if(callPrologue2(ctor.as!(MDClosure), thisSlot, 0, thisSlot, numParams)) 
     4709                        if(callPrologue2(ctor.mFunction, thisSlot, 0, thisSlot, numParams)) 
    47124710                            execute(); 
    47134711                    } 
     
    47164714                    catch(MDException e) 
    47174715                        throw new MDRuntimeException(startTraceback(), &e.value); 
    4718                
     4716                   
    47194717                 
    47204718                mStack[slot] = n; 
     
    47444742 
    47454743            case MDValue.Type.Thread: 
    4746                 MDState thread = func.as!(MDState)
     4744                MDState thread = func.mThread
    47474745                 
    47484746                if(thread is this) 
     
    48304828                MDValue* method = getMM(*func, MM.Call); 
    48314829 
    4832                 if(!method.isFunction()
     4830                if(method.mType != MDValue.Type.Function
    48334831                    throwRuntimeException("Attempting to call a value of type '{}'", func.typeString()); 
    48344832 
    4835                 copyAbsStack(slot + 1, slot)
     4833                mStack[slot + 1] = mStack[slot]
    48364834                paramSlot = slot + 1; 
    4837                 closure = method.as!(MDClosure)
     4835                closure = method.mFunction
    48384836                break; 
    48394837        } 
     
    49164914                for(int i = 0; i < funcDef.mNumParams; i++) 
    49174915                { 
    4918                     copyAbsStack(mStackIndex, oldParamSlot)
    4919                     getAbsStack(oldParamSlot).setNull(); 
     4916                    mStack[mStackIndex] = mStack[oldParamSlot]
     4917                    mStack[oldParamSlot].setNull(); 
    49204918                    oldParamSlot++; 
    49214919                    mStackIndex++; 
     
    49524950 
    49534951            for(int i = base + funcDef.mStackSize; i >= 0 && i >= base + numParams; i--) 
    4954                 getAbsStack(i).setNull(); 
     4952                mStack[i].setNull(); 
    49554953 
    49564954            mCurrentAR.savedTop = mStackIndex; 
     
    52265224    } 
    52275225 
    5228     protected final void copyBasedStack(uint dest, uint src) 
    5229     { 
    5230         assert((mCurrentAR.base + dest) < mStack.length && (mCurrentAR.base + src) < mStack.length, "invalid based stack indices"); 
    5231          
    5232         if(dest != src) 
    5233             mStack[mCurrentAR.base + dest] = mStack[mCurrentAR.base + src]; 
    5234     } 
    5235  
    5236     protected final void copyAbsStack(uint dest, uint src) 
    5237     { 
    5238         assert(dest < mStack.length && src < mStack.length, "invalid copyAbsStack indices"); 
    5239  
    5240         if(dest != src) 
    5241             mStack[dest] = mStack[src]; 
    5242     } 
    5243      
    52445226    protected final void moveStackFrom(MDState other, uint numValues) 
    52455227    { 
     
    52565238    } 
    52575239 
    5258     protected final MDValue* getBasedStack(uint offset) 
    5259     { 
    5260         assert((mCurrentAR.base + offset) < mStack.length, "invalid based stack index"); 
    5261         return &mStack[mCurrentAR.base + offset]; 
    5262     } 
    5263  
    5264     protected final MDValue* getAbsStack(uint offset) 
    5265     { 
    5266         assert(offset < mStack.length, "invalid getAbsStack stack index"); 
    5267         return &mStack[offset]; 
    5268     } 
    5269  
    5270     protected final uint basedIndexToAbs(uint offset) 
    5271     { 
    5272         assert((mCurrentAR.base + offset) < mStack.length, "invalid basedIndexToAbs index"); 
    5273         return mCurrentAR.base + offset; 
    5274     } 
    5275      
    5276     protected final uint absIndexToBased(uint offset) 
    5277     { 
    5278         assert((cast(int)(offset - mCurrentAR.base)) >= 0 && offset < mStack.length, "invalid absIndexToBased index"); 
    5279         return offset - mCurrentAR.base; 
    5280     } 
    5281  
    52825240    protected final void close(uint index) 
    52835241    { 
    5284         MDValue* base = getBasedStack(index)
     5242        MDValue* base = &mStack[mCurrentAR.base + index]
    52855243 
    52865244        for(MDUpval* uv = mUpvalHead; uv !is null && uv.value >= base; uv = mUpvalHead) 
     
    53015259    protected final MDUpval* findUpvalue(uint num) 
    53025260    { 
    5303         MDValue* slot = getBasedStack(num)
     5261        MDValue* slot = &mStack[mCurrentAR.base + num]
    53045262 
    53055263        for(MDUpval* uv = mUpvalHead; uv !is null && uv.value >= slot; uv = uv.next) 
     
    53235281    } 
    53245282 
    5325     protected final int getBasedStackIndex() 
    5326     { 
    5327         return mStackIndex - mCurrentAR.base; 
    5328     } 
    5329  
    53305283    protected final MDValue* getMM(ref MDValue obj, MM method) 
    53315284    { 
     
    53355288        { 
    53365289            case MDValue.Type.Table: 
    5337                 m = obj.as!(MDTable)[MDValue(MetaStrings[method])]; 
    5338  
    5339                 if(!m.isFunction()
     5290                m = obj.mTable[MDValue(MetaStrings[method])]; 
     5291 
     5292                if(m.mType != MDValue.Type.Function
    53405293                    goto default; 
    53415294 
     
    53435296 
    53445297            case MDValue.Type.Instance: 
    5345                 m = obj.as!(MDInstance)[MetaStrings[method]]; 
     5298                m = obj.mInstance[MetaStrings[method]]; 
    53465299                break; 
    53475300 
     
    53565309        } 
    53575310 
    5358         if(m is null || !m.isFunction()
     5311        if(m is null || m.mType != MDValue.Type.Function
    53595312            return &MDValue.nullValue; 
    53605313        else 
     
    53655318    // Interpreter 
    53665319    // =================================================================================== 
    5367      
     5320 
    53685321    protected final MDValue binOp(MM operation, MDValue* RS, MDValue* RT) 
    53695322    { 
    53705323        debug(TIMINGS) scope _profiler_ = new Profiler("Arith"); 
    5371  
    5372         if(RS.isNum() && RT.isNum()) 
    5373         { 
    5374             if(RS.isFloat() || RT.isFloat()) 
     5324         
     5325        mdfloat f1 = void; 
     5326        mdfloat f2 = void; 
     5327 
     5328        if(RS.mType == MDValue.Type.Int) 
     5329        { 
     5330            if(RT.mType == MDValue.Type.Int) 
    53755331            { 
     5332                int i1 = RS.mInt; 
     5333