Changeset 159
- Timestamp:
- 04/13/07 23:52:22 (2 years ago)
- Files:
-
- trunk/mdcl.zip (modified) (previous)
- trunk/minid/baselib.d (modified) (3 diffs)
- trunk/minid/compiler.d (modified) (93 diffs)
- trunk/minid/minid.d (modified) (3 diffs)
- trunk/minid/opcodes.d (modified) (7 diffs)
- trunk/minid/types.d (modified) (52 diffs)
- trunk/minid/utils.d (modified) (24 diffs)
- trunk/minid2.txt (modified) (4 diffs)
- trunk/samples/simple.md (modified) (3 diffs)
- trunk/test.d (modified) (1 diff)
- trunk/test.opt (modified) (previous)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/minid/baselib.d
r147 r159 428 428 } 429 429 430 int classof(MDState s, uint numParams)431 {432 s.push(s.getParam!(MDInstance)(0).getClass());433 return 1;434 }435 436 430 int mdtoString(MDState s, uint numParams) 437 431 { … … 442 436 int getTraceback(MDState s, uint numParams) 443 437 { 444 s.push(new MDString( s.getTracebackString()));438 s.push(new MDString(MDState.getTracebackString())); 445 439 return 1; 446 440 } … … 713 707 setGlobal("getTraceback"d, newClosure(&lib.getTraceback, "getTraceback")); 714 708 setGlobal("typeof"d, newClosure(&lib.mdtypeof, "typeof")); 715 setGlobal("classof"d, newClosure(&lib.classof, "classof"));716 709 setGlobal("fieldsOf"d, newClosure(&lib.fieldsOf, "fieldsOf")); 717 710 setGlobal("methodsOf"d, newClosure(&lib.methodsOf, "methodsOf")); trunk/minid/compiler.d
r133 r159 109 109 Null, 110 110 Return, 111 Super, 111 112 Switch, 112 113 This, … … 203 204 Type.Null: "null", 204 205 Type.Return: "return", 206 Type.Super: "super", 205 207 Type.Switch: "switch", 206 208 Type.This: "this", … … 299 301 stringToType["null"] = Type.Null; 300 302 stringToType["return"] = Type.Return; 303 stringToType["super"] = Type.Super; 301 304 stringToType["switch"] = Type.Switch; 302 305 stringToType["this"] = Type.This; … … 324 327 public char[] toString() 325 328 { 326 char[] ret;327 328 329 switch(type) 329 330 { 330 case Type.Ident: 331 ret = "Identifier: " ~ utf.toUTF8(stringValue); 332 break; 333 334 case Type.CharLiteral: 335 ret = "Character Literal"; 336 break; 337 338 case Type.StringLiteral: 339 ret = "String Literal"; 340 break; 341 342 case Type.IntLiteral: 343 ret = "Integer Literal: " ~ string.toString(intValue); 344 break; 345 346 case Type.FloatLiteral: 347 ret = "Float Literal: " ~ string.toString(floatValue); 348 break; 349 350 default: 351 ret = utf.toUTF8(tokenStrings[cast(uint)type]); 352 break; 353 } 354 355 return ret; 331 case Type.Ident: return "Identifier: " ~ utf.toUTF8(stringValue); 332 case Type.CharLiteral: return "Character Literal"; 333 case Type.StringLiteral: return "String Literal"; 334 case Type.IntLiteral: return "Integer Literal: " ~ string.toString(intValue); 335 case Type.FloatLiteral: return "Float Literal: " ~ string.toString(floatValue); 336 default: return utf.toUTF8(tokenStrings[cast(uint)type]); 337 } 356 338 } 357 339 … … 361 343 } 362 344 363 public void check(Type t)345 public Token* expect(Type t) 364 346 { 365 347 if(type != t) 366 348 throw new MDCompileException(location, "'%s' expected; found '%s' instead", tokenStrings[t], tokenStrings[type]); 349 350 return nextToken; 367 351 } 368 352 … … 1732 1716 protected uint[] mLineInfo; 1733 1717 protected dchar[] mGuessedName; 1718 protected bool mIsMethod; 1734 1719 1735 1720 struct LocVarDesc … … 1754 1739 struct SwitchDesc 1755 1740 { 1756 bool isString;1757 1741 uint switchPC; 1758 1759 union 1760 { 1761 int[int] intOffsets; 1762 int[dchar[]] stringOffsets; 1763 } 1764 1742 int[MDValue] offsets; 1765 1743 int defaultOffset = -1; 1766 1744 … … 1772 1750 // ..and are then transfered to this array when they are done. 1773 1751 protected SwitchDesc*[] mSwitchTables; 1774 1775 public this(Location location, dchar[] guessedName, FuncState parent = null) 1752 1753 protected static ClassDef[] mCurrentClass; 1754 protected static uint mClassDefIndex = 0; 1755 1756 public static void enterClass(ClassDef def) 1757 { 1758 if(mClassDefIndex >= mCurrentClass.length) 1759 mCurrentClass.length = mCurrentClass.length + 3; 1760 1761 mCurrentClass[mClassDefIndex] = def; 1762 mClassDefIndex++; 1763 } 1764 1765 public static void leaveClass() 1766 { 1767 assert(mClassDefIndex != 0, "Number of classes underflow"); 1768 mClassDefIndex--; 1769 } 1770 1771 public static ClassDef currentClass() 1772 { 1773 if(mClassDefIndex == 0) 1774 return null; 1775 else 1776 return mCurrentClass[mClassDefIndex - 1]; 1777 } 1778 1779 public this(Location location, dchar[] guessedName, FuncState parent = null, bool isMethod = false) 1776 1780 { 1777 1781 mLocation = location; 1778 1782 mGuessedName = guessedName; 1783 mIsMethod = isMethod; 1779 1784 1780 1785 mParent = parent; … … 1790 1795 activateLocals(1); 1791 1796 } 1797 } 1798 1799 public bool isMethod() 1800 { 1801 return mIsMethod; 1792 1802 } 1793 1803 … … 1877 1887 } 1878 1888 1879 public void beginS tringSwitch(uint line, uint srcReg)1889 public void beginSwitch(uint line, uint srcReg) 1880 1890 { 1881 1891 SwitchDesc* sd = new SwitchDesc; 1882 sd.switchPC = codeR(line, Op.SwitchString, 0, srcReg, 0); 1883 sd.isString = true; 1884 1892 sd.switchPC = codeR(line, Op.Switch, 0, srcReg, 0); 1885 1893 sd.prev = mSwitch; 1886 mSwitch = sd; 1887 } 1888 1889 public void beginIntSwitch(uint line, uint srcReg) 1890 { 1891 SwitchDesc* sd = new SwitchDesc; 1892 sd.switchPC = codeR(line, Op.SwitchInt, 0, srcReg, 0); 1893 sd.isString = false; 1894 1895 sd.prev = mSwitch; 1894 1896 1895 mSwitch = sd; 1897 1896 } … … 1907 1906 } 1908 1907 1909 public void add Case(Expression exp)1908 public void addNullCase(Location location) 1910 1909 { 1911 1910 assert(mSwitch !is null, "adding case outside of a switch"); 1912 1913 IntExp intExp = cast(IntExp)exp; 1914 1915 if(intExp) 1916 { 1917 if(mSwitch.isString == true) 1918 throw new MDCompileException(exp.mLocation, "Case value must be a string literal"); 1919 1920 int* oldOffset = (intExp.mValue in mSwitch.intOffsets); 1921 1922 if(oldOffset !is null) 1923 throw new MDCompileException(exp.mLocation, "Duplicate case value '%s'", intExp.mValue); 1924 1925 mSwitch.intOffsets[intExp.mValue] = mCode.length - mSwitch.switchPC - 1; 1926 1927 return; 1928 } 1929 1930 StringExp stringExp = cast(StringExp)exp; 1931 1932 assert(stringExp, "added case is neither int nor string"); 1933 1934 if(mSwitch.isString == false) 1935 throw new MDCompileException(exp.mLocation, "Case value must be an integer literal"); 1936 1937 int* oldOffset = (stringExp.mValue in mSwitch.stringOffsets); 1911 int* oldOffset = (MDValue.nullValue in mSwitch.offsets); 1938 1912 1939 1913 if(oldOffset !is null) 1940 throw new MDCompileException(exp.mLocation, "Duplicate case value '%s'", stringExp.mValue); 1941 1942 mSwitch.stringOffsets[stringExp.mValue] = mCode.length - mSwitch.switchPC - 1; 1943 } 1944 1945 public void addDefault() 1946 { 1947 assert(mSwitch !is null, "adding default outside of a switch"); 1948 assert(mSwitch.defaultOffset == -1, "tried to add a second default"); 1914 throw new MDCompileException(location, "Duplicate case value 'null'"); 1915 1916 mSwitch.offsets[MDValue.nullValue] = mCode.length - mSwitch.switchPC - 1; 1917 } 1918 1919 public void addCase(T)(Location location, T v) 1920 { 1921 if(mSwitch is null) 1922 throw new MDCompileException(location, "Case statements may not exist outside of a switch"); 1923 1924 MDValue val = v; 1925 1926 int* oldOffset = (val in mSwitch.offsets); 1927 1928 if(oldOffset !is null) 1929 throw new MDCompileException(location, "Duplicate case value '%s'", v); 1930 1931 mSwitch.offsets[val] = mCode.length - mSwitch.switchPC - 1; 1932 } 1933 1934 public void addDefault(Location location) 1935 { 1936 if(mSwitch is null) 1937 throw new MDCompileException(location, "Default statements may not exist outside of a switch"); 1938 1939 if(mSwitch.defaultOffset != -1) 1940 throw new MDCompileException(location, "Multiple defaults in one switch"); 1949 1941 1950 1942 mSwitch.defaultOffset = mCode.length - mSwitch.switchPC - 1; … … 3001 2993 foreach(uint i, inout SwitchDesc* t; mSwitchTables) 3002 2994 { 3003 writef(string.repeat("\t", tab + 1), "Switch Table ", i); 3004 3005 if(t.isString) 3006 { 3007 writefln(" - String"); 3008 3009 foreach(dchar[] index; t.stringOffsets.keys.sort) 3010 writefln(string.repeat("\t", tab + 2), "\"%s\" => %s", index, t.stringOffsets[index]); 3011 } 3012 else 3013 { 3014 writefln(" - Int"); 3015 3016 foreach(int index; t.intOffsets.keys.sort) 3017 writefln(string.repeat("\t", tab + 2), "%s => %s", index, t.intOffsets[index]); 3018 } 2995 writefln(string.repeat("\t", tab + 1), "Switch Table ", i); 2996 2997 foreach(index; t.offsets.keys) 2998 writefln(string.repeat("\t", tab + 2), "%s => %s", index, t.offsets[index]); 3019 2999 3020 3000 writefln(string.repeat("\t", tab + 2), "Default: ", t.defaultOffset); … … 3103 3083 with(*mSwitchTables[i]) 3104 3084 { 3105 ret.mSwitchTables[i].isString = isString; 3106 3107 if(isString) 3108 ret.mSwitchTables[i].stringOffsets = stringOffsets; 3109 else 3110 ret.mSwitchTables[i].intOffsets = intOffsets; 3111 3085 ret.mSwitchTables[i].offsets = offsets; 3112 3086 ret.mSwitchTables[i].defaultOffset = defaultOffset; 3113 3087 } … … 3147 3121 } 3148 3122 3149 public static void parseBody(Location location, inout Token* t, out FuncDef[] methods, out Field[] fields, out Location endLocation) 3150 { 3151 t.check(Token.Type.LBrace); 3152 t = t.nextToken; 3153 3154 methods = new FuncDef[10]; 3155 int iMethod = 0; 3123 public static void parseBody(Location location, inout Token* t, out FuncDef[] oMethods, out Field[] oFields, out Location oEndLocation) 3124 { 3125 t = t.expect(Token.Type.LBrace); 3126 3127 FuncDef[dchar[]] methods; 3156 3128 3157 3129 void addMethod(FuncDef m) 3158 3130 { 3159 if(iMethod >= methods.length) 3160 methods.length = methods.length * 2; 3161 3162 methods[iMethod] = m; 3163 iMethod++; 3164 } 3165 3166 fields = new Field[10]; 3167 int iField = 0; 3168 3169 void addField(dchar[] name, Expression v) 3170 { 3171 if(iField >= fields.length) 3172 fields.length = fields.length * 2; 3173 3174 fields[iField].name = name; 3175 fields[iField].initializer = v; 3176 3177 iField++; 3131 dchar[] name = m.mName.mName; 3132 3133 if(name in methods) 3134 throw new MDCompileException(m.mLocation, "Redeclaration of method '%s'", name); 3135 3136 methods[name] = m; 3137 } 3138 3139 Expression[dchar[]] fields; 3140 3141 void addField(Identifier name, Expression v) 3142 { 3143 if(name.mName in fields) 3144 throw new MDCompileException(name.mLocation, "Redeclaration of field '%s'", name.mName); 3145 3146 fields[name.mName] = v; 3178 3147 } 3179 3148 … … 3182 3151 switch(t.type) 3183 3152 { 3153 case Token.Type.This: 3154 Location ctorLocation = t.location; 3155 Identifier name = new Identifier("constructor", t.location); 3156 t = t.nextToken; 3157 3158 bool isVararg; 3159 Identifier[] params = FuncDef.parseParams(t, isVararg); 3160 3161 CompoundStatement funcBody = CompoundStatement.parse(t); 3162 addMethod(new FuncDef(ctorLocation, funcBody.mEndLocation, params, isVararg, funcBody, name)); 3163 break; 3164 3184 3165 case Token.Type.Function: 3185 3166 addMethod(FuncDef.parseSimple(t)); … … 3199 3180 v = new NullExp(id.mLocation); 3200 3181 3201 dchar[] name = id.mName; 3202 3203 t.check(Token.Type.Semicolon); 3204 t = t.nextToken; 3205 3206 addField(name, v); 3182 t = t.expect(Token.Type.Semicolon); 3183 addField(id, v); 3207 3184 break; 3208 3185 … … 3211 3188 3212 3189 default: 3190 throw new MDCompileException(t.location, "Class method or field expected, not '%s'", t.toString()); 3213 3191 break; 3214 3192 } 3215 3193 } 3216 3194 3217 methods.length = iMethod; 3218 fields.length = iField; 3219 3220 if(t.type != Token.Type.RBrace) 3221 throw new MDCompileException(t.location, "Class at ", location.toString(), " is missing its closing brace"); 3222 3223 endLocation = t.location; 3224 3195 oMethods = methods.values; 3196 3197 oFields.length = fields.length; 3198 3199 uint i = 0; 3200 3201 foreach(name, initializer; fields) 3202 { 3203 oFields[i].name = name; 3204 oFields[i].initializer = initializer; 3205 i++; 3206 } 3207 3208 t.expect(Token.Type.RBrace); 3209 oEndLocation = t.location; 3225 3210 t = t.nextToken; 3226 3211 } … … 3251 3236 uint nameConst = s.tagConst(s.codeStringConst(mName.mName)); 3252 3237 s.codeR(mLocation.line, Op.Class, destReg, nameConst, base.index); 3238 3239 FuncState.enterClass(this); 3253 3240 3254 3241 foreach(Field field; mFields) … … 3269 3256 uint index = s.tagConst(s.codeStringConst(method.mName.mName)); 3270 3257 3271 method.codeGen(s );3258 method.codeGen(s, true); 3272 3259 Exp val; 3273 3260 s.popSource(method.mEndLocation.line, val); … … 3277 3264 s.freeExpTempRegs(&val); 3278 3265 } 3266 3267 FuncState.leaveClass(); 3279 3268 3280 3269 s.pushTempReg(destReg); … … 3293 3282 return this; 3294 3283 } 3284 3285 public bool hasBase() 3286 { 3287 return (mBaseClass !is null); 3288 } 3295 3289 } 3296 3290 … … 3318 3312 Location location = t.location; 3319 3313 3320 t.check(Token.Type.Function); 3321 t = t.nextToken; 3314 t = t.expect(Token.Type.Function); 3322 3315 3323 3316 Identifier name = Identifier.parse(t); … … 3335 3328 Location location = t.location; 3336 3329 3337 t.check(Token.Type.Function); 3338 t = t.nextToken; 3330 t = t.expect(Token.Type.Function); 3339 3331 3340 3332 Identifier name; … … 3364 3356 ret ~= new Identifier("this", t.location); 3365 3357 3366 t.check(Token.Type.LParen); 3367 t = t.nextToken; 3368 3358 t = t.expect(Token.Type.LParen); 3359 3369 3360 if(t.type == Token.Type.Vararg) 3370 3361 { … … 3388 3379 break; 3389 3380 3390 t.check(Token.Type.Comma); 3391 t = t.nextToken; 3381 t = t.expect(Token.Type.Comma); 3392 3382 } 3393 3383 } 3394 3384 3395 t.check(Token.Type.RParen); 3396 t = t.nextToken; 3397 3385 t = t.expect(Token.Type.RParen); 3398 3386 return ret; 3399 3387 } 3400 3388 3401 public void codeGen(FuncState s )3402 { 3403 FuncState fs = new FuncState(mLocation, mName.mName, s );3389 public void codeGen(FuncState s, bool isMethod = false) 3390 { 3391 FuncState fs = new FuncState(mLocation, mName.mName, s, isMethod); 3404 3392 3405 3393 fs.mIsVararg = mIsVararg; … … 3448 3436 ModuleDeclaration modDecl = ModuleDeclaration.parse(t); 3449 3437 3450 Statement[] statements = new Statement[32]; 3451 uint i = 0; 3438 List!(Statement) statements; 3452 3439 3453 3440 bool[dchar[][]] imports; 3454 3455 void add(Statement s)3456 {3457 if(i >= statements.length)3458 statements.length = statements.length * 2;3459 3460 statements[i] = s;3461 i++;3462 }3463 3441 3464 3442 void addImport(ImportStatement imp) … … 3472 3450 addImport(ImportStatement.parse(t)); 3473 3451 else 3474 add(Statement.parse(t)); 3475 } 3476 3477 t.check(Token.Type.EOF); 3478 3479 statements.length = i; 3480 3481 return new Module(location, t.location, modDecl, imports.keys.sort, statements); 3452 statements.add(Statement.parse(t)); 3453 } 3454 3455 t.expect(Token.Type.EOF); 3456 3457 return new Module(location, t.location, modDecl, imports.keys.sort, statements.toArray()); 3482 3458 } 3483 3459 … … 3539 3515 public static ModuleDeclaration parse(inout Token* t) 3540 3516 { 3541 t.check(Token.Type.Module); 3542 t = t.nextToken; 3543 3517 t = t.expect(Token.Type.Module); 3518 3544 3519 Identifier[] names; 3545 3520 names ~= Identifier.parse(t); … … 3551 3526 } 3552 3527 3553 t.check(Token.Type.Semicolon); 3554 t = t.nextToken; 3555 3528 t = t.expect(Token.Type.Semicolon); 3529 3556 3530 return new ModuleDeclaration(names); 3557 3531 } … … 3576 3550 { 3577 3551 case 3578 Token.Type.CharLiteral,3579 3552 Token.Type.Dec, 3580 Token.Type.Dot,3581 Token.Type.False,3582 Token.Type.FloatLiteral,3583 3553 Token.Type.Ident, 3584 3554 Token.Type.Inc, 3585 Token.Type.IntLiteral,3586 3555 Token.Type.LParen, 3587 Token.Type.Null, 3588 Token.Type.StringLiteral, 3589 Token.Type.Sub, 3556 Token.Type.Super, 3590 3557 Token.Type.This, 3591 Token.Type.True,3592 3558 Token.Type.Yield: 3593 3559 … … 3618 3584 case Token.Type.Switch: 3619 3585 return SwitchStatement.parse(t); 3620 3586 3621 3587 case Token.Type.Case: 3622 3588 return CaseStatement.parse(t); … … 3674 3640 Location location = t.location; 3675 3641 3676 t.check(Token.Type.Import); 3677 t = t.nextToken; 3678 3642 t = t.expect(Token.Type.Import); 3643 3679 3644 Identifier[] names; 3680 3645 names ~= Identifier.parse(t); … … 3686 3651 } 3687 3652 3688 t. check(Token.Type.Semicolon);3653 t.expect(Token.Type.Semicolon); 3689 3654 Location endLocation = t.location; 3690 3655 t = t.nextToken; … … 3738 3703 Expression exp = Expression.parseStatement(t); 3739 3704 3740 t. check(Token.Type.Semicolon);3705 t.expect(Token.Type.Semicolon); 3741 3706 Location endLocation = t.location; 3742 3707 t = t.nextToken; … … 3820 3785 VarDecl ret = VarDecl.parse(t); 3821 3786 3822 t.check(Token.Type.Semicolon); 3823 t = t.nextToken; 3787 t = t.expect(Token.Type.Semicolon); 3824 3788 3825 3789 return ret; … … 3837 3801 return ClassDecl.parse(t); 3838 3802 else 3839 throw new MDCompileException(location, "Declaration expected ");3803 throw new MDCompileException(location, "Declaration expected, not '%s'", t.toString()); 3840 3804 } 3841 3805 … … 3876 3840 t = t.nextToken; 3877 3841 3878 t.check(Token.Type.Class); 3879 t = t.nextToken; 3842 t = t.expect(Token.Type.Class); 3880 3843 3881 3844 Identifier name = Identifier.parse(t); … … 3908 3871 3909 3872 mDef.codeGen(s); 3873 3910 3874 s.popAssign(mEndLocation.line); 3911 3875 } … … 3943 3907 } 3944 3908 else 3945 { 3946 t.check(Token.Type.Local); 3947 t = t.nextToken; 3948 } 3909 t = t.expect(Token.Type.Local); 3949 3910 3950 3911 Identifier[] names; … … 4144 4105 public static Identifier parse(inout Token* t) 4145 4106 { 4146 t.check(Token.Type.Ident); 4147 4107 t.expect(Token.Type.Ident); 4148 4108 Identifier id = new Identifier(t.stringValue, t.location); 4149 4109 t = t.nextToken; … … 4193 4153 Location location = t.location; 4194 4154 4195 t.check(Token.Type.LBrace); 4196 t = t.nextToken; 4197 4198 Statement[] statements = new Statement[10]; 4199 int i = 0; 4200 4201 void addStatement(Statement s) 4202 { 4203 if(i >= statements.length) 4204 statements.length = statements.length * 2; 4205 4206 statements[i] = s; 4207 i++; 4208 } 4155 t = t.expect(Token.Type.LBrace); 4156 4157 List!(Statement) statements; 4209 4158 4210 4159 while(t.type != Token.Type.RBrace) 4211 addStatement(Statement.parse(t)); 4212 4213 statements.length = i; 4214 4215 t.check(Token.Type.RBrace); 4160 statements.add(Statement.parse(t)); 4161 4162 t.expect(Token.Type.RBrace); 4216 4163 Location endLocation = t.location; 4217 4164 t = t.nextToken; 4218 4165 4219 return new CompoundStatement(location, endLocation, statements );4166 return new CompoundStatement(location, endLocation, statements.toArray()); 4220 4167 } 4221 4168 … … 4254 4201 Location location = t.location; 4255 4202 4256 t.check(Token.Type.If); 4257 t = t.nextToken; 4258 t.check(Token.Type.LParen); 4259 t = t.nextToken; 4203 t = t.expect(Token.Type.If); 4204 t = t.expect(Token.Type.LParen); 4260 4205 4261 4206 Expression condition = Expression.parse(t); 4262 4207 4263 t.check(Token.Type.RParen); 4264 t = t.nextToken; 4208 t = t.expect(Token.Type.RParen); 4265 4209 4266 4210 Statement ifBody = Statement.parse(t); … … 4357 4301 Location location = t.location; 4358 4302 4359 t.check(Token.Type.While); 4360 t = t.nextToken; 4361 t.check(Token.Type.LParen); 4362 t = t.nextToken; 4303 t = t.expect(Token.Type.While); 4304 t = t.expect(Token.Type.LParen); 4363 4305 4364 4306 Expression condition = Expression.parse(t); 4365 4307 4366 t.check(Token.Type.RParen); 4367 t = t.nextToken; 4308 t = t.expect(Token.Type.RParen); 4368 4309 4369 4310 Statement whileBody = Statement.parse(t); … … 4443 4384 Location location = t.location; 4444 4385 4445 t.check(Token.Type.Do); 4446 t = t.nextToken; 4386 t = t.expect(Token.Type.Do); 4447 4387 4448 4388 Statement doBody = Statement.parse(t); 4449 4389 4450 t.check(Token.Type.While); 4451 t = t.nextToken; 4452 t.check(Token.Type.LParen); 4453 t = t.nextToken; 4390 t = t.expect(Token.Type.While); 4391 t = t.expect(Token.Type.LParen); 4454 4392 4455 4393 Expression condition = Expression.parse(t); 4456 4394 4457 t. check(Token.Type.RParen);4395 t.expect(Token.Type.RParen); 4458 4396 Location endLocation = t.location; 4459 4397 t = t.nextToken; … … 4538 4476 Location location = t.location; 4539 4477 4540 t.check(Token.Type.For); 4541 t = t.nextToken; 4542 t.check(Token.Type.LParen); 4543 t = t.nextToken; 4544 4478 t = t.expect(Token.Type.For); 4479 t = t.expect(Token.Type.LParen); 4480 4545 4481 Expression init; 4546 4482 VarDecl initDecl; … … 4555 4491 init = Expression.parseStatement(t); 4556 4492 4557 t.check(Token.Type.Semicolon); 4558 t = t.nextToken; 4493 t = t.expect(Token.Type.Semicolon); 4559 4494 } 4560 4495 … … 4566 4501 { 4567 4502 condition = Expression.parse(t); 4568 t.check(Token.Type.Semicolon); 4569 t = t.nextToken; 4503 t = t.expect(Token.Type.Semicolon); 4570 4504 } 4571 4505 … … 4577 4511 { 4578 4512 increment = Expression.parseStatement(t); 4579 t.check(Token.Type.RParen); 4580 t = t.nextToken; 4513 t = t.expect(Token.Type.RParen); 4581 4514 } 4582 4515 … … 4698 4631 Location location = t.location; 4699 4632 4700 t.check(Token.Type.Foreach); 4701 t = t.nextToken; 4702 t.check(Token.Type.LParen); 4703 t = t.nextToken; 4633 t = t.expect(Token.Type.Foreach); 4634 t = t.expect(Token.Type.LParen); 4704 4635 4705 4636 Identifier[] indices; 4706 4637 4707 if(t.type == Token.Type.Local) 4708 { 4709 derr.writefln("Warning ", t.location.toString(), ": 'local' in foreach indices will soon be illegal"); 4638 indices ~= Identifier.parse(t); 4639 4640 while(t.type == Token.Type.Comma) 4641 { 4710 4642 t = t.nextToken; 4711 }4712 4713 indices ~= Identifier.parse(t);4714 4715 while(t.type == Token.Type.Comma)4716 {4717 t = t.nextToken;4718 4719 if(t.type == Token.Type.Local)4720 {4721 derr.writefln("Warning ", t.location.toString(), ": 'local' in foreach indices will soon be illegal");4722 t = t.nextToken;4723 }4724 4725 4643 indices ~= Identifier.parse(t); 4726 4644 } … … 4729 4647 indices = dummyIndex(indices[0].mLocation) ~ indices; 4730 4648 4731 t.check(Token.Type.Semicolon); 4732 t = t.nextToken; 4649 t = t.expect(Token.Type.Semicolon); 4733 4650 4734 4651 Expression[] container; … … 4744 4661 throw new MDCompileException(location, "'foreach' may have a maximum of three container expressions"); 4745 4662 4746 t.check(Token.Type.RParen); 4747 t = t.nextToken; 4663 t = t.expect(Token.Type.RParen); 4748 4664 4749 4665 Statement foreachBody = Statement.parse(t); … … 4882 4798 Location location = t.location; 4883 4799 4884 t.check(Token.Type.Switch); 4885 t = t.nextToken; 4886 t.check(Token.Type.LParen); 4887 t = t.nextToken; 4800 t = t.expect(Token.Type.Switch); 4801 t = t.expect(Token.Type.LParen); 4888 4802 4889 4803 Expression condition = Expression.parse(t); 4890 4804 4891 t.check(Token.Type.RParen); 4892 t = t.nextToken; 4893 t.check(Token.Type.LBrace); 4894 t = t.nextToken; 4895 4896 CaseStatement[] cases = new CaseStatement[10]; 4897 int i = 0; 4898 4899 void addCase(CaseStatement c) 4900 { 4901 if(i >= cases.length) 4902 cases.length = cases.length * 2; 4903 4904 cases[i] = c; 4905 i++; 4906 } 4907 4908 while(true) 4909 { 4910 if(t.type == Token.Type.Case) 4911 addCase(CaseStatement.parse(t)); 4912 else 4913 break; 4914 } 4915 4916 cases.length = i; 4805 t = t.expect(Token.Type.RParen); 4806 t = t.expect(Token.Type.LBrace); 4807 4808 List!(CaseStatement) cases; 4809 4810 while(t.type == Token.Type.Case) 4811 cases.add(CaseStatement.parse(t)); 4917 4812 4918 4813 if(cases.length == 0) … … 4924 4819 caseDefault = DefaultStatement.parse(t); 4925 4820 4926 t. check(Token.Type.RBrace);4821 t.expect(Token.Type.RBrace); 4927 4822 Location endLocation = t.location; 4928 4823 t = t.nextToken; 4929 4824 4930 return new SwitchStatement(location, endLocation, condition, cases , caseDefault);4825 return new SwitchStatement(location, endLocation, condition, cases.toArray(), caseDefault); 4931 4826 } 4932 4827 … … 4940 4835 s.popSource(mLocation.line, src); 4941 4836 4942 if(cast(IntExp)mCases[0].mCondition) 4943 s.beginIntSwitch(mLocation.line, src.index); 4944 else 4945 s.beginStringSwitch(mLocation.line, src.index); 4837 s.beginSwitch(mLocation.line, src.index); 4946 4838 4947 4839 s.freeExpTempRegs(&src); … … 4989 4881 Location location = t.location; 4990 4882 4991 t.check(Token.Type.Case); 4992 t = t.nextToken; 4993 4994 Expression[] cases = new Expression[10]; 4995 int i = 0; 4996 4997 void addCase(Expression c) 4998 { 4999 if(i >= cases.length) 5000 cases.length = cases.length * 2; 5001 5002 cases[i] = c; 5003 i++; 4883 t = t.expect(Token.Type.Case); 4884 4885 List!(Expression) cases; 4886 cases.add(Expression.parse(t)); 4887 4888 while(t.type == Token.Type.Comma) 4889 { 4890 t = t.nextToken; 4891 cases.add(Expression.parse(t)); 5004 4892 } 5005 4893 5006 addCase(Expression.parse(t)); 5007 5008 while(t.type == Token.Type.Comma) 5009 { 5010 t = t.nextToken; 5011 addCase(Expression.parse(t)); 5012 } 5013 5014 cases.length = i; 5015 5016 t.check(Token.Type.Colon); 5017 t = t.nextToken; 5018 5019 Statement[] statements = new Statement[10]; 5020 i = 0; 5021 5022 void addStatement(Statement s) 5023 { 5024 if(i >= statements.length) 5025 statements.length = statements.length * 2; 5026 5027 statements[i] = s; 5028 i++; 5029 } 4894 t = t.expect(Token.Type.Colon); 4895 4896 List!(Statement) statements; 5030 4897 5031 4898 while(t.type != Token.Type.Case && t.type != Token.Type.Default && t.type != Token.Type.RBrace) 5032 addStatement(Statement.parse(t)); 5033 5034 statements.length = i; 4899 statements.add(Statement.parse(t)); 5035 4900 5036 4901 Location endLocation = t.location; 5037 4902 5038 Statement ret = new CompoundStatement(location, endLocation, statements );4903 Statement ret = new CompoundStatement(location, endLocation, statements.toArray()); 5039 4904 ret = new ScopeStatement(location, endLocation, ret); 5040 4905 5041 for(i = cases.length - 1; i >= 0; i--)4906 for(int i = cases.length - 1; i >= 0; i--) 5042 4907 ret = new CaseStatement(location, endLocation, cases[i], ret); 5043 4908 … … 5050 4915 throw new MDCompileException(mLocation, "Case value is not constant"); 5051 4916 5052 s.addCase(mCondition); 4917 IntExp intExp = cast(IntExp)mCondition; 4918 4919 if(intExp) 4920 s.addCase(mLocation, intExp.mValue); 4921 else 4922 { 4923 StringExp stringExp = cast(StringExp)mCondition; 4924 4925 if(stringExp) 4926 s.addCase(mLocation, stringExp.mValue); 4927 else 4928 { 4929 CharExp cha
