Mercurial > projects > dil
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) |