4
4
5
5
#include "go.h"
6
6
7
- static Node * walkprint (Node * , NodeList * * );
7
+ static Node * walkprint (Node * , NodeList * * , int );
8
8
static Node * conv (Node * , Type * );
9
9
static Node * mapfn (char * , Type * );
10
10
static Node * makenewvar (Type * , NodeList * * , Node * * );
@@ -355,7 +355,18 @@ walkstmt(Node **np)
355
355
356
356
case ODEFER :
357
357
hasdefer = 1 ;
358
- walkexpr (& n -> left , & n -> ninit );
358
+ switch (n -> left -> op ) {
359
+ case OPRINT :
360
+ case OPRINTN :
361
+ case OPANIC :
362
+ case OPANICN :
363
+ walkexprlist (n -> left -> list , & n -> ninit );
364
+ n -> left = walkprint (n -> left , & n -> ninit , 1 );
365
+ break ;
366
+ default :
367
+ walkexpr (& n -> left , & n -> ninit );
368
+ break ;
369
+ }
359
370
break ;
360
371
361
372
case OFOR :
@@ -539,7 +550,7 @@ walkexpr(Node **np, NodeList **init)
539
550
case OPANIC :
540
551
case OPANICN :
541
552
walkexprlist (n -> list , init );
542
- n = walkprint (n , init );
553
+ n = walkprint (n , init , 0 );
543
554
goto ret ;
544
555
545
556
case OLITERAL :
@@ -1510,24 +1521,40 @@ ascompatte(int op, Type **nl, NodeList *lr, int fp, NodeList **init)
1510
1521
1511
1522
// generate code for print
1512
1523
static Node *
1513
- walkprint (Node * nn , NodeList * * init )
1524
+ walkprint (Node * nn , NodeList * * init , int defer )
1514
1525
{
1515
1526
Node * r ;
1516
1527
Node * n ;
1517
1528
NodeList * l , * all ;
1518
1529
Node * on ;
1519
1530
Type * t ;
1520
1531
int notfirst , et , op ;
1521
- NodeList * calls ;
1532
+ NodeList * calls , * intypes , * args ;
1533
+ Fmt fmt ;
1522
1534
1535
+ on = nil ;
1523
1536
op = nn -> op ;
1524
1537
all = nn -> list ;
1525
1538
calls = nil ;
1526
1539
notfirst = 0 ;
1540
+ intypes = nil ;
1541
+ args = nil ;
1542
+
1543
+ memset (& fmt , 0 , sizeof fmt );
1544
+ if (defer ) {
1545
+ // defer print turns into defer printf with format string
1546
+ fmtstrinit (& fmt );
1547
+ intypes = list (intypes , nod (ODCLFIELD , N , typenod (types [TSTRING ])));
1548
+ args = list1 (nod (OXXX , N , N ));
1549
+ }
1527
1550
1528
1551
for (l = all ; l ; l = l -> next ) {
1529
- if (notfirst )
1530
- calls = list (calls , mkcall ("printsp" , T , init ));
1552
+ if (notfirst ) {
1553
+ if (defer )
1554
+ fmtprint (& fmt , " " );
1555
+ else
1556
+ calls = list (calls , mkcall ("printsp" , T , init ));
1557
+ }
1531
1558
notfirst = op == OPRINTN || op == OPANICN ;
1532
1559
1533
1560
n = l -> n ;
@@ -1548,62 +1575,121 @@ walkprint(Node *nn, NodeList **init)
1548
1575
if (n -> type == T || n -> type -> etype == TFORW )
1549
1576
continue ;
1550
1577
1578
+ t = n -> type ;
1551
1579
et = n -> type -> etype ;
1552
1580
if (isinter (n -> type )) {
1553
- if (isnilinter (n -> type ))
1554
- on = syslook ("printeface" , 1 );
1555
- else
1556
- on = syslook ("printiface" , 1 );
1557
- argtype (on , n -> type ); // any-1
1581
+ if (defer ) {
1582
+ if (isnilinter (n -> type ))
1583
+ fmtprint (& fmt , "%%e" );
1584
+ else
1585
+ fmtprint (& fmt , "%%i" );
1586
+ } else {
1587
+ if (isnilinter (n -> type ))
1588
+ on = syslook ("printeface" , 1 );
1589
+ else
1590
+ on = syslook ("printiface" , 1 );
1591
+ argtype (on , n -> type ); // any-1
1592
+ }
1558
1593
} else if (isptr [et ] || et == TCHAN || et == TMAP || et == TFUNC ) {
1559
- on = syslook ("printpointer" , 1 );
1560
- argtype (on , n -> type ); // any-1
1594
+ if (defer ) {
1595
+ fmtprint (& fmt , "%%p" );
1596
+ } else {
1597
+ on = syslook ("printpointer" , 1 );
1598
+ argtype (on , n -> type ); // any-1
1599
+ }
1561
1600
} else if (isslice (n -> type )) {
1562
- on = syslook ("printslice" , 1 );
1563
- argtype (on , n -> type ); // any-1
1601
+ if (defer ) {
1602
+ fmtprint (& fmt , "%%a" );
1603
+ } else {
1604
+ on = syslook ("printslice" , 1 );
1605
+ argtype (on , n -> type ); // any-1
1606
+ }
1564
1607
} else if (isint [et ]) {
1565
- if (et == TUINT64 )
1566
- on = syslook ("printuint" , 0 );
1567
- else
1568
- on = syslook ("printint" , 0 );
1608
+ if (defer ) {
1609
+ if (et == TUINT64 )
1610
+ fmtprint (& fmt , "%%U" );
1611
+ else {
1612
+ fmtprint (& fmt , "%%D" );
1613
+ t = types [TINT64 ];
1614
+ }
1615
+ } else {
1616
+ if (et == TUINT64 )
1617
+ on = syslook ("printuint" , 0 );
1618
+ else
1619
+ on = syslook ("printint" , 0 );
1620
+ }
1569
1621
} else if (isfloat [et ]) {
1570
- on = syslook ("printfloat" , 0 );
1622
+ if (defer ) {
1623
+ fmtprint (& fmt , "%%f" );
1624
+ t = types [TFLOAT64 ];
1625
+ } else
1626
+ on = syslook ("printfloat" , 0 );
1571
1627
} else if (et == TBOOL ) {
1572
- on = syslook ("printbool" , 0 );
1628
+ if (defer )
1629
+ fmtprint (& fmt , "%%t" );
1630
+ else
1631
+ on = syslook ("printbool" , 0 );
1573
1632
} else if (et == TSTRING ) {
1574
- on = syslook ("printstring" , 0 );
1633
+ if (defer )
1634
+ fmtprint (& fmt , "%%S" );
1635
+ else
1636
+ on = syslook ("printstring" , 0 );
1575
1637
} else {
1576
1638
badtype (OPRINT , n -> type , T );
1577
1639
continue ;
1578
1640
}
1579
1641
1580
- t = * getinarg (on -> type );
1581
- if (t != nil )
1582
- t = t -> type ;
1583
- if (t != nil )
1584
- t = t -> type ;
1642
+ if (!defer ) {
1643
+ t = * getinarg (on -> type );
1644
+ if (t != nil )
1645
+ t = t -> type ;
1646
+ if (t != nil )
1647
+ t = t -> type ;
1648
+ }
1585
1649
1586
1650
if (!eqtype (t , n -> type )) {
1587
1651
n = nod (OCONV , n , N );
1588
1652
n -> type = t ;
1589
1653
}
1590
- r = nod (OCALL , on , N );
1591
- r -> list = list1 (n );
1592
- calls = list (calls , r );
1654
+
1655
+ if (defer ) {
1656
+ intypes = list (intypes , nod (ODCLFIELD , N , typenod (t )));
1657
+ args = list (args , n );
1658
+ } else {
1659
+ r = nod (OCALL , on , N );
1660
+ r -> list = list1 (n );
1661
+ calls = list (calls , r );
1662
+ }
1593
1663
}
1594
1664
1595
- if (op == OPRINTN )
1596
- calls = list (calls , mkcall ("printnl" , T , nil ));
1597
- typechecklist (calls , Etop );
1598
- walkexprlist (calls , init );
1599
-
1600
- if (op == OPANIC || op == OPANICN )
1601
- r = mkcall ("panicl" , T , nil );
1602
- else
1603
- r = nod (OEMPTY , N , N );
1604
- typecheck (& r , Etop );
1605
- walkexpr (& r , init );
1606
- r -> ninit = calls ;
1665
+ if (defer ) {
1666
+ if (op == OPRINTN )
1667
+ fmtprint (& fmt , "\n" );
1668
+ if (op == OPANIC || op == OPANICN )
1669
+ fmtprint (& fmt , "%%!" );
1670
+ on = syslook ("printf" , 1 );
1671
+ on -> type = functype (nil , intypes , nil );
1672
+ args -> n = nod (OLITERAL , N , N );
1673
+ args -> n -> val .ctype = CTSTR ;
1674
+ args -> n -> val .u .sval = strlit (fmtstrflush (& fmt ));
1675
+ r = nod (OCALL , on , N );
1676
+ r -> list = args ;
1677
+ typecheck (& r , Etop );
1678
+ walkexpr (& r , init );
1679
+ } else {
1680
+ if (op == OPRINTN )
1681
+ calls = list (calls , mkcall ("printnl" , T , nil ));
1682
+ typechecklist (calls , Etop );
1683
+ walkexprlist (calls , init );
1684
+
1685
+ if (op == OPANIC || op == OPANICN )
1686
+ r = mkcall ("panicl" , T , nil );
1687
+ else
1688
+ r = nod (OEMPTY , N , N );
1689
+ typecheck (& r , Etop );
1690
+ walkexpr (& r , init );
1691
+ r -> ninit = calls ;
1692
+ }
1607
1693
return r ;
1608
1694
}
1609
1695
0 commit comments