Changeset 209
- Timestamp:
- 10/08/07 11:22:17 (1 year ago)
- Files:
-
- trunk/lib.brf (modified) (1 diff)
- trunk/mdcl.brf (modified) (1 diff)
- trunk/mdcl.zip (modified) (previous)
- trunk/minid/baselib.d (modified) (3 diffs)
- trunk/minid/compiler.d (modified) (5 diffs)
- trunk/minid/iolib.d (modified) (1 diff)
- trunk/minid/types.d (modified) (145 diffs)
- trunk/minid/utils.d (modified) (1 diff)
- trunk/samples/simple.md (modified) (5 diffs)
- trunk/samples/speed.md (modified) (6 diffs)
- trunk/test.opt (modified) (previous)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/lib.brf
r176 r209 1 1 minid/arraylib.d 2 minid/bind.d 2 3 minid/baselib.d 3 4 minid/charlib.d 5 minid/commandline.d 4 6 minid/compiler.d 5 7 minid/iolib.d trunk/mdcl.brf
r176 r209 2 2 -clean 3 3 -release 4 -op 4 5 -O 5 -optrunk/minid/baselib.d
r205 r209 480 480 481 481 baseFormat(s, s.getAllParams(), &sink); 482 Cout();482 Stdout.flush; 483 483 return 0; 484 484 } … … 486 486 int writeln(MDState s, uint numParams) 487 487 { 488 char[256] buffer = void; 489 char[] buf = buffer; 490 488 491 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 } 490 496 491 497 Stdout.newline; … … 495 501 int write(MDState s, uint numParams) 496 502 { 503 char[256] buffer = void; 504 char[] buf = buffer; 505 497 506 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; 501 513 return 0; 502 514 } trunk/minid/compiler.d
r200 r209 126 126 else 127 127 fs.codeI(stmts[$ - 1].mEndLocation.line, Op.Ret, 0, 1); 128 129 //fs.showMe(); Stdout.flush; 128 130 129 131 return fs.toFuncDef(); … … 3186 3188 public void codeGen(FuncState s) 3187 3189 { 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); 3228 3282 } 3229 3283 … … 6928 6982 cmpVal = 0; 6929 6983 else if(mOp1.isInt && mOp2.isInt) 6930 cmpVal = mOp1.asInt() - mOp2.asInt();6984 cmpVal = Compare3(mOp1.asInt(), mOp2.asInt()); 6931 6985 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()); 6940 6987 else if(mOp1.isChar && mOp2.isChar) 6941 cmpVal = mOp1.asChar() - mOp2.asChar();6988 cmpVal = Compare3(mOp1.asChar, mOp2.asChar); 6942 6989 else if(mOp1.isString && mOp2.isString) 6943 6990 cmpVal = dcmp(mOp1.asString(), mOp2.asString()); … … 6991 7038 { 6992 7039 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; 6993 7069 } 6994 7070 } … … 9156 9232 9157 9233 // 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); 9159 9235 9160 9236 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); 9162 9239 DotExp dot = new DotExp(mLocation, mEndLocation, sup, method); 9163 9240 CallExp call = new CallExp(mLocation, mEndLocation, dot, _this, mArgs); trunk/minid/iolib.d
r183 r209 423 423 mLines = new LineIterator!(char)(mInput); 424 424 } 425 425 426 426 public T readVal(T)() 427 427 { trunk/minid/types.d
r204 r209 365 365 case Type.Null: 366 366 return true; 367 367 368 368 case Type.Bool: 369 369 return this.mBool == other.mBool; … … 402 402 403 403 case Type.Int: 404 return this.mInt - other.mInt;404 return Compare3(this.mInt, other.mInt); 405 405 406 406 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); 413 408 414 409 case Type.Char: 415 return this.mChar - other.mChar;410 return Compare3(this.mChar, other.mChar); 416 411 417 412 default: … … 446 441 case Type.Int: 447 442 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); 458 444 else 459 return this.mInt - other.mInt;445 return Compare3(this.mInt, other.mInt); 460 446 461 447 case Type.Float: 462 448 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); 473 450 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); 482 452 483 453 case Type.Char: 484 return this.mChar - other.mChar;454 return this.mChar < other.mChar ? -1 : this.mChar > other.mChar ? 1 : 0; 485 455 486 456 default: … … 1463 1433 for(uint i = 0; i < values.length; i++) 1464 1434 { 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) 1468 1438 l += 1; 1469 1439 else … … 1473 1443 } 1474 1444 } 1475 1445 1476 1446 dchar[] result = new dchar[l]; 1477 1447 1478 1448 uint i = 0; 1479 1449 1480 1450 foreach(MDValue v; values) 1481 1451 { 1482 if(v. isString())1452 if(v.mType == MDValue.Type.String) 1483 1453 { 1484 MDString s = v. as!(MDString);1454 MDString s = v.mString; 1485 1455 result[i .. i + s.length] = s.mData[]; 1486 1456 i += s.length; … … 1488 1458 else 1489 1459 { 1490 result[i] = v. as!(dchar);1460 result[i] = v.mChar; 1491 1461 i++; 1492 1462 } … … 1793 1763 public MDValue* opIndex(ref MDValue index) 1794 1764 { 1795 if(index. isNull())1765 if(index.mType == MDValue.Type.Null) 1796 1766 throw new MDException("Cannot index a table with null"); 1797 1767 … … 1810 1780 public void opIndexAssign(ref MDValue value, ref MDValue index) 1811 1781 { 1812 if(index. isNull())1782 if(index.mType == MDValue.Type.Null) 1813 1783 throw new MDException("Cannot index assign a table with null"); 1814 1784 1815 if(value. isNull())1785 if(value.mType == MDValue.Type.Null) 1816 1786 { 1817 1787 if(index in mData) … … 2182 2152 private static MDArray concat(MDValue[] values) 2183 2153 { 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; 2188 2158 else 2189 return values[0]. as!(MDArray)~ values[1];2159 return values[0].mArray ~ values[1]; 2190 2160 } 2191 2161 … … 2194 2164 foreach(uint i, MDValue v; values) 2195 2165 { 2196 if(v. isArray())2197 l += v. as!(MDArray).length;2166 if(v.mType == MDValue.Type.Array) 2167 l += v.mArray.length; 2198 2168 else 2199 2169 l += 1; … … 2206 2176 foreach(MDValue v; values) 2207 2177 { 2208 if(v. isArray())2178 if(v.mType == MDValue.Type.Array) 2209 2179 { 2210 MDArray a = v. as!(MDArray);2180 MDArray a = v.mArray; 2211 2181 result.mData[i .. i + a.length] = a.mData[]; 2212 2182 i += a.length; … … 2226 2196 foreach(uint i, ref MDValue v; values) 2227 2197 { 2228 if(v. isArray())2229 dest ~= v. as!(MDArray);2198 if(v.mType == MDValue.Type.Array) 2199 dest ~= v.mArray; 2230 2200 else 2231 2201 dest ~= v; … … 2360 2330 public void opIndexAssign(ref MDValue value, MDString index) 2361 2331 { 2362 if(value. isFunction())2332 if(value.mType == MDValue.Type.Function) 2363 2333 mMethods[index] = value; 2364 2334 else … … 2435 2405 { 2436 2406 protected MDClass mClass; 2407 protected MDNamespace mMethods; 2437 2408 protected MDNamespace mFields; 2438 protected MDNamespace mMethods;2439 2409 2440 2410 private this(MDClass _class) … … 2442 2412 mType = MDValue.Type.Instance; 2443 2413 mClass = _class; 2414 mMethods = mClass.mMethods; 2444 2415 mFields = mClass.mFields.dup; 2445 mMethods = mClass.mMethods;2446 2416 } 2447 2417 … … 2488 2458 public void opIndexAssign(ref MDValue value, MDString index) 2489 2459 { 2490 if(value. isFunction())2460 if(value.mType == MDValue.Type.Function) 2491 2461 throw new MDException("Attempting to change a method of an instance of '{}'", mClass.toUtf8()); 2492 2462 else if(auto member = index in mFields) … … 2552 2522 } 2553 2523 } 2524 2525 import tango.stdc.stdlib: cmalloc = malloc, cfree = free; 2526 import tango.core.Exception; 2527 import tango.core.Memory; 2554 2528 2555 2529 /** … … 3241 3215 package static MDModuleDef function(FilePath, char[][]) tryPath; 3242 3216 version(MDDynLibs) package static char[] function(char[], char[][]) tryDynLibPath; 3243 3217 3244 3218 private Location[] mTraceback; 3245 3219 private MDState mMainThread; … … 3581 3555 else 3582 3556 { 3583 if(v. isNamespace())3584 put = v. as!(MDNamespace);3557 if(v.mType == MDValue.Type.Namespace) 3558 put = v.mNamespace; 3585 3559 else 3586 3560 throw new MDException("Error loading module \"{}\": conflicts with {}", name, join(packages[0 .. i + 1], "."d)); … … 3593 3567 if(v !is null) 3594 3568 { 3595 if( !v.isNamespace())3569 if(v.mType != MDValue.Type.Namespace) 3596 3570 throw new MDException("Error loading module \"{}\": a global of the same name already exists", name); 3597 3571 3598 modNS = v. as!(MDNamespace);3572 modNS = v.mNamespace; 3599 3573 } 3600 3574 else … … 3945 3919 3946 3920 if(numReturns == -1) 3947 return mStackIndex - basedIndexToAbs(funcSlot);3921 return mStackIndex - (mCurrentAR.base + funcSlot); 3948 3922 else 3949 3923 { 3950 mStackIndex = basedIndexToAbs(funcSlot)+ numReturns;3924 mStackIndex = mCurrentAR.base + funcSlot + numReturns; 3951 3925 return numReturns; 3952 3926 } … … 4028 4002 4029 4003 // 4. Make the call. 4030 s.call(funcIdx, 2, 1);4004 s.call(funcIdx, 3, 1); 4031 4005 4032 4006 // 5. Pop any return values. … … 4051 4025 4052 4026 if(numReturns == -1) 4053 return mStackIndex - basedIndexToAbs(slot);4027 return mStackIndex - (mCurrentAR.base + slot); 4054 4028 else 4055 4029 { 4056 mStackIndex = basedIndexToAbs(slot)+ numReturns;4030 mStackIndex = mCurrentAR.base + slot + numReturns; 4057 4031 return numReturns; 4058 4032 } … … 4122 4096 public final bool isParam(char[] type)(uint index) 4123 4097 { 4124 if(index >= ( getBasedStackIndex()- 1))4098 if(index >= (mStackIndex - mCurrentAR.base - 1)) 4125 4099 badParamError(index, "not enough parameters"); 4126 4100 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; 4140 4114 else 4141 4115 { … … 4157 4131 public final T getParam(T = MDValue)(uint index) 4158 4132 { 4159 if(index >= ( getBasedStackIndex()- 1))4133 if(index >= (mStackIndex - mCurrentAR.base - 1)) 4160 4134 badParamError(index, "not enough parameters"); 4161 4135 … … 4205 4179 public final MDValue[] getParams(int lo, int hi) 4206 4180 { 4207 int numParams = getBasedStackIndex();4181 int numParams = mStackIndex - mCurrentAR.base; 4208 4182 4209 4183 if(lo < 0) … … 4227 4201 public final MDValue[] getAllParams() 4228 4202 { 4229 if( getBasedStackIndex()== 1)4203 if(mStackIndex - mCurrentAR.base == 1) 4230 4204 return null; 4231 4205 … … 4336 4310 public final MDString valueToString(ref MDValue value) 4337 4311 { 4338 if(value. isString())4339 return value. as!(MDString);4312 if(value.mType == MDValue.Type.String) 4313 return value.mString; 4340 4314 4341 4315 MDValue* method = getMM(value, MM.ToString); 4342 4316 4343 if( !method.isFunction())4317 if(method.mType != MDValue.Type.Function) 4344 4318 return new MDString(value.toUtf8()); 4345 4319 4346 4320 mNativeCallDepth++; 4347 4321 4348 4322 scope(exit) 4349 4323 mNativeCallDepth--; 4350 4324 4351 easyCall(method. as!(MDClosure), 1, value);4325 easyCall(method.mFunction, 1, value); 4352 4326 MDValue ret = pop(); 4353 4327 4354 if( !ret.isString())4328 if(ret.mType != MDValue.Type.String) 4355 4329 throwRuntimeException("MDState.valueToString() - '{}' method did not return a string", MetaNames[MM.ToString]); 4356 4357 return ret. as!(MDString);4330 4331 return ret.mString; 4358 4332 } 4359 4333 … … 4445 4419 return binOp(MM.Mod, &a, &b); 4446 4420 } 4447 4421 4448 4422 /** 4449 4423 Negates the argument. Calls metamethods. … … 4461 4435 reflOp(MM.AddEq, &a, &b); 4462 4436 } 4463 4437 4464 4438 /// ditto 4465 4439 public final void subeq(ref MDValue a, ref MDValue b) … … 4467 4441 reflOp(MM.SubEq, &a, &b); 4468 4442 } 4469 4443 4470 4444 /// ditto 4471 4445 public final void muleq(ref MDValue a, ref MDValue b) … … 4539 4513 binaryReflOp(MM.AndEq, &a, &b); 4540 4514 } 4541 4515 4542 4516 /// ditto 4543 4517 public final void oreq(ref MDValue a, ref MDValue b) … … 4568 4542 { 4569 4543 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); 4570 4568 } 4571 4569 … … 4688 4686 assert(numParams >= 0, "negative num params in callPrologue"); 4689 4687 4690 MDValue* func = getAbsStack(slot);4688 MDValue* func = &mStack[slot]; 4691 4689 4692 4690 switch(func.type()) 4693 4691 { 4694 4692 case MDValue.Type.Function: 4695 closure = func. as!(MDClosure);4693 closure = func.mFunction; 4696 4694 paramSlot = slot + 1; 4697 4695 break; 4698 4696 4699 4697 case MDValue.Type.Class: 4700 MDClass cls = func. as!(MDClass);4698 MDClass cls = func.mClass; 4701 4699 MDInstance n = cls.newInstance(); 4702 4700 MDValue* ctor = cls.getCtor(); 4703 4701 4704 if(ctor !is null && ctor. isFunction())4702 if(ctor !is null && ctor.mType == MDValue.Type.Function) 4705 4703 { 4706 4704 uint thisSlot = slot + 1; … … 4709 4707 try 4710 4708 { 4711 if(callPrologue2(ctor. as!(MDClosure), thisSlot, 0, thisSlot, numParams))4709 if(callPrologue2(ctor.mFunction, thisSlot, 0, thisSlot, numParams)) 4712 4710 execute(); 4713 4711 } … … 4716 4714 catch(MDException e) 4717 4715 throw new MDRuntimeException(startTraceback(), &e.value); 4718 }4716 } 4719 4717 4720 4718 mStack[slot] = n; … … 4744 4742 4745 4743 case MDValue.Type.Thread: 4746 MDState thread = func. as!(MDState);4744 MDState thread = func.mThread; 4747 4745 4748 4746 if(thread is this) … … 4830 4828 MDValue* method = getMM(*func, MM.Call); 4831 4829 4832 if( !method.isFunction())4830 if(method.mType != MDValue.Type.Function) 4833 4831 throwRuntimeException("Attempting to call a value of type '{}'", func.typeString()); 4834 4832 4835 copyAbsStack(slot + 1, slot);4833 mStack[slot + 1] = mStack[slot]; 4836 4834 paramSlot = slot + 1; 4837 closure = method. as!(MDClosure);4835 closure = method.mFunction; 4838 4836 break; 4839 4837 } … … 4916 4914 for(int i = 0; i < funcDef.mNumParams; i++) 4917 4915 { 4918 copyAbsStack(mStackIndex, oldParamSlot);4919 getAbsStack(oldParamSlot).setNull();4916 mStack[mStackIndex] = mStack[oldParamSlot]; 4917 mStack[oldParamSlot].setNull(); 4920 4918 oldParamSlot++; 4921 4919 mStackIndex++; … … 4952 4950 4953 4951 for(int i = base + funcDef.mStackSize; i >= 0 && i >= base + numParams; i--) 4954 getAbsStack(i).setNull();4952 mStack[i].setNull(); 4955 4953 4956 4954 mCurrentAR.savedTop = mStackIndex; … … 5226 5224 } 5227 5225 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 5244 5226 protected final void moveStackFrom(MDState other, uint numValues) 5245 5227 { … … 5256 5238 } 5257 5239 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 5282 5240 protected final void close(uint index) 5283 5241 { 5284 MDValue* base = getBasedStack(index);5242 MDValue* base = &mStack[mCurrentAR.base + index]; 5285 5243 5286 5244 for(MDUpval* uv = mUpvalHead; uv !is null && uv.value >= base; uv = mUpvalHead) … … 5301 5259 protected final MDUpval* findUpvalue(uint num) 5302 5260 { 5303 MDValue* slot = getBasedStack(num);5261 MDValue* slot = &mStack[mCurrentAR.base + num]; 5304 5262 5305 5263 for(MDUpval* uv = mUpvalHead; uv !is null && uv.value >= slot; uv = uv.next) … … 5323 5281 } 5324 5282 5325 protected final int getBasedStackIndex()5326 {5327 return mStackIndex - mCurrentAR.base;5328 }5329 5330 5283 protected final MDValue* getMM(ref MDValue obj, MM method) 5331 5284 { … … 5335 5288 { 5336 5289 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) 5340 5293 goto default; 5341 5294 … … 5343 5296 5344 5297 case MDValue.Type.Instance: 5345 m = obj. as!(MDInstance)[MetaStrings[method]];5298 m = obj.mInstance[MetaStrings[method]]; 5346 5299 break; 5347 5300 … … 5356 5309 } 5357 5310 5358 if(m is null || !m.isFunction())5311 if(m is null || m.mType != MDValue.Type.Function) 5359 5312 return &MDValue.nullValue; 5360 5313 else … … 5365 5318 // Interpreter 5366 5319 // =================================================================================== 5367 5320 5368 5321 protected final MDValue binOp(MM operation, MDValue* RS, MDValue* RT) 5369 5322 { 5370 5323 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) 5375 5331 { 5332 int i1 = RS.mInt; 5333
