Changeset 644
- Timestamp:
- 08/28/10 20:38:24 (14 years ago)
- Files:
-
- trunk/src/parse.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/parse.c
r633 r644 1689 1689 * Parse template parameter list. 1690 1690 * Input: 1691 1691 * flag 0: parsing "( list )" 1692 1692 * 1: parsing non-empty "list )" 1693 1693 */ 1694 1694 1695 1695 TemplateParameters *Parser::parseTemplateParameterList(int flag) 1696 1696 { 1697 1697 TemplateParameters *tpl = new TemplateParameters(); 1698 1698 1699 1699 if (!flag && token.value != TOKlparen) 1700 1700 { error("parenthesized TemplateParameterList expected following TemplateIdentifier"); 1701 1701 goto Lerr; 1702 1702 } 1703 1703 nextToken(); 1704 1704 1705 1705 // Get array of TemplateParameters 1706 1706 if (flag || token.value != TOKrparen) 1707 1707 { int isvariadic = 0; 1708 1708 1709 while ( 1)1709 while (token.value != TOKrparen) 1710 1710 { TemplateParameter *tp; 1711 1711 Identifier *tp_ident = NULL; 1712 1712 Type *tp_spectype = NULL; 1713 1713 Type *tp_valtype = NULL; 1714 1714 Type *tp_defaulttype = NULL; 1715 1715 Expression *tp_specvalue = NULL; 1716 1716 Expression *tp_defaultvalue = NULL; 1717 1717 Token *t; 1718 1718 1719 1719 // Get TemplateParameter 1720 1720 1721 1721 // First, look ahead to see if it is a TypeParameter or a ValueParameter 1722 1722 t = peek(&token); 1723 1723 if (token.value == TOKalias) 1724 1724 { // AliasParameter 1725 1725 nextToken(); 1726 1726 Type *spectype = NULL; 1727 1727 if (isDeclaration(&token, 2, TOKreserved, NULL)) 1728 1728 { 1729 1729 spectype = parseType(&tp_ident); … … 1942 1942 */ 1943 1943 1944 1944 Objects *Parser::parseTemplateArgumentList() 1945 1945 { 1946 1946 //printf("Parser::parseTemplateArgumentList()\n"); 1947 1947 if (token.value != TOKlparen && token.value != TOKlcurly) 1948 1948 { error("!(TemplateArgumentList) expected following TemplateIdentifier"); 1949 1949 return new Objects(); 1950 1950 } 1951 1951 return parseTemplateArgumentList2(); 1952 1952 } 1953 1953 1954 1954 Objects *Parser::parseTemplateArgumentList2() 1955 1955 { 1956 1956 //printf("Parser::parseTemplateArgumentList2()\n"); 1957 1957 Objects *tiargs = new Objects(); 1958 1958 enum TOK endtok = TOKrparen; 1959 1959 nextToken(); 1960 1960 1961 1961 // Get TemplateArgumentList 1962 if (token.value != endtok) 1963 { 1964 while (1) 1965 { 1962 while (token.value != endtok) 1963 { 1966 1964 // See if it is an Expression or a Type 1967 1965 if (isDeclaration(&token, 0, TOKreserved, NULL)) 1968 1966 { // Template argument is a type 1969 1967 Type *ta = parseType(); 1970 1968 tiargs->push(ta); 1971 1969 } 1972 1970 else 1973 1971 { // Template argument is an expression 1974 1972 Expression *ea = parseAssignExp(); 1975 1973 1976 1974 if (ea->op == TOKfunction) 1977 1975 { FuncLiteralDeclaration *fd = ((FuncExp *)ea)->fd; 1978 1976 if (fd->type->ty == Tfunction) 1979 1977 { 1980 1978 TypeFunction *tf = (TypeFunction *)fd->type; 1981 1979 /* If there are parameters that consist of only an identifier, 1982 1980 * rather than assuming the identifier is a type, as we would 1983 1981 * for regular function declarations, assume the identifier 1984 1982 * is the parameter name, and we're building a template with 1985 1983 * a deduced type. … … 2009 2007 2010 2008 if (tpl) 2011 2009 { // Wrap a template around function fd 2012 2010 Dsymbols *decldefs = new Dsymbols(); 2013 2011 decldefs->push(fd); 2014 2012 TemplateDeclaration *tempdecl = 2015 2013 new TemplateDeclaration(fd->loc, fd->ident, tpl, NULL, decldefs, 0); 2016 2014 tempdecl->literal = 1; // it's a template 'literal' 2017 2015 tiargs->push(tempdecl); 2018 2016 goto L1; 2019 2017 } 2020 2018 } 2021 2019 } 2022 2020 2023 2021 tiargs->push(ea); 2024 2022 } 2025 2023 L1: 2026 2024 if (token.value != TOKcomma) 2027 2025 break; 2028 2026 nextToken(); 2029 }2030 2027 } 2031 2028 check(endtok, "template argument list"); 2032 2029 return tiargs; 2033 2030 } 2034 2031 2035 2032 /***************************** 2036 2033 * Parse single template argument, to support the syntax: 2037 2034 * foo!arg 2038 2035 * Input: 2039 2036 * current token is the arg 2040 2037 */ 2041 2038 2042 2039 Objects *Parser::parseTemplateArgument() 2043 2040 { 2044 2041 //printf("parseTemplateArgument()\n"); 2045 2042 Objects *tiargs = new Objects(); 2046 2043 Type *ta; 2047 2044 switch (token.value) 2048 2045 { 2049 2046 case TOKidentifier: … … 5248 5245 { // (arguments) { statements... } 5249 5246 save = TOKdelegate; 5250 5247 goto case_delegate; 5251 5248 } 5252 5249 // ( expression ) 5253 5250 nextToken(); 5254 5251 e = parseExpression(); 5255 5252 e->parens = 1; 5256 5253 check(loc, TOKrparen); 5257 5254 break; 5258 5255 5259 5256 case TOKlbracket: 5260 5257 { /* Parse array literals and associative array literals: 5261 5258 * [ value, value, value ... ] 5262 5259 * [ key:value, key:value, key:value ... ] 5263 5260 */ 5264 5261 Expressions *values = new Expressions(); 5265 5262 Expressions *keys = NULL; 5266 5263 5267 5264 nextToken(); 5268 if (token.value != TOKrbracket) 5269 { 5270 while (token.value != TOKeof) 5271 { 5265 while (token.value != TOKrbracket && token.value != TOKeof) 5266 { 5272 5267 Expression *e = parseAssignExp(); 5273 5268 if (token.value == TOKcolon && (keys || values->dim == 0)) 5274 5269 { nextToken(); 5275 5270 if (!keys) 5276 5271 keys = new Expressions(); 5277 5272 keys->push(e); 5278 5273 e = parseAssignExp(); 5279 5274 } 5280 5275 else if (keys) 5281 5276 { error("'key:value' expected for associative array literal"); 5282 5277 delete keys; 5283 5278 keys = NULL; 5284 5279 } 5285 5280 values->push(e); 5286 5281 if (token.value == TOKrbracket) 5287 5282 break; 5288 5283 check(TOKcomma); 5289 } 5290 } 5291 check(TOKrbracket); 5284 } 5285 check(loc, TOKrbracket); 5292 5286 5293 5287 if (keys) 5294 5288 e = new AssocArrayLiteralExp(loc, keys, values); 5295 5289 else 5296 5290 e = new ArrayLiteralExp(loc, values); 5297 5291 break; 5298 5292 } 5299 5293 5300 5294 case TOKlcurly: 5301 5295 // { statements... } 5302 5296 save = TOKdelegate; 5303 5297 goto case_delegate; 5304 5298 5305 5299 case TOKfunction: 5306 5300 case TOKdelegate: 5307 5301 save = token.value; 5308 5302 nextToken(); 5309 5303 case_delegate: 5310 5304 { 5311 5305 /* function type(parameters) { body } pure nothrow … … 5426 5420 { // array[] 5427 5421 e = new SliceExp(loc, e, NULL, NULL); 5428 5422 nextToken(); 5429 5423 } 5430 5424 else 5431 5425 { 5432 5426 index = parseAssignExp(); 5433 5427 if (token.value == TOKslice) 5434 5428 { // array[lwr .. upr] 5435 5429 nextToken(); 5436 5430 upr = parseAssignExp(); 5437 5431 e = new SliceExp(loc, e, index, upr); 5438 5432 } 5439 5433 else 5440 5434 { // array[index, i2, i3, i4, ...] 5441 5435 Expressions *arguments = new Expressions(); 5442 5436 arguments->push(index); 5443 5437 if (token.value == TOKcomma) 5444 5438 { 5445 5439 nextToken(); 5446 while (1) 5447 { Expression *arg; 5448 5449 arg = parseAssignExp(); 5440 while (token.value != TOKrbracket && token.value != TOKeof) 5441 { 5442 Expression *arg = parseAssignExp(); 5450 5443 arguments->push(arg); 5451 5444 if (token.value == TOKrbracket) 5452 5445 break; 5453 5446 check(TOKcomma); 5454 5447 } 5455 5448 } 5456 5449 e = new ArrayExp(loc, e, arguments); 5457 5450 } 5458 5451 check(TOKrbracket); 5459 5452 inBrackets--; 5460 5453 } 5461 5454 continue; 5462 5455 } 5463 5456 5464 5457 default: 5465 5458 return e; 5466 5459 } 5467 5460 nextToken(); 5468 5461 } 5469 5462 } … … 6128 6121 6129 6122 /************************* 6130 6123 * Collect argument list. 6131 6124 * Assume current token is ',', '(' or '['. 6132 6125 */ 6133 6126 6134 6127 Expressions *Parser::parseArguments() 6135 6128 { // function call 6136 6129 Expressions *arguments; 6137 6130 Expression *arg; 6138 6131 enum TOK endtok; 6139 6132 6140 6133 arguments = new Expressions(); 6141 6134 if (token.value == TOKlbracket) 6142 6135 endtok = TOKrbracket; 6143 6136 else 6144 6137 endtok = TOKrparen; 6145 6138 6146 6139 { 6147 6140 nextToken(); 6148 if(token.value != endtok)6141 while (token.value != endtok) 6149 6142 { 6150 while (1)6151 {6152 6143 arg = parseAssignExp(); 6153 6144 arguments->push(arg); 6154 6145 if (token.value == endtok) 6155 6146 break; 6156 6147 check(TOKcomma); 6157 }6158 6148 } 6159 6149 check(endtok); 6160 6150 } 6161 6151 return arguments; 6162 6152 } 6163 6153 6164 6154 /******************************************* 6165 6155 */ 6166 6156 6167 6157 Expression *Parser::parseNewExp(Expression *thisexp) 6168 6158 { Type *t; 6169 6159 Expressions *newargs; 6170 6160 Expressions *arguments = NULL; 6171 6161 Expression *e; 6172 6162 Loc loc = this->loc; 6173 6163 6174 6164 nextToken(); 6175 6165 newargs = NULL; 6176 6166 if (token.value == TOKlparen) 6177 6167 {
