[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gawk-diffs] [SCM] gawk branch, gawk_performance, updated. bf958505d3b16
From: |
John Haque |
Subject: |
[gawk-diffs] [SCM] gawk branch, gawk_performance, updated. bf958505d3b1681a91f10e866636e9088d732a60 |
Date: |
Fri, 07 Oct 2011 10:13:55 +0000 |
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gawk".
The branch, gawk_performance has been updated
via bf958505d3b1681a91f10e866636e9088d732a60 (commit)
from a95ec08516e3a7693274ac75a87eea6cf651de22 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=bf958505d3b1681a91f10e866636e9088d732a60
commit bf958505d3b1681a91f10e866636e9088d732a60
Author: john haque <address@hidden>
Date: Fri Oct 7 05:13:25 2011 -0500
Optimize tail-recursive calls.
diff --git a/ChangeLog b/ChangeLog
index c093ad2..535d30a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2011-10-07 John Haque <address@hidden>
+ Tail recursion optimization.
+ * awkgram.y (grammar, mk_function): Recognize tail-recursive
+ calls.
+ * awk.h (tail_call, num_tail_calls): New defines.
+ * eval.c (setup_frame): Reuse function call stack for
+ tail-recursive calls.
+ (dump_fcall_stack): Reworked.
+
2011-09-08 John Haque <address@hidden>
Optimization for compound assignment, increment and
decrement operators; Avoid unref and make_number calls
diff --git a/array.c b/array.c
index 436002a..e6e0c26 100644
--- a/array.c
+++ b/array.c
@@ -1285,6 +1285,7 @@ assoc_list(NODE *symbol, const char *sort_str, SORT_CTXT
sort_ctxt)
qsort_compfunc cmp_func = 0;
INSTRUCTION *code = NULL;
extern int currule;
+ int save_rule;
num_elems = symbol->table_size;
assert(num_elems > 0);
@@ -1345,7 +1346,7 @@ assoc_list(NODE *symbol, const char *sort_str, SORT_CTXT
sort_ctxt)
* to undefined (0). `exit' is handled in sort_user_func.
*/
- (code + 1)->inrule = currule; /* save current rule */
+ save_rule = currule; /* save current rule */
currule = 0;
PUSH_CODE(code);
@@ -1360,7 +1361,7 @@ assoc_list(NODE *symbol, const char *sort_str, SORT_CTXT
sort_ctxt)
if (cmp_func == sort_user_func) {
code = POP_CODE();
- currule = (code + 1)->inrule; /* restore current rule */
+ currule = save_rule; /* restore current rule */
bcfree(code->nexti); /* Op_stop */
bcfree(code); /* Op_func_call */
}
diff --git a/awk.h b/awk.h
index f5e1325..cef1bc3 100644
--- a/awk.h
+++ b/awk.h
@@ -454,6 +454,7 @@ typedef struct exp_node {
#define stack sub.nodep.r.av
#define func_node sub.nodep.x.extra
#define reti sub.nodep.reflags
+#define num_tail_calls sub.nodep.cnt
/* Node_var: */
#define var_value lnode
@@ -706,7 +707,6 @@ typedef struct exp_instruction {
#define lextok d.name
#define param_count x.xl
-
/* Op_rule */
#define in_rule x.xl
#define source_file d.name
@@ -743,7 +743,8 @@ typedef struct exp_instruction {
#define func_body x.xn
/* Op_func_call */
-#define inrule d.dl
+#define tail_call d.dl
+
/* Op_subscript */
#define sub_count d.dl
diff --git a/awkgram.c b/awkgram.c
index d6474f2..432473f 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -128,7 +128,7 @@ static int one_line_close(int fd);
static int want_source = FALSE;
static int want_regexp; /* lexical scanning kludge */
-static int can_return; /* parsing kludge */
+static char *in_function; /* parsing kludge */
static int rule = 0;
const char *const ruletab[] = {
@@ -707,20 +707,20 @@ static const yytype_uint16 yyrline[] =
317, 326, 336, 338, 340, 346, 351, 352, 356, 375,
374, 408, 410, 415, 416, 429, 434, 435, 439, 441,
443, 450, 540, 582, 624, 739, 746, 753, 763, 772,
- 781, 790, 805, 821, 820, 832, 844, 844, 938, 938,
- 963, 986, 992, 993, 999, 1000, 1007, 1012, 1024, 1038,
- 1040, 1046, 1051, 1053, 1061, 1063, 1072, 1073, 1081, 1086,
- 1086, 1097, 1101, 1109, 1110, 1113, 1115, 1120, 1121, 1130,
- 1131, 1136, 1141, 1147, 1149, 1151, 1158, 1159, 1165, 1166,
- 1171, 1173, 1178, 1180, 1182, 1184, 1190, 1197, 1199, 1201,
- 1217, 1227, 1234, 1236, 1241, 1243, 1245, 1253, 1255, 1260,
- 1262, 1267, 1269, 1271, 1321, 1323, 1325, 1327, 1329, 1331,
- 1333, 1335, 1358, 1363, 1368, 1393, 1399, 1401, 1403, 1405,
- 1407, 1409, 1414, 1418, 1449, 1451, 1457, 1463, 1476, 1477,
- 1478, 1483, 1488, 1492, 1496, 1509, 1522, 1527, 1563, 1581,
- 1582, 1588, 1589, 1594, 1596, 1603, 1620, 1637, 1639, 1646,
- 1651, 1659, 1669, 1682, 1691, 1695, 1699, 1703, 1707, 1711,
- 1714, 1716, 1720, 1724, 1728
+ 781, 790, 805, 821, 820, 844, 856, 856, 950, 950,
+ 975, 998, 1004, 1005, 1011, 1012, 1019, 1024, 1036, 1050,
+ 1052, 1058, 1063, 1065, 1073, 1075, 1084, 1085, 1093, 1098,
+ 1098, 1109, 1113, 1121, 1122, 1125, 1127, 1132, 1133, 1142,
+ 1143, 1148, 1153, 1159, 1161, 1163, 1170, 1171, 1177, 1178,
+ 1183, 1185, 1190, 1192, 1194, 1196, 1202, 1209, 1211, 1213,
+ 1229, 1239, 1246, 1248, 1253, 1255, 1257, 1265, 1267, 1272,
+ 1274, 1279, 1281, 1283, 1333, 1335, 1337, 1339, 1341, 1343,
+ 1345, 1347, 1370, 1375, 1380, 1405, 1411, 1413, 1415, 1417,
+ 1419, 1421, 1426, 1430, 1461, 1463, 1469, 1475, 1488, 1489,
+ 1490, 1495, 1500, 1504, 1508, 1521, 1534, 1539, 1575, 1593,
+ 1594, 1600, 1601, 1606, 1608, 1615, 1632, 1649, 1651, 1658,
+ 1663, 1671, 1681, 1694, 1703, 1707, 1711, 1715, 1719, 1723,
+ 1726, 1728, 1732, 1736, 1740
};
#endif
@@ -2099,7 +2099,7 @@ yyreduce:
/* Line 1821 of yacc.c */
#line 231 "awkgram.y"
{
- can_return = FALSE;
+ in_function = NULL;
(void) mk_function((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
yyerrok;
}
@@ -2293,11 +2293,11 @@ yyreduce:
(yyvsp[(1) - (6)])->source_file = source;
if (install_function((yyvsp[(2) - (6)])->lextok, (yyvsp[(1) -
(6)]), (yyvsp[(4) - (6)])) < 0)
YYABORT;
+ in_function = (yyvsp[(2) - (6)])->lextok;
(yyvsp[(2) - (6)])->lextok = NULL;
bcfree((yyvsp[(2) - (6)]));
/* $4 already free'd in install_function */
(yyval) = (yyvsp[(1) - (6)]);
- can_return = TRUE;
}
break;
@@ -2839,7 +2839,7 @@ regular_loop:
/* Line 1821 of yacc.c */
#line 821 "awkgram.y"
{
- if (! can_return)
+ if (! in_function)
yyerror(_("`return' used outside function context"));
}
break;
@@ -2853,22 +2853,34 @@ regular_loop:
(yyval) = list_create((yyvsp[(1) - (4)]));
(void) list_prepend((yyval), instruction(Op_push_i));
(yyval)->nexti->memory = dupnode(Nnull_string);
- } else
+ } else {
+ if (do_optimize > 1
+ && (yyvsp[(3) - (4)])->lasti->opcode ==
Op_func_call
+ && STREQ((yyvsp[(3) - (4)])->lasti->func_name,
in_function)
+ ) {
+ /* Do tail recursion optimization. Tail
+ * call without a return value is recognized
+ * in mk_function().
+ */
+ ((yyvsp[(3) - (4)])->lasti + 1)->tail_call =
TRUE;
+ }
+
(yyval) = list_append((yyvsp[(3) - (4)]), (yyvsp[(1) -
(4)]));
+ }
}
break;
case 56:
/* Line 1821 of yacc.c */
-#line 844 "awkgram.y"
+#line 856 "awkgram.y"
{ in_print = TRUE; in_parens = 0; }
break;
case 57:
/* Line 1821 of yacc.c */
-#line 845 "awkgram.y"
+#line 857 "awkgram.y"
{
/*
* Optimization: plain `print' has no expression list, so $3 is
null.
@@ -2966,14 +2978,14 @@ regular_loop:
case 58:
/* Line 1821 of yacc.c */
-#line 938 "awkgram.y"
+#line 950 "awkgram.y"
{ sub_counter = 0; }
break;
case 59:
/* Line 1821 of yacc.c */
-#line 939 "awkgram.y"
+#line 951 "awkgram.y"
{
char *arr = (yyvsp[(2) - (4)])->lextok;
@@ -3003,7 +3015,7 @@ regular_loop:
case 60:
/* Line 1821 of yacc.c */
-#line 968 "awkgram.y"
+#line 980 "awkgram.y"
{
static short warned = FALSE;
char *arr = (yyvsp[(3) - (4)])->lextok;
@@ -3027,35 +3039,35 @@ regular_loop:
case 61:
/* Line 1821 of yacc.c */
-#line 987 "awkgram.y"
+#line 999 "awkgram.y"
{ (yyval) = optimize_assignment((yyvsp[(1) - (1)])); }
break;
case 62:
/* Line 1821 of yacc.c */
-#line 992 "awkgram.y"
+#line 1004 "awkgram.y"
{ (yyval) = NULL; }
break;
case 63:
/* Line 1821 of yacc.c */
-#line 994 "awkgram.y"
+#line 1006 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 64:
/* Line 1821 of yacc.c */
-#line 999 "awkgram.y"
+#line 1011 "awkgram.y"
{ (yyval) = NULL; }
break;
case 65:
/* Line 1821 of yacc.c */
-#line 1001 "awkgram.y"
+#line 1013 "awkgram.y"
{
if ((yyvsp[(1) - (2)]) == NULL)
(yyval) = list_create((yyvsp[(2) - (2)]));
@@ -3067,14 +3079,14 @@ regular_loop:
case 66:
/* Line 1821 of yacc.c */
-#line 1008 "awkgram.y"
+#line 1020 "awkgram.y"
{ (yyval) = NULL; }
break;
case 67:
/* Line 1821 of yacc.c */
-#line 1013 "awkgram.y"
+#line 1025 "awkgram.y"
{
INSTRUCTION *casestmt = (yyvsp[(5) - (5)]);
if ((yyvsp[(5) - (5)]) == NULL)
@@ -3091,7 +3103,7 @@ regular_loop:
case 68:
/* Line 1821 of yacc.c */
-#line 1025 "awkgram.y"
+#line 1037 "awkgram.y"
{
INSTRUCTION *casestmt = (yyvsp[(4) - (4)]);
if ((yyvsp[(4) - (4)]) == NULL)
@@ -3107,14 +3119,14 @@ regular_loop:
case 69:
/* Line 1821 of yacc.c */
-#line 1039 "awkgram.y"
+#line 1051 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 70:
/* Line 1821 of yacc.c */
-#line 1041 "awkgram.y"
+#line 1053 "awkgram.y"
{
(yyvsp[(2) - (2)])->memory->numbr = -(force_number((yyvsp[(2) -
(2)])->memory));
bcfree((yyvsp[(1) - (2)]));
@@ -3125,7 +3137,7 @@ regular_loop:
case 71:
/* Line 1821 of yacc.c */
-#line 1047 "awkgram.y"
+#line 1059 "awkgram.y"
{
bcfree((yyvsp[(1) - (2)]));
(yyval) = (yyvsp[(2) - (2)]);
@@ -3135,14 +3147,14 @@ regular_loop:
case 72:
/* Line 1821 of yacc.c */
-#line 1052 "awkgram.y"
+#line 1064 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 73:
/* Line 1821 of yacc.c */
-#line 1054 "awkgram.y"
+#line 1066 "awkgram.y"
{
(yyvsp[(1) - (1)])->opcode = Op_push_re;
(yyval) = (yyvsp[(1) - (1)]);
@@ -3152,21 +3164,21 @@ regular_loop:
case 74:
/* Line 1821 of yacc.c */
-#line 1062 "awkgram.y"
+#line 1074 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 75:
/* Line 1821 of yacc.c */
-#line 1064 "awkgram.y"
+#line 1076 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 77:
/* Line 1821 of yacc.c */
-#line 1074 "awkgram.y"
+#line 1086 "awkgram.y"
{
(yyval) = (yyvsp[(2) - (3)]);
}
@@ -3175,7 +3187,7 @@ regular_loop:
case 78:
/* Line 1821 of yacc.c */
-#line 1081 "awkgram.y"
+#line 1093 "awkgram.y"
{
in_print = FALSE;
in_parens = 0;
@@ -3186,14 +3198,14 @@ regular_loop:
case 79:
/* Line 1821 of yacc.c */
-#line 1086 "awkgram.y"
+#line 1098 "awkgram.y"
{ in_print = FALSE; in_parens = 0; }
break;
case 80:
/* Line 1821 of yacc.c */
-#line 1087 "awkgram.y"
+#line 1099 "awkgram.y"
{
if ((yyvsp[(1) - (3)])->redir_type == redirect_twoway
&& (yyvsp[(3) - (3)])->lasti->opcode ==
Op_K_getline_redir
@@ -3206,7 +3218,7 @@ regular_loop:
case 81:
/* Line 1821 of yacc.c */
-#line 1098 "awkgram.y"
+#line 1110 "awkgram.y"
{
(yyval) = mk_condition((yyvsp[(3) - (6)]), (yyvsp[(1) - (6)]),
(yyvsp[(6) - (6)]), NULL, NULL);
}
@@ -3215,7 +3227,7 @@ regular_loop:
case 82:
/* Line 1821 of yacc.c */
-#line 1103 "awkgram.y"
+#line 1115 "awkgram.y"
{
(yyval) = mk_condition((yyvsp[(3) - (9)]), (yyvsp[(1) - (9)]),
(yyvsp[(6) - (9)]), (yyvsp[(7) - (9)]), (yyvsp[(9) - (9)]));
}
@@ -3224,14 +3236,14 @@ regular_loop:
case 87:
/* Line 1821 of yacc.c */
-#line 1120 "awkgram.y"
+#line 1132 "awkgram.y"
{ (yyval) = NULL; }
break;
case 88:
/* Line 1821 of yacc.c */
-#line 1122 "awkgram.y"
+#line 1134 "awkgram.y"
{
bcfree((yyvsp[(1) - (2)]));
(yyval) = (yyvsp[(2) - (2)]);
@@ -3241,21 +3253,21 @@ regular_loop:
case 89:
/* Line 1821 of yacc.c */
-#line 1130 "awkgram.y"
+#line 1142 "awkgram.y"
{ (yyval) = NULL; }
break;
case 90:
/* Line 1821 of yacc.c */
-#line 1132 "awkgram.y"
+#line 1144 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]) ; }
break;
case 91:
/* Line 1821 of yacc.c */
-#line 1137 "awkgram.y"
+#line 1149 "awkgram.y"
{
(yyvsp[(1) - (1)])->param_count = 0;
(yyval) = list_create((yyvsp[(1) - (1)]));
@@ -3265,7 +3277,7 @@ regular_loop:
case 92:
/* Line 1821 of yacc.c */
-#line 1142 "awkgram.y"
+#line 1154 "awkgram.y"
{
(yyvsp[(3) - (3)])->param_count = (yyvsp[(1) -
(3)])->lasti->param_count + 1;
(yyval) = list_append((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]));
@@ -3276,63 +3288,63 @@ regular_loop:
case 93:
/* Line 1821 of yacc.c */
-#line 1148 "awkgram.y"
+#line 1160 "awkgram.y"
{ (yyval) = NULL; }
break;
case 94:
/* Line 1821 of yacc.c */
-#line 1150 "awkgram.y"
+#line 1162 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (2)]); }
break;
case 95:
/* Line 1821 of yacc.c */
-#line 1152 "awkgram.y"
+#line 1164 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (3)]); }
break;
case 96:
/* Line 1821 of yacc.c */
-#line 1158 "awkgram.y"
+#line 1170 "awkgram.y"
{ (yyval) = NULL; }
break;
case 97:
/* Line 1821 of yacc.c */
-#line 1160 "awkgram.y"
+#line 1172 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 98:
/* Line 1821 of yacc.c */
-#line 1165 "awkgram.y"
+#line 1177 "awkgram.y"
{ (yyval) = NULL; }
break;
case 99:
/* Line 1821 of yacc.c */
-#line 1167 "awkgram.y"
+#line 1179 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 100:
/* Line 1821 of yacc.c */
-#line 1172 "awkgram.y"
+#line 1184 "awkgram.y"
{ (yyval) = mk_expression_list(NULL, (yyvsp[(1) - (1)])); }
break;
case 101:
/* Line 1821 of yacc.c */
-#line 1174 "awkgram.y"
+#line 1186 "awkgram.y"
{
(yyval) = mk_expression_list((yyvsp[(1) - (3)]), (yyvsp[(3) -
(3)]));
yyerrok;
@@ -3342,35 +3354,35 @@ regular_loop:
case 102:
/* Line 1821 of yacc.c */
-#line 1179 "awkgram.y"
+#line 1191 "awkgram.y"
{ (yyval) = NULL; }
break;
case 103:
/* Line 1821 of yacc.c */
-#line 1181 "awkgram.y"
+#line 1193 "awkgram.y"
{ (yyval) = NULL; }
break;
case 104:
/* Line 1821 of yacc.c */
-#line 1183 "awkgram.y"
+#line 1195 "awkgram.y"
{ (yyval) = NULL; }
break;
case 105:
/* Line 1821 of yacc.c */
-#line 1185 "awkgram.y"
+#line 1197 "awkgram.y"
{ (yyval) = NULL; }
break;
case 106:
/* Line 1821 of yacc.c */
-#line 1191 "awkgram.y"
+#line 1203 "awkgram.y"
{
if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode ==
Op_match_rec)
lintwarn_ln((yyvsp[(2) - (3)])->source_line,
@@ -3382,21 +3394,21 @@ regular_loop:
case 107:
/* Line 1821 of yacc.c */
-#line 1198 "awkgram.y"
+#line 1210 "awkgram.y"
{ (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2)
- (3)])); }
break;
case 108:
/* Line 1821 of yacc.c */
-#line 1200 "awkgram.y"
+#line 1212 "awkgram.y"
{ (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2)
- (3)])); }
break;
case 109:
/* Line 1821 of yacc.c */
-#line 1202 "awkgram.y"
+#line 1214 "awkgram.y"
{
if ((yyvsp[(1) - (3)])->lasti->opcode == Op_match_rec)
warning_ln((yyvsp[(2) - (3)])->source_line,
@@ -3417,7 +3429,7 @@ regular_loop:
case 110:
/* Line 1821 of yacc.c */
-#line 1218 "awkgram.y"
+#line 1230 "awkgram.y"
{
if (do_lint_old)
warning_ln((yyvsp[(2) - (3)])->source_line,
@@ -3432,7 +3444,7 @@ regular_loop:
case 111:
/* Line 1821 of yacc.c */
-#line 1228 "awkgram.y"
+#line 1240 "awkgram.y"
{
if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode ==
Op_match_rec)
lintwarn_ln((yyvsp[(2) - (3)])->source_line,
@@ -3444,35 +3456,35 @@ regular_loop:
case 112:
/* Line 1821 of yacc.c */
-#line 1235 "awkgram.y"
+#line 1247 "awkgram.y"
{ (yyval) = mk_condition((yyvsp[(1) - (5)]), (yyvsp[(2) - (5)]),
(yyvsp[(3) - (5)]), (yyvsp[(4) - (5)]), (yyvsp[(5) - (5)])); }
break;
case 113:
/* Line 1821 of yacc.c */
-#line 1237 "awkgram.y"
+#line 1249 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 114:
/* Line 1821 of yacc.c */
-#line 1242 "awkgram.y"
+#line 1254 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 115:
/* Line 1821 of yacc.c */
-#line 1244 "awkgram.y"
+#line 1256 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 116:
/* Line 1821 of yacc.c */
-#line 1246 "awkgram.y"
+#line 1258 "awkgram.y"
{
(yyvsp[(2) - (2)])->opcode = Op_assign_quotient;
(yyval) = (yyvsp[(2) - (2)]);
@@ -3482,49 +3494,49 @@ regular_loop:
case 117:
/* Line 1821 of yacc.c */
-#line 1254 "awkgram.y"
+#line 1266 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 118:
/* Line 1821 of yacc.c */
-#line 1256 "awkgram.y"
+#line 1268 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 119:
/* Line 1821 of yacc.c */
-#line 1261 "awkgram.y"
+#line 1273 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 120:
/* Line 1821 of yacc.c */
-#line 1263 "awkgram.y"
+#line 1275 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 121:
/* Line 1821 of yacc.c */
-#line 1268 "awkgram.y"
+#line 1280 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 122:
/* Line 1821 of yacc.c */
-#line 1270 "awkgram.y"
+#line 1282 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 123:
/* Line 1821 of yacc.c */
-#line 1272 "awkgram.y"
+#line 1284 "awkgram.y"
{
int count = 2;
int is_simple_var = FALSE;
@@ -3576,49 +3588,49 @@ regular_loop:
case 125:
/* Line 1821 of yacc.c */
-#line 1324 "awkgram.y"
+#line 1336 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 126:
/* Line 1821 of yacc.c */
-#line 1326 "awkgram.y"
+#line 1338 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 127:
/* Line 1821 of yacc.c */
-#line 1328 "awkgram.y"
+#line 1340 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 128:
/* Line 1821 of yacc.c */
-#line 1330 "awkgram.y"
+#line 1342 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 129:
/* Line 1821 of yacc.c */
-#line 1332 "awkgram.y"
+#line 1344 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 130:
/* Line 1821 of yacc.c */
-#line 1334 "awkgram.y"
+#line 1346 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 131:
/* Line 1821 of yacc.c */
-#line 1336 "awkgram.y"
+#line 1348 "awkgram.y"
{
/*
* In BEGINFILE/ENDFILE, allow `getline var < file'
@@ -3646,7 +3658,7 @@ regular_loop:
case 132:
/* Line 1821 of yacc.c */
-#line 1359 "awkgram.y"
+#line 1371 "awkgram.y"
{
(yyvsp[(2) - (2)])->opcode = Op_postincrement;
(yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) -
(2)]));
@@ -3656,7 +3668,7 @@ regular_loop:
case 133:
/* Line 1821 of yacc.c */
-#line 1364 "awkgram.y"
+#line 1376 "awkgram.y"
{
(yyvsp[(2) - (2)])->opcode = Op_postdecrement;
(yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) -
(2)]));
@@ -3666,7 +3678,7 @@ regular_loop:
case 134:
/* Line 1821 of yacc.c */
-#line 1369 "awkgram.y"
+#line 1381 "awkgram.y"
{
if (do_lint_old) {
warning_ln((yyvsp[(4) - (5)])->source_line,
@@ -3691,7 +3703,7 @@ regular_loop:
case 135:
/* Line 1821 of yacc.c */
-#line 1394 "awkgram.y"
+#line 1406 "awkgram.y"
{
(yyval) = mk_getline((yyvsp[(3) - (4)]), (yyvsp[(4) - (4)]),
(yyvsp[(1) - (4)]), (yyvsp[(2) - (4)])->redir_type);
bcfree((yyvsp[(2) - (4)]));
@@ -3701,49 +3713,49 @@ regular_loop:
case 136:
/* Line 1821 of yacc.c */
-#line 1400 "awkgram.y"
+#line 1412 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 137:
/* Line 1821 of yacc.c */
-#line 1402 "awkgram.y"
+#line 1414 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 138:
/* Line 1821 of yacc.c */
-#line 1404 "awkgram.y"
+#line 1416 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 139:
/* Line 1821 of yacc.c */
-#line 1406 "awkgram.y"
+#line 1418 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 140:
/* Line 1821 of yacc.c */
-#line 1408 "awkgram.y"
+#line 1420 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 141:
/* Line 1821 of yacc.c */
-#line 1410 "awkgram.y"
+#line 1422 "awkgram.y"
{ (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) -
(3)])); }
break;
case 142:
/* Line 1821 of yacc.c */
-#line 1415 "awkgram.y"
+#line 1427 "awkgram.y"
{
(yyval) = list_create((yyvsp[(1) - (1)]));
}
@@ -3752,7 +3764,7 @@ regular_loop:
case 143:
/* Line 1821 of yacc.c */
-#line 1419 "awkgram.y"
+#line 1431 "awkgram.y"
{
if ((yyvsp[(2) - (2)])->opcode == Op_match_rec) {
(yyvsp[(2) - (2)])->opcode = Op_nomatch;
@@ -3788,14 +3800,14 @@ regular_loop:
case 144:
/* Line 1821 of yacc.c */
-#line 1450 "awkgram.y"
+#line 1462 "awkgram.y"
{ (yyval) = (yyvsp[(2) - (3)]); }
break;
case 145:
/* Line 1821 of yacc.c */
-#line 1452 "awkgram.y"
+#line 1464 "awkgram.y"
{
(yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
if ((yyval) == NULL)
@@ -3806,7 +3818,7 @@ regular_loop:
case 146:
/* Line 1821 of yacc.c */
-#line 1458 "awkgram.y"
+#line 1470 "awkgram.y"
{
(yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
if ((yyval) == NULL)
@@ -3817,7 +3829,7 @@ regular_loop:
case 147:
/* Line 1821 of yacc.c */
-#line 1464 "awkgram.y"
+#line 1476 "awkgram.y"
{
static short warned1 = FALSE;
@@ -3835,7 +3847,7 @@ regular_loop:
case 150:
/* Line 1821 of yacc.c */
-#line 1479 "awkgram.y"
+#line 1491 "awkgram.y"
{
(yyvsp[(1) - (2)])->opcode = Op_preincrement;
(yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) -
(2)]));
@@ -3845,7 +3857,7 @@ regular_loop:
case 151:
/* Line 1821 of yacc.c */
-#line 1484 "awkgram.y"
+#line 1496 "awkgram.y"
{
(yyvsp[(1) - (2)])->opcode = Op_predecrement;
(yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) -
(2)]));
@@ -3855,7 +3867,7 @@ regular_loop:
case 152:
/* Line 1821 of yacc.c */
-#line 1489 "awkgram.y"
+#line 1501 "awkgram.y"
{
(yyval) = list_create((yyvsp[(1) - (1)]));
}
@@ -3864,7 +3876,7 @@ regular_loop:
case 153:
/* Line 1821 of yacc.c */
-#line 1493 "awkgram.y"
+#line 1505 "awkgram.y"
{
(yyval) = list_create((yyvsp[(1) - (1)]));
}
@@ -3873,7 +3885,7 @@ regular_loop:
case 154:
/* Line 1821 of yacc.c */
-#line 1497 "awkgram.y"
+#line 1509 "awkgram.y"
{
if ((yyvsp[(2) - (2)])->lasti->opcode == Op_push_i
&& ((yyvsp[(2) - (2)])->lasti->memory->flags &
(STRCUR|STRING)) == 0
@@ -3891,7 +3903,7 @@ regular_loop:
case 155:
/* Line 1821 of yacc.c */
-#line 1510 "awkgram.y"
+#line 1522 "awkgram.y"
{
/*
* was: $$ = $2
@@ -3906,7 +3918,7 @@ regular_loop:
case 156:
/* Line 1821 of yacc.c */
-#line 1523 "awkgram.y"
+#line 1535 "awkgram.y"
{
func_use((yyvsp[(1) - (1)])->lasti->func_name, FUNC_USE);
(yyval) = (yyvsp[(1) - (1)]);
@@ -3916,7 +3928,7 @@ regular_loop:
case 157:
/* Line 1821 of yacc.c */
-#line 1528 "awkgram.y"
+#line 1540 "awkgram.y"
{
/* indirect function call */
INSTRUCTION *f, *t;
@@ -3954,7 +3966,7 @@ regular_loop:
case 158:
/* Line 1821 of yacc.c */
-#line 1564 "awkgram.y"
+#line 1576 "awkgram.y"
{
param_sanity((yyvsp[(3) - (4)]));
(yyvsp[(1) - (4)])->opcode = Op_func_call;
@@ -3973,42 +3985,42 @@ regular_loop:
case 159:
/* Line 1821 of yacc.c */
-#line 1581 "awkgram.y"
+#line 1593 "awkgram.y"
{ (yyval) = NULL; }
break;
case 160:
/* Line 1821 of yacc.c */
-#line 1583 "awkgram.y"
+#line 1595 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 161:
/* Line 1821 of yacc.c */
-#line 1588 "awkgram.y"
+#line 1600 "awkgram.y"
{ (yyval) = NULL; }
break;
case 162:
/* Line 1821 of yacc.c */
-#line 1590 "awkgram.y"
+#line 1602 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (2)]); }
break;
case 163:
/* Line 1821 of yacc.c */
-#line 1595 "awkgram.y"
+#line 1607 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 164:
/* Line 1821 of yacc.c */
-#line 1597 "awkgram.y"
+#line 1609 "awkgram.y"
{
(yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
}
@@ -4017,7 +4029,7 @@ regular_loop:
case 165:
/* Line 1821 of yacc.c */
-#line 1604 "awkgram.y"
+#line 1616 "awkgram.y"
{
INSTRUCTION *ip = (yyvsp[(1) - (1)])->lasti;
int count = ip->sub_count; /* # of SUBSEP-seperated
expressions */
@@ -4036,7 +4048,7 @@ regular_loop:
case 166:
/* Line 1821 of yacc.c */
-#line 1621 "awkgram.y"
+#line 1633 "awkgram.y"
{
INSTRUCTION *t = (yyvsp[(2) - (3)]);
if ((yyvsp[(2) - (3)]) == NULL) {
@@ -4055,14 +4067,14 @@ regular_loop:
case 167:
/* Line 1821 of yacc.c */
-#line 1638 "awkgram.y"
+#line 1650 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 168:
/* Line 1821 of yacc.c */
-#line 1640 "awkgram.y"
+#line 1652 "awkgram.y"
{
(yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
}
@@ -4071,14 +4083,14 @@ regular_loop:
case 169:
/* Line 1821 of yacc.c */
-#line 1647 "awkgram.y"
+#line 1659 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (2)]); }
break;
case 170:
/* Line 1821 of yacc.c */
-#line 1652 "awkgram.y"
+#line 1664 "awkgram.y"
{
char *var_name = (yyvsp[(1) - (1)])->lextok;
@@ -4091,7 +4103,7 @@ regular_loop:
case 171:
/* Line 1821 of yacc.c */
-#line 1660 "awkgram.y"
+#line 1672 "awkgram.y"
{
char *arr = (yyvsp[(1) - (2)])->lextok;
(yyvsp[(1) - (2)])->memory = variable((yyvsp[(1) -
(2)])->source_line, arr, Node_var_new);
@@ -4103,7 +4115,7 @@ regular_loop:
case 172:
/* Line 1821 of yacc.c */
-#line 1670 "awkgram.y"
+#line 1682 "awkgram.y"
{
INSTRUCTION *ip = (yyvsp[(1) - (1)])->nexti;
if (ip->opcode == Op_push
@@ -4121,7 +4133,7 @@ regular_loop:
case 173:
/* Line 1821 of yacc.c */
-#line 1683 "awkgram.y"
+#line 1695 "awkgram.y"
{
(yyval) = list_append((yyvsp[(2) - (3)]), (yyvsp[(1) - (3)]));
if ((yyvsp[(3) - (3)]) != NULL)
@@ -4132,7 +4144,7 @@ regular_loop:
case 174:
/* Line 1821 of yacc.c */
-#line 1692 "awkgram.y"
+#line 1704 "awkgram.y"
{
(yyvsp[(1) - (1)])->opcode = Op_postincrement;
}
@@ -4141,7 +4153,7 @@ regular_loop:
case 175:
/* Line 1821 of yacc.c */
-#line 1696 "awkgram.y"
+#line 1708 "awkgram.y"
{
(yyvsp[(1) - (1)])->opcode = Op_postdecrement;
}
@@ -4150,49 +4162,49 @@ regular_loop:
case 176:
/* Line 1821 of yacc.c */
-#line 1699 "awkgram.y"
+#line 1711 "awkgram.y"
{ (yyval) = NULL; }
break;
case 178:
/* Line 1821 of yacc.c */
-#line 1707 "awkgram.y"
+#line 1719 "awkgram.y"
{ yyerrok; }
break;
case 179:
/* Line 1821 of yacc.c */
-#line 1711 "awkgram.y"
+#line 1723 "awkgram.y"
{ yyerrok; }
break;
case 182:
/* Line 1821 of yacc.c */
-#line 1720 "awkgram.y"
+#line 1732 "awkgram.y"
{ yyerrok; }
break;
case 183:
/* Line 1821 of yacc.c */
-#line 1724 "awkgram.y"
+#line 1736 "awkgram.y"
{ (yyval) = (yyvsp[(1) - (1)]); yyerrok; }
break;
case 184:
/* Line 1821 of yacc.c */
-#line 1728 "awkgram.y"
+#line 1740 "awkgram.y"
{ yyerrok; }
break;
/* Line 1821 of yacc.c */
-#line 4208 "awkgram.c"
+#line 4220 "awkgram.c"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -4423,7 +4435,7 @@ yyreturn:
/* Line 2067 of yacc.c */
-#line 1730 "awkgram.y"
+#line 1742 "awkgram.y"
struct token {
@@ -6586,6 +6598,19 @@ mk_function(INSTRUCTION *fi, INSTRUCTION *def)
thisfunc = fi->func_body;
assert(thisfunc != NULL);
+ if (do_optimize > 1 && def->lasti->opcode == Op_pop) {
+ /* tail call which does not return any value. */
+
+ INSTRUCTION *t;
+
+ for (t = def->nexti; t->nexti != def->lasti; t = t->nexti)
+ ;
+ if (t->opcode == Op_func_call
+ && STREQ(t->func_name, thisfunc->vname)
+ )
+ (t + 1)->tail_call = TRUE;
+ }
+
/* add an implicit return at end;
* also used by 'return' command in debugger
*/
@@ -7461,7 +7486,7 @@ optimize_assignment(INSTRUCTION *exp)
if ( ! do_optimize
|| ( i1->opcode != Op_assign
&& i1->opcode != Op_field_assign)
- )
+ )
return list_append(exp, instruction(Op_pop));
for (i2 = exp->nexti; i2 != i1; i2 = i2->nexti) {
diff --git a/awkgram.y b/awkgram.y
index b606453..12ea769 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -84,7 +84,7 @@ static int one_line_close(int fd);
static int want_source = FALSE;
static int want_regexp; /* lexical scanning kludge */
-static int can_return; /* parsing kludge */
+static char *in_function; /* parsing kludge */
static int rule = 0;
const char *const ruletab[] = {
@@ -229,7 +229,7 @@ rule
}
| function_prologue action
{
- can_return = FALSE;
+ in_function = NULL;
(void) mk_function($1, $2);
yyerrok;
}
@@ -358,11 +358,11 @@ function_prologue
$1->source_file = source;
if (install_function($2->lextok, $1, $4) < 0)
YYABORT;
+ in_function = $2->lextok;
$2->lextok = NULL;
bcfree($2);
/* $4 already free'd in install_function */
$$ = $1;
- can_return = TRUE;
}
;
@@ -819,15 +819,27 @@ non_compound_stmt
}
| LEX_RETURN
{
- if (! can_return)
+ if (! in_function)
yyerror(_("`return' used outside function context"));
} opt_exp statement_term {
if ($3 == NULL) {
$$ = list_create($1);
(void) list_prepend($$, instruction(Op_push_i));
$$->nexti->memory = dupnode(Nnull_string);
- } else
+ } else {
+ if (do_optimize > 1
+ && $3->lasti->opcode == Op_func_call
+ && STREQ($3->lasti->func_name, in_function)
+ ) {
+ /* Do tail recursion optimization. Tail
+ * call without a return value is recognized
+ * in mk_function().
+ */
+ ($3->lasti + 1)->tail_call = TRUE;
+ }
+
$$ = list_append($3, $1);
+ }
}
| simple_stmt statement_term
;
@@ -3889,6 +3901,19 @@ mk_function(INSTRUCTION *fi, INSTRUCTION *def)
thisfunc = fi->func_body;
assert(thisfunc != NULL);
+ if (do_optimize > 1 && def->lasti->opcode == Op_pop) {
+ /* tail call which does not return any value. */
+
+ INSTRUCTION *t;
+
+ for (t = def->nexti; t->nexti != def->lasti; t = t->nexti)
+ ;
+ if (t->opcode == Op_func_call
+ && STREQ(t->func_name, thisfunc->vname)
+ )
+ (t + 1)->tail_call = TRUE;
+ }
+
/* add an implicit return at end;
* also used by 'return' command in debugger
*/
@@ -4764,7 +4789,7 @@ optimize_assignment(INSTRUCTION *exp)
if ( ! do_optimize
|| ( i1->opcode != Op_assign
&& i1->opcode != Op_field_assign)
- )
+ )
return list_append(exp, instruction(Op_pop));
for (i2 = exp->nexti; i2 != i1; i2 = i2->nexti) {
diff --git a/eval.c b/eval.c
index f3d2c26..960dfe6 100644
--- a/eval.c
+++ b/eval.c
@@ -687,7 +687,7 @@ pop_frame()
}
#else /* not PROFILING or DEBUGGING */
#define push_frame(p) /* nothing */
-#define pop_frame() /* nothing */
+#define pop_frame() /* nothing */
#endif
@@ -698,9 +698,8 @@ pop_frame()
void
dump_fcall_stack(FILE *fp)
{
-
NODE *f, *func;
- long i = 0;
+ long i = 0, j, k = 0;
if (fcall_count == 0)
return;
@@ -708,16 +707,18 @@ dump_fcall_stack(FILE *fp)
/* current frame */
func = frame_ptr->func_node;
- fprintf(fp, "\t# %3ld. %s\n", i, func->lnode->param);
+ for (j = 0; j <= frame_ptr->num_tail_calls; j++)
+ fprintf(fp, "\t# %3ld. %s\n", k++, func->vname);
/* outer frames except main */
for (i = 1; i < fcall_count; i++) {
f = fcall_list[i];
func = f->func_node;
- fprintf(fp, "\t# %3ld. %s\n", i, func->lnode->param);
+ for (j = 0; j <= f->num_tail_calls; j++)
+ fprintf(fp, "\t# %3ld. %s\n", k++, func->vname);
}
- fprintf(fp, "\t# %3ld. -- main --\n", fcall_count);
+ fprintf(fp, "\t# %3ld. -- main --\n", k);
}
#endif /* PROFILING */
@@ -1111,6 +1112,7 @@ grow_stack()
frame_ptr->type = Node_frame;
frame_ptr->stack = NULL;
frame_ptr->func_node = NULL; /* in main */
+ frame_ptr->num_tail_calls = 0;
frame_ptr->vname = NULL;
return stack_ptr;
}
@@ -1249,6 +1251,7 @@ calc_exp(AWKNUM x1, AWKNUM x2)
/* setup_frame --- setup new frame for function call */
+
static void
setup_frame(INSTRUCTION *pc)
{
@@ -1256,12 +1259,40 @@ setup_frame(INSTRUCTION *pc)
NODE *m, *f, *fp;
NODE **sp = NULL;
int pcount, arg_count, i, j;
+ int tail_optimize = FALSE;
f = pc->func_body;
pcount = f->param_cnt;
fp = f->fparms;
arg_count = (pc + 1)->expr_count;
+#ifndef DEBUGGING
+ /* tail recursion optimization */
+ tail_optimize = (do_optimize > 1 && (pc + 1)->tail_call);
+#endif
+
+ if (tail_optimize) {
+ /* free local vars of calling frame */
+
+ NODE *func;
+ int n;
+
+ func = frame_ptr->func_node;
+ for (n = func->param_cnt, sp = frame_ptr->stack; n > 0; n--) {
+ r = *sp++;
+ if (r->type == Node_var) /* local variable */
+ DEREF(r->var_value);
+ else if (r->type == Node_var_array) /* local array
*/
+ assoc_clear(r);
+ }
+ sp = frame_ptr->stack;
+
+ } else if (pcount > 0) {
+ emalloc(sp, NODE **, pcount * sizeof(NODE *), "setup_frame");
+ memset(sp, 0, pcount * sizeof(NODE *));
+ }
+
+
/* check for extra args */
if (arg_count > pcount) {
warning(
@@ -1274,15 +1305,15 @@ setup_frame(INSTRUCTION *pc)
} while (--arg_count > pcount);
}
- if (pcount > 0) {
- emalloc(sp, NODE **, pcount * sizeof(NODE *), "setup_frame");
- memset(sp, 0, pcount * sizeof(NODE *));
- }
-
for (i = 0, j = arg_count - 1; i < pcount; i++, j--) {
- getnode(r);
- memset(r, 0, sizeof(NODE));
- sp[i] = r;
+ if (tail_optimize)
+ r = sp[i];
+ else {
+ getnode(r);
+ memset(r, 0, sizeof(NODE));
+ sp[i] = r;
+ }
+
if (i >= arg_count) {
/* local variable */
r->type = Node_var_new;
@@ -1328,8 +1359,14 @@ setup_frame(INSTRUCTION *pc)
}
r->vname = fp[i].param;
}
+
stack_adj(-arg_count); /* adjust stack pointer */
+ if (tail_optimize) {
+ frame_ptr->num_tail_calls++;
+ return;
+ }
+
if (pc->opcode == Op_indirect_func_call) {
r = POP(); /* indirect var */
DEREF(r);
@@ -1345,6 +1382,7 @@ setup_frame(INSTRUCTION *pc)
frame_ptr->type = Node_frame;
frame_ptr->stack = sp;
frame_ptr->func_node = f;
+ frame_ptr->num_tail_calls = 0;
frame_ptr->vname = NULL;
frame_ptr->reti = (unsigned long) pc; /* on return execute pc->nexti */
@@ -1374,6 +1412,7 @@ restore_frame(NODE *fp)
assoc_clear(r);
freenode(r);
}
+
if (frame_ptr->stack != NULL)
efree(frame_ptr->stack);
ri = (INSTRUCTION *) frame_ptr->reti; /* execution in calling frame
@@ -1651,7 +1690,7 @@ top:
/* avoid false source indications */
source = NULL;
sourceline = 0;
- (void) nextfile(&curfile, TRUE); /* close input
data file */
+ (void) nextfile(& curfile, TRUE); /* close input
data file */
/*
* This used to be:
*
@@ -2404,6 +2443,7 @@ match_re:
f = pc->func_body;
if (f != NULL && STREQ(f->vname, t1->stptr)) {
/* indirect var hasn't been reassigned
*/
+
goto func_call;
}
f = lookup(t1->stptr);
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 9 ++
array.c | 5 +-
awk.h | 5 +-
awkgram.c | 305 +++++++++++++++++++++++++++++++++----------------------------
awkgram.y | 37 ++++++-
eval.c | 70 +++++++++++---
6 files changed, 266 insertions(+), 165 deletions(-)
hooks/post-receive
--
gawk
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gawk-diffs] [SCM] gawk branch, gawk_performance, updated. bf958505d3b1681a91f10e866636e9088d732a60,
John Haque <=