gawk-diffs
[Top][All Lists]
Advanced

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

[gawk-diffs] [SCM] gawk branch, symtab, created. b9a82851866f84ca306a280


From: Arnold Robbins
Subject: [gawk-diffs] [SCM] gawk branch, symtab, created. b9a82851866f84ca306a2802b4ca50089a2fe683
Date: Tue, 25 Sep 2012 11:01:40 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gawk".

The branch, symtab has been created
        at  b9a82851866f84ca306a2802b4ca50089a2fe683 (commit)

- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=b9a82851866f84ca306a2802b4ca50089a2fe683

commit b9a82851866f84ca306a2802b4ca50089a2fe683
Author: Arnold D. Robbins <address@hidden>
Date:   Tue Sep 25 12:58:05 2012 +0200

    First cut at SYMTAB and FUNCTAB.

diff --git a/ChangeLog b/ChangeLog
index bee035b..4e1eb4d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2012-09-25         Arnold D. Robbins     <address@hidden>
+
+       First cut at SYMTAB and FUNCTAB. This does the following:
+       - Change symbol table handling to use gawk arrays.
+       - Store symbols in SYMTAB array and allow indirect access
+         through SYMTAB to variables, both getting and setting.
+       - List function names in FUNCTAB indexes; Values cannot be
+         used at the moment.
+       - No documentation yet.
+
+       * awk.h (Node_hashnode, hnext, hname, hlength, hcode, hvalue):
+       Removed, not needed any more.
+       (init_symbol_table, symbol_table): Add declarations.
+       * awkgram.y: Disallow delete on SYMTAB, fix warning for tawk
+       extension if traditional.
+       * eval.c (nodetypes): Remove Node_hashnode element.
+       * interpret.h (Op_subscript, Op_store_sub): Handle SYMTAB and go
+       through to the actual value.
+       * main.c (main): Init Nnull_string earlier. Add call to
+       init_symbol_table().
+       * profile.c (pp_str, pp_len): Change definitions.
+       (pp_next): New macro.
+       (pp_push, pp_pop): Adjust uses.
+       * symbol.c (variables): Removed.
+       (global_table, param_table, func_table, symbol_table,
+       installing_specials): New variables.
+       (lookup, make_params, install_params, remove_params, remove_symbol,
+       make_symbol, install, get_symbols, release_all_vars, append_symbol,
+       release_symbols, load_symbols): Rework logic considerably.
+       (init_symbol_table): New function.
+
 2012-09-23         Arnold D. Robbins     <address@hidden>
 
        `delete array' and `nextfile' are now in POSIX.
diff --git a/awk.h b/awk.h
index bafb4b9..7f64ce4 100644
--- a/awk.h
+++ b/awk.h
@@ -314,7 +314,6 @@ typedef enum nodevals {
        Node_func,              /* lnode is param. list, rnode is body */
        Node_ext_func,          /* extension function, code_ptr is builtin code 
*/
 
-       Node_hashnode,          /* an identifier in the symbol table */
        Node_array_ref,         /* array passed by ref as parameter */
        Node_array_tree,        /* Hashed array tree (HAT) */
        Node_array_leaf,        /* Linear 1-D array */
@@ -462,17 +461,11 @@ typedef struct exp_node {
 #define nextp  sub.nodep.l.lptr
 #define rnode  sub.nodep.r.rptr
 
-/* Node_hashnode, Node_param_list */
-#define hnext  sub.nodep.r.rptr
-#define hname  vname
-#define hlength        sub.nodep.reserved
-#define hcode  sub.nodep.cnt
-#define hvalue sub.nodep.x.extra
+/* Node_param_list */
+#define param      vname
 
 /* Node_param_list, Node_func */
 #define param_cnt  sub.nodep.l.ll
-/* Node_param_list */
-#define param      vname
 
 /* Node_func */
 #define fparms         sub.nodep.rn
@@ -1373,15 +1366,15 @@ if (--val) \
 /* array.c */
 typedef enum sort_context { SORTED_IN = 1, ASORT, ASORTI } SORT_CTXT;
 enum assoc_list_flags {
-AINDEX = 0x01,         /* list of indices */ 
-AVALUE = 0x02,         /* list of values */
-AINUM = 0x04,          /* numeric index */
-AISTR = 0x08,          /* string index */
-AVNUM = 0x10,          /* numeric scalar value */
-AVSTR = 0x20,          /* string scalar value */
-AASC = 0x40,           /* ascending order */
-ADESC = 0x80,          /* descending order */
-ADELETE = 0x100,       /* need a single index; for use in do_delete_loop */
+       AINDEX = 0x01,          /* list of indices */ 
+       AVALUE = 0x02,          /* list of values */
+       AINUM = 0x04,           /* numeric index */
+       AISTR = 0x08,           /* string index */
+       AVNUM = 0x10,           /* numeric scalar value */
+       AVSTR = 0x20,           /* string scalar value */
+       AASC = 0x40,            /* ascending order */
+       ADESC = 0x80,           /* descending order */
+       ADELETE = 0x100,        /* need a single index; for use in 
do_delete_loop */
 };
 
 extern NODE *make_array(void);
@@ -1671,6 +1664,8 @@ extern int get_numbase(const char *str, bool use_locale);
 
 /* symbol.c */
 extern void load_symbols();
+extern void init_symbol_table();
+extern NODE *symbol_table;
 extern NODE *install_symbol(char *name, NODETYPE type);
 extern NODE *remove_symbol(NODE *r);
 extern void destroy_symbol(NODE *r);
diff --git a/awkgram.c b/awkgram.c
index d83aa03..0c51a28 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -733,19 +733,19 @@ static const yytype_uint16 yyrline[] =
      372,   373,   377,   396,   395,   429,   431,   436,   437,   450,
      455,   456,   460,   462,   464,   471,   561,   603,   645,   758,
      765,   772,   782,   791,   800,   809,   820,   836,   835,   859,
-     871,   871,   969,   969,   995,  1018,  1024,  1025,  1031,  1032,
-    1039,  1044,  1056,  1070,  1072,  1080,  1085,  1087,  1095,  1097,
-    1106,  1107,  1115,  1120,  1120,  1131,  1135,  1143,  1144,  1147,
-    1149,  1154,  1155,  1164,  1165,  1170,  1175,  1181,  1183,  1185,
-    1192,  1193,  1199,  1200,  1205,  1207,  1212,  1214,  1216,  1218,
-    1224,  1231,  1233,  1235,  1251,  1261,  1268,  1270,  1275,  1277,
-    1279,  1287,  1289,  1294,  1296,  1301,  1303,  1305,  1355,  1357,
-    1359,  1361,  1363,  1365,  1367,  1369,  1392,  1397,  1402,  1427,
-    1433,  1435,  1437,  1439,  1441,  1443,  1448,  1452,  1484,  1486,
-    1492,  1498,  1511,  1512,  1513,  1518,  1523,  1527,  1531,  1546,
-    1559,  1564,  1600,  1618,  1619,  1625,  1626,  1631,  1633,  1640,
-    1657,  1674,  1676,  1683,  1688,  1696,  1706,  1718,  1727,  1731,
-    1735,  1739,  1743,  1747,  1750,  1752,  1756,  1760,  1764
+     871,   871,   969,   969,   998,  1024,  1030,  1031,  1037,  1038,
+    1045,  1050,  1062,  1076,  1078,  1086,  1091,  1093,  1101,  1103,
+    1112,  1113,  1121,  1126,  1126,  1137,  1141,  1149,  1150,  1153,
+    1155,  1160,  1161,  1170,  1171,  1176,  1181,  1187,  1189,  1191,
+    1198,  1199,  1205,  1206,  1211,  1213,  1218,  1220,  1222,  1224,
+    1230,  1237,  1239,  1241,  1257,  1267,  1274,  1276,  1281,  1283,
+    1285,  1293,  1295,  1300,  1302,  1307,  1309,  1311,  1361,  1363,
+    1365,  1367,  1369,  1371,  1373,  1375,  1398,  1403,  1408,  1433,
+    1439,  1441,  1443,  1445,  1447,  1449,  1454,  1458,  1490,  1492,
+    1498,  1504,  1517,  1518,  1519,  1524,  1529,  1533,  1537,  1552,
+    1565,  1570,  1606,  1624,  1625,  1631,  1632,  1637,  1639,  1646,
+    1663,  1680,  1682,  1689,  1694,  1702,  1712,  1724,  1733,  1737,
+    1741,  1745,  1749,  1753,  1756,  1758,  1762,  1766,  1770
 };
 #endif
 
@@ -2990,6 +2990,9 @@ regular_print:
                (yyvsp[(2) - (4)])->opcode = Op_push_array;
                (yyvsp[(2) - (4)])->memory = variable((yyvsp[(2) - 
(4)])->source_line, arr, Node_var_new);
 
+               if ((yyvsp[(2) - (4)])->memory == symbol_table)
+                       fatal(_("`delete' is not allowed with SYMTAB"));
+
                if ((yyvsp[(4) - (4)]) == NULL) {
                        /*
                         * As of September 2012, POSIX has added support
@@ -3013,7 +3016,7 @@ regular_print:
 
   case 64:
 /* Line 1787 of yacc.c  */
-#line 1000 "awkgram.y"
+#line 1003 "awkgram.y"
     {
                static bool warned = false;
                char *arr = (yyvsp[(3) - (4)])->lextok;
@@ -3031,36 +3034,39 @@ regular_print:
                (yyvsp[(3) - (4)])->opcode = Op_push_array;
                (yyvsp[(1) - (4)])->expr_count = 0;
                (yyval) = list_append(list_create((yyvsp[(3) - (4)])), 
(yyvsp[(1) - (4)]));
+
+               if ((yyvsp[(3) - (4)])->memory == symbol_table)
+                       fatal(_("`delete' is not allowed with SYMTAB"));
          }
     break;
 
   case 65:
 /* Line 1787 of yacc.c  */
-#line 1019 "awkgram.y"
+#line 1025 "awkgram.y"
     {  (yyval) = optimize_assignment((yyvsp[(1) - (1)])); }
     break;
 
   case 66:
 /* Line 1787 of yacc.c  */
-#line 1024 "awkgram.y"
+#line 1030 "awkgram.y"
     { (yyval) = NULL; }
     break;
 
   case 67:
 /* Line 1787 of yacc.c  */
-#line 1026 "awkgram.y"
+#line 1032 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 68:
 /* Line 1787 of yacc.c  */
-#line 1031 "awkgram.y"
+#line 1037 "awkgram.y"
     { (yyval) = NULL; }
     break;
 
   case 69:
 /* Line 1787 of yacc.c  */
-#line 1033 "awkgram.y"
+#line 1039 "awkgram.y"
     {
                if ((yyvsp[(1) - (2)]) == NULL)
                        (yyval) = list_create((yyvsp[(2) - (2)]));
@@ -3071,13 +3077,13 @@ regular_print:
 
   case 70:
 /* Line 1787 of yacc.c  */
-#line 1040 "awkgram.y"
+#line 1046 "awkgram.y"
     { (yyval) = NULL; }
     break;
 
   case 71:
 /* Line 1787 of yacc.c  */
-#line 1045 "awkgram.y"
+#line 1051 "awkgram.y"
     {
                INSTRUCTION *casestmt = (yyvsp[(5) - (5)]);
                if ((yyvsp[(5) - (5)]) == NULL)
@@ -3093,7 +3099,7 @@ regular_print:
 
   case 72:
 /* Line 1787 of yacc.c  */
-#line 1057 "awkgram.y"
+#line 1063 "awkgram.y"
     {
                INSTRUCTION *casestmt = (yyvsp[(4) - (4)]);
                if ((yyvsp[(4) - (4)]) == NULL)
@@ -3108,13 +3114,13 @@ regular_print:
 
   case 73:
 /* Line 1787 of yacc.c  */
-#line 1071 "awkgram.y"
+#line 1077 "awkgram.y"
     {  (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 74:
 /* Line 1787 of yacc.c  */
-#line 1073 "awkgram.y"
+#line 1079 "awkgram.y"
     { 
                NODE *n = (yyvsp[(2) - (2)])->memory;
                (void) force_number(n);
@@ -3126,7 +3132,7 @@ regular_print:
 
   case 75:
 /* Line 1787 of yacc.c  */
-#line 1081 "awkgram.y"
+#line 1087 "awkgram.y"
     {
                bcfree((yyvsp[(1) - (2)]));
                (yyval) = (yyvsp[(2) - (2)]);
@@ -3135,13 +3141,13 @@ regular_print:
 
   case 76:
 /* Line 1787 of yacc.c  */
-#line 1086 "awkgram.y"
+#line 1092 "awkgram.y"
     {  (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 77:
 /* Line 1787 of yacc.c  */
-#line 1088 "awkgram.y"
+#line 1094 "awkgram.y"
     {
                (yyvsp[(1) - (1)])->opcode = Op_push_re;
                (yyval) = (yyvsp[(1) - (1)]);
@@ -3150,19 +3156,19 @@ regular_print:
 
   case 78:
 /* Line 1787 of yacc.c  */
-#line 1096 "awkgram.y"
+#line 1102 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 79:
 /* Line 1787 of yacc.c  */
-#line 1098 "awkgram.y"
+#line 1104 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 81:
 /* Line 1787 of yacc.c  */
-#line 1108 "awkgram.y"
+#line 1114 "awkgram.y"
     {
                (yyval) = (yyvsp[(2) - (3)]);
          }
@@ -3170,7 +3176,7 @@ regular_print:
 
   case 82:
 /* Line 1787 of yacc.c  */
-#line 1115 "awkgram.y"
+#line 1121 "awkgram.y"
     {
                in_print = false;
                in_parens = 0;
@@ -3180,13 +3186,13 @@ regular_print:
 
   case 83:
 /* Line 1787 of yacc.c  */
-#line 1120 "awkgram.y"
+#line 1126 "awkgram.y"
     { in_print = false; in_parens = 0; }
     break;
 
   case 84:
 /* Line 1787 of yacc.c  */
-#line 1121 "awkgram.y"
+#line 1127 "awkgram.y"
     {
                if ((yyvsp[(1) - (3)])->redir_type == redirect_twoway
                        && (yyvsp[(3) - (3)])->lasti->opcode == 
Op_K_getline_redir
@@ -3198,7 +3204,7 @@ regular_print:
 
   case 85:
 /* Line 1787 of yacc.c  */
-#line 1132 "awkgram.y"
+#line 1138 "awkgram.y"
     {
                (yyval) = mk_condition((yyvsp[(3) - (6)]), (yyvsp[(1) - (6)]), 
(yyvsp[(6) - (6)]), NULL, NULL);
          }
@@ -3206,7 +3212,7 @@ regular_print:
 
   case 86:
 /* Line 1787 of yacc.c  */
-#line 1137 "awkgram.y"
+#line 1143 "awkgram.y"
     {
                (yyval) = mk_condition((yyvsp[(3) - (9)]), (yyvsp[(1) - (9)]), 
(yyvsp[(6) - (9)]), (yyvsp[(7) - (9)]), (yyvsp[(9) - (9)]));
          }
@@ -3214,13 +3220,13 @@ regular_print:
 
   case 91:
 /* Line 1787 of yacc.c  */
-#line 1154 "awkgram.y"
+#line 1160 "awkgram.y"
     { (yyval) = NULL; }
     break;
 
   case 92:
 /* Line 1787 of yacc.c  */
-#line 1156 "awkgram.y"
+#line 1162 "awkgram.y"
     {
                bcfree((yyvsp[(1) - (2)]));
                (yyval) = (yyvsp[(2) - (2)]);
@@ -3229,19 +3235,19 @@ regular_print:
 
   case 93:
 /* Line 1787 of yacc.c  */
-#line 1164 "awkgram.y"
+#line 1170 "awkgram.y"
     { (yyval) = NULL; }
     break;
 
   case 94:
 /* Line 1787 of yacc.c  */
-#line 1166 "awkgram.y"
+#line 1172 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]) ; }
     break;
 
   case 95:
 /* Line 1787 of yacc.c  */
-#line 1171 "awkgram.y"
+#line 1177 "awkgram.y"
     {
                (yyvsp[(1) - (1)])->param_count = 0;
                (yyval) = list_create((yyvsp[(1) - (1)]));
@@ -3250,7 +3256,7 @@ regular_print:
 
   case 96:
 /* Line 1787 of yacc.c  */
-#line 1176 "awkgram.y"
+#line 1182 "awkgram.y"
     {
                (yyvsp[(3) - (3)])->param_count =  (yyvsp[(1) - 
(3)])->lasti->param_count + 1;
                (yyval) = list_append((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]));
@@ -3260,55 +3266,55 @@ regular_print:
 
   case 97:
 /* Line 1787 of yacc.c  */
-#line 1182 "awkgram.y"
+#line 1188 "awkgram.y"
     { (yyval) = NULL; }
     break;
 
   case 98:
 /* Line 1787 of yacc.c  */
-#line 1184 "awkgram.y"
+#line 1190 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (2)]); }
     break;
 
   case 99:
 /* Line 1787 of yacc.c  */
-#line 1186 "awkgram.y"
+#line 1192 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (3)]); }
     break;
 
   case 100:
 /* Line 1787 of yacc.c  */
-#line 1192 "awkgram.y"
+#line 1198 "awkgram.y"
     { (yyval) = NULL; }
     break;
 
   case 101:
 /* Line 1787 of yacc.c  */
-#line 1194 "awkgram.y"
+#line 1200 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 102:
 /* Line 1787 of yacc.c  */
-#line 1199 "awkgram.y"
+#line 1205 "awkgram.y"
     { (yyval) = NULL; }
     break;
 
   case 103:
 /* Line 1787 of yacc.c  */
-#line 1201 "awkgram.y"
+#line 1207 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 104:
 /* Line 1787 of yacc.c  */
-#line 1206 "awkgram.y"
+#line 1212 "awkgram.y"
     {  (yyval) = mk_expression_list(NULL, (yyvsp[(1) - (1)])); }
     break;
 
   case 105:
 /* Line 1787 of yacc.c  */
-#line 1208 "awkgram.y"
+#line 1214 "awkgram.y"
     {
                (yyval) = mk_expression_list((yyvsp[(1) - (3)]), (yyvsp[(3) - 
(3)]));
                yyerrok;
@@ -3317,31 +3323,31 @@ regular_print:
 
   case 106:
 /* Line 1787 of yacc.c  */
-#line 1213 "awkgram.y"
+#line 1219 "awkgram.y"
     { (yyval) = NULL; }
     break;
 
   case 107:
 /* Line 1787 of yacc.c  */
-#line 1215 "awkgram.y"
+#line 1221 "awkgram.y"
     { (yyval) = NULL; }
     break;
 
   case 108:
 /* Line 1787 of yacc.c  */
-#line 1217 "awkgram.y"
+#line 1223 "awkgram.y"
     { (yyval) = NULL; }
     break;
 
   case 109:
 /* Line 1787 of yacc.c  */
-#line 1219 "awkgram.y"
+#line 1225 "awkgram.y"
     { (yyval) = NULL; }
     break;
 
   case 110:
 /* Line 1787 of yacc.c  */
-#line 1225 "awkgram.y"
+#line 1231 "awkgram.y"
     {
                if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == 
Op_match_rec)
                        lintwarn_ln((yyvsp[(2) - (3)])->source_line,
@@ -3352,19 +3358,19 @@ regular_print:
 
   case 111:
 /* Line 1787 of yacc.c  */
-#line 1232 "awkgram.y"
+#line 1238 "awkgram.y"
     {  (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) 
- (3)])); }
     break;
 
   case 112:
 /* Line 1787 of yacc.c  */
-#line 1234 "awkgram.y"
+#line 1240 "awkgram.y"
     {  (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) 
- (3)])); }
     break;
 
   case 113:
 /* Line 1787 of yacc.c  */
-#line 1236 "awkgram.y"
+#line 1242 "awkgram.y"
     {
                if ((yyvsp[(1) - (3)])->lasti->opcode == Op_match_rec)
                        warning_ln((yyvsp[(2) - (3)])->source_line,
@@ -3384,7 +3390,7 @@ regular_print:
 
   case 114:
 /* Line 1787 of yacc.c  */
-#line 1252 "awkgram.y"
+#line 1258 "awkgram.y"
     {
                if (do_lint_old)
                        warning_ln((yyvsp[(2) - (3)])->source_line,
@@ -3398,7 +3404,7 @@ regular_print:
 
   case 115:
 /* Line 1787 of yacc.c  */
-#line 1262 "awkgram.y"
+#line 1268 "awkgram.y"
     {
                if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == 
Op_match_rec)
                        lintwarn_ln((yyvsp[(2) - (3)])->source_line,
@@ -3409,31 +3415,31 @@ regular_print:
 
   case 116:
 /* Line 1787 of yacc.c  */
-#line 1269 "awkgram.y"
+#line 1275 "awkgram.y"
     { (yyval) = mk_condition((yyvsp[(1) - (5)]), (yyvsp[(2) - (5)]), 
(yyvsp[(3) - (5)]), (yyvsp[(4) - (5)]), (yyvsp[(5) - (5)])); }
     break;
 
   case 117:
 /* Line 1787 of yacc.c  */
-#line 1271 "awkgram.y"
+#line 1277 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 118:
 /* Line 1787 of yacc.c  */
-#line 1276 "awkgram.y"
+#line 1282 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 119:
 /* Line 1787 of yacc.c  */
-#line 1278 "awkgram.y"
+#line 1284 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 120:
 /* Line 1787 of yacc.c  */
-#line 1280 "awkgram.y"
+#line 1286 "awkgram.y"
     {  
                (yyvsp[(2) - (2)])->opcode = Op_assign_quotient;
                (yyval) = (yyvsp[(2) - (2)]);
@@ -3442,43 +3448,43 @@ regular_print:
 
   case 121:
 /* Line 1787 of yacc.c  */
-#line 1288 "awkgram.y"
+#line 1294 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 122:
 /* Line 1787 of yacc.c  */
-#line 1290 "awkgram.y"
+#line 1296 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 123:
 /* Line 1787 of yacc.c  */
-#line 1295 "awkgram.y"
+#line 1301 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 124:
 /* Line 1787 of yacc.c  */
-#line 1297 "awkgram.y"
+#line 1303 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 125:
 /* Line 1787 of yacc.c  */
-#line 1302 "awkgram.y"
+#line 1308 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 126:
 /* Line 1787 of yacc.c  */
-#line 1304 "awkgram.y"
+#line 1310 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 127:
 /* Line 1787 of yacc.c  */
-#line 1306 "awkgram.y"
+#line 1312 "awkgram.y"
     {
                int count = 2;
                bool is_simple_var = false;
@@ -3529,43 +3535,43 @@ regular_print:
 
   case 129:
 /* Line 1787 of yacc.c  */
-#line 1358 "awkgram.y"
+#line 1364 "awkgram.y"
     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - 
(3)])); }
     break;
 
   case 130:
 /* Line 1787 of yacc.c  */
-#line 1360 "awkgram.y"
+#line 1366 "awkgram.y"
     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - 
(3)])); }
     break;
 
   case 131:
 /* Line 1787 of yacc.c  */
-#line 1362 "awkgram.y"
+#line 1368 "awkgram.y"
     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - 
(3)])); }
     break;
 
   case 132:
 /* Line 1787 of yacc.c  */
-#line 1364 "awkgram.y"
+#line 1370 "awkgram.y"
     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - 
(3)])); }
     break;
 
   case 133:
 /* Line 1787 of yacc.c  */
-#line 1366 "awkgram.y"
+#line 1372 "awkgram.y"
     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - 
(3)])); }
     break;
 
   case 134:
 /* Line 1787 of yacc.c  */
-#line 1368 "awkgram.y"
+#line 1374 "awkgram.y"
     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - 
(3)])); }
     break;
 
   case 135:
 /* Line 1787 of yacc.c  */
-#line 1370 "awkgram.y"
+#line 1376 "awkgram.y"
     {
                /*
                 * In BEGINFILE/ENDFILE, allow `getline var < file'
@@ -3592,7 +3598,7 @@ regular_print:
 
   case 136:
 /* Line 1787 of yacc.c  */
-#line 1393 "awkgram.y"
+#line 1399 "awkgram.y"
     {
                (yyvsp[(2) - (2)])->opcode = Op_postincrement;
                (yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) - 
(2)]));
@@ -3601,7 +3607,7 @@ regular_print:
 
   case 137:
 /* Line 1787 of yacc.c  */
-#line 1398 "awkgram.y"
+#line 1404 "awkgram.y"
     {
                (yyvsp[(2) - (2)])->opcode = Op_postdecrement;
                (yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) - 
(2)]));
@@ -3610,7 +3616,7 @@ regular_print:
 
   case 138:
 /* Line 1787 of yacc.c  */
-#line 1403 "awkgram.y"
+#line 1409 "awkgram.y"
     {
                if (do_lint_old) {
                    warning_ln((yyvsp[(4) - (5)])->source_line,
@@ -3634,7 +3640,7 @@ regular_print:
 
   case 139:
 /* Line 1787 of yacc.c  */
-#line 1428 "awkgram.y"
+#line 1434 "awkgram.y"
     {
                  (yyval) = mk_getline((yyvsp[(3) - (4)]), (yyvsp[(4) - (4)]), 
(yyvsp[(1) - (4)]), (yyvsp[(2) - (4)])->redir_type);
                  bcfree((yyvsp[(2) - (4)]));
@@ -3643,43 +3649,43 @@ regular_print:
 
   case 140:
 /* Line 1787 of yacc.c  */
-#line 1434 "awkgram.y"
+#line 1440 "awkgram.y"
     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - 
(3)])); }
     break;
 
   case 141:
 /* Line 1787 of yacc.c  */
-#line 1436 "awkgram.y"
+#line 1442 "awkgram.y"
     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - 
(3)])); }
     break;
 
   case 142:
 /* Line 1787 of yacc.c  */
-#line 1438 "awkgram.y"
+#line 1444 "awkgram.y"
     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - 
(3)])); }
     break;
 
   case 143:
 /* Line 1787 of yacc.c  */
-#line 1440 "awkgram.y"
+#line 1446 "awkgram.y"
     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - 
(3)])); }
     break;
 
   case 144:
 /* Line 1787 of yacc.c  */
-#line 1442 "awkgram.y"
+#line 1448 "awkgram.y"
     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - 
(3)])); }
     break;
 
   case 145:
 /* Line 1787 of yacc.c  */
-#line 1444 "awkgram.y"
+#line 1450 "awkgram.y"
     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - 
(3)])); }
     break;
 
   case 146:
 /* Line 1787 of yacc.c  */
-#line 1449 "awkgram.y"
+#line 1455 "awkgram.y"
     {
                (yyval) = list_create((yyvsp[(1) - (1)]));
          }
@@ -3687,7 +3693,7 @@ regular_print:
 
   case 147:
 /* Line 1787 of yacc.c  */
-#line 1453 "awkgram.y"
+#line 1459 "awkgram.y"
     {
                if ((yyvsp[(2) - (2)])->opcode == Op_match_rec) {
                        (yyvsp[(2) - (2)])->opcode = Op_nomatch;
@@ -3723,13 +3729,13 @@ regular_print:
 
   case 148:
 /* Line 1787 of yacc.c  */
-#line 1485 "awkgram.y"
+#line 1491 "awkgram.y"
     { (yyval) = (yyvsp[(2) - (3)]); }
     break;
 
   case 149:
 /* Line 1787 of yacc.c  */
-#line 1487 "awkgram.y"
+#line 1493 "awkgram.y"
     {
                (yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
                if ((yyval) == NULL)
@@ -3739,7 +3745,7 @@ regular_print:
 
   case 150:
 /* Line 1787 of yacc.c  */
-#line 1493 "awkgram.y"
+#line 1499 "awkgram.y"
     {
                (yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
                if ((yyval) == NULL)
@@ -3749,7 +3755,7 @@ regular_print:
 
   case 151:
 /* Line 1787 of yacc.c  */
-#line 1499 "awkgram.y"
+#line 1505 "awkgram.y"
     {
                static bool warned = false;
 
@@ -3766,7 +3772,7 @@ regular_print:
 
   case 154:
 /* Line 1787 of yacc.c  */
-#line 1514 "awkgram.y"
+#line 1520 "awkgram.y"
     {
                (yyvsp[(1) - (2)])->opcode = Op_preincrement;
                (yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) - 
(2)]));
@@ -3775,7 +3781,7 @@ regular_print:
 
   case 155:
 /* Line 1787 of yacc.c  */
-#line 1519 "awkgram.y"
+#line 1525 "awkgram.y"
     {
                (yyvsp[(1) - (2)])->opcode = Op_predecrement;
                (yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) - 
(2)]));
@@ -3784,7 +3790,7 @@ regular_print:
 
   case 156:
 /* Line 1787 of yacc.c  */
-#line 1524 "awkgram.y"
+#line 1530 "awkgram.y"
     {
                (yyval) = list_create((yyvsp[(1) - (1)]));
          }
@@ -3792,7 +3798,7 @@ regular_print:
 
   case 157:
 /* Line 1787 of yacc.c  */
-#line 1528 "awkgram.y"
+#line 1534 "awkgram.y"
     {
                (yyval) = list_create((yyvsp[(1) - (1)]));
          }
@@ -3800,7 +3806,7 @@ regular_print:
 
   case 158:
 /* Line 1787 of yacc.c  */
-#line 1532 "awkgram.y"
+#line 1538 "awkgram.y"
     {
                if ((yyvsp[(2) - (2)])->lasti->opcode == Op_push_i
                        && ((yyvsp[(2) - (2)])->lasti->memory->flags & 
(STRCUR|STRING)) == 0
@@ -3819,7 +3825,7 @@ regular_print:
 
   case 159:
 /* Line 1787 of yacc.c  */
-#line 1547 "awkgram.y"
+#line 1553 "awkgram.y"
     {
            /*
             * was: $$ = $2
@@ -3833,7 +3839,7 @@ regular_print:
 
   case 160:
 /* Line 1787 of yacc.c  */
-#line 1560 "awkgram.y"
+#line 1566 "awkgram.y"
     {
                func_use((yyvsp[(1) - (1)])->lasti->func_name, FUNC_USE);
                (yyval) = (yyvsp[(1) - (1)]);
@@ -3842,7 +3848,7 @@ regular_print:
 
   case 161:
 /* Line 1787 of yacc.c  */
-#line 1565 "awkgram.y"
+#line 1571 "awkgram.y"
     {
                /* indirect function call */
                INSTRUCTION *f, *t;
@@ -3879,7 +3885,7 @@ regular_print:
 
   case 162:
 /* Line 1787 of yacc.c  */
-#line 1601 "awkgram.y"
+#line 1607 "awkgram.y"
     {
                param_sanity((yyvsp[(3) - (4)]));
                (yyvsp[(1) - (4)])->opcode = Op_func_call;
@@ -3897,37 +3903,37 @@ regular_print:
 
   case 163:
 /* Line 1787 of yacc.c  */
-#line 1618 "awkgram.y"
+#line 1624 "awkgram.y"
     { (yyval) = NULL; }
     break;
 
   case 164:
 /* Line 1787 of yacc.c  */
-#line 1620 "awkgram.y"
+#line 1626 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 165:
 /* Line 1787 of yacc.c  */
-#line 1625 "awkgram.y"
+#line 1631 "awkgram.y"
     { (yyval) = NULL; }
     break;
 
   case 166:
 /* Line 1787 of yacc.c  */
-#line 1627 "awkgram.y"
+#line 1633 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (2)]); }
     break;
 
   case 167:
 /* Line 1787 of yacc.c  */
-#line 1632 "awkgram.y"
+#line 1638 "awkgram.y"
     {  (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 168:
 /* Line 1787 of yacc.c  */
-#line 1634 "awkgram.y"
+#line 1640 "awkgram.y"
     {
                (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
          }
@@ -3935,7 +3941,7 @@ regular_print:
 
   case 169:
 /* Line 1787 of yacc.c  */
-#line 1641 "awkgram.y"
+#line 1647 "awkgram.y"
     {
                INSTRUCTION *ip = (yyvsp[(1) - (1)])->lasti; 
                int count = ip->sub_count;      /* # of SUBSEP-seperated 
expressions */
@@ -3953,7 +3959,7 @@ regular_print:
 
   case 170:
 /* Line 1787 of yacc.c  */
-#line 1658 "awkgram.y"
+#line 1664 "awkgram.y"
     {
                INSTRUCTION *t = (yyvsp[(2) - (3)]);
                if ((yyvsp[(2) - (3)]) == NULL) {
@@ -3971,13 +3977,13 @@ regular_print:
 
   case 171:
 /* Line 1787 of yacc.c  */
-#line 1675 "awkgram.y"
+#line 1681 "awkgram.y"
     {  (yyval) = (yyvsp[(1) - (1)]); }
     break;
 
   case 172:
 /* Line 1787 of yacc.c  */
-#line 1677 "awkgram.y"
+#line 1683 "awkgram.y"
     {
                (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
          }
@@ -3985,13 +3991,13 @@ regular_print:
 
   case 173:
 /* Line 1787 of yacc.c  */
-#line 1684 "awkgram.y"
+#line 1690 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (2)]); }
     break;
 
   case 174:
 /* Line 1787 of yacc.c  */
-#line 1689 "awkgram.y"
+#line 1695 "awkgram.y"
     {
                char *var_name = (yyvsp[(1) - (1)])->lextok;
 
@@ -4003,7 +4009,7 @@ regular_print:
 
   case 175:
 /* Line 1787 of yacc.c  */
-#line 1697 "awkgram.y"
+#line 1703 "awkgram.y"
     {
                char *arr = (yyvsp[(1) - (2)])->lextok;
                (yyvsp[(1) - (2)])->memory = variable((yyvsp[(1) - 
(2)])->source_line, arr, Node_var_new);
@@ -4014,7 +4020,7 @@ regular_print:
 
   case 176:
 /* Line 1787 of yacc.c  */
-#line 1707 "awkgram.y"
+#line 1713 "awkgram.y"
     {
                INSTRUCTION *ip = (yyvsp[(1) - (1)])->nexti;
                if (ip->opcode == Op_push
@@ -4030,7 +4036,7 @@ regular_print:
 
   case 177:
 /* Line 1787 of yacc.c  */
-#line 1719 "awkgram.y"
+#line 1725 "awkgram.y"
     {
                (yyval) = list_append((yyvsp[(2) - (3)]), (yyvsp[(1) - (3)]));
                if ((yyvsp[(3) - (3)]) != NULL)
@@ -4040,7 +4046,7 @@ regular_print:
 
   case 178:
 /* Line 1787 of yacc.c  */
-#line 1728 "awkgram.y"
+#line 1734 "awkgram.y"
     {
                (yyvsp[(1) - (1)])->opcode = Op_postincrement;
          }
@@ -4048,7 +4054,7 @@ regular_print:
 
   case 179:
 /* Line 1787 of yacc.c  */
-#line 1732 "awkgram.y"
+#line 1738 "awkgram.y"
     {
                (yyvsp[(1) - (1)])->opcode = Op_postdecrement;
          }
@@ -4056,43 +4062,43 @@ regular_print:
 
   case 180:
 /* Line 1787 of yacc.c  */
-#line 1735 "awkgram.y"
+#line 1741 "awkgram.y"
     { (yyval) = NULL; }
     break;
 
   case 182:
 /* Line 1787 of yacc.c  */
-#line 1743 "awkgram.y"
+#line 1749 "awkgram.y"
     { yyerrok; }
     break;
 
   case 183:
 /* Line 1787 of yacc.c  */
-#line 1747 "awkgram.y"
+#line 1753 "awkgram.y"
     { yyerrok; }
     break;
 
   case 186:
 /* Line 1787 of yacc.c  */
-#line 1756 "awkgram.y"
+#line 1762 "awkgram.y"
     { yyerrok; }
     break;
 
   case 187:
 /* Line 1787 of yacc.c  */
-#line 1760 "awkgram.y"
+#line 1766 "awkgram.y"
     { (yyval) = (yyvsp[(1) - (1)]); yyerrok; }
     break;
 
   case 188:
 /* Line 1787 of yacc.c  */
-#line 1764 "awkgram.y"
+#line 1770 "awkgram.y"
     { yyerrok; }
     break;
 
 
 /* Line 1787 of yacc.c  */
-#line 4108 "awkgram.c"
+#line 4114 "awkgram.c"
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -4322,7 +4328,7 @@ yyreturn:
 
 
 /* Line 2048 of yacc.c  */
-#line 1766 "awkgram.y"
+#line 1772 "awkgram.y"
 
 
 struct token {
diff --git a/awkgram.y b/awkgram.y
index f5294e4..da585d4 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -973,6 +973,9 @@ regular_print:
                $2->opcode = Op_push_array;
                $2->memory = variable($2->source_line, arr, Node_var_new);
 
+               if ($2->memory == symbol_table)
+                       fatal(_("`delete' is not allowed with SYMTAB"));
+
                if ($4 == NULL) {
                        /*
                         * As of September 2012, POSIX has added support
@@ -1014,6 +1017,9 @@ regular_print:
                $3->opcode = Op_push_array;
                $1->expr_count = 0;
                $$ = list_append(list_create($3), $1);
+
+               if ($3->memory == symbol_table)
+                       fatal(_("`delete' is not allowed with SYMTAB"));
          }
        | exp
          {     $$ = optimize_assignment($1); }
diff --git a/eval.c b/eval.c
index f703787..4c3e6ab 100644
--- a/eval.c
+++ b/eval.c
@@ -243,7 +243,6 @@ static const char *const nodetypes[] = {
        "Node_param_list",
        "Node_func",
        "Node_ext_func",
-       "Node_hashnode",
        "Node_array_ref",
        "Node_array_tree",
        "Node_array_leaf",
diff --git a/interpret.h b/interpret.h
index c7380bd..208155a 100644
--- a/interpret.h
+++ b/interpret.h
@@ -212,6 +212,10 @@ top:
 
                        r = *assoc_lookup(t1, t2);
                        DEREF(t2);
+
+                       if (t1 == symbol_table && r->type == Node_var)
+                               r = r->var_value;
+
                        if (r->type == Node_val)
                                UPREF(r);
                        PUSH(r);
@@ -531,6 +535,10 @@ mod:
                                                array_vname(t1), (int) 
t2->stlen, t2->stptr);
                        }
                        DEREF(t2);
+
+                       if (t1 == symbol_table && (*lhs)->type == Node_var)
+                               lhs = & ((*lhs)->var_value);
+
                        unref(*lhs);
                        *lhs = POP_SCALAR();
                        break;
diff --git a/main.c b/main.c
index f2a3c66..e1cdd3d 100644
--- a/main.c
+++ b/main.c
@@ -288,12 +288,18 @@ main(int argc, char **argv)
        if (argc < 2)
                usage(EXIT_FAILURE, stderr);
 
+       /* initialize the null string */
+       Nnull_string = make_string("", 0);
+
        /* Robustness: check that file descriptors 0, 1, 2 are open */
        init_fds();
 
        /* init array handling. */
        array_init();
 
+       /* init the symbol tables */
+       init_symbol_table();
+
        output_fp = stdout;
 
        /* we do error messages ourselves on invalid options */
@@ -588,8 +594,6 @@ out:
        /* load group set */
        init_groupset();
 
-       /* initialize the null string */
-       Nnull_string = make_string("", 0);
 #ifdef HAVE_MPFR
        if (do_mpfr) {
                mpz_init(Nnull_string->mpg_i);
diff --git a/profile.c b/profile.c
index 16aa1cd..dfac5c1 100644
--- a/profile.c
+++ b/profile.c
@@ -37,8 +37,9 @@ static NODE *pp_pop(void);
 static void pp_free(NODE *n);
 const char *redir2str(int redirtype);
 
-#define pp_str hname
-#define pp_len hlength
+#define pp_str vname
+#define pp_len sub.nodep.reserved
+#define pp_next        rnode
 
 #define DONT_FREE 1
 #define CAN_FREE  2
@@ -135,7 +136,7 @@ pp_push(int type, char *s, int flag)
        n->pp_len = strlen(s);
        n->flags = flag;
        n->type = type;
-       n->hnext = pp_stack;
+       n->pp_next = pp_stack;
        pp_stack = n;
 }
 
@@ -144,7 +145,7 @@ pp_pop()
 {
        NODE *n;
        n = pp_stack;
-       pp_stack = n->hnext;
+       pp_stack = n->pp_next;
        return n;
 }
 
diff --git a/symbol.c b/symbol.c
index dd89796..61408c4 100644
--- a/symbol.c
+++ b/symbol.c
@@ -30,19 +30,44 @@ extern INSTRUCTION *rule_list;
 
 #define HASHSIZE       1021
 
-static NODE *variables[HASHSIZE];
 static int func_count; /* total number of functions */
 static int var_count;  /* total number of global variables and functions */
 
 static NODE *symbol_list;
 static void (*install_func)(NODE *) = NULL;
 static NODE *make_symbol(char *name, NODETYPE type);
-static NODE *install(char *name, NODE *hp, NODETYPE type);
+static NODE *install(char *name, NODE *parm, NODETYPE type);
 static void free_bcpool(INSTRUCTION *pl);
 
 static AWK_CONTEXT *curr_ctxt = NULL;
 static int ctxt_level;
 
+static NODE *global_table, *param_table, *func_table;
+NODE *symbol_table;
+
+/* Use a flag to avoid a strcmp() call inside install() */
+static bool installing_specials = false;
+
+/* init_symbol_table --- make sure the symbol tables are initialized */
+
+void
+init_symbol_table()
+{
+       getnode(global_table);
+       memset(global_table, '\0', sizeof(NODE));
+       init_array(global_table);
+
+       getnode(param_table);
+       memset(param_table, '\0', sizeof(NODE));
+       init_array(param_table);
+
+       installing_specials = true;
+       func_table = install_symbol(estrdup("FUNCTAB", 7), Node_var_array);
+
+       symbol_table = install_symbol(estrdup("SYMTAB", 6), Node_var_array);
+       installing_specials = false;
+}
+
 /*
  * install_symbol:
  * Install a global name in the symbol table, even if it is already there.
@@ -56,24 +81,41 @@ install_symbol(char *name, NODETYPE type)
 }
 
 
-/* lookup --- find the most recent global or param node for name
+/*
+ * lookup --- find the most recent global or param node for name
  *     installed by install_symbol
  */
 
 NODE *
 lookup(const char *name)
 {
-       NODE *hp;
-       size_t len;
-       int hash1;
-
-       len = strlen(name);
-       hash1 = hash(name, len, (unsigned long) HASHSIZE, NULL);
-       for (hp = variables[hash1]; hp != NULL; hp = hp->hnext) {
-               if (hp->hlength == len && strncmp(hp->hname, name, len) == 0)
-                       return hp->hvalue;
+       NODE *n;
+       NODE *tmp;
+       /* ``It's elephants, all the way down.'' */
+       NODE *tables[] = {
+               param_table,    /* parameters shadow everything */
+               global_table,   /* SYMTAB and FUNCTAB found first, can't be 
redefined */
+               func_table,     /* then functions */
+               symbol_table,   /* then globals */
+               NULL,
+       };
+       int i;
+
+       tmp = make_string(name, strlen(name));
+
+       n = NULL;
+       for (i = 0; tables[i] != NULL; i++) {
+               if (tables[i]->table_size == 0)
+                       continue;
+               n = in_array(tables[i], tmp);
+               if (n != NULL) {
+                       unref(tmp);
+                       return n;
+               }
        }
-       return NULL;
+
+       unref(tmp);
+       return n;       /* NULL */
 }
 
 /* make_params --- allocate function parameters for the symbol table */
@@ -81,7 +123,7 @@ lookup(const char *name)
 NODE *
 make_params(char **pnames, int pcount)
 {
-       NODE *hp, *parms;
+       NODE *p, *parms;
        int i;
        
        if (pcount <= 0 || pnames == NULL)
@@ -90,12 +132,10 @@ make_params(char **pnames, int pcount)
        emalloc(parms, NODE *, pcount * sizeof(NODE), "make_params");
        memset(parms, '\0', pcount * sizeof(NODE));
 
-       for (i = 0, hp = parms; i < pcount; i++, hp++) {
-               hp->type = Node_param_list;
-               hp->hname = pnames[i];  /* shadows pname and vname */
-               hp->hlength = strlen(pnames[i]);
-               hp->param_cnt = i;
-               hp->hvalue = hp;        /* points to itself */
+       for (i = 0, p = parms; i < pcount; i++, p++) {
+               p->type = Node_param_list;
+               p->param = pnames[i];   /* shadows pname and vname */
+               p->param_cnt = i;
        }
 
        return parms;
@@ -117,7 +157,7 @@ install_params(NODE *func)
        )
                return;
        for (i = 0; i < pcount; i++)
-               (void) install(NULL, parms + i, Node_param_list);
+               (void) install(parms[i].param, parms + i, Node_param_list);
 }
 
 
@@ -128,8 +168,8 @@ install_params(NODE *func)
 void
 remove_params(NODE *func)
 {
-       NODE *parms, *p, *prev, *n;
-       int i, pcount, hash1;
+       NODE *parms, *p;
+       int i, pcount;
 
        if (func == NULL)
                return;
@@ -140,22 +180,15 @@ remove_params(NODE *func)
                return;
 
        for (i = pcount - 1; i >= 0; i--) {
+               NODE *tmp;
+
                p = parms + i;
-               hash1 = p->hcode;
-               if (hash1 < 0 || hash1 >= HASHSIZE)
-                       continue;
-               for (prev = NULL, n = variables[hash1]; n != NULL;
-                                       prev = n, n = n->hnext) {
-                       if (n == p)
-                               break;
-               }
-               if (n == NULL)
-                       continue;
-               if (prev == NULL)
-                       variables[hash1] = n->hnext;    /* param at the head of 
the chain */
-               else
-                       prev->hnext = n->hnext;         /* param not at the 
head */ 
+               tmp = make_string(p->vname, strlen(p->vname));
+               (void) assoc_remove(param_table, tmp);
+               unref(tmp);
        }
+
+       assoc_clear(param_table);       /* shazzam! */
 }
 
 
@@ -164,33 +197,16 @@ remove_params(NODE *func)
 NODE *
 remove_symbol(NODE *r)
 {
-       NODE *prev, *hp;
-       int hash1;
-       
-       hash1 = hash(r->vname, strlen(r->vname), (unsigned long) HASHSIZE, 
NULL);
-       for (prev = NULL, hp = variables[hash1]; hp != NULL;
-                               prev = hp, hp = hp->hnext) {
-               if (hp->hvalue == r)
-                       break;
-       }
+       NODE *n = in_array(symbol_table, r);
 
-       if (hp == NULL)
-               return NULL;
-       assert(hp->hcode == hash1);
-
-       if (prev == NULL)
-               variables[hash1] = hp->hnext;   /* symbol at the head of chain 
*/
-       else
-               prev->hnext = hp->hnext;        /* symbol not at the head */
-
-       if (r->type == Node_param_list)
-               return r;       /* r == hp */
-       if (r->type == Node_func)
-               func_count--;
-       if (r->type != Node_ext_func)
-               var_count--;
-       freenode(hp);
-       return r;
+       if (n == NULL)
+               return n;
+
+       n = dupnode(n);
+
+       (void) assoc_remove(symbol_table, r);
+
+       return n;
 }
 
 
@@ -248,46 +264,56 @@ destroy_symbol(NODE *r)
 static NODE *
 make_symbol(char *name, NODETYPE type)
 {
-       NODE *hp, *r;
+       NODE *r;
 
-       getnode(hp);
-       hp->type = Node_hashnode;
-       hp->hlength = strlen(name);
-       hp->hname = name;
        getnode(r);
        memset(r, '\0', sizeof(NODE));
-       hp->hvalue = r;
        if (type == Node_var_array)
                init_array(r);
        else if (type == Node_var)
                r->var_value = dupnode(Nnull_string);
        r->vname = name;
        r->type = type;
-       return hp;
+
+       return r;
 }
 
 /* install --- install a global name or function parameter in the symbol table 
*/
 
 static NODE *
-install(char *name, NODE *hp, NODETYPE type)
+install(char *name, NODE *parm, NODETYPE type)
 {
-       int hash1;
        NODE *r;
+       NODE **aptr;
+       NODE *table;
+       NODE *n_name;
+
+       n_name = make_string(name, strlen(name));
+       table = symbol_table;
+
+       if (type == Node_param_list) {
+               table = param_table;
+       } else if (type == Node_func || type == Node_ext_func) {
+               table = func_table;
+       } else if (installing_specials) {
+               table = global_table;
+       }
 
-       if (hp == NULL) {
+       if (parm != NULL) {
+               r = parm;
+       } else {
                /* global symbol */
-               hp = make_symbol(name, type);
+               r = make_symbol(name, type);
                if (type == Node_func)
                        func_count++;
-               if (type != Node_ext_func)
+               if (type != Node_ext_func && table != global_table)
                        var_count++;    /* total, includes Node_func */
        }
 
-       r = hp->hvalue;
-       hash1 = hash(hp->hname, hp->hlength, (unsigned long) HASHSIZE, NULL);
-       hp->hcode = hash1;
-       hp->hnext = variables[hash1];
-       variables[hash1] = hp;
+       aptr = assoc_lookup(table, n_name);
+       unref(*aptr);
+       *aptr = r;
+       unref(n_name);
 
        if (install_func)
                (*install_func)(r);
@@ -322,30 +348,33 @@ get_symbols(SYMBOL_TYPE what, int sort)
 {
        int i;
        NODE **table;
-       NODE *hp, *r;
+       NODE **list;
+       NODE *r;
        long j, count = 0;
+       long max;
+       NODE *the_table;
 
-       if (what == FUNCTION)
+       if (what == FUNCTION) {
                count = func_count;
-       else    /* if (what == VARIABLE) */
+               the_table = func_table;
+       } else {        /* what == VARIABLE */
                count = var_count;
+               the_table = symbol_table;
+               update_global_values();
+       }
 
        emalloc(table, NODE **, (count + 1) * sizeof(NODE *), "symbol_list");
-       if (what == VARIABLE)
-               update_global_values();
 
-       for (i = j = 0; i < HASHSIZE; i++)
-               for (hp = variables[i]; hp != NULL; hp = hp->hnext) {
-                       if (hp->type != Node_hashnode)
-                               continue;
-                       r = hp->hvalue;
-                       if (r->type == Node_ext_func)
-                               continue;
-                       if (what == FUNCTION && r->type == Node_func)
-                               table[j++] = r;
-                       else if (what == VARIABLE)
-                               table[j++] = r;
-               }
+       max = the_table->table_size * 2;
+       list = assoc_list(the_table, "@unsorted", ASORTI);
+       for (i = j = 0; i < max; i += 2) {
+               r = list[i+1];
+               if (r->type == Node_ext_func)
+                       continue;
+               if (what == VARIABLE || r->type == Node_func)
+                       table[j++] = r;
+       }
+       efree(list);
 
        if (sort && count > 1)
                qsort(table, count, sizeof(NODE *), comp_symbol);       /* 
Shazzam! */
@@ -417,25 +446,8 @@ foreach_func(NODE **table, int (*pfunc)(INSTRUCTION *, 
void *), void *data)
 void
 release_all_vars()
 {
-       int i;
-       NODE *hp, *r, *next;
-
-       for (i = 0; i < HASHSIZE; i++)
-               for (hp = variables[i]; hp != NULL; hp = next) {
-                       next = hp->hnext;
-                       if (hp->type != Node_hashnode)
-                               continue;
-                       r = hp->hvalue;
-                       if (r->type == Node_func || r->type == Node_ext_func)
-                               continue;
-                       if (r->type == Node_var_array)
-                               assoc_clear(r);
-                       else if (r->type == Node_var)
-                               unref(r->var_value);
-                       efree(r->vname);
-                       freenode(r);
-                       freenode(hp);
-               }
+       assoc_clear(symbol_table);
+       assoc_clear(global_table);
 }
 
 
@@ -446,12 +458,12 @@ release_all_vars()
 void
 append_symbol(NODE *r)
 {
-       NODE *hp;
+       NODE *p;
 
-       getnode(hp);
-       hp->lnode = r;
-       hp->rnode = symbol_list->rnode;
-       symbol_list->rnode = hp;
+       getnode(p);
+       p->lnode = r;
+       p->rnode = symbol_list->rnode;
+       symbol_list->rnode = p;
 }
 
 /* release_symbol --- free symbol list and optionally remove symbol from 
symbol table */
@@ -459,17 +471,17 @@ append_symbol(NODE *r)
 void
 release_symbols(NODE *symlist, int keep_globals)
 {
-       NODE *hp, *next;
+       NODE *p, *next;
 
-       for (hp = symlist->rnode; hp != NULL; hp = next) {
+       for (p = symlist->rnode; p != NULL; p = next) {
                if (! keep_globals) {
                        /* destroys globals, function, and params
                         * if still in symbol table
                         */
-                       destroy_symbol(hp->lnode);
+                       destroy_symbol(p->lnode);
                }
-               next = hp->rnode;
-               freenode(hp);
+               next = p->rnode;
+               freenode(p);
        }
        symlist->rnode = NULL;
 }
@@ -479,12 +491,19 @@ release_symbols(NODE *symlist, int keep_globals)
 void
 load_symbols()
 {
-       NODE *hp, *r;
+       NODE *r;
        NODE *tmp;
        NODE *sym_array;
        NODE **aptr;
-       long i;
-       NODE *user, *extension, *variable, *scalar,*array;
+       long i, j, max;
+       NODE *user, *extension, *untyped, *scalar, *array;
+       NODE **list;
+       NODE *tables[] = {
+               func_table,
+               symbol_table,
+               global_table,
+               NULL
+       };
 
        if (PROCINFO_node == NULL)
                return;
@@ -506,15 +525,16 @@ load_symbols()
        user = make_string("user", 4);
        extension = make_string("extension", 9);
        scalar = make_string("scalar", 6);
-       variable = make_string("variable", 8);
+       untyped = make_string("untyped", 7);
        array = make_string("array", 5);
 
-       for (i = 0; i < HASHSIZE; i++) {
-               for (hp = variables[i]; hp != NULL; hp = hp->hnext) {
-                       if (hp->type != Node_hashnode)
-                               continue;
-
-                       r = hp->hvalue;
+       for (i = 0; tables[i] != NULL; i++) {
+               list = assoc_list(tables[i], "@unsorted", ASORTI);
+               max = tables[i]->table_size * 2;
+               if (max == 0)
+                       continue;
+               for (j = 0; j < max; j += 2) {
+                       r = list[j+1];
                        if (   r->type == Node_ext_func
                            || r->type == Node_func
                            || r->type == Node_var
@@ -538,7 +558,7 @@ load_symbols()
                                        *aptr = dupnode(array);
                                        break;
                                case Node_var_new:
-                                       *aptr = dupnode(variable);
+                                       *aptr = dupnode(untyped);
                                        break;
                                default:
                                        cant_happen();
@@ -546,12 +566,13 @@ load_symbols()
                                }
                        }
                }
+               efree(list);
        }
 
        unref(user);
        unref(extension);
        unref(scalar);
-       unref(variable);
+       unref(untyped);
        unref(array);
 }
 

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


hooks/post-receive
-- 
gawk



reply via email to

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