gawk-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gawk-diffs] [SCM] gawk branch, feature/namespaces, updated. gawk-4.1.0-


From: Arnold Robbins
Subject: [gawk-diffs] [SCM] gawk branch, feature/namespaces, updated. gawk-4.1.0-2576-g6e7a374
Date: Tue, 6 Jun 2017 01:28:42 -0400 (EDT)

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, feature/namespaces has been updated
       via  6e7a37483b47d388f3792a24c4b09817cb873cd4 (commit)
       via  d5e40fc211797a272d26ce416a6d1197757cd5fd (commit)
       via  ae6c8675d11441a345b889488541e9870a122508 (commit)
      from  a1599e31c31096b4d9d8fab1158e70bc1bc335da (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=6e7a37483b47d388f3792a24c4b09817cb873cd4

commit 6e7a37483b47d388f3792a24c4b09817cb873cd4
Merge: ae6c867 d5e40fc
Author: Arnold D. Robbins <address@hidden>
Date:   Tue Jun 6 08:28:31 2017 +0300

    Merge branch 'master' into feature/namespaces

diff --cc doc/ChangeLog
index 6eb3d9f,f6b6674..92afd91
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@@ -1,9 -1,4 +1,9 @@@
 +2017-06-06         Arnold D. Robbins     <address@hidden>
 +
 +      * gawktexi.in (Namespaces): Further clarifications. Move to
 +      `::' as the namespace separator.
 +
- 2017-06-05         Arnold D. Robbins     <address@hidden>
+ 2017-06-05         Andrew J. Schorr     <address@hidden>
  
        * gawktexi.in (Checking for MPFR): Fix typo.
  

http://git.sv.gnu.org/cgit/gawk.git/commit/?id=ae6c8675d11441a345b889488541e9870a122508

commit ae6c8675d11441a345b889488541e9870a122508
Author: Arnold D. Robbins <address@hidden>
Date:   Tue Jun 6 08:24:25 2017 +0300

    Make :: the namespace separator. Allow it in identifiers. Update doc.

diff --git a/ChangeLog b/ChangeLog
index 1257afb..b977cee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2017-06-06         Arnold D. Robbins     <address@hidden>
+
+       * awkgram.y (yylex): Allow :: in identifiers (the "NAME" token).
+       Use validate_qualified_name to check it.
+       (validate_qualified_name): New function.
+
 2017-05-30         Arnold D. Robbins     <address@hidden>
 
        * awkgram.y (nextc): Force -e chunks to be syntactic units.
diff --git a/awkgram.c b/awkgram.c
index 0e9a8d7..bf44ba8 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -98,6 +98,7 @@ static int load_library(INSTRUCTION *file);
 static void next_sourcefile(void);
 static char *tokexpand(void);
 static NODE *set_profile_text(NODE *n, const char *str, size_t len);
+static void validate_qualified_name(char *token);
 
 #define instruction(t) bcalloc(t, 1, 0)
 
@@ -212,7 +213,7 @@ extern double fmod(double x, double y);
 
 #define YYSTYPE INSTRUCTION *
 
-#line 216 "awkgram.c" /* yacc.c:339  */
+#line 217 "awkgram.c" /* yacc.c:339  */
 
 # ifndef YY_NULLPTR
 #  if defined __cplusplus && 201103L <= __cplusplus
@@ -368,7 +369,7 @@ int yyparse (void);
 
 /* Copy the second part of user declarations.  */
 
-#line 372 "awkgram.c" /* yacc.c:358  */
+#line 373 "awkgram.c" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -670,27 +671,27 @@ static const yytype_uint8 yytranslate[] =
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   215,   215,   217,   222,   223,   227,   239,   244,   255,
-     262,   268,   277,   285,   287,   292,   300,   302,   308,   316,
-     326,   356,   370,   384,   392,   403,   415,   417,   419,   425,
-     433,   434,   438,   438,   484,   483,   517,   532,   534,   539,
-     549,   596,   601,   602,   606,   608,   610,   617,   707,   749,
-     791,   904,   911,   918,   929,   939,   949,   959,   971,   988,
-     987,  1012,  1024,  1024,  1123,  1123,  1157,  1188,  1197,  1198,
-    1204,  1205,  1212,  1217,  1229,  1243,  1245,  1253,  1260,  1262,
-    1270,  1279,  1281,  1290,  1291,  1299,  1304,  1304,  1315,  1319,
-    1327,  1328,  1331,  1333,  1338,  1339,  1348,  1349,  1354,  1359,
-    1368,  1370,  1372,  1379,  1380,  1386,  1387,  1392,  1394,  1399,
-    1401,  1409,  1414,  1423,  1424,  1429,  1431,  1436,  1438,  1446,
-    1451,  1459,  1460,  1465,  1472,  1476,  1478,  1480,  1493,  1510,
-    1520,  1527,  1529,  1534,  1536,  1538,  1546,  1548,  1553,  1555,
-    1560,  1562,  1564,  1620,  1622,  1624,  1626,  1628,  1630,  1632,
-    1634,  1648,  1653,  1658,  1683,  1689,  1691,  1693,  1695,  1697,
-    1699,  1704,  1708,  1740,  1742,  1748,  1754,  1767,  1768,  1769,
-    1774,  1779,  1783,  1787,  1802,  1823,  1828,  1865,  1894,  1895,
-    1901,  1902,  1907,  1909,  1916,  1933,  1950,  1952,  1959,  1964,
-    1972,  1982,  1994,  2003,  2007,  2011,  2015,  2019,  2023,  2026,
-    2028,  2032,  2036,  2040
+       0,   216,   216,   218,   223,   224,   228,   240,   245,   256,
+     263,   269,   278,   286,   288,   293,   301,   303,   309,   317,
+     327,   357,   371,   385,   393,   404,   416,   418,   420,   426,
+     434,   435,   439,   439,   485,   484,   518,   533,   535,   540,
+     550,   597,   602,   603,   607,   609,   611,   618,   708,   750,
+     792,   905,   912,   919,   930,   940,   950,   960,   972,   989,
+     988,  1013,  1025,  1025,  1124,  1124,  1158,  1189,  1198,  1199,
+    1205,  1206,  1213,  1218,  1230,  1244,  1246,  1254,  1261,  1263,
+    1271,  1280,  1282,  1291,  1292,  1300,  1305,  1305,  1316,  1320,
+    1328,  1329,  1332,  1334,  1339,  1340,  1349,  1350,  1355,  1360,
+    1369,  1371,  1373,  1380,  1381,  1387,  1388,  1393,  1395,  1400,
+    1402,  1410,  1415,  1424,  1425,  1430,  1432,  1437,  1439,  1447,
+    1452,  1460,  1461,  1466,  1473,  1477,  1479,  1481,  1494,  1511,
+    1521,  1528,  1530,  1535,  1537,  1539,  1547,  1549,  1554,  1556,
+    1561,  1563,  1565,  1621,  1623,  1625,  1627,  1629,  1631,  1633,
+    1635,  1649,  1654,  1659,  1684,  1690,  1692,  1694,  1696,  1698,
+    1700,  1705,  1709,  1741,  1743,  1749,  1755,  1768,  1769,  1770,
+    1775,  1780,  1784,  1788,  1803,  1824,  1829,  1866,  1895,  1896,
+    1902,  1903,  1908,  1910,  1917,  1934,  1951,  1953,  1960,  1965,
+    1973,  1983,  1995,  2004,  2008,  2012,  2016,  2020,  2024,  2027,
+    2029,  2033,  2037,  2041
 };
 #endif
 
@@ -1888,24 +1889,24 @@ yyreduce:
   switch (yyn)
     {
         case 3:
-#line 218 "awkgram.y" /* yacc.c:1646  */
+#line 219 "awkgram.y" /* yacc.c:1646  */
     {
                rule = 0;
                yyerrok;
          }
-#line 1897 "awkgram.c" /* yacc.c:1646  */
+#line 1898 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 5:
-#line 224 "awkgram.y" /* yacc.c:1646  */
+#line 225 "awkgram.y" /* yacc.c:1646  */
     {
                next_sourcefile();
          }
-#line 1905 "awkgram.c" /* yacc.c:1646  */
+#line 1906 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 6:
-#line 228 "awkgram.y" /* yacc.c:1646  */
+#line 229 "awkgram.y" /* yacc.c:1646  */
     {
                rule = 0;
                /*
@@ -1914,20 +1915,20 @@ yyreduce:
                 */
                /* yyerrok; */
          }
-#line 1918 "awkgram.c" /* yacc.c:1646  */
+#line 1919 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 7:
-#line 240 "awkgram.y" /* yacc.c:1646  */
+#line 241 "awkgram.y" /* yacc.c:1646  */
     {
                (void) append_rule((yyvsp[-1]), (yyvsp[0]));
                first_rule = false;
          }
-#line 1927 "awkgram.c" /* yacc.c:1646  */
+#line 1928 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 8:
-#line 245 "awkgram.y" /* yacc.c:1646  */
+#line 246 "awkgram.y" /* yacc.c:1646  */
     {
                if (rule != Rule) {
                        msg(_("%s blocks must have an action part"), 
ruletab[rule]);
@@ -1938,42 +1939,42 @@ yyreduce:
                } else          /* pattern rule with non-empty pattern */
                        (void) append_rule((yyvsp[-1]), NULL);
          }
-#line 1942 "awkgram.c" /* yacc.c:1646  */
+#line 1943 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 9:
-#line 256 "awkgram.y" /* yacc.c:1646  */
+#line 257 "awkgram.y" /* yacc.c:1646  */
     {
                in_function = NULL;
                (void) mk_function((yyvsp[-1]), (yyvsp[0]));
                want_param_names = DONT_CHECK;
                yyerrok;
          }
-#line 1953 "awkgram.c" /* yacc.c:1646  */
+#line 1954 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 10:
-#line 263 "awkgram.y" /* yacc.c:1646  */
+#line 264 "awkgram.y" /* yacc.c:1646  */
     {
                want_source = false;
                at_seen = false;
                yyerrok;
          }
-#line 1963 "awkgram.c" /* yacc.c:1646  */
+#line 1964 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 11:
-#line 269 "awkgram.y" /* yacc.c:1646  */
+#line 270 "awkgram.y" /* yacc.c:1646  */
     {
                want_source = false;
                at_seen = false;
                yyerrok;
          }
-#line 1973 "awkgram.c" /* yacc.c:1646  */
+#line 1974 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 12:
-#line 278 "awkgram.y" /* yacc.c:1646  */
+#line 279 "awkgram.y" /* yacc.c:1646  */
     {
                if (include_source((yyvsp[0])) < 0)
                        YYABORT;
@@ -1981,23 +1982,23 @@ yyreduce:
                bcfree((yyvsp[0]));
                (yyval) = NULL;
          }
-#line 1985 "awkgram.c" /* yacc.c:1646  */
+#line 1986 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 13:
-#line 286 "awkgram.y" /* yacc.c:1646  */
+#line 287 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 1991 "awkgram.c" /* yacc.c:1646  */
+#line 1992 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 14:
-#line 288 "awkgram.y" /* yacc.c:1646  */
+#line 289 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 1997 "awkgram.c" /* yacc.c:1646  */
+#line 1998 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 15:
-#line 293 "awkgram.y" /* yacc.c:1646  */
+#line 294 "awkgram.y" /* yacc.c:1646  */
     {
                if (load_library((yyvsp[0])) < 0)
                        YYABORT;
@@ -2005,23 +2006,23 @@ yyreduce:
                bcfree((yyvsp[0]));
                (yyval) = NULL;
          }
-#line 2009 "awkgram.c" /* yacc.c:1646  */
+#line 2010 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 16:
-#line 301 "awkgram.y" /* yacc.c:1646  */
+#line 302 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 2015 "awkgram.c" /* yacc.c:1646  */
+#line 2016 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 17:
-#line 303 "awkgram.y" /* yacc.c:1646  */
+#line 304 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 2021 "awkgram.c" /* yacc.c:1646  */
+#line 2022 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 18:
-#line 308 "awkgram.y" /* yacc.c:1646  */
+#line 309 "awkgram.y" /* yacc.c:1646  */
     {
                rule = Rule;
                if (comment != NULL) {
@@ -2030,11 +2031,11 @@ yyreduce:
                } else
                        (yyval) = NULL;
          }
-#line 2034 "awkgram.c" /* yacc.c:1646  */
+#line 2035 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 19:
-#line 317 "awkgram.y" /* yacc.c:1646  */
+#line 318 "awkgram.y" /* yacc.c:1646  */
     {
                rule = Rule;
                if (comment != NULL) {
@@ -2043,11 +2044,11 @@ yyreduce:
                } else
                        (yyval) = (yyvsp[0]);
          }
-#line 2047 "awkgram.c" /* yacc.c:1646  */
+#line 2048 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 20:
-#line 327 "awkgram.y" /* yacc.c:1646  */
+#line 328 "awkgram.y" /* yacc.c:1646  */
     {
                INSTRUCTION *tp;
 
@@ -2077,11 +2078,11 @@ yyreduce:
                        (yyval) = list_append(list_merge((yyvsp[-3]), 
(yyvsp[0])), tp);
                rule = Rule;
          }
-#line 2081 "awkgram.c" /* yacc.c:1646  */
+#line 2082 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 21:
-#line 357 "awkgram.y" /* yacc.c:1646  */
+#line 358 "awkgram.y" /* yacc.c:1646  */
     {
                static int begin_seen = 0;
 
@@ -2095,11 +2096,11 @@ yyreduce:
                check_comment();
                (yyval) = (yyvsp[0]);
          }
-#line 2099 "awkgram.c" /* yacc.c:1646  */
+#line 2100 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 22:
-#line 371 "awkgram.y" /* yacc.c:1646  */
+#line 372 "awkgram.y" /* yacc.c:1646  */
     {
                static int end_seen = 0;
 
@@ -2113,11 +2114,11 @@ yyreduce:
                check_comment();
                (yyval) = (yyvsp[0]);
          }
-#line 2117 "awkgram.c" /* yacc.c:1646  */
+#line 2118 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 23:
-#line 385 "awkgram.y" /* yacc.c:1646  */
+#line 386 "awkgram.y" /* yacc.c:1646  */
     {
                func_first = false;
                (yyvsp[0])->in_rule = rule = BEGINFILE;
@@ -2125,11 +2126,11 @@ yyreduce:
                check_comment();
                (yyval) = (yyvsp[0]);
          }
-#line 2129 "awkgram.c" /* yacc.c:1646  */
+#line 2130 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 24:
-#line 393 "awkgram.y" /* yacc.c:1646  */
+#line 394 "awkgram.y" /* yacc.c:1646  */
     {
                func_first = false;
                (yyvsp[0])->in_rule = rule = ENDFILE;
@@ -2137,11 +2138,11 @@ yyreduce:
                check_comment();
                (yyval) = (yyvsp[0]);
          }
-#line 2141 "awkgram.c" /* yacc.c:1646  */
+#line 2142 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 25:
-#line 404 "awkgram.y" /* yacc.c:1646  */
+#line 405 "awkgram.y" /* yacc.c:1646  */
     {
                INSTRUCTION *ip;
                if ((yyvsp[-3]) == NULL)
@@ -2150,48 +2151,48 @@ yyreduce:
                        ip = (yyvsp[-3]);
                (yyval) = ip;
          }
-#line 2154 "awkgram.c" /* yacc.c:1646  */
+#line 2155 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 26:
-#line 416 "awkgram.y" /* yacc.c:1646  */
+#line 417 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 2160 "awkgram.c" /* yacc.c:1646  */
+#line 2161 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 27:
-#line 418 "awkgram.y" /* yacc.c:1646  */
+#line 419 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 2166 "awkgram.c" /* yacc.c:1646  */
+#line 2167 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 28:
-#line 420 "awkgram.y" /* yacc.c:1646  */
+#line 421 "awkgram.y" /* yacc.c:1646  */
     {
                yyerror(_("`%s' is a built-in function, it cannot be 
redefined"),
                                        tokstart);
                YYABORT;
          }
-#line 2176 "awkgram.c" /* yacc.c:1646  */
+#line 2177 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 29:
-#line 426 "awkgram.y" /* yacc.c:1646  */
+#line 427 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = (yyvsp[0]);
                at_seen = false;
          }
-#line 2185 "awkgram.c" /* yacc.c:1646  */
+#line 2186 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 32:
-#line 438 "awkgram.y" /* yacc.c:1646  */
+#line 439 "awkgram.y" /* yacc.c:1646  */
     { want_param_names = FUNC_HEADER; }
-#line 2191 "awkgram.c" /* yacc.c:1646  */
+#line 2192 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 33:
-#line 439 "awkgram.y" /* yacc.c:1646  */
+#line 440 "awkgram.y" /* yacc.c:1646  */
     {
                /*
                 *  treat any comments between BOF and the first function
@@ -2229,17 +2230,17 @@ yyreduce:
                (yyval) = (yyvsp[-6]);
                want_param_names = FUNC_BODY;
          }
-#line 2233 "awkgram.c" /* yacc.c:1646  */
+#line 2234 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 34:
-#line 484 "awkgram.y" /* yacc.c:1646  */
+#line 485 "awkgram.y" /* yacc.c:1646  */
     { want_regexp = true; }
-#line 2239 "awkgram.c" /* yacc.c:1646  */
+#line 2240 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 35:
-#line 486 "awkgram.y" /* yacc.c:1646  */
+#line 487 "awkgram.y" /* yacc.c:1646  */
     {
                  NODE *n, *exp;
                  char *re;
@@ -2268,11 +2269,11 @@ yyreduce:
                  (yyval)->opcode = Op_match_rec;
                  (yyval)->memory = n;
                }
-#line 2272 "awkgram.c" /* yacc.c:1646  */
+#line 2273 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 36:
-#line 518 "awkgram.y" /* yacc.c:1646  */
+#line 519 "awkgram.y" /* yacc.c:1646  */
     {
                  char *re;
                  size_t len;
@@ -2285,17 +2286,17 @@ yyreduce:
                  (yyval)->opcode = Op_push_re;
                  (yyval)->memory = make_typed_regex(re, len);
                }
-#line 2289 "awkgram.c" /* yacc.c:1646  */
+#line 2290 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 37:
-#line 533 "awkgram.y" /* yacc.c:1646  */
+#line 534 "awkgram.y" /* yacc.c:1646  */
     { bcfree((yyvsp[0])); }
-#line 2295 "awkgram.c" /* yacc.c:1646  */
+#line 2296 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 39:
-#line 539 "awkgram.y" /* yacc.c:1646  */
+#line 540 "awkgram.y" /* yacc.c:1646  */
     {
                if (prior_comment != NULL) {
                        (yyval) = list_create(prior_comment);
@@ -2306,11 +2307,11 @@ yyreduce:
                } else
                        (yyval) = NULL;
          }
-#line 2310 "awkgram.c" /* yacc.c:1646  */
+#line 2311 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 40:
-#line 550 "awkgram.y" /* yacc.c:1646  */
+#line 551 "awkgram.y" /* yacc.c:1646  */
     {
                if ((yyvsp[0]) == NULL) {
                        if (prior_comment != NULL) {
@@ -2357,40 +2358,40 @@ yyreduce:
                }
                yyerrok;
          }
-#line 2361 "awkgram.c" /* yacc.c:1646  */
+#line 2362 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 41:
-#line 597 "awkgram.y" /* yacc.c:1646  */
+#line 598 "awkgram.y" /* yacc.c:1646  */
     {  (yyval) = NULL; }
-#line 2367 "awkgram.c" /* yacc.c:1646  */
+#line 2368 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 44:
-#line 607 "awkgram.y" /* yacc.c:1646  */
+#line 608 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 2373 "awkgram.c" /* yacc.c:1646  */
+#line 2374 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 45:
-#line 609 "awkgram.y" /* yacc.c:1646  */
+#line 610 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[-1]); }
-#line 2379 "awkgram.c" /* yacc.c:1646  */
+#line 2380 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 46:
-#line 611 "awkgram.y" /* yacc.c:1646  */
+#line 612 "awkgram.y" /* yacc.c:1646  */
     {
                if (do_pretty_print)
                        (yyval) = list_prepend((yyvsp[0]), 
instruction(Op_exec_count));
                else
                        (yyval) = (yyvsp[0]);
          }
-#line 2390 "awkgram.c" /* yacc.c:1646  */
+#line 2391 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 47:
-#line 618 "awkgram.y" /* yacc.c:1646  */
+#line 619 "awkgram.y" /* yacc.c:1646  */
     {
                INSTRUCTION *dflt, *curr = NULL, *cexp, *cstmt;
                INSTRUCTION *ip, *nextc, *tbreak;
@@ -2480,11 +2481,11 @@ yyreduce:
                break_allowed--;
                fix_break_continue(ip, tbreak, NULL);
          }
-#line 2484 "awkgram.c" /* yacc.c:1646  */
+#line 2485 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 48:
-#line 708 "awkgram.y" /* yacc.c:1646  */
+#line 709 "awkgram.y" /* yacc.c:1646  */
     {
                /*
                 *    -----------------
@@ -2526,11 +2527,11 @@ yyreduce:
                continue_allowed--;
                fix_break_continue(ip, tbreak, tcont);
          }
-#line 2530 "awkgram.c" /* yacc.c:1646  */
+#line 2531 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 49:
-#line 750 "awkgram.y" /* yacc.c:1646  */
+#line 751 "awkgram.y" /* yacc.c:1646  */
     {
                /*
                 *    -----------------
@@ -2572,11 +2573,11 @@ yyreduce:
                } /* else
                        $1 and $4 are NULLs */
          }
-#line 2576 "awkgram.c" /* yacc.c:1646  */
+#line 2577 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 50:
-#line 792 "awkgram.y" /* yacc.c:1646  */
+#line 793 "awkgram.y" /* yacc.c:1646  */
     {
                INSTRUCTION *ip;
                char *var_name = (yyvsp[-5])->lextok;
@@ -2689,33 +2690,33 @@ regular_loop:
                break_allowed--;
                continue_allowed--;
          }
-#line 2693 "awkgram.c" /* yacc.c:1646  */
+#line 2694 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 51:
-#line 905 "awkgram.y" /* yacc.c:1646  */
+#line 906 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = mk_for_loop((yyvsp[-11]), (yyvsp[-9]), (yyvsp[-6]), 
(yyvsp[-3]), (yyvsp[0]));
 
                break_allowed--;
                continue_allowed--;
          }
-#line 2704 "awkgram.c" /* yacc.c:1646  */
+#line 2705 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 52:
-#line 912 "awkgram.y" /* yacc.c:1646  */
+#line 913 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = mk_for_loop((yyvsp[-10]), (yyvsp[-8]), (INSTRUCTION 
*) NULL, (yyvsp[-3]), (yyvsp[0]));
 
                break_allowed--;
                continue_allowed--;
          }
-#line 2715 "awkgram.c" /* yacc.c:1646  */
+#line 2716 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 53:
-#line 919 "awkgram.y" /* yacc.c:1646  */
+#line 920 "awkgram.y" /* yacc.c:1646  */
     {
                if (do_pretty_print)
                        (yyval) = list_prepend((yyvsp[0]), 
instruction(Op_exec_count));
@@ -2723,11 +2724,11 @@ regular_loop:
                        (yyval) = (yyvsp[0]);
                (yyval) = add_pending_comment((yyval));
          }
-#line 2727 "awkgram.c" /* yacc.c:1646  */
+#line 2728 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 54:
-#line 930 "awkgram.y" /* yacc.c:1646  */
+#line 931 "awkgram.y" /* yacc.c:1646  */
     {
                if (! break_allowed)
                        error_ln((yyvsp[-1])->source_line,
@@ -2737,11 +2738,11 @@ regular_loop:
                (yyval) = add_pending_comment((yyval));
 
          }
-#line 2741 "awkgram.c" /* yacc.c:1646  */
+#line 2742 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 55:
-#line 940 "awkgram.y" /* yacc.c:1646  */
+#line 941 "awkgram.y" /* yacc.c:1646  */
     {
                if (! continue_allowed)
                        error_ln((yyvsp[-1])->source_line,
@@ -2751,11 +2752,11 @@ regular_loop:
                (yyval) = add_pending_comment((yyval));
 
          }
-#line 2755 "awkgram.c" /* yacc.c:1646  */
+#line 2756 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 56:
-#line 950 "awkgram.y" /* yacc.c:1646  */
+#line 951 "awkgram.y" /* yacc.c:1646  */
     {
                /* if inside function (rule = 0), resolve context at run-time */
                if (rule && rule != Rule)
@@ -2765,11 +2766,11 @@ regular_loop:
                (yyval) = list_create((yyvsp[-1]));
                (yyval) = add_pending_comment((yyval));
          }
-#line 2769 "awkgram.c" /* yacc.c:1646  */
+#line 2770 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 57:
-#line 960 "awkgram.y" /* yacc.c:1646  */
+#line 961 "awkgram.y" /* yacc.c:1646  */
     {
                /* if inside function (rule = 0), resolve context at run-time */
                if (rule == BEGIN || rule == END || rule == ENDFILE)
@@ -2781,11 +2782,11 @@ regular_loop:
                (yyval) = list_create((yyvsp[-1]));
                (yyval) = add_pending_comment((yyval));
          }
-#line 2785 "awkgram.c" /* yacc.c:1646  */
+#line 2786 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 58:
-#line 972 "awkgram.y" /* yacc.c:1646  */
+#line 973 "awkgram.y" /* yacc.c:1646  */
     {
                /* Initialize the two possible jump targets, the actual target
                 * is resolved at run-time.
@@ -2801,20 +2802,20 @@ regular_loop:
                        (yyval) = list_append((yyvsp[-1]), (yyvsp[-2]));
                (yyval) = add_pending_comment((yyval));
          }
-#line 2805 "awkgram.c" /* yacc.c:1646  */
+#line 2806 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 59:
-#line 988 "awkgram.y" /* yacc.c:1646  */
+#line 989 "awkgram.y" /* yacc.c:1646  */
     {
                if (! in_function)
                        yyerror(_("`return' used outside function context"));
          }
-#line 2814 "awkgram.c" /* yacc.c:1646  */
+#line 2815 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 60:
-#line 991 "awkgram.y" /* yacc.c:1646  */
+#line 992 "awkgram.y" /* yacc.c:1646  */
     {
                if ((yyvsp[-1]) == NULL) {
                        (yyval) = list_create((yyvsp[-3]));
@@ -2836,17 +2837,17 @@ regular_loop:
                }
                (yyval) = add_pending_comment((yyval));
          }
-#line 2840 "awkgram.c" /* yacc.c:1646  */
+#line 2841 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 62:
-#line 1024 "awkgram.y" /* yacc.c:1646  */
+#line 1025 "awkgram.y" /* yacc.c:1646  */
     { in_print = true; in_parens = 0; }
-#line 2846 "awkgram.c" /* yacc.c:1646  */
+#line 2847 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 63:
-#line 1025 "awkgram.y" /* yacc.c:1646  */
+#line 1026 "awkgram.y" /* yacc.c:1646  */
     {
                /*
                 * Optimization: plain `print' has no expression list, so $3 is 
null.
@@ -2944,17 +2945,17 @@ regular_print:
                }
                (yyval) = add_pending_comment((yyval));
          }
-#line 2948 "awkgram.c" /* yacc.c:1646  */
+#line 2949 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 64:
-#line 1123 "awkgram.y" /* yacc.c:1646  */
+#line 1124 "awkgram.y" /* yacc.c:1646  */
     { sub_counter = 0; }
-#line 2954 "awkgram.c" /* yacc.c:1646  */
+#line 2955 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 65:
-#line 1124 "awkgram.y" /* yacc.c:1646  */
+#line 1125 "awkgram.y" /* yacc.c:1646  */
     {
                char *arr = (yyvsp[-2])->lextok;
 
@@ -2988,11 +2989,11 @@ regular_print:
                }
                (yyval) = add_pending_comment((yyval));
          }
-#line 2992 "awkgram.c" /* yacc.c:1646  */
+#line 2993 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 66:
-#line 1162 "awkgram.y" /* yacc.c:1646  */
+#line 1163 "awkgram.y" /* yacc.c:1646  */
     {
                static bool warned = false;
                char *arr = (yyvsp[-1])->lextok;
@@ -3019,55 +3020,55 @@ regular_print:
                }
                (yyval) = add_pending_comment((yyval));
          }
-#line 3023 "awkgram.c" /* yacc.c:1646  */
+#line 3024 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 67:
-#line 1189 "awkgram.y" /* yacc.c:1646  */
+#line 1190 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = optimize_assignment((yyvsp[0]));
                (yyval) = add_pending_comment((yyval));
          }
-#line 3032 "awkgram.c" /* yacc.c:1646  */
+#line 3033 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 68:
-#line 1197 "awkgram.y" /* yacc.c:1646  */
+#line 1198 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 3038 "awkgram.c" /* yacc.c:1646  */
+#line 3039 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 69:
-#line 1199 "awkgram.y" /* yacc.c:1646  */
+#line 1200 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3044 "awkgram.c" /* yacc.c:1646  */
+#line 3045 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 70:
-#line 1204 "awkgram.y" /* yacc.c:1646  */
+#line 1205 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 3050 "awkgram.c" /* yacc.c:1646  */
+#line 3051 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 71:
-#line 1206 "awkgram.y" /* yacc.c:1646  */
+#line 1207 "awkgram.y" /* yacc.c:1646  */
     {
                if ((yyvsp[-1]) == NULL)
                        (yyval) = list_create((yyvsp[0]));
                else
                        (yyval) = list_prepend((yyvsp[-1]), (yyvsp[0]));
          }
-#line 3061 "awkgram.c" /* yacc.c:1646  */
+#line 3062 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 72:
-#line 1213 "awkgram.y" /* yacc.c:1646  */
+#line 1214 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 3067 "awkgram.c" /* yacc.c:1646  */
+#line 3068 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 73:
-#line 1218 "awkgram.y" /* yacc.c:1646  */
+#line 1219 "awkgram.y" /* yacc.c:1646  */
     {
                INSTRUCTION *casestmt = (yyvsp[0]);
                if ((yyvsp[0]) == NULL)
@@ -3079,11 +3080,11 @@ regular_print:
                bcfree((yyvsp[-2]));
                (yyval) = (yyvsp[-4]);
          }
-#line 3083 "awkgram.c" /* yacc.c:1646  */
+#line 3084 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 74:
-#line 1230 "awkgram.y" /* yacc.c:1646  */
+#line 1231 "awkgram.y" /* yacc.c:1646  */
     {
                INSTRUCTION *casestmt = (yyvsp[0]);
                if ((yyvsp[0]) == NULL)
@@ -3094,17 +3095,17 @@ regular_print:
                (yyvsp[-3])->case_stmt = casestmt;
                (yyval) = (yyvsp[-3]);
          }
-#line 3098 "awkgram.c" /* yacc.c:1646  */
+#line 3099 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 75:
-#line 1244 "awkgram.y" /* yacc.c:1646  */
+#line 1245 "awkgram.y" /* yacc.c:1646  */
     {  (yyval) = (yyvsp[0]); }
-#line 3104 "awkgram.c" /* yacc.c:1646  */
+#line 3105 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 76:
-#line 1246 "awkgram.y" /* yacc.c:1646  */
+#line 1247 "awkgram.y" /* yacc.c:1646  */
     {
                NODE *n = (yyvsp[0])->memory;
                (void) force_number(n);
@@ -3112,28 +3113,28 @@ regular_print:
                bcfree((yyvsp[-1]));
                (yyval) = (yyvsp[0]);
          }
-#line 3116 "awkgram.c" /* yacc.c:1646  */
+#line 3117 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 77:
-#line 1254 "awkgram.y" /* yacc.c:1646  */
+#line 1255 "awkgram.y" /* yacc.c:1646  */
     {
                NODE *n = (yyvsp[0])->lasti->memory;
                bcfree((yyvsp[-1]));
                add_sign_to_num(n, '+');
                (yyval) = (yyvsp[0]);
          }
-#line 3127 "awkgram.c" /* yacc.c:1646  */
+#line 3128 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 78:
-#line 1261 "awkgram.y" /* yacc.c:1646  */
+#line 1262 "awkgram.y" /* yacc.c:1646  */
     {  (yyval) = (yyvsp[0]); }
-#line 3133 "awkgram.c" /* yacc.c:1646  */
+#line 3134 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 79:
-#line 1263 "awkgram.y" /* yacc.c:1646  */
+#line 1264 "awkgram.y" /* yacc.c:1646  */
     {
                if ((yyvsp[0])->memory->type == Node_regex)
                        (yyvsp[0])->opcode = Op_push_re;
@@ -3141,57 +3142,57 @@ regular_print:
                        (yyvsp[0])->opcode = Op_push;
                (yyval) = (yyvsp[0]);
          }
-#line 3145 "awkgram.c" /* yacc.c:1646  */
+#line 3146 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 80:
-#line 1271 "awkgram.y" /* yacc.c:1646  */
+#line 1272 "awkgram.y" /* yacc.c:1646  */
     {
                assert(((yyvsp[0])->memory->flags & REGEX) == REGEX);
                (yyvsp[0])->opcode = Op_push_re;
                (yyval) = (yyvsp[0]);
          }
-#line 3155 "awkgram.c" /* yacc.c:1646  */
+#line 3156 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 81:
-#line 1280 "awkgram.y" /* yacc.c:1646  */
+#line 1281 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3161 "awkgram.c" /* yacc.c:1646  */
+#line 3162 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 82:
-#line 1282 "awkgram.y" /* yacc.c:1646  */
+#line 1283 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3167 "awkgram.c" /* yacc.c:1646  */
+#line 3168 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 84:
-#line 1292 "awkgram.y" /* yacc.c:1646  */
+#line 1293 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = (yyvsp[-1]);
          }
-#line 3175 "awkgram.c" /* yacc.c:1646  */
+#line 3176 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 85:
-#line 1299 "awkgram.y" /* yacc.c:1646  */
+#line 1300 "awkgram.y" /* yacc.c:1646  */
     {
                in_print = false;
                in_parens = 0;
                (yyval) = NULL;
          }
-#line 3185 "awkgram.c" /* yacc.c:1646  */
+#line 3186 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 86:
-#line 1304 "awkgram.y" /* yacc.c:1646  */
+#line 1305 "awkgram.y" /* yacc.c:1646  */
     { in_print = false; in_parens = 0; }
-#line 3191 "awkgram.c" /* yacc.c:1646  */
+#line 3192 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 87:
-#line 1305 "awkgram.y" /* yacc.c:1646  */
+#line 1306 "awkgram.y" /* yacc.c:1646  */
     {
                if ((yyvsp[-2])->redir_type == redirect_twoway
                        && (yyvsp[0])->lasti->opcode == Op_K_getline_redir
@@ -3199,63 +3200,63 @@ regular_print:
                        yyerror(_("multistage two-way pipelines don't work"));
                (yyval) = list_prepend((yyvsp[0]), (yyvsp[-2]));
          }
-#line 3203 "awkgram.c" /* yacc.c:1646  */
+#line 3204 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 88:
-#line 1316 "awkgram.y" /* yacc.c:1646  */
+#line 1317 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = mk_condition((yyvsp[-3]), (yyvsp[-5]), (yyvsp[0]), 
NULL, NULL);
          }
-#line 3211 "awkgram.c" /* yacc.c:1646  */
+#line 3212 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 89:
-#line 1321 "awkgram.y" /* yacc.c:1646  */
+#line 1322 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = mk_condition((yyvsp[-6]), (yyvsp[-8]), (yyvsp[-3]), 
(yyvsp[-2]), (yyvsp[0]));
          }
-#line 3219 "awkgram.c" /* yacc.c:1646  */
+#line 3220 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 94:
-#line 1338 "awkgram.y" /* yacc.c:1646  */
+#line 1339 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 3225 "awkgram.c" /* yacc.c:1646  */
+#line 3226 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 95:
-#line 1340 "awkgram.y" /* yacc.c:1646  */
+#line 1341 "awkgram.y" /* yacc.c:1646  */
     {
                bcfree((yyvsp[-1]));
                (yyval) = (yyvsp[0]);
          }
-#line 3234 "awkgram.c" /* yacc.c:1646  */
+#line 3235 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 96:
-#line 1348 "awkgram.y" /* yacc.c:1646  */
+#line 1349 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 3240 "awkgram.c" /* yacc.c:1646  */
+#line 3241 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 97:
-#line 1350 "awkgram.y" /* yacc.c:1646  */
+#line 1351 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3246 "awkgram.c" /* yacc.c:1646  */
+#line 3247 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 98:
-#line 1355 "awkgram.y" /* yacc.c:1646  */
+#line 1356 "awkgram.y" /* yacc.c:1646  */
     {
                (yyvsp[0])->param_count = 0;
                (yyval) = list_create((yyvsp[0]));
          }
-#line 3255 "awkgram.c" /* yacc.c:1646  */
+#line 3256 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 99:
-#line 1360 "awkgram.y" /* yacc.c:1646  */
+#line 1361 "awkgram.y" /* yacc.c:1646  */
     {
                if ((yyvsp[-2]) != NULL && (yyvsp[0]) != NULL) {
                        (yyvsp[0])->param_count =  
(yyvsp[-2])->lasti->param_count + 1;
@@ -3264,74 +3265,74 @@ regular_print:
                } else
                        (yyval) = NULL;
          }
-#line 3268 "awkgram.c" /* yacc.c:1646  */
+#line 3269 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 100:
-#line 1369 "awkgram.y" /* yacc.c:1646  */
+#line 1370 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 3274 "awkgram.c" /* yacc.c:1646  */
+#line 3275 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 101:
-#line 1371 "awkgram.y" /* yacc.c:1646  */
+#line 1372 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[-1]); }
-#line 3280 "awkgram.c" /* yacc.c:1646  */
+#line 3281 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 102:
-#line 1373 "awkgram.y" /* yacc.c:1646  */
+#line 1374 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[-2]); }
-#line 3286 "awkgram.c" /* yacc.c:1646  */
+#line 3287 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 103:
-#line 1379 "awkgram.y" /* yacc.c:1646  */
+#line 1380 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 3292 "awkgram.c" /* yacc.c:1646  */
+#line 3293 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 104:
-#line 1381 "awkgram.y" /* yacc.c:1646  */
+#line 1382 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3298 "awkgram.c" /* yacc.c:1646  */
+#line 3299 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 105:
-#line 1386 "awkgram.y" /* yacc.c:1646  */
+#line 1387 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 3304 "awkgram.c" /* yacc.c:1646  */
+#line 3305 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 106:
-#line 1388 "awkgram.y" /* yacc.c:1646  */
+#line 1389 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3310 "awkgram.c" /* yacc.c:1646  */
+#line 3311 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 107:
-#line 1393 "awkgram.y" /* yacc.c:1646  */
+#line 1394 "awkgram.y" /* yacc.c:1646  */
     {  (yyval) = mk_expression_list(NULL, (yyvsp[0])); }
-#line 3316 "awkgram.c" /* yacc.c:1646  */
+#line 3317 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 108:
-#line 1395 "awkgram.y" /* yacc.c:1646  */
+#line 1396 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0]));
                yyerrok;
          }
-#line 3325 "awkgram.c" /* yacc.c:1646  */
+#line 3326 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 109:
-#line 1400 "awkgram.y" /* yacc.c:1646  */
+#line 1401 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 3331 "awkgram.c" /* yacc.c:1646  */
+#line 3332 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 110:
-#line 1402 "awkgram.y" /* yacc.c:1646  */
+#line 1403 "awkgram.y" /* yacc.c:1646  */
     {
                /*
                 * Returning the expression list instead of NULL lets
@@ -3339,62 +3340,62 @@ regular_print:
                 */
                (yyval) = (yyvsp[-1]);
          }
-#line 3343 "awkgram.c" /* yacc.c:1646  */
+#line 3344 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 111:
-#line 1410 "awkgram.y" /* yacc.c:1646  */
+#line 1411 "awkgram.y" /* yacc.c:1646  */
     {
                /* Ditto */
                (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0]));
          }
-#line 3352 "awkgram.c" /* yacc.c:1646  */
+#line 3353 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 112:
-#line 1415 "awkgram.y" /* yacc.c:1646  */
+#line 1416 "awkgram.y" /* yacc.c:1646  */
     {
                /* Ditto */
                (yyval) = (yyvsp[-2]);
          }
-#line 3361 "awkgram.c" /* yacc.c:1646  */
+#line 3362 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 113:
-#line 1423 "awkgram.y" /* yacc.c:1646  */
+#line 1424 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 3367 "awkgram.c" /* yacc.c:1646  */
+#line 3368 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 114:
-#line 1425 "awkgram.y" /* yacc.c:1646  */
+#line 1426 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3373 "awkgram.c" /* yacc.c:1646  */
+#line 3374 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 115:
-#line 1430 "awkgram.y" /* yacc.c:1646  */
+#line 1431 "awkgram.y" /* yacc.c:1646  */
     {  (yyval) = mk_expression_list(NULL, (yyvsp[0])); }
-#line 3379 "awkgram.c" /* yacc.c:1646  */
+#line 3380 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 116:
-#line 1432 "awkgram.y" /* yacc.c:1646  */
+#line 1433 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0]));
                yyerrok;
          }
-#line 3388 "awkgram.c" /* yacc.c:1646  */
+#line 3389 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 117:
-#line 1437 "awkgram.y" /* yacc.c:1646  */
+#line 1438 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 3394 "awkgram.c" /* yacc.c:1646  */
+#line 3395 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 118:
-#line 1439 "awkgram.y" /* yacc.c:1646  */
+#line 1440 "awkgram.y" /* yacc.c:1646  */
     {
                /*
                 * Returning the expression list instead of NULL lets
@@ -3402,72 +3403,72 @@ regular_print:
                 */
                (yyval) = (yyvsp[-1]);
          }
-#line 3406 "awkgram.c" /* yacc.c:1646  */
+#line 3407 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 119:
-#line 1447 "awkgram.y" /* yacc.c:1646  */
+#line 1448 "awkgram.y" /* yacc.c:1646  */
     {
                /* Ditto */
                (yyval) = mk_expression_list((yyvsp[-2]), (yyvsp[0]));
          }
-#line 3415 "awkgram.c" /* yacc.c:1646  */
+#line 3416 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 120:
-#line 1452 "awkgram.y" /* yacc.c:1646  */
+#line 1453 "awkgram.y" /* yacc.c:1646  */
     {
                /* Ditto */
                (yyval) = (yyvsp[-2]);
          }
-#line 3424 "awkgram.c" /* yacc.c:1646  */
+#line 3425 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 121:
-#line 1459 "awkgram.y" /* yacc.c:1646  */
+#line 1460 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3430 "awkgram.c" /* yacc.c:1646  */
+#line 3431 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 122:
-#line 1460 "awkgram.y" /* yacc.c:1646  */
+#line 1461 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = list_create((yyvsp[0])); }
-#line 3436 "awkgram.c" /* yacc.c:1646  */
+#line 3437 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 123:
-#line 1466 "awkgram.y" /* yacc.c:1646  */
+#line 1467 "awkgram.y" /* yacc.c:1646  */
     {
                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 3447 "awkgram.c" /* yacc.c:1646  */
+#line 3448 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 124:
-#line 1473 "awkgram.y" /* yacc.c:1646  */
+#line 1474 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = mk_assignment((yyvsp[-2]), list_create((yyvsp[0])), 
(yyvsp[-1]));
          }
-#line 3455 "awkgram.c" /* yacc.c:1646  */
+#line 3456 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 125:
-#line 1477 "awkgram.y" /* yacc.c:1646  */
+#line 1478 "awkgram.y" /* yacc.c:1646  */
     {  (yyval) = mk_boolean((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3461 "awkgram.c" /* yacc.c:1646  */
+#line 3462 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 126:
-#line 1479 "awkgram.y" /* yacc.c:1646  */
+#line 1480 "awkgram.y" /* yacc.c:1646  */
     {  (yyval) = mk_boolean((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3467 "awkgram.c" /* yacc.c:1646  */
+#line 3468 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 127:
-#line 1481 "awkgram.y" /* yacc.c:1646  */
+#line 1482 "awkgram.y" /* yacc.c:1646  */
     {
                if ((yyvsp[-2])->lasti->opcode == Op_match_rec)
                        warning_ln((yyvsp[-1])->source_line,
@@ -3480,11 +3481,11 @@ regular_print:
                bcfree((yyvsp[0]));
                (yyval) = list_append((yyvsp[-2]), (yyvsp[-1]));
          }
-#line 3484 "awkgram.c" /* yacc.c:1646  */
+#line 3485 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 128:
-#line 1494 "awkgram.y" /* yacc.c:1646  */
+#line 1495 "awkgram.y" /* yacc.c:1646  */
     {
                if ((yyvsp[-2])->lasti->opcode == Op_match_rec)
                        warning_ln((yyvsp[-1])->source_line,
@@ -3501,11 +3502,11 @@ regular_print:
                        (yyval) = list_append(list_merge((yyvsp[-2]), 
(yyvsp[0])), (yyvsp[-1]));
                }
          }
-#line 3505 "awkgram.c" /* yacc.c:1646  */
+#line 3506 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 129:
-#line 1511 "awkgram.y" /* yacc.c:1646  */
+#line 1512 "awkgram.y" /* yacc.c:1646  */
     {
                if (do_lint_old)
                        warning_ln((yyvsp[-1])->source_line,
@@ -3515,91 +3516,91 @@ regular_print:
                (yyvsp[-1])->expr_count = 1;
                (yyval) = list_append(list_merge((yyvsp[-2]), (yyvsp[0])), 
(yyvsp[-1]));
          }
-#line 3519 "awkgram.c" /* yacc.c:1646  */
+#line 3520 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 130:
-#line 1521 "awkgram.y" /* yacc.c:1646  */
+#line 1522 "awkgram.y" /* yacc.c:1646  */
     {
                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 3530 "awkgram.c" /* yacc.c:1646  */
+#line 3531 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 131:
-#line 1528 "awkgram.y" /* yacc.c:1646  */
+#line 1529 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = mk_condition((yyvsp[-4]), (yyvsp[-3]), (yyvsp[-2]), 
(yyvsp[-1]), (yyvsp[0])); }
-#line 3536 "awkgram.c" /* yacc.c:1646  */
+#line 3537 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 132:
-#line 1530 "awkgram.y" /* yacc.c:1646  */
+#line 1531 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3542 "awkgram.c" /* yacc.c:1646  */
+#line 3543 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 133:
-#line 1535 "awkgram.y" /* yacc.c:1646  */
+#line 1536 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3548 "awkgram.c" /* yacc.c:1646  */
+#line 3549 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 134:
-#line 1537 "awkgram.y" /* yacc.c:1646  */
+#line 1538 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3554 "awkgram.c" /* yacc.c:1646  */
+#line 3555 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 135:
-#line 1539 "awkgram.y" /* yacc.c:1646  */
+#line 1540 "awkgram.y" /* yacc.c:1646  */
     {
                (yyvsp[0])->opcode = Op_assign_quotient;
                (yyval) = (yyvsp[0]);
          }
-#line 3563 "awkgram.c" /* yacc.c:1646  */
+#line 3564 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 136:
-#line 1547 "awkgram.y" /* yacc.c:1646  */
+#line 1548 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3569 "awkgram.c" /* yacc.c:1646  */
+#line 3570 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 137:
-#line 1549 "awkgram.y" /* yacc.c:1646  */
+#line 1550 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3575 "awkgram.c" /* yacc.c:1646  */
+#line 3576 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 138:
-#line 1554 "awkgram.y" /* yacc.c:1646  */
+#line 1555 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3581 "awkgram.c" /* yacc.c:1646  */
+#line 3582 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 139:
-#line 1556 "awkgram.y" /* yacc.c:1646  */
+#line 1557 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3587 "awkgram.c" /* yacc.c:1646  */
+#line 3588 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 140:
-#line 1561 "awkgram.y" /* yacc.c:1646  */
+#line 1562 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3593 "awkgram.c" /* yacc.c:1646  */
+#line 3594 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 141:
-#line 1563 "awkgram.y" /* yacc.c:1646  */
+#line 1564 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 3599 "awkgram.c" /* yacc.c:1646  */
+#line 3600 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 142:
-#line 1565 "awkgram.y" /* yacc.c:1646  */
+#line 1566 "awkgram.y" /* yacc.c:1646  */
     {
                int count = 2;
                bool is_simple_var = false;
@@ -3652,47 +3653,47 @@ regular_print:
                                max_args = count;
                }
          }
-#line 3656 "awkgram.c" /* yacc.c:1646  */
+#line 3657 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 144:
-#line 1623 "awkgram.y" /* yacc.c:1646  */
+#line 1624 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3662 "awkgram.c" /* yacc.c:1646  */
+#line 3663 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 145:
-#line 1625 "awkgram.y" /* yacc.c:1646  */
+#line 1626 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3668 "awkgram.c" /* yacc.c:1646  */
+#line 3669 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 146:
-#line 1627 "awkgram.y" /* yacc.c:1646  */
+#line 1628 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3674 "awkgram.c" /* yacc.c:1646  */
+#line 3675 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 147:
-#line 1629 "awkgram.y" /* yacc.c:1646  */
+#line 1630 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3680 "awkgram.c" /* yacc.c:1646  */
+#line 3681 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 148:
-#line 1631 "awkgram.y" /* yacc.c:1646  */
+#line 1632 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3686 "awkgram.c" /* yacc.c:1646  */
+#line 3687 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 149:
-#line 1633 "awkgram.y" /* yacc.c:1646  */
+#line 1634 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3692 "awkgram.c" /* yacc.c:1646  */
+#line 3693 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 150:
-#line 1635 "awkgram.y" /* yacc.c:1646  */
+#line 1636 "awkgram.y" /* yacc.c:1646  */
     {
                /*
                 * In BEGINFILE/ENDFILE, allow `getline [var] < file'
@@ -3706,29 +3707,29 @@ regular_print:
                                _("non-redirected `getline' undefined inside 
END action"));
                (yyval) = mk_getline((yyvsp[-2]), (yyvsp[-1]), (yyvsp[0]), 
redirect_input);
          }
-#line 3710 "awkgram.c" /* yacc.c:1646  */
+#line 3711 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 151:
-#line 1649 "awkgram.y" /* yacc.c:1646  */
+#line 1650 "awkgram.y" /* yacc.c:1646  */
     {
                (yyvsp[0])->opcode = Op_postincrement;
                (yyval) = mk_assignment((yyvsp[-1]), NULL, (yyvsp[0]));
          }
-#line 3719 "awkgram.c" /* yacc.c:1646  */
+#line 3720 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 152:
-#line 1654 "awkgram.y" /* yacc.c:1646  */
+#line 1655 "awkgram.y" /* yacc.c:1646  */
     {
                (yyvsp[0])->opcode = Op_postdecrement;
                (yyval) = mk_assignment((yyvsp[-1]), NULL, (yyvsp[0]));
          }
-#line 3728 "awkgram.c" /* yacc.c:1646  */
+#line 3729 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 153:
-#line 1659 "awkgram.y" /* yacc.c:1646  */
+#line 1660 "awkgram.y" /* yacc.c:1646  */
     {
                if (do_lint_old) {
                    warning_ln((yyvsp[-1])->source_line,
@@ -3748,64 +3749,64 @@ regular_print:
                        (yyval) = list_append(list_merge(t, (yyvsp[0])), 
(yyvsp[-1]));
                }
          }
-#line 3752 "awkgram.c" /* yacc.c:1646  */
+#line 3753 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 154:
-#line 1684 "awkgram.y" /* yacc.c:1646  */
+#line 1685 "awkgram.y" /* yacc.c:1646  */
     {
                  (yyval) = mk_getline((yyvsp[-1]), (yyvsp[0]), (yyvsp[-3]), 
(yyvsp[-2])->redir_type);
                  bcfree((yyvsp[-2]));
                }
-#line 3761 "awkgram.c" /* yacc.c:1646  */
+#line 3762 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 155:
-#line 1690 "awkgram.y" /* yacc.c:1646  */
+#line 1691 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3767 "awkgram.c" /* yacc.c:1646  */
+#line 3768 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 156:
-#line 1692 "awkgram.y" /* yacc.c:1646  */
+#line 1693 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3773 "awkgram.c" /* yacc.c:1646  */
+#line 3774 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 157:
-#line 1694 "awkgram.y" /* yacc.c:1646  */
+#line 1695 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3779 "awkgram.c" /* yacc.c:1646  */
+#line 3780 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 158:
-#line 1696 "awkgram.y" /* yacc.c:1646  */
+#line 1697 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3785 "awkgram.c" /* yacc.c:1646  */
+#line 3786 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 159:
-#line 1698 "awkgram.y" /* yacc.c:1646  */
+#line 1699 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3791 "awkgram.c" /* yacc.c:1646  */
+#line 3792 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 160:
-#line 1700 "awkgram.y" /* yacc.c:1646  */
+#line 1701 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = mk_binary((yyvsp[-2]), (yyvsp[0]), (yyvsp[-1])); }
-#line 3797 "awkgram.c" /* yacc.c:1646  */
+#line 3798 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 161:
-#line 1705 "awkgram.y" /* yacc.c:1646  */
+#line 1706 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = list_create((yyvsp[0]));
          }
-#line 3805 "awkgram.c" /* yacc.c:1646  */
+#line 3806 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 162:
-#line 1709 "awkgram.y" /* yacc.c:1646  */
+#line 1710 "awkgram.y" /* yacc.c:1646  */
     {
                if ((yyvsp[0])->opcode == Op_match_rec) {
                        (yyvsp[0])->opcode = Op_nomatch;
@@ -3837,37 +3838,37 @@ regular_print:
                        }
                }
           }
-#line 3841 "awkgram.c" /* yacc.c:1646  */
+#line 3842 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 163:
-#line 1741 "awkgram.y" /* yacc.c:1646  */
+#line 1742 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[-1]); }
-#line 3847 "awkgram.c" /* yacc.c:1646  */
+#line 3848 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 164:
-#line 1743 "awkgram.y" /* yacc.c:1646  */
+#line 1744 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = snode((yyvsp[-1]), (yyvsp[-3]));
                if ((yyval) == NULL)
                        YYABORT;
          }
-#line 3857 "awkgram.c" /* yacc.c:1646  */
+#line 3858 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 165:
-#line 1749 "awkgram.y" /* yacc.c:1646  */
+#line 1750 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = snode((yyvsp[-1]), (yyvsp[-3]));
                if ((yyval) == NULL)
                        YYABORT;
          }
-#line 3867 "awkgram.c" /* yacc.c:1646  */
+#line 3868 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 166:
-#line 1755 "awkgram.y" /* yacc.c:1646  */
+#line 1756 "awkgram.y" /* yacc.c:1646  */
     {
                static bool warned = false;
 
@@ -3880,45 +3881,45 @@ regular_print:
                if ((yyval) == NULL)
                        YYABORT;
          }
-#line 3884 "awkgram.c" /* yacc.c:1646  */
+#line 3885 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 169:
-#line 1770 "awkgram.y" /* yacc.c:1646  */
+#line 1771 "awkgram.y" /* yacc.c:1646  */
     {
                (yyvsp[-1])->opcode = Op_preincrement;
                (yyval) = mk_assignment((yyvsp[0]), NULL, (yyvsp[-1]));
          }
-#line 3893 "awkgram.c" /* yacc.c:1646  */
+#line 3894 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 170:
-#line 1775 "awkgram.y" /* yacc.c:1646  */
+#line 1776 "awkgram.y" /* yacc.c:1646  */
     {
                (yyvsp[-1])->opcode = Op_predecrement;
                (yyval) = mk_assignment((yyvsp[0]), NULL, (yyvsp[-1]));
          }
-#line 3902 "awkgram.c" /* yacc.c:1646  */
+#line 3903 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 171:
-#line 1780 "awkgram.y" /* yacc.c:1646  */
+#line 1781 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = list_create((yyvsp[0]));
          }
-#line 3910 "awkgram.c" /* yacc.c:1646  */
+#line 3911 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 172:
-#line 1784 "awkgram.y" /* yacc.c:1646  */
+#line 1785 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = list_create((yyvsp[0]));
          }
-#line 3918 "awkgram.c" /* yacc.c:1646  */
+#line 3919 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 173:
-#line 1788 "awkgram.y" /* yacc.c:1646  */
+#line 1789 "awkgram.y" /* yacc.c:1646  */
     {
                if ((yyvsp[0])->lasti->opcode == Op_push_i
                        && ((yyvsp[0])->lasti->memory->flags & STRING) == 0
@@ -3933,11 +3934,11 @@ regular_print:
                        (yyval) = list_append((yyvsp[0]), (yyvsp[-1]));
                }
          }
-#line 3937 "awkgram.c" /* yacc.c:1646  */
+#line 3938 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 174:
-#line 1803 "awkgram.y" /* yacc.c:1646  */
+#line 1804 "awkgram.y" /* yacc.c:1646  */
     {
                if ((yyvsp[0])->lasti->opcode == Op_push_i
                        && ((yyvsp[0])->lasti->memory->flags & STRING) == 0
@@ -3955,20 +3956,20 @@ regular_print:
                        (yyval) = list_append((yyvsp[0]), (yyvsp[-1]));
                }
          }
-#line 3959 "awkgram.c" /* yacc.c:1646  */
+#line 3960 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 175:
-#line 1824 "awkgram.y" /* yacc.c:1646  */
+#line 1825 "awkgram.y" /* yacc.c:1646  */
     {
                func_use((yyvsp[0])->lasti->func_name, FUNC_USE);
                (yyval) = (yyvsp[0]);
          }
-#line 3968 "awkgram.c" /* yacc.c:1646  */
+#line 3969 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 176:
-#line 1829 "awkgram.y" /* yacc.c:1646  */
+#line 1830 "awkgram.y" /* yacc.c:1646  */
     {
                /* indirect function call */
                INSTRUCTION *f, *t;
@@ -4002,11 +4003,11 @@ regular_print:
                (yyval) = list_prepend((yyvsp[0]), t);
                at_seen = false;
          }
-#line 4006 "awkgram.c" /* yacc.c:1646  */
+#line 4007 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 177:
-#line 1866 "awkgram.y" /* yacc.c:1646  */
+#line 1867 "awkgram.y" /* yacc.c:1646  */
     {
                NODE *n;
 
@@ -4031,49 +4032,49 @@ regular_print:
                        (yyval) = list_append(t, (yyvsp[-3]));
                }
          }
-#line 4035 "awkgram.c" /* yacc.c:1646  */
+#line 4036 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 178:
-#line 1894 "awkgram.y" /* yacc.c:1646  */
+#line 1895 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 4041 "awkgram.c" /* yacc.c:1646  */
+#line 4042 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 179:
-#line 1896 "awkgram.y" /* yacc.c:1646  */
+#line 1897 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); }
-#line 4047 "awkgram.c" /* yacc.c:1646  */
+#line 4048 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 180:
-#line 1901 "awkgram.y" /* yacc.c:1646  */
+#line 1902 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 4053 "awkgram.c" /* yacc.c:1646  */
+#line 4054 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 181:
-#line 1903 "awkgram.y" /* yacc.c:1646  */
+#line 1904 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[-1]); }
-#line 4059 "awkgram.c" /* yacc.c:1646  */
+#line 4060 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 182:
-#line 1908 "awkgram.y" /* yacc.c:1646  */
+#line 1909 "awkgram.y" /* yacc.c:1646  */
     {  (yyval) = (yyvsp[0]); }
-#line 4065 "awkgram.c" /* yacc.c:1646  */
+#line 4066 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 183:
-#line 1910 "awkgram.y" /* yacc.c:1646  */
+#line 1911 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = list_merge((yyvsp[-1]), (yyvsp[0]));
          }
-#line 4073 "awkgram.c" /* yacc.c:1646  */
+#line 4074 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 184:
-#line 1917 "awkgram.y" /* yacc.c:1646  */
+#line 1918 "awkgram.y" /* yacc.c:1646  */
     {
                INSTRUCTION *ip = (yyvsp[0])->lasti;
                int count = ip->sub_count;      /* # of SUBSEP-seperated 
expressions */
@@ -4087,11 +4088,11 @@ regular_print:
                sub_counter++;  /* count # of dimensions */
                (yyval) = (yyvsp[0]);
          }
-#line 4091 "awkgram.c" /* yacc.c:1646  */
+#line 4092 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 185:
-#line 1934 "awkgram.y" /* yacc.c:1646  */
+#line 1935 "awkgram.y" /* yacc.c:1646  */
     {
                INSTRUCTION *t = (yyvsp[-1]);
                if ((yyvsp[-1]) == NULL) {
@@ -4105,31 +4106,31 @@ regular_print:
                        (yyvsp[0])->sub_count = count_expressions(&t, false);
                (yyval) = list_append(t, (yyvsp[0]));
          }
-#line 4109 "awkgram.c" /* yacc.c:1646  */
+#line 4110 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 186:
-#line 1951 "awkgram.y" /* yacc.c:1646  */
+#line 1952 "awkgram.y" /* yacc.c:1646  */
     {  (yyval) = (yyvsp[0]); }
-#line 4115 "awkgram.c" /* yacc.c:1646  */
+#line 4116 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 187:
-#line 1953 "awkgram.y" /* yacc.c:1646  */
+#line 1954 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = list_merge((yyvsp[-1]), (yyvsp[0]));
          }
-#line 4123 "awkgram.c" /* yacc.c:1646  */
+#line 4124 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 188:
-#line 1960 "awkgram.y" /* yacc.c:1646  */
+#line 1961 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[-1]); }
-#line 4129 "awkgram.c" /* yacc.c:1646  */
+#line 4130 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 189:
-#line 1965 "awkgram.y" /* yacc.c:1646  */
+#line 1966 "awkgram.y" /* yacc.c:1646  */
     {
                char *var_name = (yyvsp[0])->lextok;
 
@@ -4137,22 +4138,22 @@ regular_print:
                (yyvsp[0])->memory = variable((yyvsp[0])->source_line, 
var_name, Node_var_new);
                (yyval) = list_create((yyvsp[0]));
          }
-#line 4141 "awkgram.c" /* yacc.c:1646  */
+#line 4142 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 190:
-#line 1973 "awkgram.y" /* yacc.c:1646  */
+#line 1974 "awkgram.y" /* yacc.c:1646  */
     {
                char *arr = (yyvsp[-1])->lextok;
                (yyvsp[-1])->memory = variable((yyvsp[-1])->source_line, arr, 
Node_var_new);
                (yyvsp[-1])->opcode = Op_push_array;
                (yyval) = list_prepend((yyvsp[0]), (yyvsp[-1]));
          }
-#line 4152 "awkgram.c" /* yacc.c:1646  */
+#line 4153 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 191:
-#line 1983 "awkgram.y" /* yacc.c:1646  */
+#line 1984 "awkgram.y" /* yacc.c:1646  */
     {
                INSTRUCTION *ip = (yyvsp[0])->nexti;
                if (ip->opcode == Op_push
@@ -4164,73 +4165,73 @@ regular_print:
                } else
                        (yyval) = (yyvsp[0]);
          }
-#line 4168 "awkgram.c" /* yacc.c:1646  */
+#line 4169 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 192:
-#line 1995 "awkgram.y" /* yacc.c:1646  */
+#line 1996 "awkgram.y" /* yacc.c:1646  */
     {
                (yyval) = list_append((yyvsp[-1]), (yyvsp[-2]));
                if ((yyvsp[0]) != NULL)
                        mk_assignment((yyvsp[-1]), NULL, (yyvsp[0]));
          }
-#line 4178 "awkgram.c" /* yacc.c:1646  */
+#line 4179 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 193:
-#line 2004 "awkgram.y" /* yacc.c:1646  */
+#line 2005 "awkgram.y" /* yacc.c:1646  */
     {
                (yyvsp[0])->opcode = Op_postincrement;
          }
-#line 4186 "awkgram.c" /* yacc.c:1646  */
+#line 4187 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 194:
-#line 2008 "awkgram.y" /* yacc.c:1646  */
+#line 2009 "awkgram.y" /* yacc.c:1646  */
     {
                (yyvsp[0])->opcode = Op_postdecrement;
          }
-#line 4194 "awkgram.c" /* yacc.c:1646  */
+#line 4195 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 195:
-#line 2011 "awkgram.y" /* yacc.c:1646  */
+#line 2012 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = NULL; }
-#line 4200 "awkgram.c" /* yacc.c:1646  */
+#line 4201 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 197:
-#line 2019 "awkgram.y" /* yacc.c:1646  */
+#line 2020 "awkgram.y" /* yacc.c:1646  */
     { yyerrok; }
-#line 4206 "awkgram.c" /* yacc.c:1646  */
+#line 4207 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 198:
-#line 2023 "awkgram.y" /* yacc.c:1646  */
+#line 2024 "awkgram.y" /* yacc.c:1646  */
     { yyerrok; }
-#line 4212 "awkgram.c" /* yacc.c:1646  */
+#line 4213 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 201:
-#line 2032 "awkgram.y" /* yacc.c:1646  */
+#line 2033 "awkgram.y" /* yacc.c:1646  */
     { yyerrok; }
-#line 4218 "awkgram.c" /* yacc.c:1646  */
+#line 4219 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 202:
-#line 2036 "awkgram.y" /* yacc.c:1646  */
+#line 2037 "awkgram.y" /* yacc.c:1646  */
     { (yyval) = (yyvsp[0]); yyerrok; }
-#line 4224 "awkgram.c" /* yacc.c:1646  */
+#line 4225 "awkgram.c" /* yacc.c:1646  */
     break;
 
   case 203:
-#line 2040 "awkgram.y" /* yacc.c:1646  */
+#line 2041 "awkgram.y" /* yacc.c:1646  */
     { yyerrok; }
-#line 4230 "awkgram.c" /* yacc.c:1646  */
+#line 4231 "awkgram.c" /* yacc.c:1646  */
     break;
 
 
-#line 4234 "awkgram.c" /* yacc.c:1646  */
+#line 4235 "awkgram.c" /* yacc.c:1646  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -4458,7 +4459,7 @@ yyreturn:
 #endif
   return yyresult;
 }
-#line 2042 "awkgram.y" /* yacc.c:1906  */
+#line 2043 "awkgram.y" /* yacc.c:1906  */
 
 
 struct token {
@@ -6540,10 +6541,23 @@ retry:
        while (c != END_FILE && is_identchar(c)) {
                tokadd(c);
                c = nextc(true);
+               if (! do_traditional && c == ':') {
+                       int peek = nextc(true);
+
+                       if (peek == ':') {
+                               tokadd(c);
+                               tokadd(c);
+                               c = nextc(true);
+                       } else
+                               pushback();
+                               // then continue around the loop, c == ':'
+               }
        }
        tokadd('\0');
        pushback();
 
+       validate_qualified_name(tokstart);
+
        /* See if it is a special token. */
        if ((mid = check_special(tokstart)) >= 0) {
                static int warntab[sizeof(tokentab) / sizeof(tokentab[0])];
@@ -7266,7 +7280,10 @@ check_params(char *fname, int pcount, INSTRUCTION *list)
                        error_ln(p->source_line,
                                _("function `%s': can't use special variable 
`%s' as a function parameter"),
                                        fname, name);
-               }
+               } else if (strchr(name, ':'))
+                       error_ln(p->source_line,
+                               _("function `%s': parameter `%s' cannot contain 
a namespace"),
+                                       fname, name);
 
                /* check for duplicate parameters */
                for (j = 0; j < i; j++) {
@@ -8760,3 +8777,25 @@ set_profile_text(NODE *n, const char *str, size_t len)
 
        return n;
 }
+
+/* validate_qualified_name --- make sure that a qualified name is built 
correctly */
+
+static void
+validate_qualified_name(char *token)
+{
+       char *cp;
+
+       if ((cp = strchr(token, ':')) == NULL)
+               return;
+
+       if (cp[2] != '_' && ! is_alpha(cp[2]))
+               error_ln(sourceline,
+                               _("qualified identifier `%s' is badly formed"),
+                               token);
+
+       cp += 2;
+       if ((cp = strchr(cp, ':')) != NULL)
+               error_ln(sourceline,
+                       _("identifier `%s': namespace separator can only appear 
once in a qualified name"),
+                       token);
+}
diff --git a/awkgram.y b/awkgram.y
index 37acf28..9b81250 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -58,6 +58,7 @@ static int load_library(INSTRUCTION *file);
 static void next_sourcefile(void);
 static char *tokexpand(void);
 static NODE *set_profile_text(NODE *n, const char *str, size_t len);
+static void validate_qualified_name(char *token);
 
 #define instruction(t) bcalloc(t, 1, 0)
 
@@ -4120,10 +4121,23 @@ retry:
        while (c != END_FILE && is_identchar(c)) {
                tokadd(c);
                c = nextc(true);
+               if (! do_traditional && c == ':') {
+                       int peek = nextc(true);
+
+                       if (peek == ':') {
+                               tokadd(c);
+                               tokadd(c);
+                               c = nextc(true);
+                       } else
+                               pushback();
+                               // then continue around the loop, c == ':'
+               }
        }
        tokadd('\0');
        pushback();
 
+       validate_qualified_name(tokstart);
+
        /* See if it is a special token. */
        if ((mid = check_special(tokstart)) >= 0) {
                static int warntab[sizeof(tokentab) / sizeof(tokentab[0])];
@@ -4846,7 +4860,10 @@ check_params(char *fname, int pcount, INSTRUCTION *list)
                        error_ln(p->source_line,
                                _("function `%s': can't use special variable 
`%s' as a function parameter"),
                                        fname, name);
-               }
+               } else if (strchr(name, ':'))
+                       error_ln(p->source_line,
+                               _("function `%s': parameter `%s' cannot contain 
a namespace"),
+                                       fname, name);
 
                /* check for duplicate parameters */
                for (j = 0; j < i; j++) {
@@ -6340,3 +6357,25 @@ set_profile_text(NODE *n, const char *str, size_t len)
 
        return n;
 }
+
+/* validate_qualified_name --- make sure that a qualified name is built 
correctly */
+
+static void
+validate_qualified_name(char *token)
+{
+       char *cp;
+
+       if ((cp = strchr(token, ':')) == NULL)
+               return;
+
+       if (cp[2] != '_' && ! is_alpha(cp[2]))
+               error_ln(sourceline,
+                               _("qualified identifier `%s' is badly formed"),
+                               token);
+
+       cp += 2;
+       if ((cp = strchr(cp, ':')) != NULL)
+               error_ln(sourceline,
+                       _("identifier `%s': namespace separator can only appear 
once in a qualified name"),
+                       token);
+}
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 81f4cdc..6eb3d9f 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,8 @@
+2017-06-06         Arnold D. Robbins     <address@hidden>
+
+       * gawktexi.in (Namespaces): Further clarifications. Move to
+       `::' as the namespace separator.
+
 2017-06-05         Arnold D. Robbins     <address@hidden>
 
        * gawktexi.in (Checking for MPFR): Fix typo.
diff --git a/doc/gawk.info b/doc/gawk.info
index 7c5fb6e..e9d686b 100644
--- a/doc/gawk.info
+++ b/doc/gawk.info
@@ -19753,6 +19753,7 @@ This major node describes a feature that is specific to 
'gawk'.
 * Qualified Names::             How to qualify names with a namespace.
 * Default Namespace::           The default namespace.
 * Changing The Namespace::      How to change the namespace.
+* Internal Name Management::    How names are stored internally.
 * Namespace Example::           An example of code using a namespace.
 * Namespace Misc::              Namespace notes for developers.
 
@@ -19763,9 +19764,9 @@ File: gawk.info,  Node: Global Namespace,  Next: 
Qualified Names,  Up: Namespace
 ======================================
 
 In standard 'awk', there is a single, global, "namespace".  This means
-that _all_ function names and global variable names must be unique.  Two
-different 'awk' source files cannot both define a function named
-'sort()', for example.
+that _all_ function names and global variable names must be unique.  For
+example, two different 'awk' source files cannot both define a function
+named 'min()'.
 
    This situation is okay when programs are small, say a few hundred
 lines, or even a few thousand, but it prevents the development of
@@ -19775,7 +19776,7 @@ other's "private" global variables (*note Library 
Names::).
 
    Most other programming languages solve this issue by providing some
 kind of namespace control: a way to say "this function is in namespace
-X, and that function is in namespace Y."  (Of course, there is then
+XXX, and that function is in namespace YYY."  (Of course, there is then
 still a single namespace for the namespaces, but the hope is that there
 are much fewer namespaces in use by any given program, and thus much
 less chance for collisions.)
@@ -19789,15 +19790,21 @@ File: gawk.info,  Node: Qualified Names,  Next: 
Default Namespace,  Prev: Global
 12.2 Qualified Names
 ====================
 
-A "qualified name" is an identifier that includes a namespace name.  For
-example, one might have a function named 'posix.getpid()'.  Here, the
-namespace is 'posix' and the function name within the namespace is
-'getpid()'.  The namespace and variable or function name are separated
-by a period.  Only one period is allowed in a qualified name.
+A "qualified name" is an identifier that includes a namespace name and
+the namespace separator, '::'.  For example, one might have a function
+named 'posix::getpid()'.  Here, the namespace is 'posix' and the
+function name within the namespace is 'getpid()'.  The namespace and
+variable or function name are separated by a double-colon.  Only one
+such separator is allowed in a qualified name.
+
+     NOTE: Unlike C++, the '::' is _not_ an operator.  No spaces are
+     allowed between the namespace name, the '::', and the rest of the
+     name.
 
    You must use fully qualified names from one namespace to access
-variables in another.  This is especially important when using variable
-names to index the special 'SYMTAB' array.
+variables and functions in another.  This is especially important when
+using variable names to index the special 'SYMTAB' array, and when
+making indirect function calls.  *FIXME:* and xref.
 
 
 File: gawk.info,  Node: Default Namespace,  Next: Changing The Namespace,  
Prev: Qualified Names,  Up: Namespaces
@@ -19807,7 +19814,7 @@ File: gawk.info,  Node: Default Namespace,  Next: 
Changing The Namespace,  Prev:
 
 The default namespace, not surprisingly, is 'awk'.  All of the
 predefined 'awk' and 'gawk' variables are in this namespace, and thus
-have qualified names like 'awk.ARGC', 'awk.NF', and so on.
+have qualified names like 'awk::ARGC', 'awk::NF', and so on.
 
    Furthermore, even when you have changed the namespace for your
 current source file (*note Changing The Namespace::), 'gawk' forces
@@ -19815,11 +19822,11 @@ unqualified identifiers whose names are all uppercase 
letters to be in
 the 'awk' namespace.  This makes it possible for you to easily reference
 'gawk''s global variables from different namespaces.
 
-   It is a syntactic error to use qualified names for function parameter
+   It is a syntax error to use qualified names for function parameter
 names.
 
 
-File: gawk.info,  Node: Changing The Namespace,  Next: Namespace Example,  
Prev: Default Namespace,  Up: Namespaces
+File: gawk.info,  Node: Changing The Namespace,  Next: Internal Name 
Management,  Prev: Default Namespace,  Up: Namespaces
 
 12.4 Changing The Namespace
 ===========================
@@ -19832,18 +19839,18 @@ the top level of your program:
      BEGIN { ... }
      ...
 
-   After this directive, all simple non-uppercase identifiers are placed
-into the 'passwd' namespace.
+   After this directive, all simple non-completely-uppercase identifiers
+are placed into the 'passwd' namespace.
 
    You can change the namespace multiple times within a single source
-file, although this is likely to become confusing if you do it a lot.
+file, although this is likely to become confusing if you do it too much.
 
      NOTE: The namespace concept is one handled while your program is
      being parsed by 'gawk'.  There is no concept of a "current"
      namespace during runtime.  Be sure you understand the distinction.
 
-   Each source file for '-i' and '-f' starts out with an implicit
-'@namespace "awk"'.
+   Each source file for '-i' and '-f' (FIXME: pxref) starts out with an
+implicit '@namespace "awk"'.
 
    Similarly, each chunk of command-line code with '-e' has such an
 implicit statement.
@@ -19852,9 +19859,39 @@ implicit statement.
 of 'BEGIN', 'BEGINFILE', 'END', and 'ENDFILE' rules.
 
 
-File: gawk.info,  Node: Namespace Example,  Next: Namespace Misc,  Prev: 
Changing The Namespace,  Up: Namespaces
+File: gawk.info,  Node: Internal Name Management,  Next: Namespace Example,  
Prev: Changing The Namespace,  Up: Namespaces
+
+12.5 Internal Name Management
+=============================
+
+For backwards compatibility, all identifiers in the 'awk' namespace are
+stored internally as unadorned identifiers.  This is mainly relevant
+when using such identifiers as indices for 'SYMTAB', 'FUNCTAB', and
+'PROCINFO["identifiers"]' (FIXME: xref), and for use in indirect
+function calls (FIXME: xref).
+
+   In program code, to refer to variables and functions in the 'awk'
+namespace from another namespace, you must still use the 'awk::' prefix.
+For example:
+
+     @namespace "awk"          # the default
+
+     BEGIN {
+         Title = "My Report"   # fully qualified name is awk::Title
+     }
+
+     @namespace "report"       # now in "report" namespace
+
+     function compute()          # this is really report::compute()
+     {
+         print awk::Title      # but would be SYMTAB["Title"]
+         ...
+     }
 
-12.5 Namespace Example
+
+File: gawk.info,  Node: Namespace Example,  Next: Namespace Misc,  Prev: 
Internal Name Management,  Up: Namespaces
+
+12.6 Namespace Example
 ======================
 
      # FIXME: fix this up for real, dates etc
@@ -19937,41 +19974,39 @@ File: gawk.info,  Node: Namespace Example,  Next: 
Namespace Misc,  Prev: Changin
 
      function getpwnam(name)
      {
-         return passwd.Getpwnam(name)
+         return passwd::Getpwnam(name)
      }
 
      function getpwuid(uid)
      {
-         return passwd.Getpwuid(uid)
+         return passwd::Getpwuid(uid)
      }
 
      function getpwent()
      {
-         return passwd.Getpwent()
+         return passwd::Getpwent()
      }
 
      function endpwent()
      {
-         passwd.Endpwent()
+         passwd::Endpwent()
      }
 
 
 File: gawk.info,  Node: Namespace Misc,  Prev: Namespace Example,  Up: 
Namespaces
 
-12.6 Miscellaneous Notes
+12.7 Miscellaneous Notes
 ========================
 
 Other notes for reviewers:
 
-'SYMTAB', 'FUNCTAB' and 'PROCINFO["identifiers"]'
-     The subscripts are all fully qualified names.
-
 Profiler:
      When profiling, we can add an 'Op_Namespace' to the start of each
-     rule.  If it has changed since the previous one, output an
-     '@namespace' statement.  For each identifier, if it starts with the
-     current namespace, output only the simple part.  For all 'awk.XXX'
-     if 'XXX' is all uppercase, strip off the 'awk' part.
+     rule and function definition.  If this is different than the
+     previous one, output an '@namespace' statement.  For each
+     identifier, if it starts with the current namespace, output only
+     the simple part.  For all 'awk::XXX' if 'XXX' is all uppercase,
+     strip off the 'awk::' part.
 
 Debugger:
      Simply print fully qualified names all the time.  Maybe allow a
@@ -19979,28 +20014,6 @@ Debugger:
      will use that to create fully qualified names?  Have to be careful
      about all uppercase names though.
 
-How does this affect indirect calls?
-     The current namespace is a parse time thing, not a dynamic thing,
-     so for indirect calls to work, use something like:
-
-          @namespace "foo"
-
-          function bar() { ...  }
-
-          {
-              ...
-              x = "foo.bar"
-              ...
-              @x()
-          }
-
-     This is particularly true if 'x' is passed as a "function pointer"
-     to another function in another namespace for that function to call
-     through it.
-
-     For backwards compatibility, if 'x' contains an unadorned
-     identifier, 'gawk' forces it to be in the 'awk' namespace.
-
 How does this affect '@include'?
      Basically '@include' should push and pop the namespace.  Each
      '@include' saves the current namespace and starts over with
@@ -20013,6 +20026,12 @@ Extension functions
      compatibility at the source level while providing access to
      namespaces as needed.
 
+     Actually, since we've decided that 'awk' namespace variables and
+     function are stored unadorned, the current macros that pass '""'
+     would continue to work.  Internally, we need to recognize '"awk"'
+     and _not_ fully qualify the name before storing it in the symbol
+     table.
+
 
 File: gawk.info,  Node: Advanced Features,  Next: Internationalization,  Prev: 
Namespaces,  Up: Top
 
@@ -23563,7 +23582,7 @@ File: gawk.info,  Node: Checking for MPFR,  Next: POSIX 
Floating Point Problems,
 ======================================
 
 Occasionally, you might like to be able to check if 'gawk' was invoked
-with the '-M' option, enabling aribtrary-precision arithmetic.  You can
+with the '-M' option, enabling arbitrary-precision arithmetic.  You can
 do so with the following function, contributed by Andrew Schorr:
 
      # adequate_math_precision --- return true if we have enough bits
@@ -36376,235 +36395,236 @@ Node: Programs Summary799357
 Node: Programs Exercises800571
 Ref: Programs Exercises-Footnote-1804700
 Node: Namespaces804791
-Node: Global Namespace805406
-Node: Qualified Names806646
-Node: Default Namespace807327
-Node: Changing The Namespace808105
-Node: Namespace Example809194
-Node: Namespace Misc811257
-Node: Advanced Features813299
-Node: Nondecimal Data815284
-Node: Array Sorting816875
-Node: Controlling Array Traversal817575
-Ref: Controlling Array Traversal-Footnote-1825942
-Node: Array Sorting Functions826060
-Ref: Array Sorting Functions-Footnote-1831151
-Node: Two-way I/O831347
-Ref: Two-way I/O-Footnote-1837898
-Ref: Two-way I/O-Footnote-2838085
-Node: TCP/IP Networking838167
-Node: Profiling841285
-Ref: Profiling-Footnote-1849957
-Node: Advanced Features Summary850280
-Node: Internationalization852124
-Node: I18N and L10N853604
-Node: Explaining gettext854291
-Ref: Explaining gettext-Footnote-1860183
-Ref: Explaining gettext-Footnote-2860368
-Node: Programmer i18n860533
-Ref: Programmer i18n-Footnote-1865482
-Node: Translator i18n865531
-Node: String Extraction866325
-Ref: String Extraction-Footnote-1867457
-Node: Printf Ordering867543
-Ref: Printf Ordering-Footnote-1870329
-Node: I18N Portability870393
-Ref: I18N Portability-Footnote-1872849
-Node: I18N Example872912
-Ref: I18N Example-Footnote-1875718
-Node: Gawk I18N875791
-Node: I18N Summary876436
-Node: Debugger877777
-Node: Debugging878799
-Node: Debugging Concepts879240
-Node: Debugging Terms881049
-Node: Awk Debugging883624
-Node: Sample Debugging Session884530
-Node: Debugger Invocation885064
-Node: Finding The Bug886450
-Node: List of Debugger Commands892928
-Node: Breakpoint Control894261
-Node: Debugger Execution Control897955
-Node: Viewing And Changing Data901317
-Node: Execution Stack904691
-Node: Debugger Info906328
-Node: Miscellaneous Debugger Commands910399
-Node: Readline Support915487
-Node: Limitations916383
-Node: Debugging Summary918492
-Node: Arbitrary Precision Arithmetic919771
-Node: Computer Arithmetic921256
-Ref: table-numeric-ranges924847
-Ref: Computer Arithmetic-Footnote-1925569
-Node: Math Definitions925626
-Ref: table-ieee-formats928940
-Ref: Math Definitions-Footnote-1929543
-Node: MPFR features929648
-Node: FP Math Caution931365
-Ref: FP Math Caution-Footnote-1932437
-Node: Inexactness of computations932806
-Node: Inexact representation933766
-Node: Comparing FP Values935126
-Node: Errors accumulate936208
-Node: Getting Accuracy937641
-Node: Try To Round940351
-Node: Setting precision941250
-Ref: table-predefined-precision-strings941947
-Node: Setting the rounding mode943777
-Ref: table-gawk-rounding-modes944151
-Ref: Setting the rounding mode-Footnote-1947559
-Node: Arbitrary Precision Integers947738
-Ref: Arbitrary Precision Integers-Footnote-1952643
-Node: Checking for MPFR952792
-Node: POSIX Floating Point Problems954089
-Ref: POSIX Floating Point Problems-Footnote-1957960
-Node: Floating point summary957998
-Node: Dynamic Extensions960188
-Node: Extension Intro961741
-Node: Plugin License963007
-Node: Extension Mechanism Outline963804
-Ref: figure-load-extension964243
-Ref: figure-register-new-function965808
-Ref: figure-call-new-function966900
-Node: Extension API Description968962
-Node: Extension API Functions Introduction970604
-Node: General Data Types975938
-Ref: General Data Types-Footnote-1983143
-Node: Memory Allocation Functions983442
-Ref: Memory Allocation Functions-Footnote-1986287
-Node: Constructor Functions986386
-Node: Registration Functions989385
-Node: Extension Functions990070
-Node: Exit Callback Functions995283
-Node: Extension Version String996533
-Node: Input Parsers997196
-Node: Output Wrappers1009903
-Node: Two-way processors1014415
-Node: Printing Messages1016680
-Ref: Printing Messages-Footnote-11017851
-Node: Updating ERRNO1018004
-Node: Requesting Values1018743
-Ref: table-value-types-returned1019480
-Node: Accessing Parameters1020416
-Node: Symbol Table Access1021651
-Node: Symbol table by name1022163
-Node: Symbol table by cookie1023952
-Ref: Symbol table by cookie-Footnote-11028137
-Node: Cached values1028201
-Ref: Cached values-Footnote-11031737
-Node: Array Manipulation1031828
-Ref: Array Manipulation-Footnote-11032919
-Node: Array Data Types1032956
-Ref: Array Data Types-Footnote-11035614
-Node: Array Functions1035706
-Node: Flattening Arrays1040105
-Node: Creating Arrays1047046
-Node: Redirection API1051815
-Node: Extension API Variables1054657
-Node: Extension Versioning1055290
-Ref: gawk-api-version1055727
-Node: Extension API Informational Variables1057455
-Node: Extension API Boilerplate1058519
-Node: Changes from API V11062381
-Node: Finding Extensions1063041
-Node: Extension Example1063600
-Node: Internal File Description1064398
-Node: Internal File Ops1068478
-Ref: Internal File Ops-Footnote-11079878
-Node: Using Internal File Ops1080018
-Ref: Using Internal File Ops-Footnote-11082401
-Node: Extension Samples1082675
-Node: Extension Sample File Functions1084204
-Node: Extension Sample Fnmatch1091853
-Node: Extension Sample Fork1093340
-Node: Extension Sample Inplace1094558
-Node: Extension Sample Ord1097768
-Node: Extension Sample Readdir1098604
-Ref: table-readdir-file-types1099493
-Node: Extension Sample Revout1100298
-Node: Extension Sample Rev2way1100887
-Node: Extension Sample Read write array1101627
-Node: Extension Sample Readfile1103569
-Node: Extension Sample Time1104664
-Node: Extension Sample API Tests1106012
-Node: gawkextlib1106504
-Node: Extension summary1108951
-Node: Extension Exercises1112653
-Node: Language History1114151
-Node: V7/SVR3.11115807
-Node: SVR41117959
-Node: POSIX1119393
-Node: BTL1120772
-Node: POSIX/GNU1121501
-Node: Feature History1127393
-Node: Common Extensions1141817
-Node: Ranges and Locales1143100
-Ref: Ranges and Locales-Footnote-11147716
-Ref: Ranges and Locales-Footnote-21147743
-Ref: Ranges and Locales-Footnote-31147978
-Node: Contributors1148199
-Node: History summary1153759
-Node: Installation1155139
-Node: Gawk Distribution1156083
-Node: Getting1156567
-Node: Extracting1157528
-Node: Distribution contents1159166
-Node: Unix Installation1165508
-Node: Quick Installation1166190
-Node: Shell Startup Files1168604
-Node: Additional Configuration Options1169693
-Node: Configuration Philosophy1171682
-Node: Non-Unix Installation1174051
-Node: PC Installation1174511
-Node: PC Binary Installation1175349
-Node: PC Compiling1175784
-Node: PC Using1176901
-Node: Cygwin1179946
-Node: MSYS1180716
-Node: VMS Installation1181217
-Node: VMS Compilation1182008
-Ref: VMS Compilation-Footnote-11183237
-Node: VMS Dynamic Extensions1183295
-Node: VMS Installation Details1184980
-Node: VMS Running1187233
-Node: VMS GNV1191512
-Node: VMS Old Gawk1192247
-Node: Bugs1192718
-Node: Bug address1193381
-Node: Usenet1195778
-Node: Maintainers1196555
-Node: Other Versions1197931
-Node: Installation summary1204515
-Node: Notes1205550
-Node: Compatibility Mode1206415
-Node: Additions1207197
-Node: Accessing The Source1208122
-Node: Adding Code1209557
-Node: New Ports1215775
-Node: Derived Files1220263
-Ref: Derived Files-Footnote-11225748
-Ref: Derived Files-Footnote-21225783
-Ref: Derived Files-Footnote-31226381
-Node: Future Extensions1226495
-Node: Implementation Limitations1227153
-Node: Extension Design1228336
-Node: Old Extension Problems1229490
-Ref: Old Extension Problems-Footnote-11231008
-Node: Extension New Mechanism Goals1231065
-Ref: Extension New Mechanism Goals-Footnote-11234429
-Node: Extension Other Design Decisions1234618
-Node: Extension Future Growth1236731
-Node: Old Extension Mechanism1237567
-Node: Notes summary1239330
-Node: Basic Concepts1240512
-Node: Basic High Level1241193
-Ref: figure-general-flow1241475
-Ref: figure-process-flow1242160
-Ref: Basic High Level-Footnote-11245461
-Node: Basic Data Typing1245646
-Node: Glossary1248974
-Node: Copying1280921
-Node: GNU Free Documentation License1318460
-Node: Index1343578
+Node: Global Namespace805471
+Node: Qualified Names806714
+Node: Default Namespace807671
+Node: Changing The Namespace808448
+Node: Internal Name Management809573
+Node: Namespace Example810567
+Node: Namespace Misc812636
+Node: Advanced Features814278
+Node: Nondecimal Data816263
+Node: Array Sorting817854
+Node: Controlling Array Traversal818554
+Ref: Controlling Array Traversal-Footnote-1826921
+Node: Array Sorting Functions827039
+Ref: Array Sorting Functions-Footnote-1832130
+Node: Two-way I/O832326
+Ref: Two-way I/O-Footnote-1838877
+Ref: Two-way I/O-Footnote-2839064
+Node: TCP/IP Networking839146
+Node: Profiling842264
+Ref: Profiling-Footnote-1850936
+Node: Advanced Features Summary851259
+Node: Internationalization853103
+Node: I18N and L10N854583
+Node: Explaining gettext855270
+Ref: Explaining gettext-Footnote-1861162
+Ref: Explaining gettext-Footnote-2861347
+Node: Programmer i18n861512
+Ref: Programmer i18n-Footnote-1866461
+Node: Translator i18n866510
+Node: String Extraction867304
+Ref: String Extraction-Footnote-1868436
+Node: Printf Ordering868522
+Ref: Printf Ordering-Footnote-1871308
+Node: I18N Portability871372
+Ref: I18N Portability-Footnote-1873828
+Node: I18N Example873891
+Ref: I18N Example-Footnote-1876697
+Node: Gawk I18N876770
+Node: I18N Summary877415
+Node: Debugger878756
+Node: Debugging879778
+Node: Debugging Concepts880219
+Node: Debugging Terms882028
+Node: Awk Debugging884603
+Node: Sample Debugging Session885509
+Node: Debugger Invocation886043
+Node: Finding The Bug887429
+Node: List of Debugger Commands893907
+Node: Breakpoint Control895240
+Node: Debugger Execution Control898934
+Node: Viewing And Changing Data902296
+Node: Execution Stack905670
+Node: Debugger Info907307
+Node: Miscellaneous Debugger Commands911378
+Node: Readline Support916466
+Node: Limitations917362
+Node: Debugging Summary919471
+Node: Arbitrary Precision Arithmetic920750
+Node: Computer Arithmetic922235
+Ref: table-numeric-ranges925826
+Ref: Computer Arithmetic-Footnote-1926548
+Node: Math Definitions926605
+Ref: table-ieee-formats929919
+Ref: Math Definitions-Footnote-1930522
+Node: MPFR features930627
+Node: FP Math Caution932344
+Ref: FP Math Caution-Footnote-1933416
+Node: Inexactness of computations933785
+Node: Inexact representation934745
+Node: Comparing FP Values936105
+Node: Errors accumulate937187
+Node: Getting Accuracy938620
+Node: Try To Round941330
+Node: Setting precision942229
+Ref: table-predefined-precision-strings942926
+Node: Setting the rounding mode944756
+Ref: table-gawk-rounding-modes945130
+Ref: Setting the rounding mode-Footnote-1948538
+Node: Arbitrary Precision Integers948717
+Ref: Arbitrary Precision Integers-Footnote-1953622
+Node: Checking for MPFR953771
+Node: POSIX Floating Point Problems955068
+Ref: POSIX Floating Point Problems-Footnote-1958939
+Node: Floating point summary958977
+Node: Dynamic Extensions961167
+Node: Extension Intro962720
+Node: Plugin License963986
+Node: Extension Mechanism Outline964783
+Ref: figure-load-extension965222
+Ref: figure-register-new-function966787
+Ref: figure-call-new-function967879
+Node: Extension API Description969941
+Node: Extension API Functions Introduction971583
+Node: General Data Types976917
+Ref: General Data Types-Footnote-1984122
+Node: Memory Allocation Functions984421
+Ref: Memory Allocation Functions-Footnote-1987266
+Node: Constructor Functions987365
+Node: Registration Functions990364
+Node: Extension Functions991049
+Node: Exit Callback Functions996262
+Node: Extension Version String997512
+Node: Input Parsers998175
+Node: Output Wrappers1010882
+Node: Two-way processors1015394
+Node: Printing Messages1017659
+Ref: Printing Messages-Footnote-11018830
+Node: Updating ERRNO1018983
+Node: Requesting Values1019722
+Ref: table-value-types-returned1020459
+Node: Accessing Parameters1021395
+Node: Symbol Table Access1022630
+Node: Symbol table by name1023142
+Node: Symbol table by cookie1024931
+Ref: Symbol table by cookie-Footnote-11029116
+Node: Cached values1029180
+Ref: Cached values-Footnote-11032716
+Node: Array Manipulation1032807
+Ref: Array Manipulation-Footnote-11033898
+Node: Array Data Types1033935
+Ref: Array Data Types-Footnote-11036593
+Node: Array Functions1036685
+Node: Flattening Arrays1041084
+Node: Creating Arrays1048025
+Node: Redirection API1052794
+Node: Extension API Variables1055636
+Node: Extension Versioning1056269
+Ref: gawk-api-version1056706
+Node: Extension API Informational Variables1058434
+Node: Extension API Boilerplate1059498
+Node: Changes from API V11063360
+Node: Finding Extensions1064020
+Node: Extension Example1064579
+Node: Internal File Description1065377
+Node: Internal File Ops1069457
+Ref: Internal File Ops-Footnote-11080857
+Node: Using Internal File Ops1080997
+Ref: Using Internal File Ops-Footnote-11083380
+Node: Extension Samples1083654
+Node: Extension Sample File Functions1085183
+Node: Extension Sample Fnmatch1092832
+Node: Extension Sample Fork1094319
+Node: Extension Sample Inplace1095537
+Node: Extension Sample Ord1098747
+Node: Extension Sample Readdir1099583
+Ref: table-readdir-file-types1100472
+Node: Extension Sample Revout1101277
+Node: Extension Sample Rev2way1101866
+Node: Extension Sample Read write array1102606
+Node: Extension Sample Readfile1104548
+Node: Extension Sample Time1105643
+Node: Extension Sample API Tests1106991
+Node: gawkextlib1107483
+Node: Extension summary1109930
+Node: Extension Exercises1113632
+Node: Language History1115130
+Node: V7/SVR3.11116786
+Node: SVR41118938
+Node: POSIX1120372
+Node: BTL1121751
+Node: POSIX/GNU1122480
+Node: Feature History1128372
+Node: Common Extensions1142796
+Node: Ranges and Locales1144079
+Ref: Ranges and Locales-Footnote-11148695
+Ref: Ranges and Locales-Footnote-21148722
+Ref: Ranges and Locales-Footnote-31148957
+Node: Contributors1149178
+Node: History summary1154738
+Node: Installation1156118
+Node: Gawk Distribution1157062
+Node: Getting1157546
+Node: Extracting1158507
+Node: Distribution contents1160145
+Node: Unix Installation1166487
+Node: Quick Installation1167169
+Node: Shell Startup Files1169583
+Node: Additional Configuration Options1170672
+Node: Configuration Philosophy1172661
+Node: Non-Unix Installation1175030
+Node: PC Installation1175490
+Node: PC Binary Installation1176328
+Node: PC Compiling1176763
+Node: PC Using1177880
+Node: Cygwin1180925
+Node: MSYS1181695
+Node: VMS Installation1182196
+Node: VMS Compilation1182987
+Ref: VMS Compilation-Footnote-11184216
+Node: VMS Dynamic Extensions1184274
+Node: VMS Installation Details1185959
+Node: VMS Running1188212
+Node: VMS GNV1192491
+Node: VMS Old Gawk1193226
+Node: Bugs1193697
+Node: Bug address1194360
+Node: Usenet1196757
+Node: Maintainers1197534
+Node: Other Versions1198910
+Node: Installation summary1205494
+Node: Notes1206529
+Node: Compatibility Mode1207394
+Node: Additions1208176
+Node: Accessing The Source1209101
+Node: Adding Code1210536
+Node: New Ports1216754
+Node: Derived Files1221242
+Ref: Derived Files-Footnote-11226727
+Ref: Derived Files-Footnote-21226762
+Ref: Derived Files-Footnote-31227360
+Node: Future Extensions1227474
+Node: Implementation Limitations1228132
+Node: Extension Design1229315
+Node: Old Extension Problems1230469
+Ref: Old Extension Problems-Footnote-11231987
+Node: Extension New Mechanism Goals1232044
+Ref: Extension New Mechanism Goals-Footnote-11235408
+Node: Extension Other Design Decisions1235597
+Node: Extension Future Growth1237710
+Node: Old Extension Mechanism1238546
+Node: Notes summary1240309
+Node: Basic Concepts1241491
+Node: Basic High Level1242172
+Ref: figure-general-flow1242454
+Ref: figure-process-flow1243139
+Ref: Basic High Level-Footnote-11246440
+Node: Basic Data Typing1246625
+Node: Glossary1249953
+Node: Copying1281900
+Node: GNU Free Documentation License1319439
+Node: Index1344557
 
 End Tag Table
diff --git a/doc/gawk.texi b/doc/gawk.texi
index 6c75912..5364895 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -27617,6 +27617,7 @@ This @value{CHAPTER} describes a feature that is 
specific to @command{gawk}.
 * Qualified Names::             How to qualify names with a namespace.
 * Default Namespace::           The default namespace.
 * Changing The Namespace::      How to change the namespace.
+* Internal Name Management::    How names are stored internally.
 * Namespace Example::           An example of code using a namespace.
 * Namespace Misc::              Namespace notes for developers.
 @end menu
@@ -27626,8 +27627,8 @@ This @value{CHAPTER} describes a feature that is 
specific to @command{gawk}.
 
 In standard @command{awk}, there is a single, global, @dfn{namespace}.
 This means that @emph{all} function names and global variable names must
-be unique.  Two different @command{awk} source files cannot both define
-a function named @code{sort()}, for example.
+be unique. For example, two different @command{awk} source files cannot both 
define
+a function named @code{min()}.
 
 This situation is okay when programs are small, say a few hundred lines,
 or even a few thousand, but it prevents the development of reusable
@@ -27637,8 +27638,8 @@ independently-developed library files to accidentally 
step on each other's
 (@pxref{Library Names}).
 
 Most other programming languages solve this issue by providing some kind
-of namespace control: a way to say ``this function is in namespace @var{X},
-and that function is in namespace @var{Y}.''  (Of course, there is then
+of namespace control: a way to say ``this function is in namespace @var{xxx},
+and that function is in namespace @var{yyy}.''  (Of course, there is then
 still a single namespace for the namespaces, but the hope is that there
 are much fewer namespaces in use by any given program, and thus much
 less chance for collisions.)
@@ -27651,15 +27652,21 @@ namespaces.
 @section Qualified Names
 
 A @dfn{qualified name} is an identifier that includes a namespace
-name.  For example, one might have a function named @code{posix.getpid()}.
-Here, the namespace is @samp{posix} and the function name within the
-namespace is @samp{getpid()}.  The namespace and variable or function
-name are separated by a period.  Only one period is allowed in
+name and the namespace separator, @code{::}.  For example, one might have a 
function named @code{posix::getpid()}.
+Here, the namespace is @code{posix} and the function name within the
+namespace is @code{getpid()}.  The namespace and variable or function
+name are separated by a double-colon.  Only one such separator is allowed in
 a qualified name.
 
address@hidden  NOTE
+Unlike C++, the @code{::} is @emph{not} an operator.  No spaces are allowed 
between
+the namespace name, the @code{::}, and the rest of the name.
address@hidden quotation
+
 You must use fully qualified names from one namespace to access variables
-in another.  This is especially important when using variable
-names to index the special @code{SYMTAB} array.
+and functions in another.  This is especially important when using variable
+names to index the special @code{SYMTAB} array, and when making indirect 
function calls.
address@hidden:} and xref.
 
 @node Default Namespace
 @section The Default Namespace
@@ -27667,7 +27674,7 @@ names to index the special @code{SYMTAB} array.
 The default namespace, not surprisingly, is @samp{awk}.
 All of the predefined @command{awk} and @command{gawk} variables
 are in this namespace, and thus have qualified names like
address@hidden, @code{awk.NF}, and so on.
address@hidden::ARGC}, @code{awk::NF}, and so on.
 
 Furthermore, even when you have changed the namespace for your
 current source file (@pxref{Changing The Namespace}), @command{gawk}
@@ -27675,7 +27682,7 @@ forces unqualified identifiers whose names are all 
uppercase letters
 to be in the @samp{awk} namespace.  This makes it possible for you to easily
 reference @command{gawk}'s global variables from different namespaces.
 
-It is a syntactic error to use qualified names for function parameter names.
+It is a syntax error to use qualified names for function parameter names.
 
 @node Changing The Namespace
 @section Changing The Namespace
@@ -27690,12 +27697,12 @@ BEGIN @{ @dots{} @}
 @dots{}
 @end example
 
-After this directive, all simple non-uppercase identifiers are
-placed into the @samp{passwd} namespace.
+After this directive, all simple non-completely-uppercase identifiers are
+placed into the @code{passwd} namespace.
 
 You can change the namespace multiple times within a single
 source file, although this is likely to become confusing if you
-do it a lot.
+do it too much.
 
 @quotation NOTE
 The namespace concept is one handled while your program is
@@ -27704,8 +27711,9 @@ being parsed by @command{gawk}. There is no concept of a
 the distinction.
 @end quotation
 
-Each source file for @option{-i} and @option{-f} starts out with an implicit
address@hidden@@namespace "awk"}.
+Each source file for @option{-i} and @option{-f}
+(FIXME: pxref)
+starts out with an implicit @samp{@@namespace "awk"}.
 
 Similarly, each chunk of command-line code with @option{-e} has such an 
implicit
 statement.
@@ -27713,6 +27721,36 @@ statement.
 The use of @samp{@@namespace} has no influence upon the order of execution
 of @code{BEGIN}, @code{BEGINFILE}, @code{END}, and @code{ENDFILE} rules.
 
address@hidden Internal Name Management
address@hidden Internal Name Management
+
+For backwards compatibility, all identifiers in the @samp{awk}
+namespace are stored internally as unadorned identifiers.  This
+is mainly relevant when using such identifiers as indices for
address@hidden, @code{FUNCTAB}, and @code{PROCINFO["identifiers"]}
+(FIXME: xref),
+and for use in indirect function calls
+(FIXME: xref).
+
+In program code, to refer to variables and functions in the @samp{awk} 
namespace from
+another namespace, you must still use the @samp{awk::} prefix. For example:
+
address@hidden
+@@namespace "awk"          # the default
+
+BEGIN @{
+    Title = "My Report"   # fully qualified name is awk::Title
address@hidden
+
+@@namespace "report"       # now in "report" namespace
+
+function compute()       # this is really report::compute()
address@hidden
+    print awk::Title      # but would be SYMTAB["Title"]
+    @dots{}
address@hidden
address@hidden example
+
 @node Namespace Example
 @section Namespace Example
 
@@ -27797,22 +27835,22 @@ function Endpwent()
 
 function getpwnam(name)
 @{
-    return passwd.Getpwnam(name)
+    return passwd::Getpwnam(name)
 @}
 
 function getpwuid(uid)
 @{
-    return passwd.Getpwuid(uid)
+    return passwd::Getpwuid(uid)
 @}
 
 function getpwent()
 @{
-    return passwd.Getpwent()
+    return passwd::Getpwent()
 @}
 
 function endpwent()
 @{
-    passwd.Endpwent()
+    passwd::Endpwent()
 @}
 @end example
 
@@ -27822,16 +27860,14 @@ function endpwent()
 Other notes for reviewers:
 
 @table @asis
address@hidden @code{SYMTAB}, @code{FUNCTAB} and @code{PROCINFO["identifiers"]}
-The subscripts are all fully qualified names.
-
 @item Profiler:
 When profiling, we can add an @code{Op_Namespace} to the start of
-each rule.  If it has changed since the previous one, output an
+each rule and function definition.  If this is different than the previous
+one, output an
 @samp{@@namespace} statement.  For each identifier, if it starts
 with the current namespace, output only the simple part.
-For all @samp{awk.XXX} if @samp{XXX} is all uppercase, strip
-off the @samp{awk} part.
+For all @samp{awk::XXX} if @samp{XXX} is all uppercase, strip
+off the @samp{awk::} part.
 
 @item Debugger:
 Simply print fully qualified names all the time. Maybe allow a
@@ -27839,32 +27875,6 @@ Simply print fully qualified names all the time. Maybe 
allow a
 namespace and it will use that to create fully qualified names?
 Have to be careful about all uppercase names though.
 
address@hidden How does this affect indirect calls?
-The current namespace is a parse time thing, not a dynamic
-thing, so for indirect calls to work, use something like:
-
address@hidden
-@@namespace "foo"
-
-function bar() @{ @dots{}  @}
-
address@hidden
-    @dots{}
-    x = "foo.bar"
-    @dots{}
-    @@x()
address@hidden
address@hidden example
-
address@hidden
-This is particularly true if @code{x} is passed as a ``function pointer''
-to another function in another namespace for that function to call
-through it.
-
-For backwards compatibility, if @code{x} contains an unadorned
-identifier, @command{gawk} forces it to be in the @samp{awk}
-namespace.
-
 @item How does this affect @code{@@include}?
 Basically @code{@@include} should push and pop the namespace. Each 
@code{@@include}
 saves the current namespace and starts over with namespace @samp{awk} until
@@ -27876,6 +27886,11 @@ argument and add new macros with @samp{_ns} or some 
such in the name that
 pass the namespace of the extension.  This preserves backwards
 compatibility at the source level while providing access to namespaces
 as needed.
+
+Actually, since we've decided that @code{awk} namespace variables and
+function are stored unadorned, the current macros that pass @code{""}
+would continue to work. Internally, we need to recognize @code{"awk"} and
address@hidden fully qualify the name before storing it in the symbol table.
 @end table
 
 @node Advanced Features
@@ -32417,7 +32432,7 @@ word sizes. See
 @cindex MPFR, checking availability of
 @cindex checking for MPFR
 Occasionally, you might like to be able to check if @command{gawk}
-was invoked with the @option{-M} option, enabling aribtrary-precision
+was invoked with the @option{-M} option, enabling arbitrary-precision
 arithmetic.  You can do so with the following function, contributed
 by Andrew Schorr:
 
diff --git a/doc/gawktexi.in b/doc/gawktexi.in
index 834923a..192fc0e 100644
--- a/doc/gawktexi.in
+++ b/doc/gawktexi.in
@@ -26631,6 +26631,7 @@ This @value{CHAPTER} describes a feature that is 
specific to @command{gawk}.
 * Qualified Names::             How to qualify names with a namespace.
 * Default Namespace::           The default namespace.
 * Changing The Namespace::      How to change the namespace.
+* Internal Name Management::    How names are stored internally.
 * Namespace Example::           An example of code using a namespace.
 * Namespace Misc::              Namespace notes for developers.
 @end menu
@@ -26640,8 +26641,8 @@ This @value{CHAPTER} describes a feature that is 
specific to @command{gawk}.
 
 In standard @command{awk}, there is a single, global, @dfn{namespace}.
 This means that @emph{all} function names and global variable names must
-be unique.  Two different @command{awk} source files cannot both define
-a function named @code{sort()}, for example.
+be unique. For example, two different @command{awk} source files cannot both 
define
+a function named @code{min()}.
 
 This situation is okay when programs are small, say a few hundred lines,
 or even a few thousand, but it prevents the development of reusable
@@ -26651,8 +26652,8 @@ independently-developed library files to accidentally 
step on each other's
 (@pxref{Library Names}).
 
 Most other programming languages solve this issue by providing some kind
-of namespace control: a way to say ``this function is in namespace @var{X},
-and that function is in namespace @var{Y}.''  (Of course, there is then
+of namespace control: a way to say ``this function is in namespace @var{xxx},
+and that function is in namespace @var{yyy}.''  (Of course, there is then
 still a single namespace for the namespaces, but the hope is that there
 are much fewer namespaces in use by any given program, and thus much
 less chance for collisions.)
@@ -26665,15 +26666,21 @@ namespaces.
 @section Qualified Names
 
 A @dfn{qualified name} is an identifier that includes a namespace
-name.  For example, one might have a function named @code{posix.getpid()}.
-Here, the namespace is @samp{posix} and the function name within the
-namespace is @samp{getpid()}.  The namespace and variable or function
-name are separated by a period.  Only one period is allowed in
+name and the namespace separator, @code{::}.  For example, one might have a 
function named @code{posix::getpid()}.
+Here, the namespace is @code{posix} and the function name within the
+namespace is @code{getpid()}.  The namespace and variable or function
+name are separated by a double-colon.  Only one such separator is allowed in
 a qualified name.
 
address@hidden  NOTE
+Unlike C++, the @code{::} is @emph{not} an operator.  No spaces are allowed 
between
+the namespace name, the @code{::}, and the rest of the name.
address@hidden quotation
+
 You must use fully qualified names from one namespace to access variables
-in another.  This is especially important when using variable
-names to index the special @code{SYMTAB} array.
+and functions in another.  This is especially important when using variable
+names to index the special @code{SYMTAB} array, and when making indirect 
function calls.
address@hidden:} and xref.
 
 @node Default Namespace
 @section The Default Namespace
@@ -26681,7 +26688,7 @@ names to index the special @code{SYMTAB} array.
 The default namespace, not surprisingly, is @samp{awk}.
 All of the predefined @command{awk} and @command{gawk} variables
 are in this namespace, and thus have qualified names like
address@hidden, @code{awk.NF}, and so on.
address@hidden::ARGC}, @code{awk::NF}, and so on.
 
 Furthermore, even when you have changed the namespace for your
 current source file (@pxref{Changing The Namespace}), @command{gawk}
@@ -26689,7 +26696,7 @@ forces unqualified identifiers whose names are all 
uppercase letters
 to be in the @samp{awk} namespace.  This makes it possible for you to easily
 reference @command{gawk}'s global variables from different namespaces.
 
-It is a syntactic error to use qualified names for function parameter names.
+It is a syntax error to use qualified names for function parameter names.
 
 @node Changing The Namespace
 @section Changing The Namespace
@@ -26704,12 +26711,12 @@ BEGIN @{ @dots{} @}
 @dots{}
 @end example
 
-After this directive, all simple non-uppercase identifiers are
-placed into the @samp{passwd} namespace.
+After this directive, all simple non-completely-uppercase identifiers are
+placed into the @code{passwd} namespace.
 
 You can change the namespace multiple times within a single
 source file, although this is likely to become confusing if you
-do it a lot.
+do it too much.
 
 @quotation NOTE
 The namespace concept is one handled while your program is
@@ -26718,8 +26725,9 @@ being parsed by @command{gawk}. There is no concept of a
 the distinction.
 @end quotation
 
-Each source file for @option{-i} and @option{-f} starts out with an implicit
address@hidden@@namespace "awk"}.
+Each source file for @option{-i} and @option{-f}
+(FIXME: pxref)
+starts out with an implicit @samp{@@namespace "awk"}.
 
 Similarly, each chunk of command-line code with @option{-e} has such an 
implicit
 statement.
@@ -26727,6 +26735,36 @@ statement.
 The use of @samp{@@namespace} has no influence upon the order of execution
 of @code{BEGIN}, @code{BEGINFILE}, @code{END}, and @code{ENDFILE} rules.
 
address@hidden Internal Name Management
address@hidden Internal Name Management
+
+For backwards compatibility, all identifiers in the @samp{awk}
+namespace are stored internally as unadorned identifiers.  This
+is mainly relevant when using such identifiers as indices for
address@hidden, @code{FUNCTAB}, and @code{PROCINFO["identifiers"]}
+(FIXME: xref),
+and for use in indirect function calls
+(FIXME: xref).
+
+In program code, to refer to variables and functions in the @samp{awk} 
namespace from
+another namespace, you must still use the @samp{awk::} prefix. For example:
+
address@hidden
+@@namespace "awk"          # the default
+
+BEGIN @{
+    Title = "My Report"   # fully qualified name is awk::Title
address@hidden
+
+@@namespace "report"       # now in "report" namespace
+
+function compute()       # this is really report::compute()
address@hidden
+    print awk::Title      # but would be SYMTAB["Title"]
+    @dots{}
address@hidden
address@hidden example
+
 @node Namespace Example
 @section Namespace Example
 
@@ -26811,22 +26849,22 @@ function Endpwent()
 
 function getpwnam(name)
 @{
-    return passwd.Getpwnam(name)
+    return passwd::Getpwnam(name)
 @}
 
 function getpwuid(uid)
 @{
-    return passwd.Getpwuid(uid)
+    return passwd::Getpwuid(uid)
 @}
 
 function getpwent()
 @{
-    return passwd.Getpwent()
+    return passwd::Getpwent()
 @}
 
 function endpwent()
 @{
-    passwd.Endpwent()
+    passwd::Endpwent()
 @}
 @end example
 
@@ -26836,16 +26874,14 @@ function endpwent()
 Other notes for reviewers:
 
 @table @asis
address@hidden @code{SYMTAB}, @code{FUNCTAB} and @code{PROCINFO["identifiers"]}
-The subscripts are all fully qualified names.
-
 @item Profiler:
 When profiling, we can add an @code{Op_Namespace} to the start of
-each rule.  If it has changed since the previous one, output an
+each rule and function definition.  If this is different than the previous
+one, output an
 @samp{@@namespace} statement.  For each identifier, if it starts
 with the current namespace, output only the simple part.
-For all @samp{awk.XXX} if @samp{XXX} is all uppercase, strip
-off the @samp{awk} part.
+For all @samp{awk::XXX} if @samp{XXX} is all uppercase, strip
+off the @samp{awk::} part.
 
 @item Debugger:
 Simply print fully qualified names all the time. Maybe allow a
@@ -26853,32 +26889,6 @@ Simply print fully qualified names all the time. Maybe 
allow a
 namespace and it will use that to create fully qualified names?
 Have to be careful about all uppercase names though.
 
address@hidden How does this affect indirect calls?
-The current namespace is a parse time thing, not a dynamic
-thing, so for indirect calls to work, use something like:
-
address@hidden
-@@namespace "foo"
-
-function bar() @{ @dots{}  @}
-
address@hidden
-    @dots{}
-    x = "foo.bar"
-    @dots{}
-    @@x()
address@hidden
address@hidden example
-
address@hidden
-This is particularly true if @code{x} is passed as a ``function pointer''
-to another function in another namespace for that function to call
-through it.
-
-For backwards compatibility, if @code{x} contains an unadorned
-identifier, @command{gawk} forces it to be in the @samp{awk}
-namespace.
-
 @item How does this affect @code{@@include}?
 Basically @code{@@include} should push and pop the namespace. Each 
@code{@@include}
 saves the current namespace and starts over with namespace @samp{awk} until
@@ -26890,6 +26900,11 @@ argument and add new macros with @samp{_ns} or some 
such in the name that
 pass the namespace of the extension.  This preserves backwards
 compatibility at the source level while providing access to namespaces
 as needed.
+
+Actually, since we've decided that @code{awk} namespace variables and
+function are stored unadorned, the current macros that pass @code{""}
+would continue to work. Internally, we need to recognize @code{"awk"} and
address@hidden fully qualify the name before storing it in the symbol table.
 @end table
 
 @node Advanced Features

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog       |   6 +
 awkgram.c       | 823 +++++++++++++++++++++++++++++---------------------------
 awkgram.y       |  41 ++-
 doc/ChangeLog   |   7 +-
 doc/gawk.info   | 592 ++++++++++++++++++++--------------------
 doc/gawk.texi   | 123 +++++----
 doc/gawktexi.in | 121 +++++----
 7 files changed, 926 insertions(+), 787 deletions(-)


hooks/post-receive
-- 
gawk



reply via email to

[Prev in Thread] Current Thread [Next in Thread]