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");