Mercurial > projects > ldc
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 { |