From f00e74ffc73f6ba6fe74fb7a26319770b8c3792c Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 14 Apr 2022 07:00:15 -0700 Subject: @let: allow trailing comma. We allow forms like @let(x,) and @let(x, y=1,) with the trailing comma. This is helpful for code generators and macros, which can then treat temporary variables as comma-terminated items. * awkgram.y (let_var_list_opt): Add a production which matches a trailing comma after let_var_list. * test/let1.awk, test/let1.ok: Test cases. * doc/gawkt.texi, doc/gawktexi.in: Trailing comma documented. * awkgram.c: Regenerated with Bison 3.8. --- awkgram.c | 906 ++++++++++++++++++++++++++++---------------------------- awkgram.y | 2 + doc/gawk.texi | 7 +- doc/gawktexi.in | 7 +- test/let1.awk | 14 + test/let1.ok | 6 + 6 files changed, 490 insertions(+), 452 deletions(-) diff --git a/awkgram.c b/awkgram.c index a646f56d..73f7a307 100644 --- a/awkgram.c +++ b/awkgram.c @@ -913,7 +913,7 @@ union yyalloc /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 75 /* YYNRULES -- Number of rules. */ -#define YYNRULES 220 +#define YYNRULES 221 /* YYNSTATES -- Number of states. */ #define YYNSTATES 375 @@ -981,18 +981,18 @@ static const yytype_int16 yyrline[] = 1413, 1428, 1430, 1438, 1445, 1447, 1455, 1464, 1466, 1475, 1476, 1484, 1489, 1489, 1502, 1509, 1522, 1526, 1548, 1549, 1555, 1556, 1565, 1566, 1571, 1576, 1593, 1595, 1597, 1603, - 1604, 1609, 1625, 1645, 1663, 1686, 1688, 1690, 1697, 1698, - 1704, 1705, 1710, 1712, 1719, 1721, 1729, 1734, 1745, 1746, - 1751, 1753, 1760, 1762, 1770, 1775, 1785, 1786, 1791, 1792, - 1797, 1804, 1808, 1810, 1812, 1825, 1842, 1852, 1859, 1861, - 1866, 1868, 1870, 1878, 1880, 1885, 1887, 1892, 1894, 1896, - 1953, 1955, 1957, 1959, 1961, 1963, 1965, 1967, 1981, 1986, - 1991, 2017, 2023, 2025, 2027, 2029, 2031, 2033, 2038, 2042, - 2074, 2082, 2088, 2094, 2107, 2108, 2109, 2114, 2119, 2123, - 2127, 2142, 2163, 2168, 2205, 2242, 2243, 2249, 2250, 2255, - 2257, 2264, 2281, 2298, 2300, 2307, 2312, 2318, 2329, 2341, - 2350, 2354, 2359, 2363, 2367, 2371, 2376, 2377, 2381, 2385, - 2389 + 1604, 1606, 1611, 1627, 1647, 1665, 1688, 1690, 1692, 1699, + 1700, 1706, 1707, 1712, 1714, 1721, 1723, 1731, 1736, 1747, + 1748, 1753, 1755, 1762, 1764, 1772, 1777, 1787, 1788, 1793, + 1794, 1799, 1806, 1810, 1812, 1814, 1827, 1844, 1854, 1861, + 1863, 1868, 1870, 1872, 1880, 1882, 1887, 1889, 1894, 1896, + 1898, 1955, 1957, 1959, 1961, 1963, 1965, 1967, 1969, 1983, + 1988, 1993, 2019, 2025, 2027, 2029, 2031, 2033, 2035, 2040, + 2044, 2076, 2084, 2090, 2096, 2109, 2110, 2111, 2116, 2121, + 2125, 2129, 2144, 2165, 2170, 2207, 2244, 2245, 2251, 2252, + 2257, 2259, 2266, 2283, 2300, 2302, 2309, 2314, 2320, 2331, + 2343, 2352, 2356, 2361, 2365, 2369, 2373, 2378, 2379, 2383, + 2387, 2391 }; #endif @@ -1050,7 +1050,7 @@ yysymbol_name (yysymbol_kind_t yysymbol) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) -#define YYTABLE_NINF (-130) +#define YYTABLE_NINF (-131) #define yytable_value_is_error(Yyn) \ ((Yyn) == YYTABLE_NINF) @@ -1059,43 +1059,43 @@ yysymbol_name (yysymbol_kind_t yysymbol) STATE-NUM. */ static const yytype_int16 yypact[] = { - -305, 380, -305, -305, -20, -26, -305, -305, -305, -305, - 162, -305, -305, 11, 11, 11, -17, 5, -305, -305, + -305, 380, -305, -305, -33, -26, -305, -305, -305, -305, + 205, -305, -305, 11, 11, 11, -30, -20, -305, -305, -305, 1128, 1128, -305, 1128, 1157, 890, 21, -305, 100, - -18, -305, -305, 71, 934, 1054, 251, 290, -305, -305, - -305, -305, 238, 812, 890, -305, 3, -305, -305, -305, - -305, -305, 77, 69, -305, 98, -305, -305, -305, 812, - 812, 158, 127, 123, 127, 127, 1128, 136, -305, -305, - 16, 351, 32, 190, 237, -305, 116, -305, -305, -305, - 71, -305, 116, -305, 200, -305, -305, 1083, 208, 1128, - 1128, 1128, 116, -305, -305, -305, 1128, 1128, 183, 251, + -22, -305, -305, 71, 934, 1054, 254, 290, -305, -305, + -305, -305, 269, 812, 890, -305, 3, -305, -305, -305, + -305, -305, 7, 5, -305, 68, -305, -305, -305, 812, + 812, 154, 93, 126, 93, 93, 1128, 136, -305, -305, + 16, 351, 32, 162, 190, -305, 85, -305, -305, -305, + 71, -305, 85, -305, 200, -305, -305, 1083, 191, 1128, + 1128, 1128, 85, -305, -305, -305, 1128, 1128, 177, 254, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, - 1128, 1128, -305, 222, -305, -305, 218, 1128, -305, -305, - -305, 164, 114, -305, 1098, 59, 1098, -305, -305, -305, - -305, 1128, -305, 164, 164, 351, -305, -305, -305, 1128, - -305, 203, 919, -305, -305, 8, 102, -305, 15, 102, + 1128, 1128, -305, 212, -305, -305, 208, 1128, -305, -305, + -305, 160, 114, -305, 1098, 59, 1098, -305, -305, -305, + -305, 1128, -305, 160, 160, 351, -305, -305, -305, 1128, + -305, 193, 919, -305, -305, 8, 102, -305, 15, 102, -305, 55, 102, 71, -305, 609, -305, -305, -305, 19, - -305, 239, 159, 1195, -305, 161, 1098, 11, -19, -19, - 127, 127, 127, 127, -19, -19, 127, 127, 127, 127, - -305, -305, 1098, -305, 1083, 841, -305, 50, 251, -305, - -305, 1098, 208, -305, 1098, -305, -305, -305, -305, -305, - -305, -305, 177, -305, 64, 186, 189, 116, 191, 102, - 102, -305, -305, 102, 1128, 102, 31, 116, -305, -305, - 102, -305, -305, 1098, -305, 185, 116, 1128, -305, -305, - -305, -305, -305, -305, 164, 118, -305, 1128, 1083, -305, - 256, 1128, 1128, 729, 964, -305, -305, -305, 102, 1098, - -305, 194, -305, -305, 658, 609, 116, -305, -305, 1098, - 116, -305, 35, 351, -305, 102, -26, 197, 351, 351, - 243, -6, -305, 185, -305, -305, 890, 261, -305, 60, - -305, -305, -305, -305, -305, 116, -305, -305, 10, -305, - -305, -305, 116, 116, 207, 208, 116, 51, 16, -305, - -305, 729, -305, -305, -18, 729, 1128, 164, 763, -305, - 259, 164, 135, 203, 1128, 258, -305, -305, 351, 116, - 1172, 116, 1128, 116, -305, 36, 1054, 116, 134, 116, - 729, 116, 1009, 1098, 729, -305, 270, 729, -305, 341, - 229, -305, 211, -305, -305, 1009, 164, -305, 1128, -305, - -305, -305, 281, 282, -305, -305, 229, -305, 116, -305, - 164, 116, 1098, -305, -305, 116, -305, 116, 729, -305, + -305, 239, 159, 1195, -305, 202, 1098, 11, -19, -19, + 93, 93, 93, 93, -19, -19, 93, 93, 93, 93, + -305, -305, 1098, -305, 1083, 841, -305, 50, 254, -305, + -305, 1098, 191, -305, 1098, -305, -305, -305, -305, -305, + -305, -305, 165, -305, 64, 168, 173, 85, 174, 102, + 102, -305, -305, 102, 1128, 102, 31, 85, -305, -305, + 102, -305, -305, 1098, -305, 170, 85, 1128, -305, -305, + -305, -305, -305, -305, 160, 118, -305, 1128, 1083, -305, + 252, 1128, 1128, 729, 964, -305, -305, -305, 102, 1098, + -305, 189, -305, -305, 658, 609, 85, -305, -305, 1098, + 85, -305, 35, 351, -305, 102, -26, 197, 351, 351, + 233, -6, -305, 170, -305, -305, 890, 253, -305, 60, + -305, -305, -305, -305, -305, 85, -305, -305, 10, -305, + -305, -305, 85, 85, 203, 191, 85, 51, 16, -305, + -305, 729, -305, -305, -22, 729, 1128, 160, 763, -305, + 256, 160, 135, 193, 1128, 251, -305, -305, 351, 85, + 1172, 85, 1128, 85, -305, 161, 1054, 85, 134, 85, + 729, 85, 1009, 1098, 729, -305, 265, 729, -305, 341, + 227, -305, 210, -305, -305, 1009, 160, -305, 1128, -305, + -305, -305, 280, 281, -305, -305, 227, -305, 85, -305, + 160, 85, 1098, -305, -305, 85, -305, 85, 729, -305, 455, 729, -305, 532, -305 }; @@ -1104,56 +1104,56 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 2, 0, 1, 6, 0, 206, 188, 189, 25, 26, - 0, 27, 28, 195, 0, 0, 0, 183, 5, 96, + 2, 0, 1, 6, 0, 207, 189, 190, 25, 26, + 0, 27, 28, 196, 0, 0, 0, 184, 5, 96, 42, 0, 0, 41, 0, 0, 0, 0, 3, 0, - 0, 178, 38, 4, 23, 149, 157, 158, 160, 184, - 192, 208, 185, 0, 0, 203, 0, 207, 31, 30, - 34, 35, 0, 0, 32, 100, 196, 186, 187, 0, - 0, 0, 191, 185, 190, 179, 0, 212, 185, 124, - 0, 122, 0, 0, 0, 193, 98, 218, 7, 8, - 46, 43, 98, 9, 0, 97, 153, 0, 0, 0, - 0, 0, 98, 154, 156, 155, 0, 0, 0, 159, + 0, 179, 38, 4, 23, 150, 158, 159, 161, 185, + 193, 209, 186, 0, 0, 204, 0, 208, 31, 30, + 34, 35, 0, 0, 32, 100, 197, 187, 188, 0, + 0, 0, 192, 186, 191, 180, 0, 213, 186, 125, + 0, 123, 0, 0, 0, 194, 98, 219, 7, 8, + 46, 43, 98, 9, 0, 97, 154, 0, 0, 0, + 0, 0, 98, 155, 157, 156, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 151, 150, 168, 169, 0, 0, 132, 40, - 137, 0, 0, 130, 136, 0, 122, 205, 204, 33, - 36, 0, 167, 0, 0, 0, 210, 211, 209, 125, - 215, 0, 0, 180, 15, 0, 0, 18, 0, 0, - 21, 0, 0, 99, 213, 0, 47, 39, 144, 145, - 146, 142, 143, 0, 220, 147, 24, 195, 165, 166, - 162, 163, 164, 161, 176, 177, 173, 174, 175, 172, - 141, 152, 140, 194, 133, 0, 202, 0, 101, 181, - 182, 126, 0, 127, 123, 14, 10, 17, 11, 20, + 0, 0, 152, 151, 169, 170, 0, 0, 133, 40, + 138, 0, 0, 131, 137, 0, 123, 206, 205, 33, + 36, 0, 168, 0, 0, 0, 211, 212, 210, 126, + 216, 0, 0, 181, 15, 0, 0, 18, 0, 0, + 21, 0, 0, 99, 214, 0, 47, 39, 145, 146, + 147, 143, 144, 0, 221, 148, 24, 196, 166, 167, + 163, 164, 165, 162, 177, 178, 174, 175, 176, 173, + 142, 153, 141, 195, 134, 0, 203, 0, 101, 182, + 183, 127, 0, 128, 124, 14, 10, 17, 11, 20, 12, 45, 0, 65, 0, 0, 0, 98, 0, 0, - 0, 87, 88, 0, 118, 0, 0, 98, 44, 59, - 0, 68, 50, 73, 43, 216, 98, 0, 171, 134, - 135, 131, 106, 104, 0, 0, 170, 0, 138, 70, - 0, 0, 0, 0, 74, 60, 61, 62, 0, 119, - 63, 0, 214, 67, 0, 0, 98, 217, 48, 148, - 98, 107, 0, 0, 139, 0, 197, 0, 0, 0, - 0, 206, 75, 0, 64, 57, 0, 91, 89, 0, - 49, 29, 37, 108, 105, 98, 66, 71, 0, 199, - 201, 72, 98, 98, 0, 0, 98, 0, 0, 92, - 69, 0, 198, 200, 0, 0, 0, 0, 0, 115, - 111, 0, 0, 90, 0, 94, 76, 52, 0, 98, - 0, 98, 0, 98, 116, 0, 93, 98, 0, 98, - 0, 98, 74, 113, 0, 117, 112, 0, 78, 0, + 0, 87, 88, 0, 119, 0, 0, 98, 44, 59, + 0, 68, 50, 73, 43, 217, 98, 0, 172, 135, + 136, 132, 106, 104, 0, 0, 171, 0, 139, 70, + 0, 0, 0, 0, 74, 60, 61, 62, 0, 120, + 63, 0, 215, 67, 0, 0, 98, 218, 48, 149, + 98, 107, 0, 0, 140, 0, 198, 0, 0, 0, + 0, 207, 75, 0, 64, 57, 0, 91, 89, 0, + 49, 29, 37, 108, 105, 98, 66, 71, 0, 200, + 202, 72, 98, 98, 0, 0, 98, 0, 0, 92, + 69, 0, 199, 201, 0, 0, 0, 0, 0, 116, + 112, 0, 0, 90, 0, 94, 76, 52, 0, 98, + 0, 98, 0, 98, 117, 0, 93, 98, 0, 98, + 0, 98, 74, 114, 0, 118, 113, 0, 78, 0, 0, 77, 0, 53, 54, 74, 0, 58, 0, 95, - 81, 84, 0, 0, 85, 86, 0, 219, 98, 51, - 0, 98, 114, 83, 82, 98, 43, 98, 0, 43, + 81, 84, 0, 0, 85, 86, 0, 220, 98, 51, + 0, 98, 115, 83, 82, 98, 43, 98, 0, 43, 0, 0, 56, 0, 55 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -305, -305, -305, -305, -305, -305, -305, 262, -305, -305, - -305, -305, -44, -305, -82, -305, -211, 117, -123, -305, + -305, -305, -305, -305, -305, -305, -305, 259, -305, -305, + -305, -305, -47, -305, -82, -305, -211, 117, -123, -305, -305, -305, -221, -305, -305, -304, -305, -305, -305, -305, -305, -305, -305, -305, 81, 48, -305, -305, -305, -305, - -305, -305, -305, -37, 139, -305, -22, -305, -1, -305, - -305, -305, -14, 42, -305, 277, -305, -13, 142, -305, - -305, 22, -42, -305, -305, -80, -3, -305, -28, -229, + -305, -305, -305, -37, 139, -305, -18, -305, -1, -305, + -305, -305, -21, 42, -305, 270, -305, -13, 133, -305, + -305, 14, -42, -305, -305, -80, -3, -305, -28, -229, -40, -305, -23, -53, -31 }; @@ -1178,36 +1178,36 @@ static const yytype_int16 yytable[] = 34, 81, 81, 97, 128, 158, 82, 125, 160, 195, 56, 57, 58, 255, 75, 5, 197, 139, 63, 63, 127, 63, 68, 272, 4, 71, 280, 302, 346, 86, - 141, 180, 63, 144, 4, 295, 283, 335, 145, 284, - 336, 360, 124, 126, 102, 103, 104, 44, 75, 105, - 43, 232, 309, 59, 233, 310, 199, 76, 124, 124, + 141, 180, 63, 144, 4, 295, 283, 43, 145, 284, + 59, 360, 124, 126, 102, 103, 104, 44, 75, 105, + 60, 232, 309, 76, 233, 310, 199, 129, 124, 124, 139, 139, -13, 62, 64, 135, 65, 44, 239, -16, - 72, -121, 73, 74, 92, 60, 44, 99, 93, 94, + 72, -122, 73, 74, 92, 130, 44, 99, 93, 94, 25, 183, 33, 44, 251, -13, 159, 140, 161, 162, 163, 185, -16, 189, 190, 165, 166, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, -19, - 80, 272, 236, 359, -121, 184, 182, 92, 92, 261, - 270, -102, -109, 82, 272, 85, 82, 129, 63, 82, - 156, -121, -19, 186, 240, 338, 324, -121, 191, 130, + 80, 272, 236, 359, -122, 184, 182, 92, 92, 261, + 270, -102, -109, 82, 272, 85, 82, 131, 63, 82, + 156, -122, -19, 186, 240, 338, 324, -122, 191, 19, 164, 194, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 19, 370, 19, 131, 373, 339, - 340, 4, 229, 231, 56, 48, 49, 114, 115, 86, - 19, -130, 92, 188, 87, 76, 92, 77, 315, 77, - 136, 137, 317, 124, 124, -129, 82, 82, 19, -103, - 82, 147, 82, 92, 260, 105, 148, 82, 133, 134, - 88, 89, 257, 75, 262, 157, -110, 344, 50, 51, - -98, 347, 5, 249, 349, 307, 264, 279, 93, 94, - -130, -130, 167, 285, 290, 82, 259, 80, 292, 293, - 80, 119, 181, 80, 52, 140, 263, 124, 150, 298, - 268, 269, 82, 151, 192, 372, 290, 237, 374, 86, - 296, 112, 113, 126, 87, 243, 241, 355, 313, 242, - 267, 244, 77, 196, 275, 252, 198, 319, 291, 200, - 294, 323, 299, 322, 258, 71, 316, 306, 329, 327, - 88, 325, 114, 115, 348, 321, 357, 217, 363, 364, - 80, 80, 83, 116, 80, 354, 80, 331, 93, 94, - 326, 80, 67, 365, 281, 318, 361, 320, 282, 228, - 303, 63, 100, 101, 102, 103, 104, 0, 0, 105, - 367, 333, 0, 63, 0, 0, 245, 246, 0, 80, + 176, 177, 178, 179, 19, 370, 19, 4, 373, 339, + 340, 105, 335, 147, 56, 336, 229, 231, 148, 86, + 114, 115, 92, 188, 87, 76, 92, 77, 315, 77, + 136, 137, 317, 124, 124, -130, 82, 82, 19, -103, + 82, 150, 82, 92, 260, 5, 151, 82, 133, 134, + 88, 89, 257, 75, 262, 157, -110, 344, 48, 49, + -98, 347, -131, 249, 349, 307, 167, 279, 93, 94, + 264, 119, 181, 285, 290, 82, 259, 80, 292, 293, + 80, 140, -111, 80, 192, 237, 263, 124, 241, 298, + 268, 269, 82, 242, 244, 372, 290, 77, 374, 86, + 296, 50, 51, 126, 87, 243, 267, 355, 313, 275, + 294, -131, -131, 196, 299, 252, 198, 319, 291, 200, + 322, 323, 327, 306, 258, 71, 316, 52, 329, 348, + 88, 325, 112, 113, 357, 321, 217, 363, 364, 83, + 80, 80, 354, 326, 80, 67, 80, 331, 93, 94, + 228, 80, 303, 365, 281, 318, 361, 320, 282, 0, + 0, 63, 0, 114, 115, 100, 101, 102, 103, 104, + 367, 333, 105, 63, 116, 0, 245, 246, 0, 80, 247, 0, 250, 301, 0, 0, 0, 253, 0, 0, 304, 305, 0, 0, 308, 0, 80, 362, 350, 351, 119, 106, 107, 108, 109, 110, 0, 0, 111, 0, @@ -1241,14 +1241,14 @@ static const yytype_int16 yytable[] = 0, 203, 204, 205, 0, 0, 206, 207, 208, 209, 210, 211, 212, 213, 214, 0, 0, 0, 13, 215, 0, 0, 0, 14, 15, 16, 17, 0, 0, 69, - 0, 4, 5, 0, 20, 6, 7, 0, 0, -120, + 0, 4, 5, 0, 20, 6, 7, 0, 0, -121, 21, 22, 0, 23, 0, 24, 0, 0, 25, 26, 0, 216, 0, 0, 76, 217, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 0, - 0, 0, -120, 20, 0, 0, 0, 0, 0, 21, - 22, 0, 23, 0, 24, 0, 0, 25, 276, -120, - 61, 0, 4, 5, 0, -120, 6, 7, 0, 0, + 0, 0, -121, 20, 0, 0, 0, 0, 0, 21, + 22, 0, 23, 0, 24, 0, 0, 25, 276, -121, + 61, 0, 4, 5, 0, -121, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 0, 203, 204, 205, 0, 0, 206, 207, 208, 209, 210, 211, 212, 213, 214, 0, 4, 5, 13, 215, @@ -1263,7 +1263,7 @@ static const yytype_int16 yytable[] = 119, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 21, 22, 0, 23, 0, 24, 0, - 13, 25, 26, -128, 61, 14, 15, 16, 17, 0, + 13, 25, 26, -129, 61, 14, 15, 16, 17, 0, 0, 69, 0, 4, 5, 0, 20, 6, 7, 0, 0, 0, 21, 22, 0, 23, 0, 24, 0, 0, 25, 26, 0, 61, 0, 0, 0, 0, 0, 0, @@ -1308,36 +1308,36 @@ static const yytype_int16 yycheck[] = 1, 29, 30, 34, 46, 87, 29, 44, 88, 1, 13, 14, 15, 224, 27, 4, 1, 1, 21, 22, 17, 24, 25, 244, 3, 26, 255, 17, 332, 10, - 70, 113, 35, 1, 3, 41, 1, 1, 6, 4, - 4, 345, 43, 44, 63, 64, 65, 73, 61, 68, - 70, 1, 1, 70, 4, 4, 1, 75, 59, 60, + 70, 113, 35, 1, 3, 41, 1, 70, 6, 4, + 70, 345, 43, 44, 63, 64, 65, 73, 61, 68, + 70, 1, 1, 75, 4, 4, 1, 50, 59, 60, 1, 1, 54, 21, 22, 66, 24, 73, 4, 54, 49, 11, 51, 52, 58, 70, 73, 35, 59, 60, 69, 121, 1, 73, 53, 77, 87, 71, 89, 90, 91, 122, 77, 133, 134, 96, 97, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 54, 29, 332, 192, 342, 54, 1, 117, 58, 58, 1, - 243, 71, 71, 146, 345, 54, 149, 50, 131, 152, - 82, 71, 77, 74, 70, 1, 1, 77, 139, 70, + 243, 71, 71, 146, 345, 54, 149, 59, 131, 152, + 82, 71, 77, 74, 70, 1, 1, 77, 139, 54, 92, 142, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 54, 366, 54, 59, 369, 25, - 26, 3, 184, 185, 167, 3, 4, 44, 45, 10, - 54, 10, 58, 131, 15, 75, 58, 77, 301, 77, + 108, 109, 110, 111, 54, 366, 54, 3, 369, 25, + 26, 68, 1, 1, 167, 4, 184, 185, 6, 10, + 44, 45, 58, 131, 15, 75, 58, 77, 301, 77, 44, 45, 305, 184, 185, 71, 209, 210, 54, 71, - 213, 1, 215, 58, 234, 68, 6, 220, 59, 60, - 41, 42, 225, 216, 235, 5, 71, 330, 46, 47, - 76, 334, 4, 214, 337, 295, 238, 254, 59, 60, - 59, 60, 39, 263, 266, 248, 227, 146, 268, 269, - 149, 9, 14, 152, 72, 71, 237, 238, 1, 276, - 241, 242, 265, 6, 41, 368, 288, 70, 371, 10, - 273, 13, 14, 254, 15, 207, 70, 339, 298, 70, - 4, 70, 77, 146, 70, 217, 149, 307, 71, 152, - 27, 311, 11, 14, 226, 276, 304, 70, 318, 21, - 41, 312, 44, 45, 14, 308, 57, 76, 7, 7, - 209, 210, 30, 55, 213, 339, 215, 320, 59, 60, - 314, 220, 25, 356, 256, 306, 346, 308, 260, 167, - 288, 314, 61, 62, 63, 64, 65, -1, -1, 68, - 360, 322, -1, 326, -1, -1, 209, 210, -1, 248, + 213, 1, 215, 58, 234, 4, 6, 220, 59, 60, + 41, 42, 225, 216, 235, 5, 71, 330, 3, 4, + 76, 334, 10, 214, 337, 295, 39, 254, 59, 60, + 238, 9, 14, 263, 266, 248, 227, 146, 268, 269, + 149, 71, 71, 152, 41, 70, 237, 238, 70, 276, + 241, 242, 265, 70, 70, 368, 288, 77, 371, 10, + 273, 46, 47, 254, 15, 207, 4, 339, 298, 70, + 27, 59, 60, 146, 11, 217, 149, 307, 71, 152, + 14, 311, 21, 70, 226, 276, 304, 72, 318, 14, + 41, 312, 13, 14, 57, 308, 76, 7, 7, 30, + 209, 210, 339, 314, 213, 25, 215, 320, 59, 60, + 167, 220, 288, 356, 256, 306, 346, 308, 260, -1, + -1, 314, -1, 44, 45, 61, 62, 63, 64, 65, + 360, 322, 68, 326, 55, -1, 209, 210, -1, 248, 213, -1, 215, 285, -1, -1, -1, 220, -1, -1, 292, 293, -1, -1, 296, -1, 265, 348, 7, 8, 9, 61, 62, 63, 64, 65, -1, -1, 68, -1, @@ -1491,18 +1491,18 @@ static const yytype_uint8 yyr1[] = 105, 106, 106, 106, 106, 106, 106, 107, 107, 108, 108, 109, 110, 109, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 116, 116, 116, 117, - 117, 118, 118, 118, 118, 118, 118, 118, 119, 119, - 120, 120, 121, 121, 121, 121, 121, 121, 122, 122, - 123, 123, 123, 123, 123, 123, 124, 124, 125, 125, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 127, 127, 127, 128, 128, 129, 129, 130, 130, 130, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 132, 132, 132, 132, 132, 132, 132, 133, 133, + 117, 117, 118, 118, 118, 118, 118, 118, 118, 119, + 119, 120, 120, 121, 121, 121, 121, 121, 121, 122, + 122, 123, 123, 123, 123, 123, 123, 124, 124, 125, + 125, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 127, 127, 127, 128, 128, 129, 129, 130, 130, + 130, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 132, 132, 132, 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, - 133, 133, 134, 134, 135, 136, 136, 137, 137, 138, - 138, 139, 140, 141, 141, 142, 143, 143, 144, 144, - 145, 145, 145, 146, 147, 148, 149, 149, 150, 151, - 152 + 133, 133, 133, 134, 134, 135, 136, 136, 137, 137, + 138, 138, 139, 140, 141, 141, 142, 143, 143, 144, + 144, 145, 145, 145, 146, 147, 148, 149, 149, 150, + 151, 152 }; /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ @@ -1519,18 +1519,18 @@ static const yytype_int8 yyr2[] = 4, 1, 2, 2, 1, 1, 1, 1, 1, 1, 3, 0, 0, 3, 6, 9, 1, 2, 0, 1, 0, 2, 0, 1, 1, 3, 1, 2, 3, 0, - 1, 1, 3, 3, 5, 1, 2, 3, 0, 1, - 0, 1, 1, 3, 1, 2, 3, 3, 0, 1, - 1, 3, 1, 2, 3, 3, 1, 1, 0, 1, - 3, 3, 3, 3, 3, 3, 3, 3, 5, 1, - 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, - 1, 3, 3, 3, 3, 3, 3, 3, 2, 2, - 5, 4, 3, 3, 3, 3, 3, 3, 1, 2, - 3, 4, 4, 1, 1, 1, 2, 2, 1, 1, - 2, 2, 1, 2, 4, 0, 1, 0, 2, 1, - 2, 1, 3, 1, 2, 2, 1, 2, 1, 3, - 1, 1, 0, 2, 2, 1, 0, 1, 1, 1, - 2 + 1, 2, 1, 3, 3, 5, 1, 2, 3, 0, + 1, 0, 1, 1, 3, 1, 2, 3, 3, 0, + 1, 1, 3, 1, 2, 3, 3, 1, 1, 0, + 1, 3, 3, 3, 3, 3, 3, 3, 3, 5, + 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, + 2, 1, 3, 3, 3, 3, 3, 3, 3, 2, + 2, 5, 4, 3, 3, 3, 3, 3, 3, 1, + 2, 3, 4, 4, 1, 1, 1, 2, 2, 1, + 1, 2, 2, 1, 2, 4, 0, 1, 0, 2, + 1, 2, 1, 3, 1, 2, 2, 1, 2, 1, + 3, 1, 1, 0, 2, 2, 1, 0, 1, 1, + 1, 2 }; @@ -3665,8 +3665,14 @@ regular_print: #line 3666 "awkgram.c" break; - case 111: /* let_var_list: NAME */ -#line 1610 "awkgram.y" + case 111: /* let_var_list_opt: let_var_list comma */ +#line 1607 "awkgram.y" + { yyval = yyvsp[-1]; } +#line 3672 "awkgram.c" + break; + + case 112: /* let_var_list: NAME */ +#line 1612 "awkgram.y" { bool is_reused_location = add_let(in_function, yyvsp[0]); @@ -3682,11 +3688,11 @@ regular_print: yyval = list_create(yyvsp[0]); } } -#line 3686 "awkgram.c" +#line 3692 "awkgram.c" break; - case 112: /* let_var_list: let_var_list comma NAME */ -#line 1626 "awkgram.y" + case 113: /* let_var_list: let_var_list comma NAME */ +#line 1628 "awkgram.y" { bool is_reused_location = add_let(in_function, yyvsp[0]); @@ -3706,11 +3712,11 @@ regular_print: yyval = list_append(yyvsp[-2], yyvsp[0]); } } -#line 3710 "awkgram.c" +#line 3716 "awkgram.c" break; - case 113: /* let_var_list: NAME ASSIGN exp */ -#line 1646 "awkgram.y" + case 114: /* let_var_list: NAME ASSIGN exp */ +#line 1648 "awkgram.y" { bool is_reused_location = add_let(in_function, yyvsp[-2]); yyvsp[-2]->opcode = Op_push; @@ -3728,11 +3734,11 @@ regular_print: yyval = list_prepend(yyval, clr); } } -#line 3732 "awkgram.c" +#line 3738 "awkgram.c" break; - case 114: /* let_var_list: let_var_list comma NAME ASSIGN exp */ -#line 1664 "awkgram.y" + case 115: /* let_var_list: let_var_list comma NAME ASSIGN exp */ +#line 1666 "awkgram.y" { INSTRUCTION *assn; bool is_reused_location = add_let(in_function, yyvsp[-2]); @@ -3755,76 +3761,76 @@ regular_print: yyval = list_prepend(yyval, clr); } } -#line 3759 "awkgram.c" - break; - - case 115: /* let_var_list: error */ -#line 1687 "awkgram.y" - { yyval = NULL; } #line 3765 "awkgram.c" break; - case 116: /* let_var_list: let_var_list error */ + case 116: /* let_var_list: error */ #line 1689 "awkgram.y" - { yyval = yyvsp[-1]; } + { yyval = NULL; } #line 3771 "awkgram.c" break; - case 117: /* let_var_list: let_var_list comma error */ + case 117: /* let_var_list: let_var_list error */ #line 1691 "awkgram.y" - { yyval = yyvsp[-2]; } + { yyval = yyvsp[-1]; } #line 3777 "awkgram.c" break; - case 118: /* opt_exp: %empty */ -#line 1697 "awkgram.y" - { yyval = NULL; } + case 118: /* let_var_list: let_var_list comma error */ +#line 1693 "awkgram.y" + { yyval = yyvsp[-2]; } #line 3783 "awkgram.c" break; - case 119: /* opt_exp: exp */ + case 119: /* opt_exp: %empty */ #line 1699 "awkgram.y" - { yyval = yyvsp[0]; } + { yyval = NULL; } #line 3789 "awkgram.c" break; - case 120: /* opt_expression_list: %empty */ -#line 1704 "awkgram.y" - { yyval = NULL; } + case 120: /* opt_exp: exp */ +#line 1701 "awkgram.y" + { yyval = yyvsp[0]; } #line 3795 "awkgram.c" break; - case 121: /* opt_expression_list: expression_list */ + case 121: /* opt_expression_list: %empty */ #line 1706 "awkgram.y" - { yyval = yyvsp[0]; } + { yyval = NULL; } #line 3801 "awkgram.c" break; - case 122: /* expression_list: exp */ -#line 1711 "awkgram.y" - { yyval = mk_expression_list(NULL, yyvsp[0]); } + case 122: /* opt_expression_list: expression_list */ +#line 1708 "awkgram.y" + { yyval = yyvsp[0]; } #line 3807 "awkgram.c" break; - case 123: /* expression_list: expression_list comma exp */ + case 123: /* expression_list: exp */ #line 1713 "awkgram.y" + { yyval = mk_expression_list(NULL, yyvsp[0]); } +#line 3813 "awkgram.c" + break; + + case 124: /* expression_list: expression_list comma exp */ +#line 1715 "awkgram.y" { if (yyvsp[-1] != NULL) yyvsp[-2]->lasti->comment = yyvsp[-1]; yyval = mk_expression_list(yyvsp[-2], yyvsp[0]); yyerrok; } -#line 3818 "awkgram.c" +#line 3824 "awkgram.c" break; - case 124: /* expression_list: error */ -#line 1720 "awkgram.y" + case 125: /* expression_list: error */ +#line 1722 "awkgram.y" { yyval = NULL; } -#line 3824 "awkgram.c" +#line 3830 "awkgram.c" break; - case 125: /* expression_list: expression_list error */ -#line 1722 "awkgram.y" + case 126: /* expression_list: expression_list error */ +#line 1724 "awkgram.y" { /* * Returning the expression list instead of NULL lets @@ -3832,66 +3838,66 @@ regular_print: */ yyval = yyvsp[-1]; } -#line 3836 "awkgram.c" +#line 3842 "awkgram.c" break; - case 126: /* expression_list: expression_list error exp */ -#line 1730 "awkgram.y" + case 127: /* expression_list: expression_list error exp */ +#line 1732 "awkgram.y" { /* Ditto */ yyval = mk_expression_list(yyvsp[-2], yyvsp[0]); } -#line 3845 "awkgram.c" +#line 3851 "awkgram.c" break; - case 127: /* expression_list: expression_list comma error */ -#line 1735 "awkgram.y" + case 128: /* expression_list: expression_list comma error */ +#line 1737 "awkgram.y" { /* Ditto */ if (yyvsp[-1] != NULL) yyvsp[-2]->lasti->comment = yyvsp[-1]; yyval = yyvsp[-2]; } -#line 3856 "awkgram.c" - break; - - case 128: /* opt_fcall_expression_list: %empty */ -#line 1745 "awkgram.y" - { yyval = NULL; } #line 3862 "awkgram.c" break; - case 129: /* opt_fcall_expression_list: fcall_expression_list */ + case 129: /* opt_fcall_expression_list: %empty */ #line 1747 "awkgram.y" - { yyval = yyvsp[0]; } + { yyval = NULL; } #line 3868 "awkgram.c" break; - case 130: /* fcall_expression_list: fcall_exp */ -#line 1752 "awkgram.y" - { yyval = mk_expression_list(NULL, yyvsp[0]); } + case 130: /* opt_fcall_expression_list: fcall_expression_list */ +#line 1749 "awkgram.y" + { yyval = yyvsp[0]; } #line 3874 "awkgram.c" break; - case 131: /* fcall_expression_list: fcall_expression_list comma fcall_exp */ + case 131: /* fcall_expression_list: fcall_exp */ #line 1754 "awkgram.y" + { yyval = mk_expression_list(NULL, yyvsp[0]); } +#line 3880 "awkgram.c" + break; + + case 132: /* fcall_expression_list: fcall_expression_list comma fcall_exp */ +#line 1756 "awkgram.y" { if (yyvsp[-1] != NULL) yyvsp[-2]->lasti->comment = yyvsp[-1]; yyval = mk_expression_list(yyvsp[-2], yyvsp[0]); yyerrok; } -#line 3885 "awkgram.c" +#line 3891 "awkgram.c" break; - case 132: /* fcall_expression_list: error */ -#line 1761 "awkgram.y" + case 133: /* fcall_expression_list: error */ +#line 1763 "awkgram.y" { yyval = NULL; } -#line 3891 "awkgram.c" +#line 3897 "awkgram.c" break; - case 133: /* fcall_expression_list: fcall_expression_list error */ -#line 1763 "awkgram.y" + case 134: /* fcall_expression_list: fcall_expression_list error */ +#line 1765 "awkgram.y" { /* * Returning the expression list instead of NULL lets @@ -3899,86 +3905,86 @@ regular_print: */ yyval = yyvsp[-1]; } -#line 3903 "awkgram.c" +#line 3909 "awkgram.c" break; - case 134: /* fcall_expression_list: fcall_expression_list error fcall_exp */ -#line 1771 "awkgram.y" + case 135: /* fcall_expression_list: fcall_expression_list error fcall_exp */ +#line 1773 "awkgram.y" { /* Ditto */ yyval = mk_expression_list(yyvsp[-2], yyvsp[0]); } -#line 3912 "awkgram.c" +#line 3918 "awkgram.c" break; - case 135: /* fcall_expression_list: fcall_expression_list comma error */ -#line 1776 "awkgram.y" + case 136: /* fcall_expression_list: fcall_expression_list comma error */ +#line 1778 "awkgram.y" { /* Ditto */ if (yyvsp[-1] != NULL) yyvsp[-2]->comment = yyvsp[-1]; yyval = yyvsp[-2]; } -#line 3923 "awkgram.c" +#line 3929 "awkgram.c" break; - case 136: /* fcall_exp: exp */ -#line 1785 "awkgram.y" + case 137: /* fcall_exp: exp */ +#line 1787 "awkgram.y" { yyval = yyvsp[0]; } -#line 3929 "awkgram.c" +#line 3935 "awkgram.c" break; - case 137: /* fcall_exp: typed_regexp */ -#line 1786 "awkgram.y" + case 138: /* fcall_exp: typed_regexp */ +#line 1788 "awkgram.y" { yyval = list_create(yyvsp[0]); } -#line 3935 "awkgram.c" +#line 3941 "awkgram.c" break; - case 138: /* opt_fcall_exp: %empty */ -#line 1791 "awkgram.y" + case 139: /* opt_fcall_exp: %empty */ +#line 1793 "awkgram.y" { yyval = NULL; } -#line 3941 "awkgram.c" +#line 3947 "awkgram.c" break; - case 139: /* opt_fcall_exp: fcall_exp */ -#line 1792 "awkgram.y" + case 140: /* opt_fcall_exp: fcall_exp */ +#line 1794 "awkgram.y" { yyval = yyvsp[0]; } -#line 3947 "awkgram.c" +#line 3953 "awkgram.c" break; - case 140: /* exp: variable assign_operator exp */ -#line 1798 "awkgram.y" + case 141: /* exp: variable assign_operator exp */ +#line 1800 "awkgram.y" { if (do_lint && yyvsp[0]->lasti->opcode == Op_match_rec) lintwarn_ln(yyvsp[-1]->source_line, _("regular expression on right of assignment")); yyval = mk_assignment(yyvsp[-2], yyvsp[0], yyvsp[-1]); } -#line 3958 "awkgram.c" +#line 3964 "awkgram.c" break; - case 141: /* exp: variable ASSIGN typed_regexp */ -#line 1805 "awkgram.y" + case 142: /* exp: variable ASSIGN typed_regexp */ +#line 1807 "awkgram.y" { yyval = mk_assignment(yyvsp[-2], list_create(yyvsp[0]), yyvsp[-1]); } -#line 3966 "awkgram.c" - break; - - case 142: /* exp: exp LEX_AND exp */ -#line 1809 "awkgram.y" - { yyval = mk_boolean(yyvsp[-2], yyvsp[0], yyvsp[-1]); } #line 3972 "awkgram.c" break; - case 143: /* exp: exp LEX_OR exp */ + case 143: /* exp: exp LEX_AND exp */ #line 1811 "awkgram.y" { yyval = mk_boolean(yyvsp[-2], yyvsp[0], yyvsp[-1]); } #line 3978 "awkgram.c" break; - case 144: /* exp: exp MATCHOP typed_regexp */ + case 144: /* exp: exp LEX_OR exp */ #line 1813 "awkgram.y" + { yyval = mk_boolean(yyvsp[-2], yyvsp[0], yyvsp[-1]); } +#line 3984 "awkgram.c" + break; + + case 145: /* exp: exp MATCHOP typed_regexp */ +#line 1815 "awkgram.y" { if (yyvsp[-2]->lasti->opcode == Op_match_rec) warning_ln(yyvsp[-1]->source_line, @@ -3991,11 +3997,11 @@ regular_print: bcfree(yyvsp[0]); yyval = list_append(yyvsp[-2], yyvsp[-1]); } -#line 3995 "awkgram.c" +#line 4001 "awkgram.c" break; - case 145: /* exp: exp MATCHOP exp */ -#line 1826 "awkgram.y" + case 146: /* exp: exp MATCHOP exp */ +#line 1828 "awkgram.y" { if (yyvsp[-2]->lasti->opcode == Op_match_rec) warning_ln(yyvsp[-1]->source_line, @@ -4012,11 +4018,11 @@ regular_print: yyval = list_append(list_merge(yyvsp[-2], yyvsp[0]), yyvsp[-1]); } } -#line 4016 "awkgram.c" +#line 4022 "awkgram.c" break; - case 146: /* exp: exp LEX_IN simple_variable */ -#line 1843 "awkgram.y" + case 147: /* exp: exp LEX_IN simple_variable */ +#line 1845 "awkgram.y" { if (do_lint_old) lintwarn_ln(yyvsp[-1]->source_line, @@ -4026,91 +4032,91 @@ regular_print: yyvsp[-1]->expr_count = 1; yyval = list_append(list_merge(yyvsp[-2], yyvsp[0]), yyvsp[-1]); } -#line 4030 "awkgram.c" +#line 4036 "awkgram.c" break; - case 147: /* exp: exp a_relop exp */ -#line 1853 "awkgram.y" + case 148: /* exp: exp a_relop exp */ +#line 1855 "awkgram.y" { if (do_lint && yyvsp[0]->lasti->opcode == Op_match_rec) lintwarn_ln(yyvsp[-1]->source_line, _("regular expression on right of comparison")); yyval = list_append(list_merge(yyvsp[-2], yyvsp[0]), yyvsp[-1]); } -#line 4041 "awkgram.c" - break; - - case 148: /* exp: exp '?' exp ':' exp */ -#line 1860 "awkgram.y" - { yyval = mk_condition(yyvsp[-4], yyvsp[-3], yyvsp[-2], yyvsp[-1], yyvsp[0]); } #line 4047 "awkgram.c" break; - case 149: /* exp: common_exp */ + case 149: /* exp: exp '?' exp ':' exp */ #line 1862 "awkgram.y" - { yyval = yyvsp[0]; } + { yyval = mk_condition(yyvsp[-4], yyvsp[-3], yyvsp[-2], yyvsp[-1], yyvsp[0]); } #line 4053 "awkgram.c" break; - case 150: /* assign_operator: ASSIGN */ -#line 1867 "awkgram.y" + case 150: /* exp: common_exp */ +#line 1864 "awkgram.y" { yyval = yyvsp[0]; } #line 4059 "awkgram.c" break; - case 151: /* assign_operator: ASSIGNOP */ + case 151: /* assign_operator: ASSIGN */ #line 1869 "awkgram.y" { yyval = yyvsp[0]; } #line 4065 "awkgram.c" break; - case 152: /* assign_operator: SLASH_BEFORE_EQUAL ASSIGN */ + case 152: /* assign_operator: ASSIGNOP */ #line 1871 "awkgram.y" + { yyval = yyvsp[0]; } +#line 4071 "awkgram.c" + break; + + case 153: /* assign_operator: SLASH_BEFORE_EQUAL ASSIGN */ +#line 1873 "awkgram.y" { yyvsp[0]->opcode = Op_assign_quotient; yyval = yyvsp[0]; } -#line 4074 "awkgram.c" - break; - - case 153: /* relop_or_less: RELOP */ -#line 1879 "awkgram.y" - { yyval = yyvsp[0]; } #line 4080 "awkgram.c" break; - case 154: /* relop_or_less: '<' */ + case 154: /* relop_or_less: RELOP */ #line 1881 "awkgram.y" { yyval = yyvsp[0]; } #line 4086 "awkgram.c" break; - case 155: /* a_relop: relop_or_less */ -#line 1886 "awkgram.y" + case 155: /* relop_or_less: '<' */ +#line 1883 "awkgram.y" { yyval = yyvsp[0]; } #line 4092 "awkgram.c" break; - case 156: /* a_relop: '>' */ + case 156: /* a_relop: relop_or_less */ #line 1888 "awkgram.y" { yyval = yyvsp[0]; } #line 4098 "awkgram.c" break; - case 157: /* common_exp: simp_exp */ -#line 1893 "awkgram.y" + case 157: /* a_relop: '>' */ +#line 1890 "awkgram.y" { yyval = yyvsp[0]; } #line 4104 "awkgram.c" break; - case 158: /* common_exp: simp_exp_nc */ + case 158: /* common_exp: simp_exp */ #line 1895 "awkgram.y" { yyval = yyvsp[0]; } #line 4110 "awkgram.c" break; - case 159: /* common_exp: common_exp simp_exp */ + case 159: /* common_exp: simp_exp_nc */ #line 1897 "awkgram.y" + { yyval = yyvsp[0]; } +#line 4116 "awkgram.c" + break; + + case 160: /* common_exp: common_exp simp_exp */ +#line 1899 "awkgram.y" { int count = 2; bool is_simple_var = false; @@ -4164,47 +4170,47 @@ regular_print: max_args = count; } } -#line 4168 "awkgram.c" - break; - - case 161: /* simp_exp: simp_exp '^' simp_exp */ -#line 1956 "awkgram.y" - { yyval = mk_binary(yyvsp[-2], yyvsp[0], yyvsp[-1]); } #line 4174 "awkgram.c" break; - case 162: /* simp_exp: simp_exp '*' simp_exp */ + case 162: /* simp_exp: simp_exp '^' simp_exp */ #line 1958 "awkgram.y" { yyval = mk_binary(yyvsp[-2], yyvsp[0], yyvsp[-1]); } #line 4180 "awkgram.c" break; - case 163: /* simp_exp: simp_exp '/' simp_exp */ + case 163: /* simp_exp: simp_exp '*' simp_exp */ #line 1960 "awkgram.y" { yyval = mk_binary(yyvsp[-2], yyvsp[0], yyvsp[-1]); } #line 4186 "awkgram.c" break; - case 164: /* simp_exp: simp_exp '%' simp_exp */ + case 164: /* simp_exp: simp_exp '/' simp_exp */ #line 1962 "awkgram.y" { yyval = mk_binary(yyvsp[-2], yyvsp[0], yyvsp[-1]); } #line 4192 "awkgram.c" break; - case 165: /* simp_exp: simp_exp '+' simp_exp */ + case 165: /* simp_exp: simp_exp '%' simp_exp */ #line 1964 "awkgram.y" { yyval = mk_binary(yyvsp[-2], yyvsp[0], yyvsp[-1]); } #line 4198 "awkgram.c" break; - case 166: /* simp_exp: simp_exp '-' simp_exp */ + case 166: /* simp_exp: simp_exp '+' simp_exp */ #line 1966 "awkgram.y" { yyval = mk_binary(yyvsp[-2], yyvsp[0], yyvsp[-1]); } #line 4204 "awkgram.c" break; - case 167: /* simp_exp: LEX_GETLINE opt_variable input_redir */ + case 167: /* simp_exp: simp_exp '-' simp_exp */ #line 1968 "awkgram.y" + { yyval = mk_binary(yyvsp[-2], yyvsp[0], yyvsp[-1]); } +#line 4210 "awkgram.c" + break; + + case 168: /* simp_exp: LEX_GETLINE opt_variable input_redir */ +#line 1970 "awkgram.y" { /* * In BEGINFILE/ENDFILE, allow `getline [var] < file' @@ -4218,29 +4224,29 @@ regular_print: _("non-redirected `getline' undefined inside END action")); yyval = mk_getline(yyvsp[-2], yyvsp[-1], yyvsp[0], redirect_input); } -#line 4222 "awkgram.c" +#line 4228 "awkgram.c" break; - case 168: /* simp_exp: variable INCREMENT */ -#line 1982 "awkgram.y" + case 169: /* simp_exp: variable INCREMENT */ +#line 1984 "awkgram.y" { yyvsp[0]->opcode = Op_postincrement; yyval = mk_assignment(yyvsp[-1], NULL, yyvsp[0]); } -#line 4231 "awkgram.c" +#line 4237 "awkgram.c" break; - case 169: /* simp_exp: variable DECREMENT */ -#line 1987 "awkgram.y" + case 170: /* simp_exp: variable DECREMENT */ +#line 1989 "awkgram.y" { yyvsp[0]->opcode = Op_postdecrement; yyval = mk_assignment(yyvsp[-1], NULL, yyvsp[0]); } -#line 4240 "awkgram.c" +#line 4246 "awkgram.c" break; - case 170: /* simp_exp: '(' expression_list r_paren LEX_IN simple_variable */ -#line 1992 "awkgram.y" + case 171: /* simp_exp: '(' expression_list r_paren LEX_IN simple_variable */ +#line 1994 "awkgram.y" { if (do_lint_old) { /* first one is warning so that second one comes out if warnings are fatal */ @@ -4261,64 +4267,64 @@ regular_print: yyval = list_append(list_merge(t, yyvsp[0]), yyvsp[-1]); } } -#line 4265 "awkgram.c" +#line 4271 "awkgram.c" break; - case 171: /* simp_exp_nc: common_exp IO_IN LEX_GETLINE opt_variable */ -#line 2018 "awkgram.y" + case 172: /* simp_exp_nc: common_exp IO_IN LEX_GETLINE opt_variable */ +#line 2020 "awkgram.y" { yyval = mk_getline(yyvsp[-1], yyvsp[0], yyvsp[-3], yyvsp[-2]->redir_type); bcfree(yyvsp[-2]); } -#line 4274 "awkgram.c" - break; - - case 172: /* simp_exp_nc: simp_exp_nc '^' simp_exp */ -#line 2024 "awkgram.y" - { yyval = mk_binary(yyvsp[-2], yyvsp[0], yyvsp[-1]); } #line 4280 "awkgram.c" break; - case 173: /* simp_exp_nc: simp_exp_nc '*' simp_exp */ + case 173: /* simp_exp_nc: simp_exp_nc '^' simp_exp */ #line 2026 "awkgram.y" { yyval = mk_binary(yyvsp[-2], yyvsp[0], yyvsp[-1]); } #line 4286 "awkgram.c" break; - case 174: /* simp_exp_nc: simp_exp_nc '/' simp_exp */ + case 174: /* simp_exp_nc: simp_exp_nc '*' simp_exp */ #line 2028 "awkgram.y" { yyval = mk_binary(yyvsp[-2], yyvsp[0], yyvsp[-1]); } #line 4292 "awkgram.c" break; - case 175: /* simp_exp_nc: simp_exp_nc '%' simp_exp */ + case 175: /* simp_exp_nc: simp_exp_nc '/' simp_exp */ #line 2030 "awkgram.y" { yyval = mk_binary(yyvsp[-2], yyvsp[0], yyvsp[-1]); } #line 4298 "awkgram.c" break; - case 176: /* simp_exp_nc: simp_exp_nc '+' simp_exp */ + case 176: /* simp_exp_nc: simp_exp_nc '%' simp_exp */ #line 2032 "awkgram.y" { yyval = mk_binary(yyvsp[-2], yyvsp[0], yyvsp[-1]); } #line 4304 "awkgram.c" break; - case 177: /* simp_exp_nc: simp_exp_nc '-' simp_exp */ + case 177: /* simp_exp_nc: simp_exp_nc '+' simp_exp */ #line 2034 "awkgram.y" { yyval = mk_binary(yyvsp[-2], yyvsp[0], yyvsp[-1]); } #line 4310 "awkgram.c" break; - case 178: /* non_post_simp_exp: regexp */ -#line 2039 "awkgram.y" + case 178: /* simp_exp_nc: simp_exp_nc '-' simp_exp */ +#line 2036 "awkgram.y" + { yyval = mk_binary(yyvsp[-2], yyvsp[0], yyvsp[-1]); } +#line 4316 "awkgram.c" + break; + + case 179: /* non_post_simp_exp: regexp */ +#line 2041 "awkgram.y" { yyval = list_create(yyvsp[0]); } -#line 4318 "awkgram.c" +#line 4324 "awkgram.c" break; - case 179: /* non_post_simp_exp: '!' simp_exp */ -#line 2043 "awkgram.y" + case 180: /* non_post_simp_exp: '!' simp_exp */ +#line 2045 "awkgram.y" { if (yyvsp[0]->opcode == Op_match_rec) { yyvsp[0]->opcode = Op_nomatch; @@ -4350,11 +4356,11 @@ regular_print: } } } -#line 4354 "awkgram.c" +#line 4360 "awkgram.c" break; - case 180: /* non_post_simp_exp: '(' exp r_paren */ -#line 2075 "awkgram.y" + case 181: /* non_post_simp_exp: '(' exp r_paren */ +#line 2077 "awkgram.y" { // Always include. Allows us to lint warn on // print "foo" > "bar" 1 @@ -4362,31 +4368,31 @@ regular_print: // print "foo" > ("bar" 1) yyval = list_append(yyvsp[-1], bcalloc(Op_parens, 1, sourceline)); } -#line 4366 "awkgram.c" +#line 4372 "awkgram.c" break; - case 181: /* non_post_simp_exp: LEX_BUILTIN '(' opt_fcall_expression_list r_paren */ -#line 2083 "awkgram.y" + case 182: /* non_post_simp_exp: LEX_BUILTIN '(' opt_fcall_expression_list r_paren */ +#line 2085 "awkgram.y" { yyval = snode(yyvsp[-1], yyvsp[-3]); if (yyval == NULL) YYABORT; } -#line 4376 "awkgram.c" +#line 4382 "awkgram.c" break; - case 182: /* non_post_simp_exp: LEX_LENGTH '(' opt_fcall_expression_list r_paren */ -#line 2089 "awkgram.y" + case 183: /* non_post_simp_exp: LEX_LENGTH '(' opt_fcall_expression_list r_paren */ +#line 2091 "awkgram.y" { yyval = snode(yyvsp[-1], yyvsp[-3]); if (yyval == NULL) YYABORT; } -#line 4386 "awkgram.c" +#line 4392 "awkgram.c" break; - case 183: /* non_post_simp_exp: LEX_LENGTH */ -#line 2095 "awkgram.y" + case 184: /* non_post_simp_exp: LEX_LENGTH */ +#line 2097 "awkgram.y" { static bool warned = false; @@ -4399,45 +4405,45 @@ regular_print: if (yyval == NULL) YYABORT; } -#line 4403 "awkgram.c" +#line 4409 "awkgram.c" break; - case 186: /* non_post_simp_exp: INCREMENT variable */ -#line 2110 "awkgram.y" + case 187: /* non_post_simp_exp: INCREMENT variable */ +#line 2112 "awkgram.y" { yyvsp[-1]->opcode = Op_preincrement; yyval = mk_assignment(yyvsp[0], NULL, yyvsp[-1]); } -#line 4412 "awkgram.c" +#line 4418 "awkgram.c" break; - case 187: /* non_post_simp_exp: DECREMENT variable */ -#line 2115 "awkgram.y" + case 188: /* non_post_simp_exp: DECREMENT variable */ +#line 2117 "awkgram.y" { yyvsp[-1]->opcode = Op_predecrement; yyval = mk_assignment(yyvsp[0], NULL, yyvsp[-1]); } -#line 4421 "awkgram.c" +#line 4427 "awkgram.c" break; - case 188: /* non_post_simp_exp: YNUMBER */ -#line 2120 "awkgram.y" + case 189: /* non_post_simp_exp: YNUMBER */ +#line 2122 "awkgram.y" { yyval = list_create(yyvsp[0]); } -#line 4429 "awkgram.c" +#line 4435 "awkgram.c" break; - case 189: /* non_post_simp_exp: YSTRING */ -#line 2124 "awkgram.y" + case 190: /* non_post_simp_exp: YSTRING */ +#line 2126 "awkgram.y" { yyval = list_create(yyvsp[0]); } -#line 4437 "awkgram.c" +#line 4443 "awkgram.c" break; - case 190: /* non_post_simp_exp: '-' simp_exp */ -#line 2128 "awkgram.y" + case 191: /* non_post_simp_exp: '-' simp_exp */ +#line 2130 "awkgram.y" { if (yyvsp[0]->lasti->opcode == Op_push_i && (yyvsp[0]->lasti->memory->flags & STRING) == 0 @@ -4452,11 +4458,11 @@ regular_print: yyval = list_append(yyvsp[0], yyvsp[-1]); } } -#line 4456 "awkgram.c" +#line 4462 "awkgram.c" break; - case 191: /* non_post_simp_exp: '+' simp_exp */ -#line 2143 "awkgram.y" + case 192: /* non_post_simp_exp: '+' simp_exp */ +#line 2145 "awkgram.y" { if (yyvsp[0]->lasti->opcode == Op_push_i && (yyvsp[0]->lasti->memory->flags & STRING) == 0 @@ -4474,20 +4480,20 @@ regular_print: yyval = list_append(yyvsp[0], yyvsp[-1]); } } -#line 4478 "awkgram.c" +#line 4484 "awkgram.c" break; - case 192: /* func_call: direct_func_call */ -#line 2164 "awkgram.y" + case 193: /* func_call: direct_func_call */ +#line 2166 "awkgram.y" { func_use(yyvsp[0]->lasti->func_name, FUNC_USE); yyval = yyvsp[0]; } -#line 4487 "awkgram.c" +#line 4493 "awkgram.c" break; - case 193: /* func_call: '@' direct_func_call */ -#line 2169 "awkgram.y" + case 194: /* func_call: '@' direct_func_call */ +#line 2171 "awkgram.y" { /* indirect function call */ INSTRUCTION *f, *t; @@ -4521,11 +4527,11 @@ regular_print: yyval = list_prepend(yyvsp[0], t); at_seen--; } -#line 4525 "awkgram.c" +#line 4531 "awkgram.c" break; - case 194: /* direct_func_call: FUNC_CALL '(' opt_fcall_expression_list r_paren */ -#line 2206 "awkgram.y" + case 195: /* direct_func_call: FUNC_CALL '(' opt_fcall_expression_list r_paren */ +#line 2208 "awkgram.y" { NODE *n; char *name = yyvsp[-3]->func_name; @@ -4558,49 +4564,49 @@ regular_print: yyval = list_append(t, yyvsp[-3]); } } -#line 4562 "awkgram.c" - break; - - case 195: /* opt_variable: %empty */ -#line 2242 "awkgram.y" - { yyval = NULL; } #line 4568 "awkgram.c" break; - case 196: /* opt_variable: variable */ + case 196: /* opt_variable: %empty */ #line 2244 "awkgram.y" - { yyval = yyvsp[0]; } + { yyval = NULL; } #line 4574 "awkgram.c" break; - case 197: /* delete_subscript_list: %empty */ -#line 2249 "awkgram.y" - { yyval = NULL; } + case 197: /* opt_variable: variable */ +#line 2246 "awkgram.y" + { yyval = yyvsp[0]; } #line 4580 "awkgram.c" break; - case 198: /* delete_subscript_list: delete_subscript SUBSCRIPT */ + case 198: /* delete_subscript_list: %empty */ #line 2251 "awkgram.y" - { yyval = yyvsp[-1]; } + { yyval = NULL; } #line 4586 "awkgram.c" break; - case 199: /* delete_subscript: delete_exp_list */ -#line 2256 "awkgram.y" - { yyval = yyvsp[0]; } + case 199: /* delete_subscript_list: delete_subscript SUBSCRIPT */ +#line 2253 "awkgram.y" + { yyval = yyvsp[-1]; } #line 4592 "awkgram.c" break; - case 200: /* delete_subscript: delete_subscript delete_exp_list */ + case 200: /* delete_subscript: delete_exp_list */ #line 2258 "awkgram.y" + { yyval = yyvsp[0]; } +#line 4598 "awkgram.c" + break; + + case 201: /* delete_subscript: delete_subscript delete_exp_list */ +#line 2260 "awkgram.y" { yyval = list_merge(yyvsp[-1], yyvsp[0]); } -#line 4600 "awkgram.c" +#line 4606 "awkgram.c" break; - case 201: /* delete_exp_list: bracketed_exp_list */ -#line 2265 "awkgram.y" + case 202: /* delete_exp_list: bracketed_exp_list */ +#line 2267 "awkgram.y" { INSTRUCTION *ip = yyvsp[0]->lasti; int count = ip->sub_count; /* # of SUBSEP-seperated expressions */ @@ -4614,11 +4620,11 @@ regular_print: sub_counter++; /* count # of dimensions */ yyval = yyvsp[0]; } -#line 4618 "awkgram.c" +#line 4624 "awkgram.c" break; - case 202: /* bracketed_exp_list: '[' expression_list ']' */ -#line 2282 "awkgram.y" + case 203: /* bracketed_exp_list: '[' expression_list ']' */ +#line 2284 "awkgram.y" { INSTRUCTION *t = yyvsp[-1]; if (yyvsp[-1] == NULL) { @@ -4632,41 +4638,41 @@ regular_print: yyvsp[0]->sub_count = count_expressions(&t, false); yyval = list_append(t, yyvsp[0]); } -#line 4636 "awkgram.c" +#line 4642 "awkgram.c" break; - case 203: /* subscript: bracketed_exp_list */ -#line 2299 "awkgram.y" + case 204: /* subscript: bracketed_exp_list */ +#line 2301 "awkgram.y" { yyval = yyvsp[0]; } -#line 4642 "awkgram.c" +#line 4648 "awkgram.c" break; - case 204: /* subscript: subscript bracketed_exp_list */ -#line 2301 "awkgram.y" + case 205: /* subscript: subscript bracketed_exp_list */ +#line 2303 "awkgram.y" { yyval = list_merge(yyvsp[-1], yyvsp[0]); } -#line 4650 "awkgram.c" +#line 4656 "awkgram.c" break; - case 205: /* subscript_list: subscript SUBSCRIPT */ -#line 2308 "awkgram.y" + case 206: /* subscript_list: subscript SUBSCRIPT */ +#line 2310 "awkgram.y" { yyval = yyvsp[-1]; } -#line 4656 "awkgram.c" +#line 4662 "awkgram.c" break; - case 206: /* simple_variable: NAME */ -#line 2313 "awkgram.y" + case 207: /* simple_variable: NAME */ +#line 2315 "awkgram.y" { yyvsp[0]->opcode = Op_push; yyvsp[0]->memory = variable(yyvsp[0]->source_line, yyvsp[0]->lextok, Node_var_new); yyval = list_create(yyvsp[0]); } -#line 4666 "awkgram.c" +#line 4672 "awkgram.c" break; - case 207: /* simple_variable: NAME subscript_list */ -#line 2319 "awkgram.y" + case 208: /* simple_variable: NAME subscript_list */ +#line 2321 "awkgram.y" { char *arr = yyvsp[-1]->lextok; @@ -4674,11 +4680,11 @@ regular_print: yyvsp[-1]->opcode = Op_push_array; yyval = list_prepend(yyvsp[0], yyvsp[-1]); } -#line 4678 "awkgram.c" +#line 4684 "awkgram.c" break; - case 208: /* variable: simple_variable */ -#line 2330 "awkgram.y" + case 209: /* variable: simple_variable */ +#line 2332 "awkgram.y" { INSTRUCTION *ip = yyvsp[0]->nexti; if (ip->opcode == Op_push @@ -4690,85 +4696,85 @@ regular_print: } else yyval = yyvsp[0]; } -#line 4694 "awkgram.c" +#line 4700 "awkgram.c" break; - case 209: /* variable: '$' non_post_simp_exp opt_incdec */ -#line 2342 "awkgram.y" + case 210: /* variable: '$' non_post_simp_exp opt_incdec */ +#line 2344 "awkgram.y" { yyval = list_append(yyvsp[-1], yyvsp[-2]); if (yyvsp[0] != NULL) mk_assignment(yyvsp[-1], NULL, yyvsp[0]); } -#line 4704 "awkgram.c" +#line 4710 "awkgram.c" break; - case 210: /* opt_incdec: INCREMENT */ -#line 2351 "awkgram.y" + case 211: /* opt_incdec: INCREMENT */ +#line 2353 "awkgram.y" { yyvsp[0]->opcode = Op_postincrement; } -#line 4712 "awkgram.c" +#line 4718 "awkgram.c" break; - case 211: /* opt_incdec: DECREMENT */ -#line 2355 "awkgram.y" + case 212: /* opt_incdec: DECREMENT */ +#line 2357 "awkgram.y" { yyvsp[0]->opcode = Op_postdecrement; } -#line 4720 "awkgram.c" +#line 4726 "awkgram.c" break; - case 212: /* opt_incdec: %empty */ -#line 2359 "awkgram.y" + case 213: /* opt_incdec: %empty */ +#line 2361 "awkgram.y" { yyval = NULL; } -#line 4726 "awkgram.c" +#line 4732 "awkgram.c" break; - case 213: /* l_brace: '{' opt_nls */ -#line 2363 "awkgram.y" + case 214: /* l_brace: '{' opt_nls */ +#line 2365 "awkgram.y" { yyval = yyvsp[0]; } -#line 4732 "awkgram.c" +#line 4738 "awkgram.c" break; - case 214: /* r_brace: '}' opt_nls */ -#line 2367 "awkgram.y" + case 215: /* r_brace: '}' opt_nls */ +#line 2369 "awkgram.y" { yyval = yyvsp[0]; yyerrok; } -#line 4738 "awkgram.c" +#line 4744 "awkgram.c" break; - case 215: /* r_paren: ')' */ -#line 2371 "awkgram.y" + case 216: /* r_paren: ')' */ +#line 2373 "awkgram.y" { yyerrok; } -#line 4744 "awkgram.c" +#line 4750 "awkgram.c" break; - case 216: /* opt_semi: %empty */ -#line 2376 "awkgram.y" + case 217: /* opt_semi: %empty */ +#line 2378 "awkgram.y" { yyval = NULL; } -#line 4750 "awkgram.c" +#line 4756 "awkgram.c" break; - case 218: /* semi: ';' */ -#line 2381 "awkgram.y" + case 219: /* semi: ';' */ +#line 2383 "awkgram.y" { yyerrok; } -#line 4756 "awkgram.c" +#line 4762 "awkgram.c" break; - case 219: /* colon: ':' */ -#line 2385 "awkgram.y" + case 220: /* colon: ':' */ +#line 2387 "awkgram.y" { yyval = yyvsp[0]; yyerrok; } -#line 4762 "awkgram.c" +#line 4768 "awkgram.c" break; - case 220: /* comma: ',' opt_nls */ -#line 2389 "awkgram.y" + case 221: /* comma: ',' opt_nls */ +#line 2391 "awkgram.y" { yyval = yyvsp[0]; yyerrok; } -#line 4768 "awkgram.c" +#line 4774 "awkgram.c" break; -#line 4772 "awkgram.c" +#line 4778 "awkgram.c" default: break; } @@ -4961,7 +4967,7 @@ yyreturnlab: return yyresult; } -#line 2391 "awkgram.y" +#line 2393 "awkgram.y" struct token { @@ -7782,7 +7788,7 @@ mk_function(INSTRUCTION *fi, INSTRUCTION *def) /* update lint table info */ func_use(thisfunc->vname, FUNC_DEFINE); - /* remove params/locals from symbol table */ + /* remove params from symbol table */ remove_locals(thisfunc); return fi; } diff --git a/awkgram.y b/awkgram.y index 4f568e22..fc35100d 100644 --- a/awkgram.y +++ b/awkgram.y @@ -1603,6 +1603,8 @@ let_var_list_opt { $$ = NULL; } | let_var_list { $$ = $1; } + | let_var_list comma + { $$ = $1; } ; let_var_list diff --git a/doc/gawk.texi b/doc/gawk.texi index dea485c6..2535e45a 100644 --- a/doc/gawk.texi +++ b/doc/gawk.texi @@ -21658,7 +21658,7 @@ statement. The @code{@@let} statement is introduced by the @code{@@} symbol followed by the special keyword @code{let}. These tokens are -then followed by a comma-separated list of variable declarators, +then followed by a comma-separated or comma-terminated list of variable declarators, enclosed in parentheses. After the parentheses comes a required statement, The list of variables may be empty. @@ -21809,6 +21809,11 @@ The @code{print} statement is then executed in the scope of the rightmost @code{x}. The initializing expressions @code{x + 1} have the previous @code{x} still in scope. +The @code{@@let} statement allows a trailing comma after the last +variable declarator. Effectively, the declarators can be regarded +as either comma-separated or comma-terminated. Comma termination is +easier to deal with in macro preprocessing and code generation. + @node Pass By Value/Reference @subsubsection Passing Function Arguments by Value Or by Reference diff --git a/doc/gawktexi.in b/doc/gawktexi.in index 651bd8d2..0bb4f4dc 100644 --- a/doc/gawktexi.in +++ b/doc/gawktexi.in @@ -20570,7 +20570,7 @@ statement. The @code{@@let} statement is introduced by the @code{@@} symbol followed by the special keyword @code{let}. These tokens are -then followed by a comma-separated list of variable declarators, +then followed by a comma-separated or comma-terminated list of variable declarators, enclosed in parentheses. After the parentheses comes a required statement, The list of variables may be empty. @@ -20721,6 +20721,11 @@ The @code{print} statement is then executed in the scope of the rightmost @code{x}. The initializing expressions @code{x + 1} have the previous @code{x} still in scope. +The @code{@@let} statement allows a trailing comma after the last +variable declarator. Effectively, the declarators can be regarded +as either comma-separated or comma-terminated. Comma termination is +easier to deal with in macro preprocessing and code generation. + @node Pass By Value/Reference @subsubsection Passing Function Arguments by Value Or by Reference diff --git a/test/let1.awk b/test/let1.awk index 413b6e1e..268222df 100644 --- a/test/let1.awk +++ b/test/let1.awk @@ -157,3 +157,17 @@ BEGIN { @let (x = 1, y = 2) { print "b6", x, y } @let (x = 1, y = 2, z = 3) { print "b6", x, y, z } } + +function f6() +{ + @let (x = 1) { print "f6", x } + @let (x = 1, y = 2,) { print "f6", x, y } + @let (x = 1, y = 2, z = 3,) { print "f6", x, y, z } +} + +BEGIN { + f6() + @let (x = 1) { print "b7", x } + @let (x = 1, y = 2,) { print "b7", x, y } + @let (x = 1, y = 2, z = 3,) { print "b7", x, y, z } +} diff --git a/test/let1.ok b/test/let1.ok index f3336775..70de9024 100644 --- a/test/let1.ok +++ b/test/let1.ok @@ -9,3 +9,9 @@ f5 1 2 3 b6 1 b6 1 2 b6 1 2 3 +f6 1 +f6 1 2 +f6 1 2 3 +b7 1 +b7 1 2 +b7 1 2 3 -- cgit v1.2.3