Mercurial > projects > ldc
comparison dmd2/statement.c @ 847:356e65836fb5
Merged DMD 2.021 frontend.
Removed generated files from dmd/dmd2 dirs.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Sat, 13 Dec 2008 16:14:37 +0100 |
parents | f08e0ff8d28c |
children | 03d7c4aac654 |
comparison
equal
deleted
inserted
replaced
846:bc982f1ad106 | 847:356e65836fb5 |
---|---|
1114 condition = resolveProperties(sc, condition); | 1114 condition = resolveProperties(sc, condition); |
1115 condition = condition->optimize(WANTvalue); | 1115 condition = condition->optimize(WANTvalue); |
1116 condition = condition->checkToBoolean(); | 1116 condition = condition->checkToBoolean(); |
1117 } | 1117 } |
1118 if (increment) | 1118 if (increment) |
1119 increment = increment->semantic(sc); | 1119 { increment = increment->semantic(sc); |
1120 increment = resolveProperties(sc, increment); | |
1121 } | |
1120 | 1122 |
1121 sc->sbreak = this; | 1123 sc->sbreak = this; |
1122 sc->scontinue = this; | 1124 sc->scontinue = this; |
1123 body = body->semantic(sc); | 1125 body = body->semantic(sc); |
1124 sc->noctor--; | 1126 sc->noctor--; |
1259 Statement *ForeachStatement::semantic(Scope *sc) | 1261 Statement *ForeachStatement::semantic(Scope *sc) |
1260 { | 1262 { |
1261 //printf("ForeachStatement::semantic() %p\n", this); | 1263 //printf("ForeachStatement::semantic() %p\n", this); |
1262 ScopeDsymbol *sym; | 1264 ScopeDsymbol *sym; |
1263 Statement *s = this; | 1265 Statement *s = this; |
1264 int dim = arguments->dim; | 1266 size_t dim = arguments->dim; |
1265 int i; | |
1266 TypeAArray *taa = NULL; | 1267 TypeAArray *taa = NULL; |
1267 | 1268 |
1268 Type *tn = NULL; | 1269 Type *tn = NULL; |
1269 Type *tnv = NULL; | 1270 Type *tnv = NULL; |
1270 | 1271 |
1389 s = new UnrolledLoopStatement(loc, statements); | 1390 s = new UnrolledLoopStatement(loc, statements); |
1390 s = s->semantic(sc); | 1391 s = s->semantic(sc); |
1391 return s; | 1392 return s; |
1392 } | 1393 } |
1393 | 1394 |
1394 for (i = 0; i < dim; i++) | |
1395 { Argument *arg = (Argument *)arguments->data[i]; | |
1396 if (!arg->type) | |
1397 { | |
1398 error("cannot infer type for %s", arg->ident->toChars()); | |
1399 return this; | |
1400 } | |
1401 } | |
1402 | |
1403 sym = new ScopeDsymbol(); | 1395 sym = new ScopeDsymbol(); |
1404 sym->parent = sc->scopesym; | 1396 sym->parent = sc->scopesym; |
1405 sc = sc->push(sym); | 1397 sc = sc->push(sym); |
1406 | 1398 |
1407 sc->noctor++; | 1399 sc->noctor++; |
1408 | 1400 |
1409 switch (tab->ty) | 1401 switch (tab->ty) |
1410 { | 1402 { |
1411 case Tarray: | 1403 case Tarray: |
1412 case Tsarray: | 1404 case Tsarray: |
1405 if (!checkForArgTypes()) | |
1406 return this; | |
1407 | |
1413 if (dim < 1 || dim > 2) | 1408 if (dim < 1 || dim > 2) |
1414 { | 1409 { |
1415 error("only one or two arguments for array foreach"); | 1410 error("only one or two arguments for array foreach"); |
1416 break; | 1411 break; |
1417 } | 1412 } |
1421 */ | 1416 */ |
1422 tn = tab->nextOf()->toBasetype(); | 1417 tn = tab->nextOf()->toBasetype(); |
1423 if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) | 1418 if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) |
1424 { Argument *arg; | 1419 { Argument *arg; |
1425 | 1420 |
1426 i = (dim == 1) ? 0 : 1; // index of value | 1421 int i = (dim == 1) ? 0 : 1; // index of value |
1427 arg = (Argument *)arguments->data[i]; | 1422 arg = (Argument *)arguments->data[i]; |
1428 arg->type = arg->type->semantic(loc, sc); | 1423 arg->type = arg->type->semantic(loc, sc); |
1429 tnv = arg->type->toBasetype(); | 1424 tnv = arg->type->toBasetype(); |
1430 if (tnv->ty != tn->ty && | 1425 if (tnv->ty != tn->ty && |
1431 (tnv->ty == Tchar || tnv->ty == Twchar || tnv->ty == Tdchar)) | 1426 (tnv->ty == Tchar || tnv->ty == Twchar || tnv->ty == Tdchar)) |
1439 } | 1434 } |
1440 goto Lapply; | 1435 goto Lapply; |
1441 } | 1436 } |
1442 } | 1437 } |
1443 | 1438 |
1444 for (i = 0; i < dim; i++) | 1439 for (size_t i = 0; i < dim; i++) |
1445 { // Declare args | 1440 { // Declare args |
1446 Argument *arg = (Argument *)arguments->data[i]; | 1441 Argument *arg = (Argument *)arguments->data[i]; |
1447 VarDeclaration *var; | 1442 VarDeclaration *var; |
1448 | 1443 |
1449 var = new VarDeclaration(loc, arg->type, arg->ident, NULL); | 1444 var = new VarDeclaration(loc, arg->type, arg->ident, NULL); |
1504 if (key && key->storage_class & (STCout | STCref)) | 1499 if (key && key->storage_class & (STCout | STCref)) |
1505 error("foreach: key cannot be out or ref"); | 1500 error("foreach: key cannot be out or ref"); |
1506 break; | 1501 break; |
1507 | 1502 |
1508 case Taarray: | 1503 case Taarray: |
1504 if (!checkForArgTypes()) | |
1505 return this; | |
1506 | |
1509 taa = (TypeAArray *)tab; | 1507 taa = (TypeAArray *)tab; |
1510 if (dim < 1 || dim > 2) | 1508 if (dim < 1 || dim > 2) |
1511 { | 1509 { |
1512 error("only one or two arguments for associative array foreach"); | 1510 error("only one or two arguments for associative array foreach"); |
1513 break; | 1511 break; |
1518 } | 1516 } |
1519 goto Lapply; | 1517 goto Lapply; |
1520 | 1518 |
1521 case Tclass: | 1519 case Tclass: |
1522 case Tstruct: | 1520 case Tstruct: |
1521 #if DMDV2 | |
1522 { /* Look for range iteration, i.e. the properties | |
1523 * .empty, .next, .retreat, .head and .rear | |
1524 * foreach (e; range) { ... } | |
1525 * translates to: | |
1526 * for (auto __r = range; !__r.empty; __r.next) | |
1527 * { auto e = __r.head; | |
1528 * ... | |
1529 * } | |
1530 */ | |
1531 if (dim != 1) // only one argument allowed with ranges | |
1532 goto Lapply; | |
1533 AggregateDeclaration *ad = (tab->ty == Tclass) | |
1534 ? (AggregateDeclaration *)((TypeClass *)tab)->sym | |
1535 : (AggregateDeclaration *)((TypeStruct *)tab)->sym; | |
1536 Identifier *idhead; | |
1537 Identifier *idnext; | |
1538 if (op == TOKforeach) | |
1539 { idhead = Id::Fhead; | |
1540 idnext = Id::Fnext; | |
1541 } | |
1542 else | |
1543 { idhead = Id::Ftoe; | |
1544 idnext = Id::Fretreat; | |
1545 } | |
1546 Dsymbol *shead = search_function(ad, idhead); | |
1547 if (!shead) | |
1548 goto Lapply; | |
1549 | |
1550 /* Generate a temporary __r and initialize it with the aggregate. | |
1551 */ | |
1552 Identifier *id = Identifier::generateId("__r"); | |
1553 VarDeclaration *r = new VarDeclaration(loc, NULL, id, new ExpInitializer(loc, aggr)); | |
1554 r->semantic(sc); | |
1555 Statement *init = new DeclarationStatement(loc, r); | |
1556 | |
1557 // !__r.empty | |
1558 Expression *e = new VarExp(loc, r); | |
1559 e = new DotIdExp(loc, e, Id::Fempty); | |
1560 Expression *condition = new NotExp(loc, e); | |
1561 | |
1562 // __r.next | |
1563 e = new VarExp(loc, r); | |
1564 Expression *increment = new DotIdExp(loc, e, idnext); | |
1565 | |
1566 /* Declaration statement for e: | |
1567 * auto e = __r.idhead; | |
1568 */ | |
1569 e = new VarExp(loc, r); | |
1570 Expression *einit = new DotIdExp(loc, e, idhead); | |
1571 einit = einit->semantic(sc); | |
1572 Argument *arg = (Argument *)arguments->data[0]; | |
1573 VarDeclaration *ve = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, einit)); | |
1574 ve->storage_class |= STCforeach; | |
1575 ve->storage_class |= arg->storageClass & (STCin | STCout | STCref | STCconst | STCinvariant); | |
1576 | |
1577 DeclarationExp *de = new DeclarationExp(loc, ve); | |
1578 | |
1579 Statement *body = new CompoundStatement(loc, | |
1580 new DeclarationStatement(loc, de), this->body); | |
1581 | |
1582 s = new ForStatement(loc, init, condition, increment, body); | |
1583 s = s->semantic(sc); | |
1584 break; | |
1585 } | |
1586 #endif | |
1523 case Tdelegate: | 1587 case Tdelegate: |
1524 Lapply: | 1588 Lapply: |
1525 { FuncDeclaration *fdapply; | 1589 { FuncDeclaration *fdapply; |
1526 Arguments *args; | 1590 Arguments *args; |
1527 Expression *ec; | 1591 Expression *ec; |
1534 Type *tret; | 1598 Type *tret; |
1535 TypeDelegate* dgty; | 1599 TypeDelegate* dgty; |
1536 TypeDelegate* dgty2; | 1600 TypeDelegate* dgty2; |
1537 TypeDelegate* fldeTy; | 1601 TypeDelegate* fldeTy; |
1538 | 1602 |
1603 if (!checkForArgTypes()) | |
1604 return this; | |
1605 | |
1539 tret = func->type->nextOf(); | 1606 tret = func->type->nextOf(); |
1540 | 1607 |
1541 // Need a variable to hold value from any return statements in body. | 1608 // Need a variable to hold value from any return statements in body. |
1542 if (!sc->func->vresult && tret && tret != Type::tvoid) | 1609 if (!sc->func->vresult && tret && tret != Type::tvoid) |
1543 { VarDeclaration *v; | 1610 { VarDeclaration *v; |
1553 | 1620 |
1554 /* Turn body into the function literal: | 1621 /* Turn body into the function literal: |
1555 * int delegate(ref T arg) { body } | 1622 * int delegate(ref T arg) { body } |
1556 */ | 1623 */ |
1557 args = new Arguments(); | 1624 args = new Arguments(); |
1558 for (i = 0; i < dim; i++) | 1625 for (size_t i = 0; i < dim; i++) |
1559 { Argument *arg = (Argument *)arguments->data[i]; | 1626 { Argument *arg = (Argument *)arguments->data[i]; |
1560 | 1627 |
1561 arg->type = arg->type->semantic(loc, sc); | 1628 arg->type = arg->type->semantic(loc, sc); |
1562 if (arg->storageClass & STCref) | 1629 if (arg->storageClass & STCref) |
1563 id = arg->ident; | 1630 id = arg->ident; |
1813 sc->noctor--; | 1880 sc->noctor--; |
1814 sc->pop(); | 1881 sc->pop(); |
1815 return s; | 1882 return s; |
1816 } | 1883 } |
1817 | 1884 |
1885 bool ForeachStatement::checkForArgTypes() | |
1886 { | |
1887 for (size_t i = 0; i < arguments->dim; i++) | |
1888 { Argument *arg = (Argument *)arguments->data[i]; | |
1889 if (!arg->type) | |
1890 { | |
1891 error("cannot infer type for %s", arg->ident->toChars()); | |
1892 return FALSE; | |
1893 } | |
1894 } | |
1895 return TRUE; | |
1896 } | |
1897 | |
1818 int ForeachStatement::hasBreak() | 1898 int ForeachStatement::hasBreak() |
1819 { | 1899 { |
1820 return TRUE; | 1900 return TRUE; |
1821 } | 1901 } |
1822 | 1902 |
1885 buf->writebyte('}'); | 1965 buf->writebyte('}'); |
1886 buf->writenl(); | 1966 buf->writenl(); |
1887 } | 1967 } |
1888 | 1968 |
1889 /**************************** ForeachRangeStatement ***************************/ | 1969 /**************************** ForeachRangeStatement ***************************/ |
1970 | |
1971 #if DMDV2 | |
1890 | 1972 |
1891 ForeachRangeStatement::ForeachRangeStatement(Loc loc, enum TOK op, Argument *arg, | 1973 ForeachRangeStatement::ForeachRangeStatement(Loc loc, enum TOK op, Argument *arg, |
1892 Expression *lwr, Expression *upr, Statement *body) | 1974 Expression *lwr, Expression *upr, Statement *body) |
1893 : Statement(loc) | 1975 : Statement(loc) |
1894 { | 1976 { |
2045 body->toCBuffer(buf, hgs); | 2127 body->toCBuffer(buf, hgs); |
2046 buf->writebyte('}'); | 2128 buf->writebyte('}'); |
2047 buf->writenl(); | 2129 buf->writenl(); |
2048 } | 2130 } |
2049 | 2131 |
2132 #endif | |
2133 | |
2050 /******************************** IfStatement ***************************/ | 2134 /******************************** IfStatement ***************************/ |
2051 | 2135 |
2052 IfStatement::IfStatement(Loc loc, Argument *arg, Expression *condition, Statement *ifbody, Statement *elsebody) | 2136 IfStatement::IfStatement(Loc loc, Argument *arg, Expression *condition, Statement *ifbody, Statement *elsebody) |
2053 : Statement(loc) | 2137 : Statement(loc) |
2054 { | 2138 { |
2337 fprintf(stdmsg, "\n"); | 2421 fprintf(stdmsg, "\n"); |
2338 } | 2422 } |
2339 } | 2423 } |
2340 else if (ident == Id::lib) | 2424 else if (ident == Id::lib) |
2341 { | 2425 { |
2426 #if 1 | |
2427 /* Should this be allowed? | |
2428 */ | |
2429 error("pragma(lib) not allowed as statement"); | |
2430 #else | |
2342 if (!args || args->dim != 1) | 2431 if (!args || args->dim != 1) |
2343 error("string expected for library name"); | 2432 error("string expected for library name"); |
2344 else | 2433 else |
2345 { | 2434 { |
2346 Expression *e = (Expression *)args->data[0]; | 2435 Expression *e = (Expression *)args->data[0]; |
2358 name[se->len] = 0; | 2447 name[se->len] = 0; |
2359 printf("library %s\n", name); | 2448 printf("library %s\n", name); |
2360 mem.free(name); | 2449 mem.free(name); |
2361 } | 2450 } |
2362 } | 2451 } |
2452 #endif | |
2363 } | 2453 } |
2364 else if (ident == Id::startaddress) | 2454 else if (ident == Id::startaddress) |
2365 { | 2455 { |
2366 if (!args || args->dim != 1) | 2456 if (!args || args->dim != 1) |
2367 error("function name expected for start address"); | 2457 error("function name expected for start address"); |