Changeset 172
- Timestamp:
- 05/22/07 20:53:58 (2 years ago)
- Files:
-
- trunk/mdcl.zip (modified) (previous)
- trunk/minid/compiler.d (modified) (57 diffs)
- trunk/minid/regexplib.d (modified) (3 diffs)
- trunk/minid/stringlib.d (modified) (1 diff)
- trunk/minid/types.d (modified) (2 diffs)
- trunk/test.d (modified) (1 diff)
- trunk/test.opt (modified) (previous)
- trunk/tests/compiler (added)
- trunk/tests/compiler/badshebang.md (added)
- trunk/tests/compiler/compiler.md (added)
- trunk/tests/compiler/dupimportlocals.md (added)
- trunk/tests/compiler/noimportlocals.md (added)
- trunk/tests/dummy.md (modified) (1 diff)
- trunk/tests/interpreter.md (added)
- trunk/tests/rex.md (added)
- trunk/tests/str.md (added)
- trunk/tests/tab.md (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/minid/compiler.d
r170 r172 375 375 } 376 376 377 public static char[] toString(Type type)378 {379 return utf.toUTF8(tokenStrings[type]);380 }381 382 377 public Token* expect(Type t) 383 378 { … … 458 453 459 454 char firstChar = mSource.getc(); 460 461 if(mSource.eof() == false) 455 456 if(mSource.eof()) 457 { 458 if(firstChar == char.init) 459 mCharacter = 0; 460 else 461 mCharacter = firstChar; 462 463 mEncoding = Encoding.UTF8; 464 //mCharacter = firstChar; 465 //mCharacter = 0; 466 } 467 else 462 468 { 463 469 switch(firstChar) … … 552 558 } 553 559 } 554 else 555 { 556 mEncoding = Encoding.UTF8; 557 mCharacter = 0; 558 } 559 560 560 561 if(mCharacter == '#') 561 562 { … … 834 835 catch(ConvError e) 835 836 { 837 //REACHABLE? 836 838 throw new MDCompileException(beginning, "Malformed binary int literal"); 837 839 } … … 863 865 catch(ConvError e) 864 866 { 867 //REACHABLE? 865 868 throw new MDCompileException(beginning, "Malformed octal int literal"); 866 869 } … … 875 878 nextChar(); 876 879 877 if(!isHexDigit() )880 if(!isHexDigit() && mCharacter != '_') 878 881 throw new MDCompileException(mLoc, "Hexadecimal digit expected, not '%s'", mCharacter); 879 882 … … 892 895 catch(ConvError e) 893 896 { 897 //REACHABLE? 894 898 throw new MDCompileException(beginning, "Malformed hexadecimal int literal"); 895 899 } … … 931 935 else if(mCharacter == '_') 932 936 { 937 //REACHABLE? 933 938 nextChar(); 934 939 continue; … … 946 951 nextChar(); 947 952 } 953 else if(mCharacter == '_') 954 nextChar(); 948 955 else 949 956 throw new MDCompileException(mLoc, "Floating point literal '%s' must have at least one digit after decimal point", buf[0 .. i]); … … 973 980 } 974 981 975 if(!isDecimalDigit() )982 if(!isDecimalDigit() && mCharacter != '_') 976 983 throw new MDCompileException(mLoc, "Exponent value expected in float literal '%s'", buf[0 .. i]); 977 984 … … 987 994 } 988 995 else if(mCharacter == '_') 996 { 997 nextChar(); 989 998 continue; 999 } 990 1000 else 991 1001 break; … … 1000 1010 catch(ConvError e) 1001 1011 { 1012 //REACHABLE? 1002 1013 throw new MDCompileException(beginning, "Malformed int literal '%s'", buf[0 .. i]); 1003 1014 } … … 1021 1032 catch(ConvOverflowError e) 1022 1033 { 1034 //REACHABLE? 1035 // std.conv.toDouble doesn't throw ConvOverflowErrors. 1023 1036 throw new MDCompileException(beginning, "Numeric overflow"); 1024 1037 } … … 1846 1859 public static ClassDef currentClass() 1847 1860 { 1848 if(mClassDefIndex == 0) 1849 return null; 1850 else 1851 return mCurrentClass[mClassDefIndex - 1]; 1861 assert(mClassDefIndex != 0); 1862 return mCurrentClass[mClassDefIndex - 1]; 1852 1863 } 1853 1864 … … 1957 1968 } 1958 1969 1959 public bool scopeHasUpval() 1960 { 1961 return mScope.hasUpval; 1970 public void closeUpvals(uint line) 1971 { 1972 if(mScope.hasUpval) 1973 { 1974 codeClose(line); 1975 mScope.hasUpval = false; 1976 } 1962 1977 } 1963 1978 … … 1982 1997 public int* addCase(Location location, Expression v) 1983 1998 { 1984 if(mSwitch is null) 1985 throw new MDCompileException(location, "Case statements may not exist outside of a switch"); 1999 assert(mSwitch !is null); 1986 2000 1987 2001 MDValue val; … … 2013 2027 public void addDefault(Location location) 2014 2028 { 2015 if(mSwitch is null) 2016 throw new MDCompileException(location, "Default statements may not exist outside of a switch"); 2017 2018 if(mSwitch.defaultOffset != -1) 2019 throw new MDCompileException(location, "Multiple defaults in one switch"); 2020 2029 assert(mSwitch !is null); 2030 assert(mSwitch.defaultOffset == -1); 2031 2021 2032 mSwitch.defaultOffset = mCode.length - mSwitch.switchPC - 1; 2022 2033 } … … 2841 2852 } 2842 2853 2843 public void patchTrueTo(InstRef* i, InstRef* dest)2844 {2845 for(InstRef* t = i.trueList; t !is null; )2846 {2847 patchJumpTo(t, dest);2848 2849 InstRef* next = t.trueList;2850 delete t;2851 t = next;2852 }2853 2854 i.trueList = null;2855 }2856 2857 2854 public void patchTrueToHere(InstRef* i) 2858 2855 { … … 3305 3302 default: 3306 3303 throw new MDCompileException(t.location, "Class method or field expected, not '%s'", t.toString()); 3307 break;3308 3304 } 3309 3305 } … … 3401 3397 public bool hasBase() 3402 3398 { 3403 return (mBaseClass !is null);3399 return !mBaseClass.isNull(); 3404 3400 } 3405 3401 } … … 3539 3535 mBody.codeGen(fs); 3540 3536 fs.codeI(mBody.mEndLocation.line, Op.Ret, 0, 1); 3541 3542 3537 fs.popScope(mBody.mEndLocation.line); 3543 3544 3538 s.pushClosure(fs); 3545 3539 } … … 3618 3612 s.codeGen(fs); 3619 3613 } 3620 3614 3621 3615 fs.codeI(mEndLocation.line, Op.Ret, 0, 1); 3622 3616 } … … 3682 3676 } 3683 3677 3684 public static Statement parse(ref Token* t )3678 public static Statement parse(ref Token* t, bool needScope = true) 3685 3679 { 3686 3680 Location location = t.location; … … 3701 3695 case Token.Type.Local, Token.Type.Global, Token.Type.Function, Token.Type.Class: 3702 3696 return DeclarationStatement.parse(t); 3703 3697 3704 3698 case Token.Type.LBrace: 3705 3699 CompoundStatement s = CompoundStatement.parse(t); 3706 return new ScopeStatement(s.mLocation, s.mEndLocation, s); 3700 3701 if(needScope) 3702 return new ScopeStatement(s.mLocation, s.mEndLocation, s); 3703 else 3704 return s; 3707 3705 3708 3706 case Token.Type.If: … … 4162 4160 s.popToRegisters(mEndLocation.line, reg, mNames.length); 4163 4161 4164 for(int r = reg + mNames.length ; r >= reg; r--)4162 for(int r = reg + mNames.length - 1; r >= reg; r--) 4165 4163 s.popMoveFromReg(mEndLocation.line, r); 4166 4164 } … … 4291 4289 public int opCmp(Object o) 4292 4290 { 4291 //USED? 4293 4292 Identifier other = cast(Identifier)o; 4294 4293 assert(other); … … 4315 4314 return idents[index].mName; 4316 4315 }, "."); 4317 }4318 4319 public static dchar[][] toStringArray(Identifier[] idents)4320 {4321 dchar[][] ret = new dchar[][idents.length];4322 4323 foreach(i, ident; idents)4324 ret[i] = ident.mName;4325 4326 return ret;4327 4316 } 4328 4317 … … 4502 4491 t = t.expect(Token.Type.RParen); 4503 4492 4504 Statement whileBody = Statement.parse(t );4493 Statement whileBody = Statement.parse(t, false); 4505 4494 4506 4495 return new WhileStatement(location, whileBody.mEndLocation, condition, whileBody); … … 4526 4515 InstRef* cond = mCondition.codeCondition(s); 4527 4516 s.invertJump(cond); 4528 4517 4529 4518 s.pushScope(); 4530 4519 s.patchTrueToHere(cond); … … 4533 4522 mBody.codeGen(s); 4534 4523 s.patchContinues(beginLoop); 4524 s.closeUpvals(mEndLocation.line); 4535 4525 s.codeJump(mEndLocation.line, beginLoop); 4536 4526 s.patchBreaksToHere(); … … 4580 4570 t = t.expect(Token.Type.Do); 4581 4571 4582 Statement doBody = Statement.parse(t );4572 Statement doBody = Statement.parse(t, false); 4583 4573 4584 4574 t = t.expect(Token.Type.While); … … 4615 4605 s.setContinuable(); 4616 4606 mBody.codeGen(s); 4607 s.closeUpvals(mCondition.mLocation.line); 4617 4608 s.patchContinuesToHere(); 4618 4609 InstRef* cond = mCondition.codeCondition(s); … … 4768 4759 } 4769 4760 4770 Statement forBody = Statement.parse(t );4761 Statement forBody = Statement.parse(t, false); 4771 4762 4772 4763 return new ForStatement(location, forBody.mEndLocation, init, condition, increment, forBody); … … 4777 4768 s.pushScope(); 4778 4769 s.setBreakable(); 4779 4780 s.pushScope(); 4781 s.setContinuable(); 4782 4783 foreach(init; mInit) 4770 s.setContinuable(); 4771 4772 foreach(init; mInit) 4773 { 4774 if(init.isDecl) 4775 init.decl.codeGen(s); 4776 else 4784 4777 { 4785 if(init.isDecl) 4786 init.decl.codeGen(s); 4787 else 4788 { 4789 init.init.codeGen(s); 4790 s.popToNothing(); 4791 } 4792 } 4793 4794 InstRef* beginLoop = s.getLabel(); 4795 4796 InstRef* cond; 4797 4798 if(mCondition) 4799 { 4800 cond = mCondition.codeCondition(s); 4801 s.invertJump(cond); 4802 s.patchTrueToHere(cond); 4803 } 4804 4805 mBody.codeGen(s); 4806 4807 s.patchContinuesToHere(); 4808 4809 if(s.scopeHasUpval()) 4810 s.codeClose(mLocation.line); 4811 4812 foreach(inc; mIncrement) 4813 { 4814 inc.codeGen(s); 4778 init.init.codeGen(s); 4815 4779 s.popToNothing(); 4816 4780 } 4817 s.popScope(mEndLocation.line); 4781 } 4782 4783 InstRef* beginLoop = s.getLabel(); 4784 InstRef* cond; 4785 4786 if(mCondition) 4787 { 4788 cond = mCondition.codeCondition(s); 4789 s.invertJump(cond); 4790 s.patchTrueToHere(cond); 4791 } 4792 4793 mBody.codeGen(s); 4794 4795 s.closeUpvals(mLocation.line); 4796 s.patchContinuesToHere(); 4797 4798 foreach(inc; mIncrement) 4799 { 4800 inc.codeGen(s); 4801 s.popToNothing(); 4802 } 4818 4803 4819 4804 s.codeJump(mEndLocation.line, beginLoop); … … 4899 4884 public override void codeGen(FuncState s) 4900 4885 { 4886 uint baseReg = s.nextRegister(); 4887 uint loIndex; 4888 uint hi; 4889 uint step; 4890 4901 4891 s.pushScope(); 4902 4892 s.setBreakable(); 4903 4893 s.setContinuable(); 4904 4905 uint baseReg = s.nextRegister();4906 uint loIndex;4907 uint hi;4908 uint step;4909 4894 4910 4895 loIndex = s.nextRegister(); … … 4925 4910 InstRef* beginJump = s.makeFor(mLocation.line, baseReg); 4926 4911 InstRef* beginLoop = s.getLabel(); 4927 4928 s.pushScope(); 4929 s.insertLocal(mIndex); 4930 s.activateLocals(1); 4931 mBody.codeGen(s); 4932 s.popScope(mEndLocation.line); 4912 4913 s.insertLocal(mIndex); 4914 s.activateLocals(1); 4915 4916 mBody.codeGen(s); 4917 4918 s.closeUpvals(mEndLocation.line); 4919 s.patchContinuesToHere(); 4933 4920 4934 4921 s.patchJumpToHere(beginJump); 4935 4922 delete beginJump; 4936 4923 4937 s.patchContinuesToHere();4938 4939 4924 InstRef* gotoBegin = s.makeForLoop(mEndLocation.line, baseReg); 4940 4925 s.patchJumpTo(gotoBegin, beginLoop); … … 4944 4929 4945 4930 s.patchBreaksToHere(); 4946 4947 s.popRegister(step);4948 s.popRegister(hi);4949 s.popRegister(loIndex);4950 4931 s.popScope(mEndLocation.line); 4932 4933 s.popRegister(step); 4934 s.popRegister(hi); 4935 s.popRegister(loIndex); 4951 4936 } 4952 4937 … … 5117 5102 InstRef* beginLoop = s.getLabel(); 5118 5103 5119 s.pushScope(); 5120 foreach(Identifier i; mIndices) 5121 s.insertLocal(i); 5122 5123 s.activateLocals(mIndices.length); 5124 mBody.codeGen(s); 5125 s.popScope(mEndLocation.line); 5104 foreach(Identifier i; mIndices) 5105 s.insertLocal(i); 5106 5107 s.activateLocals(mIndices.length); 5108 mBody.codeGen(s); 5126 5109 5127 5110 s.patchJumpToHere(beginJump); 5128 5111 delete beginJump; 5129 5112 5113 s.closeUpvals(mEndLocation.line); 5130 5114 s.patchContinuesToHere(); 5131 5132 5115 s.codeI(mEndLocation.line, Op.Foreach, baseReg, mIndices.length); 5133 5116 InstRef* gotoBegin = s.makeJump(mEndLocation.line, Op.Je); … … 5138 5121 5139 5122 s.patchBreaksToHere(); 5140 5141 s.popRegister(control);5142 s.popRegister(invState);5143 s.popRegister(generator);5144 5123 s.popScope(mEndLocation.line); 5124 5125 s.popRegister(control); 5126 s.popRegister(invState); 5127 s.popRegister(generator); 5145 5128 } 5146 5129 … … 5778 5761 exp = new OpEqExp(location, location, Op.SubEq, exp, new IntExp(location, 1)); 5779 5762 } 5763 else if(t.type == Token.Type.OrOr) 5764 exp = OrOrExp.parse(t, exp); 5765 else if(t.type == Token.Type.AndAnd) 5766 exp = AndAndExp.parse(t, exp); 5780 5767 } 5781 5768 … … 5787 5774 public static Expression[] parseArguments(ref Token* t) 5788 5775 { 5789 Expression[] args = new Expression[5]; 5790 uint i = 0; 5791 5792 void add(Expression arg) 5793 { 5794 if(i >= args.length) 5795 args.length = args.length * 2; 5796 5797 args[i] = arg; 5798 i++; 5799 } 5800 5801 add(Expression.parse(t)); 5776 List!(Expression) args; 5777 args.add(Expression.parse(t)); 5802 5778 5803 5779 while(t.type == Token.Type.Comma) 5804 5780 { 5805 5781 t = t.nextToken; 5806 add(Expression.parse(t)); 5807 } 5808 5809 args.length = i; 5810 return args; 5782 args.add(Expression.parse(t)); 5783 } 5784 5785 return args.toArray(); 5811 5786 } 5812 5787 … … 5855 5830 public void codeGen(FuncState s) 5856 5831 { 5857 assert(false, "unimplemented codeGen ");5832 assert(false, "unimplemented codeGen: " ~ this.classinfo.name); 5858 5833 } 5859 5834 5860 5835 public InstRef* codeCondition(FuncState s) 5861 5836 { 5862 assert(false, "unimplemented codeCondition ");5837 assert(false, "unimplemented codeCondition: " ~ this.classinfo.name); 5863 5838 } 5864 5839 5865 5840 public void checkToNothing() 5866 5841 { 5842 //REACHABLE? 5867 5843 throw new MDCompileException(mLocation, "Expression cannot exist on its own"); 5868 5844 } … … 5980 5956 t = t.expect(Token.Type.Assign); 5981 5957 5982 rhs = OrOrExp.parse(t);5958 rhs = Expression.parse(t); 5983 5959 5984 5960 foreach(exp; lhs) … … 6016 5992 public override InstRef* codeCondition(FuncState s) 6017 5993 { 5994 //REACHABLE? 6018 5995 throw new MDCompileException(mLocation, "Assignments cannot be used as a condition"); 6019 5996 } … … 6287 6264 } 6288 6265 6289 public static Expression parse(ref Token* t )6266 public static Expression parse(ref Token* t, Expression exp1 = null) 6290 6267 { 6291 6268 Location location = t.location; 6292 6269 6293 Expression exp1;6294 6270 Expression exp2; 6295 6271 6296 exp1 = AndAndExp.parse(t); 6272 if(exp1 is null) 6273 exp1 = AndAndExp.parse(t); 6297 6274 6298 6275 while(t.type == Token.Type.OrOr) … … 6368 6345 } 6369 6346 6370 public static Expression parse(ref Token* t )6347 public static Expression parse(ref Token* t, Expression exp1 = null) 6371 6348 { 6372 6349 Location location = t.location; 6373 6350 6374 Expression exp1;6375 6351 Expression exp2; 6376 6352 6377 exp1 = OrExp.parse(t); 6353 if(exp1 is null) 6354 exp1 = OrExp.parse(t); 6378 6355 6379 6356 while(t.type == Token.Type.AndAnd) … … 8112 8089 } 8113 8090 8114 public InstRef* codeCondition(FuncState s)8115 {8116 return s.makeJump(mEndLocation.line, Op.Jmp);8117 }8118 8119 8091 public override bool isConstant() 8120 8092 { … … 8162 8134 } 8163 8135 8164 public InstRef* codeCondition(FuncState s)8165 {8166 return s.makeJump(mEndLocation.line, Op.Jmp, mValue);8167 }8168 8169 8136 public override bool isConstant() 8170 8137 { … … 8248 8215 } 8249 8216 8250 public InstRef* codeCondition(FuncState s)8251 {8252 uint temp = s.pushRegister();8253 codeGen(s);8254 s.popMoveTo(mEndLocation.line, temp);8255 s.codeR(mEndLocation.line, Op.IsTrue, 0, temp, 0);8256 InstRef* ret = s.makeJump(mEndLocation.line, Op.Je);8257 s.popRegister(temp);8258 return ret;8259 }8260 8261 8217 public override bool isConstant() 8262 8218 { … … 8264 8220 } 8265 8221 8222 public override bool isTrue() 8223 { 8224 return (mValue != 0); 8225 } 8226 8266 8227 public override bool isChar() 8267 8228 { … … 8302 8263 } 8303 8264 8304 public InstRef* codeCondition(FuncState s)8305 {8306 uint temp = s.pushRegister();8307 codeGen(s);8308 s.popMoveTo(mEndLocation.line, temp);8309 s.codeR(mEndLocation.line, Op.IsTrue, 0, temp, 0);8310 InstRef* ret = s.makeJump(mEndLocation.line, Op.Je);8311 s.popRegister(temp);8312 return ret;8313 }8314 8315 8265 public override bool isConstant() 8316 8266 { … … 8365 8315 } 8366 8316 8367 public InstRef* codeCondition(FuncState s)8368 {8369 throw new MDCompileException(mLocation, "Cannot use a float literal as a condition");8370 }8371 8372 8317 public override bool isConstant() 8373 8318 { … … 8417 8362 } 8418 8363 8419 public InstRef* codeCondition(FuncState s)8420 {8421 throw new MDCompileException(mLocation, "Cannot use a string literal as a condition");8422 }8423 8424 8364 public override bool isConstant() 8425 8365 { … … 8568 8508 s.pushTempReg(reg); 8569 8509 } 8510 8511 public override InstRef* codeCondition(FuncState s) 8512 { 8513 uint temp = s.nextRegister(); 8514 mExp.codeGen(s); 8515 s.popMoveTo(mEndLocation.line, temp); 8516 s.codeR(mEndLocation.line, Op.IsTrue, 0, temp, 0); 8517 InstRef* ret = s.makeJump(mEndLocation.line, Op.Je); 8518 return ret; 8519 } 8570 8520 } 8571 8521 … … 8590 8540 t = t.expect(Token.Type.LBrace); 8591 8541 8592 Expression[2][] fields = new Expression[2][ 2];8542 Expression[2][] fields = new Expression[2][8]; 8593 8543 uint i = 0; 8594 8544 … … 8675 8625 t = t.expect(Token.Type.LBrace); 8676 8626 8677 Expression[2][] fields = new Expression[2][ 2];8627 Expression[2][] fields = new Expression[2][8]; 8678 8628 uint i = 0; 8679 8629 … … 8826 8776 public override void codeGen(FuncState s) 8827 8777 { 8828 if(mFields.length > maxFields)8778 if(mFields.length >= maxFields) 8829 8779 throw new MDCompileException(mLocation, "Array constructor has too many fields (more than %s)", maxFields); 8830 8780 trunk/minid/regexplib.d
r167 r172 183 183 } 184 184 185 protected MDRegexp newInstance(RegExp rxp)186 {187 MDRegexp n = newInstance();188 n.constructor(rxp);189 return n;190 }191 192 185 public int test(MDState s, uint numParams) 193 186 { … … 218 211 return 1; 219 212 } 220 213 221 214 public int pre(MDState s, uint numParams) 222 215 { … … 302 295 return mRegexp.match(n); 303 296 } 304 297 305 298 char[] pre() 306 299 { trunk/minid/stringlib.d
r140 r172 98 98 int icompare(MDState s, uint numParams) 99 99 { 100 char[] src1 = s.getContext!(char[]); 101 char[] src2 = s.getParam!(char[])(0); 102 103 s.push(s.safeCode(string.icmp(src1, src2))); 100 s.push(string.icmp(s.getContext!(char[]), s.getParam!(char[])(0))); 104 101 return 1; 105 102 } trunk/minid/types.d
r170 r172 530 530 { 531 531 return (mType == Type.Null) || (mType == Type.Bool && mBool == false) || 532 (mType == Type.Int && mInt == 0) || (mType == Type.Float && mFloat == 0.0) ;532 (mType == Type.Int && mInt == 0) || (mType == Type.Float && mFloat == 0.0) || (mType == Type.Char && mChar != 0); 533 533 } 534 534 … … 986 986 if(o1.mType == o2.mType) 987 987 return o1.opCmp(o2); 988 else989 throw new MDException("Attempting to compare unlike objects");990 }991 992 public static int equals(MDObject o1, MDObject o2)993 {994 if(o1.mType == o2.mType)995 return o1.opEquals(o2);996 988 else 997 989 throw new MDException("Attempting to compare unlike objects"); trunk/test.d
r168 r172 16 16 MDFileLoader().addPath(`samples`); 17 17 18 MDGlobalState().importModule(" simple");18 MDGlobalState().importModule("tests.interpreter"); 19 19 } 20 20 catch(MDException e) trunk/tests/dummy.md
r170 r172 1 1 module tests.dummy; 2 3 global XXX = 5; 4 global YYY = 10;
