comparison dmd/statement.c @ 719:7261ff0f95ff

Implemented first class delegates. closes #101
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Wed, 22 Oct 2008 21:50:08 +0200
parents 30b42a283c8e
children f08e0ff8d28c
comparison
equal deleted inserted replaced
718:72ee105be27b 719:7261ff0f95ff
1515 Argument *a; 1515 Argument *a;
1516 Type *t; 1516 Type *t;
1517 Expression *flde; 1517 Expression *flde;
1518 Identifier *id; 1518 Identifier *id;
1519 Type *tret; 1519 Type *tret;
1520 TypeDelegate* dgty;
1521 TypeDelegate* dgty2;
1522 TypeDelegate* fldeTy;
1520 1523
1521 tret = func->type->nextOf(); 1524 tret = func->type->nextOf();
1522 1525
1523 // Need a variable to hold value from any return statements in body. 1526 // Need a variable to hold value from any return statements in body.
1524 if (!sc->func->vresult && tret && tret != Type::tvoid) 1527 if (!sc->func->vresult && tret && tret != Type::tvoid)
1598 /* Call: 1601 /* Call:
1599 * _aaApply(aggr, keysize, flde) 1602 * _aaApply(aggr, keysize, flde)
1600 */ 1603 */
1601 //LDC: Build arguments. 1604 //LDC: Build arguments.
1602 static FuncDeclaration *aaApply2_fd = NULL; 1605 static FuncDeclaration *aaApply2_fd = NULL;
1606 static TypeDelegate* aaApply2_dg;
1603 if(!aaApply2_fd) { 1607 if(!aaApply2_fd) {
1604 Arguments* args = new Arguments; 1608 Arguments* args = new Arguments;
1605 args->push(new Argument(STCin, Type::tvoid->pointerTo(), NULL, NULL)); 1609 args->push(new Argument(STCin, Type::tvoid->pointerTo(), NULL, NULL));
1606 args->push(new Argument(STCin, Type::tsize_t, NULL, NULL)); 1610 args->push(new Argument(STCin, Type::tsize_t, NULL, NULL));
1607 Arguments* dgargs = new Arguments; 1611 Arguments* dgargs = new Arguments;
1608 dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL)); 1612 dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL));
1609 dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL)); 1613 dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL));
1610 TypeDelegate* dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); 1614 aaApply2_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
1611 args->push(new Argument(STCin, dgty, NULL, NULL)); 1615 args->push(new Argument(STCin, aaApply2_dg, NULL, NULL));
1612 aaApply2_fd = FuncDeclaration::genCfunc(args, Type::tindex, "_aaApply2"); 1616 aaApply2_fd = FuncDeclaration::genCfunc(args, Type::tindex, "_aaApply2");
1613 } 1617 }
1614 static FuncDeclaration *aaApply_fd = NULL; 1618 static FuncDeclaration *aaApply_fd = NULL;
1619 static TypeDelegate* aaApply_dg;
1615 if(!aaApply_fd) { 1620 if(!aaApply_fd) {
1616 Arguments* args = new Arguments; 1621 Arguments* args = new Arguments;
1617 args->push(new Argument(STCin, Type::tvoid->pointerTo(), NULL, NULL)); 1622 args->push(new Argument(STCin, Type::tvoid->pointerTo(), NULL, NULL));
1618 args->push(new Argument(STCin, Type::tsize_t, NULL, NULL)); 1623 args->push(new Argument(STCin, Type::tsize_t, NULL, NULL));
1619 Arguments* dgargs = new Arguments; 1624 Arguments* dgargs = new Arguments;
1620 dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL)); 1625 dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL));
1621 TypeDelegate* dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); 1626 aaApply_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
1622 args->push(new Argument(STCin, dgty, NULL, NULL)); 1627 args->push(new Argument(STCin, aaApply_dg, NULL, NULL));
1623 aaApply_fd = FuncDeclaration::genCfunc(args, Type::tindex, "_aaApply"); 1628 aaApply_fd = FuncDeclaration::genCfunc(args, Type::tindex, "_aaApply");
1624 } 1629 }
1625 if (dim == 2) { 1630 if (dim == 2) {
1626 fdapply = aaApply2_fd; 1631 fdapply = aaApply2_fd;
1632 fldeTy = aaApply2_dg;
1627 } else { 1633 } else {
1628 fdapply = aaApply_fd; 1634 fdapply = aaApply_fd;
1635 fldeTy = aaApply_dg;
1629 } 1636 }
1630 ec = new VarExp(0, fdapply); 1637 ec = new VarExp(0, fdapply);
1631 Expressions *exps = new Expressions(); 1638 Expressions *exps = new Expressions();
1632 exps->push(aggr); 1639 exps->push(aggr);
1633 size_t keysize = taa->key->size(); 1640 size_t keysize = taa->key->size();
1634 keysize = (keysize + 3) & ~3; 1641 keysize = (keysize + 3) & ~3;
1635 exps->push(new IntegerExp(0, keysize, Type::tsize_t)); 1642 exps->push(new IntegerExp(0, keysize, Type::tsize_t));
1643
1644 // LDC paint delegate argument to the type runtime expects
1645 if (!fldeTy->equals(flde->type))
1646 {
1647 flde = new CastExp(loc, flde, flde->type);
1648 flde->type = fldeTy;
1649 }
1636 exps->push(flde); 1650 exps->push(flde);
1651
1637 e = new CallExp(loc, ec, exps); 1652 e = new CallExp(loc, ec, exps);
1638 e->type = Type::tindex; // don't run semantic() on e 1653 e->type = Type::tindex; // don't run semantic() on e
1639 } 1654 }
1640 else if (tab->ty == Tarray || tab->ty == Tsarray) 1655 else if (tab->ty == Tarray || tab->ty == Tsarray)
1641 { 1656 {
1672 args->push(new Argument(STCin, tn->arrayOf(), NULL, NULL)); 1687 args->push(new Argument(STCin, tn->arrayOf(), NULL, NULL));
1673 if (dim == 2) { 1688 if (dim == 2) {
1674 Arguments* dgargs = new Arguments; 1689 Arguments* dgargs = new Arguments;
1675 dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL)); 1690 dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL));
1676 dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL)); 1691 dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL));
1677 TypeDelegate* dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); 1692 dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
1678 args->push(new Argument(STCin, dgty, NULL, NULL)); 1693 args->push(new Argument(STCin, dgty, NULL, NULL));
1679 fdapply = FuncDeclaration::genCfunc(args, Type::tindex, fdname); 1694 fdapply = FuncDeclaration::genCfunc(args, Type::tindex, fdname);
1680 } else { 1695 } else {
1681 Arguments* dgargs = new Arguments; 1696 Arguments* dgargs = new Arguments;
1682 dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL)); 1697 dgargs->push(new Argument(STCin, Type::tvoidptr, NULL, NULL));
1683 TypeDelegate* dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd)); 1698 dgty = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
1684 args->push(new Argument(STCin, dgty, NULL, NULL)); 1699 args->push(new Argument(STCin, dgty, NULL, NULL));
1685 fdapply = FuncDeclaration::genCfunc(args, Type::tindex, fdname); 1700 fdapply = FuncDeclaration::genCfunc(args, Type::tindex, fdname);
1686 } 1701 }
1687 1702
1688 ec = new VarExp(0, fdapply); 1703 ec = new VarExp(0, fdapply);
1689 Expressions *exps = new Expressions(); 1704 Expressions *exps = new Expressions();
1690 if (tab->ty == Tsarray) 1705 if (tab->ty == Tsarray)
1691 aggr = aggr->castTo(sc, tn->arrayOf()); 1706 aggr = aggr->castTo(sc, tn->arrayOf());
1692 exps->push(aggr); 1707 exps->push(aggr);
1708
1709 // LDC paint delegate argument to the type runtime expects
1710 if (!dgty->equals(flde->type))
1711 {
1712 flde = new CastExp(loc, flde, flde->type);
1713 flde->type = dgty;
1714 }
1693 exps->push(flde); 1715 exps->push(flde);
1716
1694 e = new CallExp(loc, ec, exps); 1717 e = new CallExp(loc, ec, exps);
1695 e->type = Type::tindex; // don't run semantic() on e 1718 e->type = Type::tindex; // don't run semantic() on e
1696 } 1719 }
1697 else if (tab->ty == Tdelegate) 1720 else if (tab->ty == Tdelegate)
1698 { 1721 {