comparison trunk/src/dil/Parser.d @ 486:bd176bc73e43

Fixed a few things in the Parser. Refactored some code that used parseArguments() to using parseExpressionList(). Added calls to set() and tidied up the code of the Parser a bit. Fixed parsing DotIdentifier in parseAsmPrimaryExpression(). Added charLiteral member to class CharExpression. Added class InformationManager. Added member infoMan to class Scope.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Sat, 01 Dec 2007 18:22:56 +0100
parents ea8c7459f1c4
children cfb3805768b6
comparison
equal deleted inserted replaced
485:ea8c7459f1c4 486:bd176bc73e43
186 /++ 186 /++
187 DeclDefs: 187 DeclDefs:
188 DeclDef 188 DeclDef
189 DeclDefs 189 DeclDefs
190 +/ 190 +/
191 Declarations parseDeclarationDefinitions() 191 Declaration[] parseDeclarationDefinitions()
192 { 192 {
193 auto decls = new Declarations; 193 Declaration[] decls;
194 while (token.type != T.EOF) 194 while (token.type != T.EOF)
195 decls ~= parseDeclarationDefinition(); 195 decls ~= parseDeclarationDefinition();
196 return decls; 196 return decls;
197 } 197 }
198 198
821 require(T.LParen); 821 require(T.LParen);
822 ident = requireId(); 822 ident = requireId();
823 823
824 if (token.type == T.Comma) 824 if (token.type == T.Comma)
825 { 825 {
826 // Parse at least one argument. 826 nT();
827 nT(); 827 args = parseExpressionList();
828 args ~= parseAssignExpression(); 828 }
829 } 829 require(T.RParen);
830
831 if (token.type == T.Comma)
832 args ~= parseArguments(T.RParen);
833 else
834 require(T.RParen);
835 830
836 if (token.type == T.Semicolon) 831 if (token.type == T.Semicolon)
837 { 832 {
838 nT(); 833 nT();
839 // TODO: call set()? 834 // TODO: call set()?
1070 error(MID.ExpectedBaseClasses, token.srcText); 1065 error(MID.ExpectedBaseClasses, token.srcText);
1071 return bases; 1066 return bases;
1072 } 1067 }
1073 nT(); // Skip protection attribute. 1068 nT(); // Skip protection attribute.
1074 LparseBasicType: 1069 LparseBasicType:
1070 auto begin = token;
1075 auto type = parseBasicType(); 1071 auto type = parseBasicType();
1076 //if (type.tid != TID.DotList) 1072 //if (type.tid != TID.DotList)
1077 // TODO: issue error msg. base classes can only be one or more identifiers or template instances separated by dots. 1073 // TODO: issue error msg. base classes can only be one or more identifiers or template instances separated by dots.
1078 bases ~= new BaseClass(prot, type); 1074 bases ~= set(new BaseClass(prot, type), begin);
1079 if (token.type != T.Comma) 1075 if (token.type != T.Comma)
1080 break; 1076 break;
1081 nT(); 1077 nT();
1082 } 1078 }
1083 return bases; 1079 return bases;
1435 Identifier !( TemplateArguments ) 1431 Identifier !( TemplateArguments )
1436 +/ 1432 +/
1437 DotListExpression parseDotListExpression() 1433 DotListExpression parseDotListExpression()
1438 { 1434 {
1439 assert(token.type == T.Identifier || token.type == T.Dot || token.type == T.Typeof); 1435 assert(token.type == T.Identifier || token.type == T.Dot || token.type == T.Typeof);
1436 auto begin = token;
1440 Expression[] identList; 1437 Expression[] identList;
1441 if (token.type == T.Dot) 1438 if (token.type == T.Dot)
1442 { 1439 {
1443 identList ~= new IdentifierExpression(token); 1440 identList ~= set(new IdentifierExpression(token), begin);
1444 nT(); 1441 nT();
1445 } 1442 }
1446 else if (token.type == T.Typeof) 1443 else if (token.type == T.Typeof)
1447 { 1444 {
1448 requireNext(T.LParen); 1445 requireNext(T.LParen);
1449 auto type = new TypeofType(parseExpression()); 1446 auto type = new TypeofType(parseExpression());
1450 require(T.RParen); 1447 require(T.RParen);
1451 identList ~= new TypeofExpression(type); 1448 set(type, begin);
1449 identList ~= set(new TypeofExpression(type), begin);
1452 if (token.type != T.Dot) 1450 if (token.type != T.Dot)
1453 goto Lreturn; 1451 goto Lreturn;
1454 nT(); 1452 nT();
1455 } 1453 }
1456 1454
1457 while (1) 1455 while (1)
1458 { 1456 {
1459 auto begin2 = token; 1457 begin = token;
1460 auto ident = requireId(); 1458 auto ident = requireId();
1461 Expression e; 1459 Expression e;
1462 if (token.type == T.Not && peekNext() == T.LParen) // Identifier !( TemplateArguments ) 1460 if (token.type == T.Not && peekNext() == T.LParen) // Identifier !( TemplateArguments )
1463 { 1461 {
1464 nT(); // Skip !. 1462 nT(); // Skip !.
1465 e = set(new TemplateInstanceExpression(ident, parseTemplateArguments()), begin2); 1463 e = set(new TemplateInstanceExpression(ident, parseTemplateArguments()), begin);
1466 } 1464 }
1467 else // Identifier 1465 else // Identifier
1468 e = set(new IdentifierExpression(ident), begin2); 1466 e = set(new IdentifierExpression(ident), begin);
1469 1467
1470 identList ~= e; 1468 identList ~= e;
1471 1469
1472 LnewExpressionLoop: 1470 LnewExpressionLoop:
1473 if (token.type != T.Dot) 1471 if (token.type != T.Dot)
1510 nT(); 1508 nT();
1511 } 1509 }
1512 else if (token.type == T.Typeof) 1510 else if (token.type == T.Typeof)
1513 { 1511 {
1514 requireNext(T.LParen); 1512 requireNext(T.LParen);
1515 identList ~= set(new TypeofType(parseExpression()), begin); 1513 auto type = new TypeofType(parseExpression());
1516 require(T.RParen); 1514 require(T.RParen);
1515 identList ~= set(type, begin);
1517 if (token.type != T.Dot) 1516 if (token.type != T.Dot)
1518 goto Lreturn; 1517 goto Lreturn;
1519 nT(); 1518 nT();
1520 } 1519 }
1521 1520
1832 T.Byte, T.Ubyte, T.Short, T.Ushort, 1831 T.Byte, T.Ubyte, T.Short, T.Ushort,
1833 T.Int, T.Uint, T.Long, T.Ulong, 1832 T.Int, T.Uint, T.Long, T.Ulong,
1834 T.Float, T.Double, T.Real, 1833 T.Float, T.Double, T.Real,
1835 T.Ifloat, T.Idouble, T.Ireal, 1834 T.Ifloat, T.Idouble, T.Ireal,
1836 T.Cfloat, T.Cdouble, T.Creal, T.Void:+/ 1835 T.Cfloat, T.Cdouble, T.Creal, T.Void:+/
1837 case T.Traits: 1836 case T.Traits: // D2.0
1838 // Tokens that can start a UnaryExpression: 1837 // Tokens that can start a UnaryExpression:
1839 case T.AndBinary, 1838 case T.AndBinary,
1840 T.PlusPlus, 1839 T.PlusPlus,
1841 T.MinusMinus, 1840 T.MinusMinus,
1842 T.Mul, 1841 T.Mul,
1853 break; 1852 break;
1854 default: 1853 default:
1855 if (token.isSpecialToken) 1854 if (token.isSpecialToken)
1856 goto case_parseExpressionStatement; 1855 goto case_parseExpressionStatement;
1857 1856
1858 // Assert that this isn't a valid expression. 1857 if (token.type != T.Dollar)
1859 assert( 1858 // Assert that this isn't a valid expression.
1860 delegate bool(){ 1859 assert(
1861 bool success; 1860 delegate bool(){
1862 auto expression = try_(&parseExpression, success); 1861 bool success;
1863 return success; 1862 auto expression = try_(&parseExpression, success);
1864 }() == false, "Any token that could start a valid expression must have been caught by a case statement in parseStatement()." 1863 return success;
1865 ); 1864 }() == false, "Didn't expect valid expression."
1865 );
1866 1866
1867 // Report error: it's an illegal statement. 1867 // Report error: it's an illegal statement.
1868 error(MID.ExpectedButFound, "Statement", token.srcText); 1868 error(MID.ExpectedButFound, "Statement", token.srcText);
1869 s = new IllegalStatement(token); 1869 s = new IllegalStatement(token);
1870 nT(); 1870 nT();
1872 assert(s !is null); 1872 assert(s !is null);
1873 set(s, begin); 1873 set(s, begin);
1874 return s; 1874 return s;
1875 } 1875 }
1876 1876
1877 /+ 1877 /++
1878 ScopeStatement: 1878 ScopeStatement:
1879 NoScopeStatement 1879 NoScopeStatement
1880 +/ 1880 +/
1881 Statement parseScopeStatement() 1881 Statement parseScopeStatement()
1882 { 1882 {
1883 return new ScopeStatement(parseNoScopeStatement()); 1883 return new ScopeStatement(parseNoScopeStatement());
1884 } 1884 }
1885 1885
1886 /+ 1886 /++
1887 NoScopeStatement: 1887 NoScopeStatement:
1888 NonEmptyStatement 1888 NonEmptyStatement
1889 BlockStatement 1889 BlockStatement
1890 BlockStatement: 1890 BlockStatement:
1891 { } 1891 { }
1892 { StatementList } 1892 { StatementList }
1893 +/ 1893 +/
1894 Statement parseNoScopeStatement() 1894 Statement parseNoScopeStatement()
1895 { 1895 {
1896 auto begin = token;
1896 Statement s; 1897 Statement s;
1897 if (token.type == T.LBrace) 1898 if (token.type == T.LBrace)
1898 { 1899 {
1899 nT(); 1900 nT();
1900 auto ss = new Statements(); 1901 auto ss = new Statements();
1901 while (token.type != T.RBrace && token.type != T.EOF) 1902 while (token.type != T.RBrace && token.type != T.EOF)
1902 ss ~= parseStatement(); 1903 ss ~= parseStatement();
1903 require(T.RBrace); 1904 require(T.RBrace);
1904 s = ss; 1905 s = set(ss, begin);
1905 } 1906 }
1906 else if (token.type == T.Semicolon) 1907 else if (token.type == T.Semicolon)
1907 { 1908 {
1908 error(MID.ExpectedButFound, "non-empty statement", ";"); 1909 error(MID.ExpectedButFound, "non-empty statement", ";");
1909 s = new EmptyStatement(); 1910 nT();
1910 nT(); 1911 s = set(new EmptyStatement(), begin);
1911 } 1912 }
1912 else 1913 else
1913 s = parseStatement(); 1914 s = parseStatement();
1914 return s; 1915 return s;
1915 } 1916 }
1916 1917
1917 /+ 1918 /++
1918 NoScopeOrEmptyStatement: 1919 NoScopeOrEmptyStatement:
1919 ; 1920 ;
1920 NoScopeStatement 1921 NoScopeStatement
1921 +/ 1922 +/
1922 Statement parseNoScopeOrEmptyStatement() 1923 Statement parseNoScopeOrEmptyStatement()
1923 { 1924 {
1924 if (token.type == T.Semicolon) 1925 if (token.type == T.Semicolon)
1925 { 1926 {
1926 nT(); 1927 auto begin = token;
1927 return new EmptyStatement(); 1928 nT();
1929 return set(new EmptyStatement(), begin);
1928 } 1930 }
1929 else 1931 else
1930 return parseNoScopeStatement(); 1932 return parseNoScopeStatement();
1931 } 1933 }
1932 1934
1936 Linkage.Category link_cat; 1938 Linkage.Category link_cat;
1937 1939
1938 void addStorageClass() 1940 void addStorageClass()
1939 { 1941 {
1940 if (stc & tmp) 1942 if (stc & tmp)
1941 {
1942 error(MID.RedundantStorageClass, token.srcText); 1943 error(MID.RedundantStorageClass, token.srcText);
1943 }
1944 else 1944 else
1945 stc |= tmp; 1945 stc |= tmp;
1946 } 1946 }
1947 1947
1948 Statement parse() 1948 Statement parse()
2193 require(T.RParen); 2193 require(T.RParen);
2194 auto switchBody = parseScopeStatement(); 2194 auto switchBody = parseScopeStatement();
2195 return new SwitchStatement(condition, switchBody); 2195 return new SwitchStatement(condition, switchBody);
2196 } 2196 }
2197 2197
2198 Statement parseCaseDefaultBody() 2198 /++
2199 Helper function for parsing the body of
2200 a default or case statement.
2201 +/
2202 Statement parseCaseOrDefaultBody()
2199 { 2203 {
2200 // This function is similar to parseNoScopeStatement() 2204 // This function is similar to parseNoScopeStatement()
2205 auto begin = token;
2201 auto s = new Statements(); 2206 auto s = new Statements();
2202 while (token.type != T.Case && 2207 while (token.type != T.Case &&
2203 token.type != T.Default && 2208 token.type != T.Default &&
2204 token.type != T.RBrace && 2209 token.type != T.RBrace &&
2205 token.type != T.EOF) 2210 token.type != T.EOF)
2206 s ~= parseStatement(); 2211 s ~= parseStatement();
2207 return new ScopeStatement(s); 2212 return set(new ScopeStatement(s), begin);
2208 } 2213 }
2209 2214
2210 Statement parseCaseStatement() 2215 Statement parseCaseStatement()
2211 { 2216 {
2212 assert(token.type == T.Case); 2217 assert(token.type == T.Case);
2217 nT(); 2222 nT();
2218 values ~= parseAssignExpression(); 2223 values ~= parseAssignExpression();
2219 } while (token.type == T.Comma) 2224 } while (token.type == T.Comma)
2220 require(T.Colon); 2225 require(T.Colon);
2221 2226
2222 auto caseBody = parseCaseDefaultBody(); 2227 auto caseBody = parseCaseOrDefaultBody();
2223 return new CaseStatement(values, caseBody); 2228 return new CaseStatement(values, caseBody);
2224 } 2229 }
2225 2230
2226 Statement parseDefaultStatement() 2231 Statement parseDefaultStatement()
2227 { 2232 {
2228 assert(token.type == T.Default); 2233 assert(token.type == T.Default);
2229 nT(); 2234 nT();
2230 require(T.Colon); 2235 require(T.Colon);
2231 return new DefaultStatement(parseCaseDefaultBody()); 2236 auto defaultBody = parseCaseOrDefaultBody();
2237 return new DefaultStatement(defaultBody);
2232 } 2238 }
2233 2239
2234 Statement parseContinueStatement() 2240 Statement parseContinueStatement()
2235 { 2241 {
2236 assert(token.type == T.Continue); 2242 assert(token.type == T.Continue);
2333 nT(); 2339 nT();
2334 Parameter param; 2340 Parameter param;
2335 if (token.type == T.LParen) 2341 if (token.type == T.LParen)
2336 { 2342 {
2337 nT(); 2343 nT();
2344 auto begin = token;
2338 Token* ident; 2345 Token* ident;
2339 auto type = parseDeclarator(ident, true); 2346 auto type = parseDeclarator(ident, true);
2340 param = new Parameter(null, type, ident, null); 2347 param = new Parameter(null, type, ident, null);
2348 set(param, begin);
2341 require(T.RParen); 2349 require(T.RParen);
2342 } 2350 }
2343 catchBodies ~= new CatchBody(param, parseNoScopeStatement()); 2351 catchBodies ~= new CatchBody(param, parseNoScopeStatement());
2344 if (param is null) 2352 if (param is null)
2345 break; // This is a LastCatch 2353 break; // This is a LastCatch
2346 } 2354 }
2347 2355
2348 if (token.type == T.Finally) 2356 if (token.type == T.Finally)
2349 { 2357 {
2358 auto begin = token;
2350 nT(); 2359 nT();
2351 finBody = new FinallyBody(parseNoScopeStatement()); 2360 finBody = new FinallyBody(parseNoScopeStatement());
2361 set(finBody, begin);
2352 } 2362 }
2353 2363
2354 if (catchBodies.length == 0 && finBody is null) 2364 if (catchBodies.length == 0 && finBody is null)
2355 { 2365 {
2356 // TODO: issue error msg. 2366 // TODO: issue error msg.
2421 require(T.LParen); 2431 require(T.LParen);
2422 ident = requireId(); 2432 ident = requireId();
2423 2433
2424 if (token.type == T.Comma) 2434 if (token.type == T.Comma)
2425 { 2435 {
2426 // Parse at least one argument. 2436 nT();
2427 nT(); 2437 args = parseExpressionList();
2428 args ~= parseAssignExpression(); 2438 }
2429 } 2439 require(T.RParen);
2430
2431 if (token.type == T.Comma)
2432 args ~= parseArguments(T.RParen);
2433 else
2434 require(T.RParen);
2435 2440
2436 pragmaBody = parseNoScopeOrEmptyStatement(); 2441 pragmaBody = parseNoScopeOrEmptyStatement();
2437 2442
2438 return new PragmaStatement(ident, args, pragmaBody); 2443 return new PragmaStatement(ident, args, pragmaBody);
2439 } 2444 }
3019 e = new AsmRegisterExpression(token); 3024 e = new AsmRegisterExpression(token);
3020 nT(); 3025 nT();
3021 break; 3026 break;
3022 default: 3027 default:
3023 // DotIdentifier 3028 // DotIdentifier
3024 auto begin2 = token;
3025 Expression[] identList; 3029 Expression[] identList;
3026 goto LenterLoop; 3030 while (1)
3027 while (token.type == T.Dot)
3028 { 3031 {
3029 nT(); 3032 auto begin2 = token;
3030 begin2 = token;
3031 auto ident = requireId(); 3033 auto ident = requireId();
3032 LenterLoop: 3034 e = new IdentifierExpression(ident);
3033 e = new IdentifierExpression(token);
3034 nT();
3035 set(e, begin2); 3035 set(e, begin2);
3036 identList ~= e; 3036 identList ~= e;
3037 if (token.type != T.Dot)
3038 break;
3039 nT(); // Skip dot.
3037 } 3040 }
3038 e = new DotListExpression(identList); 3041 e = new DotListExpression(identList);
3039 } 3042 }
3040 break; 3043 break;
3041 default: 3044 default:
3142 return e; 3145 return e;
3143 } 3146 }
3144 3147
3145 Expression parseOrOrExpression() 3148 Expression parseOrOrExpression()
3146 { 3149 {
3147 auto begin = token;
3148 alias parseAndAndExpression parseNext; 3150 alias parseAndAndExpression parseNext;
3151 auto begin = token;
3149 auto e = parseNext(); 3152 auto e = parseNext();
3150 while (token.type == T.OrLogical) 3153 while (token.type == T.OrLogical)
3151 { 3154 {
3152 auto tok = token; 3155 auto tok = token;
3153 nT(); 3156 nT();
3157 return e; 3160 return e;
3158 } 3161 }
3159 3162
3160 Expression parseAndAndExpression() 3163 Expression parseAndAndExpression()
3161 { 3164 {
3162 auto begin = token;
3163 alias parseOrExpression parseNext; 3165 alias parseOrExpression parseNext;
3166 auto begin = token;
3164 auto e = parseNext(); 3167 auto e = parseNext();
3165 while (token.type == T.AndLogical) 3168 while (token.type == T.AndLogical)
3166 { 3169 {
3167 auto tok = token; 3170 auto tok = token;
3168 nT(); 3171 nT();
3172 return e; 3175 return e;
3173 } 3176 }
3174 3177
3175 Expression parseOrExpression() 3178 Expression parseOrExpression()
3176 { 3179 {
3177 auto begin = token;
3178 alias parseXorExpression parseNext; 3180 alias parseXorExpression parseNext;
3181 auto begin = token;
3179 auto e = parseNext(); 3182 auto e = parseNext();
3180 while (token.type == T.OrBinary) 3183 while (token.type == T.OrBinary)
3181 { 3184 {
3182 auto tok = token; 3185 auto tok = token;
3183 nT(); 3186 nT();
3187 return e; 3190 return e;
3188 } 3191 }
3189 3192
3190 Expression parseXorExpression() 3193 Expression parseXorExpression()
3191 { 3194 {
3192 auto begin = token;
3193 alias parseAndExpression parseNext; 3195 alias parseAndExpression parseNext;
3196 auto begin = token;
3194 auto e = parseNext(); 3197 auto e = parseNext();
3195 while (token.type == T.Xor) 3198 while (token.type == T.Xor)
3196 { 3199 {
3197 auto tok = token; 3200 auto tok = token;
3198 nT(); 3201 nT();
3202 return e; 3205 return e;
3203 } 3206 }
3204 3207
3205 Expression parseAndExpression() 3208 Expression parseAndExpression()
3206 { 3209 {
3207 auto begin = token;
3208 alias parseCmpExpression parseNext; 3210 alias parseCmpExpression parseNext;
3211 auto begin = token;
3209 auto e = parseNext(); 3212 auto e = parseNext();
3210 while (token.type == T.AndBinary) 3213 while (token.type == T.AndBinary)
3211 { 3214 {
3212 auto tok = token; 3215 auto tok = token;
3213 nT(); 3216 nT();
3217 return e; 3220 return e;
3218 } 3221 }
3219 3222
3220 Expression parseCmpExpression() 3223 Expression parseCmpExpression()
3221 { 3224 {
3225 alias parseShiftExpression parseNext;
3222 auto begin = token; 3226 auto begin = token;
3223 auto e = parseShiftExpression(); 3227 auto e = parseShiftExpression();
3224 3228
3225 auto operator = token; 3229 auto operator = token;
3226 switch (operator.type) 3230 switch (operator.type)
3227 { 3231 {
3228 case T.Equal, T.NotEqual: 3232 case T.Equal, T.NotEqual:
3229 nT(); 3233 nT();
3230 e = new EqualExpression(e, parseShiftExpression(), operator); 3234 e = new EqualExpression(e, parseNext(), operator);
3231 break; 3235 break;
3232 case T.Not: 3236 case T.Not:
3233 if (peekNext() != T.Is) 3237 if (peekNext() != T.Is)
3234 break; 3238 break;
3235 nT(); 3239 nT();
3236 // fall through 3240 // fall through
3237 case T.Is: 3241 case T.Is:
3238 nT(); 3242 nT();
3239 e = new IdentityExpression(e, parseShiftExpression(), operator); 3243 e = new IdentityExpression(e, parseNext(), operator);
3240 break; 3244 break;
3241 case T.LessEqual, T.Less, T.GreaterEqual, T.Greater, 3245 case T.LessEqual, T.Less, T.GreaterEqual, T.Greater,
3242 T.Unordered, T.UorE, T.UorG, T.UorGorE, 3246 T.Unordered, T.UorE, T.UorG, T.UorGorE,
3243 T.UorL, T.UorLorE, T.LorEorG, T.LorG: 3247 T.UorL, T.UorLorE, T.LorEorG, T.LorG:
3244 nT(); 3248 nT();
3245 e = new RelExpression(e, parseShiftExpression(), operator); 3249 e = new RelExpression(e, parseNext(), operator);
3246 break; 3250 break;
3247 case T.In: 3251 case T.In:
3248 nT(); 3252 nT();
3249 e = new InExpression(e, parseShiftExpression(), operator); 3253 e = new InExpression(e, parseNext(), operator);
3250 break; 3254 break;
3251 default: 3255 default:
3252 return e; 3256 return e;
3253 } 3257 }
3254 set(e, begin); 3258 set(e, begin);
3255 return e; 3259 return e;
3256 } 3260 }
3257 3261
3258 Expression parseShiftExpression() 3262 Expression parseShiftExpression()
3259 { 3263 {
3260 auto begin = token; 3264 alias parseAddExpression parseNext;
3261 auto e = parseAddExpression(); 3265 auto begin = token;
3266 auto e = parseNext();
3262 while (1) 3267 while (1)
3263 { 3268 {
3264 auto operator = token; 3269 auto operator = token;
3265 switch (operator.type) 3270 switch (operator.type)
3266 { 3271 {
3267 case T.LShift: nT(); e = new LShiftExpression(e, parseAddExpression(), operator); break; 3272 case T.LShift: nT(); e = new LShiftExpression(e, parseNext(), operator); break;
3268 case T.RShift: nT(); e = new RShiftExpression(e, parseAddExpression(), operator); break; 3273 case T.RShift: nT(); e = new RShiftExpression(e, parseNext(), operator); break;
3269 case T.URShift: nT(); e = new URShiftExpression(e, parseAddExpression(), operator); break; 3274 case T.URShift: nT(); e = new URShiftExpression(e, parseNext(), operator); break;
3270 default: 3275 default:
3271 return e; 3276 return e;
3272 } 3277 }
3273 set(e, begin); 3278 set(e, begin);
3274 } 3279 }
3275 assert(0); 3280 assert(0);
3276 } 3281 }
3277 3282
3278 Expression parseAddExpression() 3283 Expression parseAddExpression()
3279 { 3284 {
3280 auto begin = token; 3285 alias parseMulExpression parseNext;
3281 auto e = parseMulExpression(); 3286 auto begin = token;
3287 auto e = parseNext();
3282 while (1) 3288 while (1)
3283 { 3289 {
3284 auto operator = token; 3290 auto operator = token;
3285 switch (operator.type) 3291 switch (operator.type)
3286 { 3292 {
3287 case T.Plus: nT(); e = new PlusExpression(e, parseMulExpression(), operator); break; 3293 case T.Plus: nT(); e = new PlusExpression(e, parseNext(), operator); break;
3288 case T.Minus: nT(); e = new MinusExpression(e, parseMulExpression(), operator); break; 3294 case T.Minus: nT(); e = new MinusExpression(e, parseNext(), operator); break;
3289 case T.Tilde: nT(); e = new CatExpression(e, parseMulExpression(), operator); break; 3295 case T.Tilde: nT(); e = new CatExpression(e, parseNext(), operator); break;
3290 default: 3296 default:
3291 return e; 3297 return e;
3292 } 3298 }
3293 set(e, begin); 3299 set(e, begin);
3294 } 3300 }
3332 break; 3338 break;
3333 case T.MinusMinus: 3339 case T.MinusMinus:
3334 e = new PostDecrExpression(e); 3340 e = new PostDecrExpression(e);
3335 break; 3341 break;
3336 case T.LParen: 3342 case T.LParen:
3337 e = new CallExpression(e, parseArguments(T.RParen)); 3343 e = new CallExpression(e, parseArguments());
3338 goto Lset; 3344 goto Lset;
3339 case T.LBracket: 3345 case T.LBracket:
3340 // parse Slice- and IndexExpression 3346 // parse Slice- and IndexExpression
3341 nT(); 3347 nT();
3342 if (token.type == T.RBracket) 3348 if (token.type == T.RBracket)
3352 nT(); 3358 nT();
3353 e = new SliceExpression(e, es[0], parseAssignExpression()); 3359 e = new SliceExpression(e, es[0], parseAssignExpression());
3354 require(T.RBracket); 3360 require(T.RBracket);
3355 goto Lset; 3361 goto Lset;
3356 } 3362 }
3357 else if (token.type == T.Comma) 3363
3364 if (token.type == T.Comma)
3358 { 3365 {
3359 es ~= parseArguments(T.RBracket); 3366 nT();
3367 es ~= parseExpressionList();
3360 } 3368 }
3361 else 3369 require(T.RBracket);
3362 require(T.RBracket);
3363 3370
3364 e = new IndexExpression(e, es); 3371 e = new IndexExpression(e, es);
3365 goto Lset; 3372 goto Lset;
3366 default: 3373 default:
3367 return e; 3374 return e;
3504 T.Imaginary32, T.Imaginary64, T.Imaginary80: 3511 T.Imaginary32, T.Imaginary64, T.Imaginary80:
3505 e = new RealExpression(token.type, token.real_); 3512 e = new RealExpression(token.type, token.real_);
3506 nT(); 3513 nT();
3507 break; 3514 break;
3508 case T.CharLiteral, T.WCharLiteral, T.DCharLiteral: 3515 case T.CharLiteral, T.WCharLiteral, T.DCharLiteral:
3509 nT(); 3516 e = new CharExpression(token);
3510 e = new CharExpression(); 3517 nT();
3511 break; 3518 break;
3512 case T.String: 3519 case T.String:
3513 Token*[] stringLiterals; 3520 Token*[] stringLiterals;
3514 do 3521 do
3515 { 3522 {
3525 if (token.type != T.RBracket) 3532 if (token.type != T.RBracket)
3526 { 3533 {
3527 e = parseAssignExpression(); 3534 e = parseAssignExpression();
3528 if (token.type == T.Colon) 3535 if (token.type == T.Colon)
3529 goto LparseAssocArray; 3536 goto LparseAssocArray;
3530 else if (token.type == T.Comma) 3537 if (token.type == T.Comma)
3531 values = [e] ~ parseArguments(T.RBracket); 3538 {
3532 else 3539 nT();
3533 require(T.RBracket); 3540 values = [e] ~ parseExpressionList();
3541 }
3542 require(T.RBracket);
3534 } 3543 }
3535 else 3544 else
3536 nT(); 3545 nT();
3537 3546
3538 e = new ArrayLiteralExpression(values); 3547 e = new ArrayLiteralExpression(values);
3730 3739
3731 Expression[] newArguments; 3740 Expression[] newArguments;
3732 Expression[] ctorArguments; 3741 Expression[] ctorArguments;
3733 3742
3734 if (token.type == T.LParen) 3743 if (token.type == T.LParen)
3735 newArguments = parseArguments(T.RParen); 3744 newArguments = parseArguments();
3736 3745
3737 // NewAnonClassExpression: 3746 // NewAnonClassExpression:
3738 // new (ArgumentList)opt class (ArgumentList)opt SuperClassopt InterfaceClassesopt ClassBody 3747 // new (ArgumentList)opt class (ArgumentList)opt SuperClassopt InterfaceClassesopt ClassBody
3739 if (token.type == T.Class) 3748 if (token.type == T.Class)
3740 { 3749 {
3741 nT(); 3750 nT();
3742 if (token.type == T.LParen) 3751 if (token.type == T.LParen)
3743 ctorArguments = parseArguments(T.RParen); 3752 ctorArguments = parseArguments();
3744 3753
3745 BaseClass[] bases = token.type != T.LBrace ? parseBaseClasses(false) : null ; 3754 BaseClass[] bases = token.type != T.LBrace ? parseBaseClasses(false) : null ;
3746 3755
3747 auto decls = parseDeclarationDefinitionsBlock(); 3756 auto decls = parseDeclarationDefinitionsBlock();
3748 return set(new NewAnonClassExpression(/*e, */newArguments, bases, ctorArguments, decls), begin); 3757 return set(new NewAnonClassExpression(/*e, */newArguments, bases, ctorArguments, decls), begin);
3753 // NewArguments Type ( ArgumentList ) 3762 // NewArguments Type ( ArgumentList )
3754 // NewArguments Type 3763 // NewArguments Type
3755 auto type = parseType(); 3764 auto type = parseType();
3756 3765
3757 if (token.type == T.LParen) 3766 if (token.type == T.LParen)
3758 ctorArguments = parseArguments(T.RParen); 3767 ctorArguments = parseArguments();
3759 3768
3760 return set(new NewExpression(/*e, */newArguments, type, ctorArguments), begin); 3769 return set(new NewExpression(/*e, */newArguments, type, ctorArguments), begin);
3761 } 3770 }
3762 3771
3763 Type parseType() 3772 Type parseType()
4001 expected(T.Identifier); 4010 expected(T.Identifier);
4002 4011
4003 return t; 4012 return t;
4004 } 4013 }
4005 4014
4006 Expression[] parseArguments(TOK terminator) 4015 /++
4007 { 4016 Parse a list of AssignExpressions.
4008 assert(token.type == T.LParen || token.type == T.LBracket || token.type == T.Comma); 4017 ExpressionList:
4009 assert(terminator == T.RParen || terminator == T.RBracket); 4018 AssignExpression
4019 AssignExpression , ExpressionList
4020 +/
4021 Expression[] parseExpressionList()
4022 {
4023 Expression[] expressions;
4024 while (1)
4025 {
4026 expressions ~= parseAssignExpression();
4027 if (token.type != T.Comma)
4028 break;
4029 nT();
4030 }
4031 return expressions;
4032 }
4033
4034 /++
4035 Arguments:
4036 ( )
4037 ( ExpressionList )
4038 +/
4039 Expression[] parseArguments()
4040 {
4041 assert(token.type == T.LParen);
4042 nT();
4010 Expression[] args; 4043 Expression[] args;
4011 4044 if (token.type != TOK.RParen)
4012 nT(); 4045 args = parseExpressionList();
4013 if (token.type == terminator) 4046 require(TOK.RParen);
4014 {
4015 nT();
4016 return null;
4017 }
4018
4019 goto LenterLoop;
4020 do
4021 {
4022 nT();
4023 LenterLoop:
4024 args ~= parseAssignExpression();
4025 } while (token.type == T.Comma)
4026
4027 require(terminator);
4028 return args; 4047 return args;
4029 } 4048 }
4030 4049
4031 Parameters parseParameterList() 4050 Parameters parseParameterList()
4032 out(params) 4051 out(params)