Introduced -devel and -extras subpackages for gawk
[platform/upstream/gawk.git] / awkgram.c
1 /* A Bison parser, made by GNU Bison 2.5.  */
2
3 /* Bison implementation for Yacc-like parsers in C
4    
5       Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
6    
7    This program is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 /* As a special exception, you may create a larger work that contains
21    part or all of the Bison parser skeleton and distribute that work
22    under terms of your choice, so long as that work isn't itself a
23    parser generator using the skeleton or a modified version thereof
24    as a parser skeleton.  Alternatively, if you modify or redistribute
25    the parser skeleton itself, you may (at your option) remove this
26    special exception, which will cause the skeleton and the resulting
27    Bison output files to be licensed under the GNU General Public
28    License without this special exception.
29    
30    This special exception was added by the Free Software Foundation in
31    version 2.2 of Bison.  */
32
33 /* C LALR(1) parser skeleton written by Richard Stallman, by
34    simplifying the original so-called "semantic" parser.  */
35
36 /* All symbols defined below should begin with yy or YY, to avoid
37    infringing on user name space.  This should be done even for local
38    variables, as they might otherwise be expanded by user macros.
39    There are some unavoidable exceptions within include files to
40    define necessary library symbols; they are noted "INFRINGES ON
41    USER NAME SPACE" below.  */
42
43 /* Identify Bison output.  */
44 #define YYBISON 1
45
46 /* Bison version.  */
47 #define YYBISON_VERSION "2.5"
48
49 /* Skeleton name.  */
50 #define YYSKELETON_NAME "yacc.c"
51
52 /* Pure parsers.  */
53 #define YYPURE 0
54
55 /* Push parsers.  */
56 #define YYPUSH 0
57
58 /* Pull parsers.  */
59 #define YYPULL 1
60
61 /* Using locations.  */
62 #define YYLSP_NEEDED 0
63
64
65
66 /* Copy the first part of user declarations.  */
67
68 /* Line 268 of yacc.c  */
69 #line 26 "awkgram.y"
70
71 #ifdef GAWKDEBUG
72 #define YYDEBUG 12
73 #endif
74
75 #include "awk.h"
76
77 #if defined(__STDC__) && __STDC__ < 1   /* VMS weirdness, maybe elsewhere */
78 #define signed /**/
79 #endif
80
81 static void yyerror(const char *m, ...) ATTRIBUTE_PRINTF_1;
82 static void error_ln(int line, const char *m, ...) ATTRIBUTE_PRINTF_2;
83 static void lintwarn_ln(int line, const char *m, ...) ATTRIBUTE_PRINTF_2;
84 static void warning_ln(int line, const char *m, ...) ATTRIBUTE_PRINTF_2;
85 static char *get_src_buf(void);
86 static int yylex(void);
87 int     yyparse(void); 
88 static INSTRUCTION *snode(INSTRUCTION *subn, INSTRUCTION *op);
89 static int func_install(INSTRUCTION *fp, INSTRUCTION *def);
90 static void pop_params(NODE *params);
91 static NODE *make_param(char *pname);
92 static NODE *mk_rexp(INSTRUCTION *exp);
93 static void append_param(char *pname);
94 static int dup_parms(INSTRUCTION *fp, NODE *func);
95 static void param_sanity(INSTRUCTION *arglist);
96 static int parms_shadow(INSTRUCTION *pc, int *shadow);
97 static int isnoeffect(OPCODE type);
98 static INSTRUCTION *make_assignable(INSTRUCTION *ip);
99 static void dumpintlstr(const char *str, size_t len);
100 static void dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2);
101 static int isarray(NODE *n);
102 static int include_source(INSTRUCTION *file);
103 static void next_sourcefile(void);
104 static char *tokexpand(void);
105
106 #define instruction(t)  bcalloc(t, 1, 0)
107
108 static INSTRUCTION *mk_program(void);
109 static INSTRUCTION *append_rule(INSTRUCTION *pattern, INSTRUCTION *action);
110 static INSTRUCTION *mk_condition(INSTRUCTION *cond, INSTRUCTION *ifp, INSTRUCTION *true_branch,
111                 INSTRUCTION *elsep,     INSTRUCTION *false_branch);
112 static INSTRUCTION *mk_expression_list(INSTRUCTION *list, INSTRUCTION *s1);
113 static INSTRUCTION *mk_for_loop(INSTRUCTION *forp, INSTRUCTION *init, INSTRUCTION *cond,
114                 INSTRUCTION *incr, INSTRUCTION *body);
115 static void fix_break_continue(INSTRUCTION *list, INSTRUCTION *b_target, INSTRUCTION *c_target);
116 static INSTRUCTION *mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op);
117 static INSTRUCTION *mk_boolean(INSTRUCTION *left, INSTRUCTION *right, INSTRUCTION *op);
118 static INSTRUCTION *mk_assignment(INSTRUCTION *lhs, INSTRUCTION *rhs, INSTRUCTION *op);
119 static INSTRUCTION *mk_getline(INSTRUCTION *op, INSTRUCTION *opt_var, INSTRUCTION *redir, int redirtype);
120 static NODE *make_regnode(int type, NODE *exp);
121 static int count_expressions(INSTRUCTION **list, int isarg);
122 static INSTRUCTION *optimize_assignment(INSTRUCTION *exp);
123 static void add_lint(INSTRUCTION *list, LINTTYPE linttype);
124
125 enum defref { FUNC_DEFINE, FUNC_USE };
126 static void func_use(const char *name, enum defref how);
127 static void check_funcs(void);
128 static void free_bcpool(INSTRUCTION *pl);
129
130 static ssize_t read_one_line(int fd, void *buffer, size_t count);
131 static int one_line_close(int fd);
132
133 static void (*install_func)(char *) = NULL;
134
135 static int want_source = FALSE;
136 static int want_regexp;         /* lexical scanning kludge */
137 static int can_return;          /* parsing kludge */
138 static int rule = 0;
139
140 const char *const ruletab[] = {
141         "?",
142         "BEGIN",
143         "Rule",
144         "END",
145         "BEGINFILE",
146         "ENDFILE",
147 };
148
149 static int in_print = FALSE;    /* lexical scanning kludge for print */
150 static int in_parens = 0;       /* lexical scanning kludge for print */
151 static int sub_counter = 0;     /* array dimension counter for use in delete */
152 static char *lexptr = NULL;             /* pointer to next char during parsing */
153 static char *lexend;
154 static char *lexptr_begin;      /* keep track of where we were for error msgs */
155 static char *lexeme;            /* beginning of lexeme for debugging */
156 static int lexeof;                      /* seen EOF for current source? */  
157 static char *thisline = NULL;
158 static int in_braces = 0;       /* count braces for firstline, lastline in an 'action' */
159 static int lastline = 0;
160 static int firstline = 0;
161 static SRCFILE *sourcefile = NULL;      /* current program source */
162 static int lasttok = 0;
163 static int eof_warned = FALSE;  /* GLOBAL: want warning for each file */
164 static int break_allowed;       /* kludge for break */
165 static int continue_allowed;    /* kludge for continue */
166
167
168 #define END_FILE        -1000
169 #define END_SRC         -2000
170
171 #define YYDEBUG_LEXER_TEXT (lexeme)
172 static int param_counter;
173 static NODE *func_params;       /* list of parameters for the current function */
174 static char *tokstart = NULL;
175 static char *tok = NULL;
176 static char *tokend;
177 static int errcount = 0;
178
179 static NODE *symbol_list;
180 extern void destroy_symbol(char *name); 
181
182 static long func_count;         /* total number of functions */
183
184 #define HASHSIZE        1021    /* this constant only used here */
185 NODE *variables[HASHSIZE];
186 static int var_count;           /* total number of global variables */
187
188 extern char *source;
189 extern int sourceline;
190 extern SRCFILE *srcfiles;
191 extern INSTRUCTION *rule_list;
192 extern int max_args;
193
194 static INSTRUCTION *rule_block[sizeof(ruletab)];
195
196 static INSTRUCTION *ip_rec;
197 static INSTRUCTION *ip_newfile;
198 static INSTRUCTION *ip_atexit = NULL;
199 static INSTRUCTION *ip_end;
200 static INSTRUCTION *ip_endfile;
201 static INSTRUCTION *ip_beginfile;
202
203 static inline INSTRUCTION *list_create(INSTRUCTION *x);
204 static inline INSTRUCTION *list_append(INSTRUCTION *l, INSTRUCTION *x);
205 static inline INSTRUCTION *list_prepend(INSTRUCTION *l, INSTRUCTION *x);
206 static inline INSTRUCTION *list_merge(INSTRUCTION *l1, INSTRUCTION *l2);
207
208 extern double fmod(double x, double y);
209 /*
210  * This string cannot occur as a real awk identifier.
211  * Use it as a special token to make function parsing
212  * uniform, but if it's seen, don't install the function.
213  * e.g.
214  *      function split(x) { return x }
215  *      function x(a) { return a }
216  * should only produce one error message, and not core dump.
217  */
218 static char builtin_func[] = "@builtin";
219
220 #define YYSTYPE INSTRUCTION *
221
222
223 /* Line 268 of yacc.c  */
224 #line 225 "awkgram.c"
225
226 /* Enabling traces.  */
227 #ifndef YYDEBUG
228 # define YYDEBUG 0
229 #endif
230
231 /* Enabling verbose error messages.  */
232 #ifdef YYERROR_VERBOSE
233 # undef YYERROR_VERBOSE
234 # define YYERROR_VERBOSE 1
235 #else
236 # define YYERROR_VERBOSE 0
237 #endif
238
239 /* Enabling the token table.  */
240 #ifndef YYTOKEN_TABLE
241 # define YYTOKEN_TABLE 0
242 #endif
243
244
245 /* Tokens.  */
246 #ifndef YYTOKENTYPE
247 # define YYTOKENTYPE
248    /* Put the tokens into the symbol table, so that GDB and other debuggers
249       know about them.  */
250    enum yytokentype {
251      FUNC_CALL = 258,
252      NAME = 259,
253      REGEXP = 260,
254      FILENAME = 261,
255      YNUMBER = 262,
256      YSTRING = 263,
257      RELOP = 264,
258      IO_OUT = 265,
259      IO_IN = 266,
260      ASSIGNOP = 267,
261      ASSIGN = 268,
262      MATCHOP = 269,
263      CONCAT_OP = 270,
264      SUBSCRIPT = 271,
265      LEX_BEGIN = 272,
266      LEX_END = 273,
267      LEX_IF = 274,
268      LEX_ELSE = 275,
269      LEX_RETURN = 276,
270      LEX_DELETE = 277,
271      LEX_SWITCH = 278,
272      LEX_CASE = 279,
273      LEX_DEFAULT = 280,
274      LEX_WHILE = 281,
275      LEX_DO = 282,
276      LEX_FOR = 283,
277      LEX_BREAK = 284,
278      LEX_CONTINUE = 285,
279      LEX_PRINT = 286,
280      LEX_PRINTF = 287,
281      LEX_NEXT = 288,
282      LEX_EXIT = 289,
283      LEX_FUNCTION = 290,
284      LEX_BEGINFILE = 291,
285      LEX_ENDFILE = 292,
286      LEX_GETLINE = 293,
287      LEX_NEXTFILE = 294,
288      LEX_IN = 295,
289      LEX_AND = 296,
290      LEX_OR = 297,
291      INCREMENT = 298,
292      DECREMENT = 299,
293      LEX_BUILTIN = 300,
294      LEX_LENGTH = 301,
295      LEX_EOF = 302,
296      LEX_INCLUDE = 303,
297      LEX_EVAL = 304,
298      NEWLINE = 305,
299      SLASH_BEFORE_EQUAL = 306,
300      UNARY = 307
301    };
302 #endif
303 /* Tokens.  */
304 #define FUNC_CALL 258
305 #define NAME 259
306 #define REGEXP 260
307 #define FILENAME 261
308 #define YNUMBER 262
309 #define YSTRING 263
310 #define RELOP 264
311 #define IO_OUT 265
312 #define IO_IN 266
313 #define ASSIGNOP 267
314 #define ASSIGN 268
315 #define MATCHOP 269
316 #define CONCAT_OP 270
317 #define SUBSCRIPT 271
318 #define LEX_BEGIN 272
319 #define LEX_END 273
320 #define LEX_IF 274
321 #define LEX_ELSE 275
322 #define LEX_RETURN 276
323 #define LEX_DELETE 277
324 #define LEX_SWITCH 278
325 #define LEX_CASE 279
326 #define LEX_DEFAULT 280
327 #define LEX_WHILE 281
328 #define LEX_DO 282
329 #define LEX_FOR 283
330 #define LEX_BREAK 284
331 #define LEX_CONTINUE 285
332 #define LEX_PRINT 286
333 #define LEX_PRINTF 287
334 #define LEX_NEXT 288
335 #define LEX_EXIT 289
336 #define LEX_FUNCTION 290
337 #define LEX_BEGINFILE 291
338 #define LEX_ENDFILE 292
339 #define LEX_GETLINE 293
340 #define LEX_NEXTFILE 294
341 #define LEX_IN 295
342 #define LEX_AND 296
343 #define LEX_OR 297
344 #define INCREMENT 298
345 #define DECREMENT 299
346 #define LEX_BUILTIN 300
347 #define LEX_LENGTH 301
348 #define LEX_EOF 302
349 #define LEX_INCLUDE 303
350 #define LEX_EVAL 304
351 #define NEWLINE 305
352 #define SLASH_BEFORE_EQUAL 306
353 #define UNARY 307
354
355
356
357
358 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
359 typedef int YYSTYPE;
360 # define YYSTYPE_IS_TRIVIAL 1
361 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
362 # define YYSTYPE_IS_DECLARED 1
363 #endif
364
365
366 /* Copy the second part of user declarations.  */
367
368
369 /* Line 343 of yacc.c  */
370 #line 371 "awkgram.c"
371
372 #ifdef short
373 # undef short
374 #endif
375
376 #ifdef YYTYPE_UINT8
377 typedef YYTYPE_UINT8 yytype_uint8;
378 #else
379 typedef unsigned char yytype_uint8;
380 #endif
381
382 #ifdef YYTYPE_INT8
383 typedef YYTYPE_INT8 yytype_int8;
384 #elif (defined __STDC__ || defined __C99__FUNC__ \
385      || defined __cplusplus || defined _MSC_VER)
386 typedef signed char yytype_int8;
387 #else
388 typedef short int yytype_int8;
389 #endif
390
391 #ifdef YYTYPE_UINT16
392 typedef YYTYPE_UINT16 yytype_uint16;
393 #else
394 typedef unsigned short int yytype_uint16;
395 #endif
396
397 #ifdef YYTYPE_INT16
398 typedef YYTYPE_INT16 yytype_int16;
399 #else
400 typedef short int yytype_int16;
401 #endif
402
403 #ifndef YYSIZE_T
404 # ifdef __SIZE_TYPE__
405 #  define YYSIZE_T __SIZE_TYPE__
406 # elif defined size_t
407 #  define YYSIZE_T size_t
408 # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
409      || defined __cplusplus || defined _MSC_VER)
410 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
411 #  define YYSIZE_T size_t
412 # else
413 #  define YYSIZE_T unsigned int
414 # endif
415 #endif
416
417 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
418
419 #ifndef YY_
420 # if defined YYENABLE_NLS && YYENABLE_NLS
421 #  if ENABLE_NLS
422 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
423 #   define YY_(msgid) dgettext ("bison-runtime", msgid)
424 #  endif
425 # endif
426 # ifndef YY_
427 #  define YY_(msgid) msgid
428 # endif
429 #endif
430
431 /* Suppress unused-variable warnings by "using" E.  */
432 #if ! defined lint || defined __GNUC__
433 # define YYUSE(e) ((void) (e))
434 #else
435 # define YYUSE(e) /* empty */
436 #endif
437
438 /* Identity function, used to suppress warnings about constant conditions.  */
439 #ifndef lint
440 # define YYID(n) (n)
441 #else
442 #if (defined __STDC__ || defined __C99__FUNC__      || defined __cplusplus || defined _MSC_VER)
443 static int
444 YYID (int yyi)
445 #else
446 static int
447 YYID (yyi)
448     int yyi;
449 #endif
450 {
451   return yyi;
452 }
453 #endif
454
455 #if ! defined yyoverflow || YYERROR_VERBOSE
456
457 /* The parser invokes alloca or malloc; define the necessary symbols.  */
458
459 # ifdef YYSTACK_USE_ALLOCA
460 #  if YYSTACK_USE_ALLOCA
461 #   ifdef __GNUC__
462 #    define YYSTACK_ALLOC __builtin_alloca
463 #   elif defined __BUILTIN_VA_ARG_INCR
464 #    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
465 #   elif defined _AIX
466 #    define YYSTACK_ALLOC __alloca
467 #   elif defined _MSC_VER
468 #    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
469 #    define alloca _alloca
470 #   else
471 #    define YYSTACK_ALLOC alloca
472 #    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
473      || defined __cplusplus || defined _MSC_VER)
474 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
475 #     ifndef EXIT_SUCCESS
476 #      define EXIT_SUCCESS 0
477 #     endif
478 #    endif
479 #   endif
480 #  endif
481 # endif
482
483 # ifdef YYSTACK_ALLOC
484    /* Pacify GCC's `empty if-body' warning.  */
485 #  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
486 #  ifndef YYSTACK_ALLOC_MAXIMUM
487     /* The OS might guarantee only one guard page at the bottom of the stack,
488        and a page size can be as small as 4096 bytes.  So we cannot safely
489        invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
490        to allow for a few compiler-allocated temporary stack slots.  */
491 #   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
492 #  endif
493 # else
494 #  define YYSTACK_ALLOC YYMALLOC
495 #  define YYSTACK_FREE YYFREE
496 #  ifndef YYSTACK_ALLOC_MAXIMUM
497 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
498 #  endif
499 #  if (defined __cplusplus && ! defined EXIT_SUCCESS \
500        && ! ((defined YYMALLOC || defined malloc) \
501              && (defined YYFREE || defined free)))
502 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
503 #   ifndef EXIT_SUCCESS
504 #    define EXIT_SUCCESS 0
505 #   endif
506 #  endif
507 #  ifndef YYMALLOC
508 #   define YYMALLOC malloc
509 #   if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
510      || defined __cplusplus || defined _MSC_VER)
511 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
512 #   endif
513 #  endif
514 #  ifndef YYFREE
515 #   define YYFREE free
516 #   if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
517      || defined __cplusplus || defined _MSC_VER)
518 void free (void *); /* INFRINGES ON USER NAME SPACE */
519 #   endif
520 #  endif
521 # endif
522 #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
523
524
525 #if (! defined yyoverflow      && (! defined __cplusplus         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
526
527 /* A type that is properly aligned for any stack member.  */
528 union yyalloc
529 {
530   yytype_int16 yyss_alloc;
531   YYSTYPE yyvs_alloc;
532 };
533
534 /* The size of the maximum gap between one aligned stack and the next.  */
535 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
536
537 /* The size of an array large to enough to hold all stacks, each with
538    N elements.  */
539 # define YYSTACK_BYTES(N) \
540      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
541       + YYSTACK_GAP_MAXIMUM)
542
543 # define YYCOPY_NEEDED 1
544
545 /* Relocate STACK from its old location to the new one.  The
546    local variables YYSIZE and YYSTACKSIZE give the old and new number of
547    elements in the stack, and YYPTR gives the new location of the
548    stack.  Advance YYPTR to a properly aligned location for the next
549    stack.  */
550 # define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
551     do                                                                  \
552       {                                                                 \
553         YYSIZE_T yynewbytes;                                            \
554         YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
555         Stack = &yyptr->Stack_alloc;                                    \
556         yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
557         yyptr += yynewbytes / sizeof (*yyptr);                          \
558       }                                                                 \
559     while (YYID (0))
560
561 #endif
562
563 #if defined YYCOPY_NEEDED && YYCOPY_NEEDED
564 /* Copy COUNT objects from FROM to TO.  The source and destination do
565    not overlap.  */
566 # ifndef YYCOPY
567 #  if defined __GNUC__ && 1 < __GNUC__
568 #   define YYCOPY(To, From, Count) \
569       __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
570 #  else
571 #   define YYCOPY(To, From, Count)              \
572       do                                        \
573         {                                       \
574           YYSIZE_T yyi;                         \
575           for (yyi = 0; yyi < (Count); yyi++)   \
576             (To)[yyi] = (From)[yyi];            \
577         }                                       \
578       while (YYID (0))
579 #  endif
580 # endif
581 #endif /* !YYCOPY_NEEDED */
582
583 /* YYFINAL -- State number of the termination state.  */
584 #define YYFINAL  2
585 /* YYLAST -- Last index in YYTABLE.  */
586 #define YYLAST   1157
587
588 /* YYNTOKENS -- Number of terminals.  */
589 #define YYNTOKENS  74
590 /* YYNNTS -- Number of nonterminals.  */
591 #define YYNNTS  65
592 /* YYNRULES -- Number of rules.  */
593 #define YYNRULES  185
594 /* YYNRULES -- Number of states.  */
595 #define YYNSTATES  330
596
597 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
598 #define YYUNDEFTOK  2
599 #define YYMAXUTOK   307
600
601 #define YYTRANSLATE(YYX)                                                \
602   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
603
604 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
605 static const yytype_uint8 yytranslate[] =
606 {
607        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
608        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
609        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
610        2,     2,     2,    62,     2,     2,    65,    61,     2,     2,
611       66,    67,    59,    57,    54,    58,     2,    60,     2,     2,
612        2,     2,     2,     2,     2,     2,     2,     2,    53,    73,
613       55,     2,    56,    52,    68,     2,     2,     2,     2,     2,
614        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
615        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
616        2,    69,     2,    70,    64,     2,     2,     2,     2,     2,
617        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
618        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
619        2,     2,     2,    71,     2,    72,     2,     2,     2,     2,
620        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
621        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
622        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
623        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
624        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
625        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
626        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
627        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
628        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
629        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
630        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
631        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
632        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
633        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
634       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
635       25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
636       35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
637       45,    46,    47,    48,    49,    50,    51,    63
638 };
639
640 #if YYDEBUG
641 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
642    YYRHS.  */
643 static const yytype_uint16 yyprhs[] =
644 {
645        0,     0,     3,     4,     7,    10,    13,    16,    19,    22,
646       25,    30,    32,    35,    37,    38,    40,    45,    47,    49,
647       51,    53,    59,    61,    63,    65,    68,    70,    72,    73,
648       81,    82,    86,    88,    90,    91,    94,    97,    99,   102,
649      105,   109,   111,   121,   128,   137,   146,   159,   171,   173,
650      176,   179,   182,   185,   189,   190,   195,   198,   199,   204,
651      205,   210,   215,   217,   218,   220,   221,   224,   227,   233,
652      238,   240,   243,   246,   248,   250,   252,   254,   256,   260,
653      261,   262,   266,   273,   283,   285,   288,   289,   291,   292,
654      295,   296,   298,   300,   304,   306,   309,   313,   314,   316,
655      317,   319,   321,   325,   327,   330,   334,   338,   342,   346,
656      350,   354,   358,   362,   368,   370,   372,   374,   377,   379,
657      381,   383,   385,   387,   389,   392,   394,   398,   402,   406,
658      410,   414,   418,   422,   425,   428,   434,   439,   443,   447,
659      451,   455,   459,   463,   465,   468,   472,   477,   482,   484,
660      486,   488,   491,   494,   496,   498,   501,   504,   506,   509,
661      514,   515,   517,   518,   521,   523,   526,   528,   532,   534,
662      537,   540,   542,   545,   547,   551,   553,   555,   556,   559,
663      562,   564,   565,   567,   569,   571
664 };
665
666 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
667 static const yytype_int16 yyrhs[] =
668 {
669       75,     0,    -1,    -1,    75,    76,    -1,    75,   104,    -1,
670       75,    47,    -1,    75,     1,    -1,    78,    79,    -1,    78,
671       88,    -1,    82,    79,    -1,    68,    48,    77,    88,    -1,
672        6,    -1,     6,     1,    -1,     1,    -1,    -1,   112,    -1,
673      112,    54,   105,   112,    -1,    17,    -1,    18,    -1,    36,
674       -1,    37,    -1,   132,    87,   133,   135,   105,    -1,     4,
675       -1,     3,    -1,    81,    -1,    68,    49,    -1,    45,    -1,
676       46,    -1,    -1,    35,    83,    80,    66,   107,   134,   105,
677       -1,    -1,    86,    85,     5,    -1,    60,    -1,    51,    -1,
678       -1,    87,    89,    -1,    87,     1,    -1,   104,    -1,   136,
679      105,    -1,   136,   105,    -1,   132,    87,   133,    -1,   103,
680       -1,    23,    66,   112,   134,   105,   132,    96,   105,   133,
681       -1,    26,    66,   112,   134,   105,    89,    -1,    27,   105,
682       89,    26,    66,   112,   134,   105,    -1,    28,    66,     4,
683       40,   129,   134,   105,    89,    -1,    28,    66,    95,   136,
684      105,   112,   136,   105,    95,   134,   105,    89,    -1,    28,
685       66,    95,   136,   105,   136,   105,    95,   134,   105,    89,
686       -1,    90,    -1,    29,    88,    -1,    30,    88,    -1,    33,
687       88,    -1,    39,    88,    -1,    34,   109,    88,    -1,    -1,
688       21,    91,   109,    88,    -1,    92,    88,    -1,    -1,    99,
689       93,   100,   101,    -1,    -1,    22,     4,    94,   123,    -1,
690       22,    66,     4,    67,    -1,   112,    -1,    -1,    92,    -1,
691       -1,    96,    97,    -1,    96,     1,    -1,    24,    98,   137,
692      105,    87,    -1,    25,   137,   105,    87,    -1,     7,    -1,
693       58,     7,    -1,    57,     7,    -1,     8,    -1,    84,    -1,
694       31,    -1,    32,    -1,   110,    -1,    66,   111,   134,    -1,
695       -1,    -1,    10,   102,   116,    -1,    19,    66,   112,   134,
696      105,    89,    -1,    19,    66,   112,   134,   105,    89,    20,
697      105,    89,    -1,    50,    -1,   104,    50,    -1,    -1,   104,
698       -1,    -1,    55,   117,    -1,    -1,   108,    -1,     4,    -1,
699      108,   138,     4,    -1,     1,    -1,   108,     1,    -1,   108,
700      138,     1,    -1,    -1,   112,    -1,    -1,   111,    -1,   112,
701       -1,   111,   138,   112,    -1,     1,    -1,   111,     1,    -1,
702      111,     1,   112,    -1,   111,   138,     1,    -1,   130,   113,
703      112,    -1,   112,    41,   112,    -1,   112,    42,   112,    -1,
704      112,    14,   112,    -1,   112,    40,   129,    -1,   112,   115,
705      112,    -1,   112,    52,   112,    53,   112,    -1,   116,    -1,
706       13,    -1,    12,    -1,    51,    13,    -1,     9,    -1,    55,
707       -1,   114,    -1,    56,    -1,   117,    -1,   118,    -1,   116,
708      117,    -1,   119,    -1,   117,    64,   117,    -1,   117,    59,
709      117,    -1,   117,    60,   117,    -1,   117,    61,   117,    -1,
710      117,    57,   117,    -1,   117,    58,   117,    -1,    38,   122,
711      106,    -1,   130,    43,    -1,   130,    44,    -1,    66,   111,
712      134,    40,   129,    -1,   116,    11,    38,   122,    -1,   118,
713       64,   117,    -1,   118,    59,   117,    -1,   118,    60,   117,
714       -1,   118,    61,   117,    -1,   118,    57,   117,    -1,   118,
715       58,   117,    -1,    84,    -1,    62,   117,    -1,    66,   112,
716      134,    -1,    45,    66,   110,   134,    -1,    46,    66,   110,
717      134,    -1,    46,    -1,   120,    -1,   130,    -1,    43,   130,
718       -1,    44,   130,    -1,     7,    -1,     8,    -1,    58,   117,
719       -1,    57,   117,    -1,   121,    -1,    68,   121,    -1,     3,
720       66,   110,   134,    -1,    -1,   130,    -1,    -1,   124,    16,
721       -1,   125,    -1,   124,   125,    -1,   126,    -1,    69,   111,
722       70,    -1,   126,    -1,   127,   126,    -1,   127,    16,    -1,
723        4,    -1,     4,   128,    -1,   129,    -1,    65,   119,   131,
724       -1,    43,    -1,    44,    -1,    -1,    71,   105,    -1,    72,
725      105,    -1,    67,    -1,    -1,   136,    -1,    73,    -1,    53,
726       -1,    54,   105,    -1
727 };
728
729 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
730 static const yytype_uint16 yyrline[] =
731 {
732        0,   218,   218,   220,   225,   226,   230,   242,   246,   257,
733      265,   273,   281,   283,   289,   290,   292,   318,   329,   340,
734      346,   355,   365,   367,   369,   380,   385,   386,   391,   390,
735      420,   419,   452,   454,   459,   460,   473,   478,   479,   483,
736      485,   487,   494,   584,   626,   668,   781,   788,   795,   805,
737      814,   823,   832,   847,   863,   862,   874,   886,   886,   982,
738      982,  1007,  1030,  1036,  1037,  1043,  1044,  1051,  1056,  1068,
739     1082,  1084,  1090,  1095,  1097,  1105,  1107,  1116,  1117,  1125,
740     1130,  1130,  1141,  1145,  1153,  1154,  1157,  1159,  1164,  1165,
741     1172,  1174,  1178,  1184,  1191,  1193,  1195,  1202,  1203,  1209,
742     1210,  1215,  1217,  1222,  1224,  1226,  1228,  1234,  1241,  1243,
743     1245,  1261,  1271,  1278,  1280,  1285,  1287,  1289,  1297,  1299,
744     1304,  1306,  1311,  1313,  1315,  1368,  1370,  1372,  1374,  1376,
745     1378,  1380,  1382,  1405,  1410,  1415,  1440,  1446,  1448,  1450,
746     1452,  1454,  1456,  1461,  1465,  1496,  1498,  1504,  1510,  1523,
747     1524,  1525,  1530,  1535,  1539,  1543,  1555,  1568,  1573,  1609,
748     1627,  1628,  1634,  1635,  1640,  1642,  1649,  1666,  1683,  1685,
749     1692,  1697,  1705,  1719,  1731,  1740,  1744,  1748,  1752,  1756,
750     1760,  1763,  1765,  1769,  1773,  1777
751 };
752 #endif
753
754 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
755 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
756    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
757 static const char *const yytname[] =
758 {
759   "$end", "error", "$undefined", "FUNC_CALL", "NAME", "REGEXP",
760   "FILENAME", "YNUMBER", "YSTRING", "RELOP", "IO_OUT", "IO_IN", "ASSIGNOP",
761   "ASSIGN", "MATCHOP", "CONCAT_OP", "SUBSCRIPT", "LEX_BEGIN", "LEX_END",
762   "LEX_IF", "LEX_ELSE", "LEX_RETURN", "LEX_DELETE", "LEX_SWITCH",
763   "LEX_CASE", "LEX_DEFAULT", "LEX_WHILE", "LEX_DO", "LEX_FOR", "LEX_BREAK",
764   "LEX_CONTINUE", "LEX_PRINT", "LEX_PRINTF", "LEX_NEXT", "LEX_EXIT",
765   "LEX_FUNCTION", "LEX_BEGINFILE", "LEX_ENDFILE", "LEX_GETLINE",
766   "LEX_NEXTFILE", "LEX_IN", "LEX_AND", "LEX_OR", "INCREMENT", "DECREMENT",
767   "LEX_BUILTIN", "LEX_LENGTH", "LEX_EOF", "LEX_INCLUDE", "LEX_EVAL",
768   "NEWLINE", "SLASH_BEFORE_EQUAL", "'?'", "':'", "','", "'<'", "'>'",
769   "'+'", "'-'", "'*'", "'/'", "'%'", "'!'", "UNARY", "'^'", "'$'", "'('",
770   "')'", "'@'", "'['", "']'", "'{'", "'}'", "';'", "$accept", "program",
771   "rule", "source", "pattern", "action", "func_name", "lex_builtin",
772   "function_prologue", "$@1", "regexp", "$@2", "a_slash", "statements",
773   "statement_term", "statement", "non_compound_stmt", "$@3", "simple_stmt",
774   "$@4", "$@5", "opt_simple_stmt", "case_statements", "case_statement",
775   "case_value", "print", "print_expression_list", "output_redir", "$@6",
776   "if_statement", "nls", "opt_nls", "input_redir", "opt_param_list",
777   "param_list", "opt_exp", "opt_expression_list", "expression_list", "exp",
778   "assign_operator", "relop_or_less", "a_relop", "common_exp", "simp_exp",
779   "simp_exp_nc", "non_post_simp_exp", "func_call", "direct_func_call",
780   "opt_variable", "delete_subscript_list", "delete_subscript",
781   "delete_exp_list", "bracketed_exp_list", "subscript", "subscript_list",
782   "simple_variable", "variable", "opt_incdec", "l_brace", "r_brace",
783   "r_paren", "opt_semi", "semi", "colon", "comma", 0
784 };
785 #endif
786
787 # ifdef YYPRINT
788 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
789    token YYLEX-NUM.  */
790 static const yytype_uint16 yytoknum[] =
791 {
792        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
793      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
794      275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
795      285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
796      295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
797      305,   306,    63,    58,    44,    60,    62,    43,    45,    42,
798       47,    37,    33,   307,    94,    36,    40,    41,    64,    91,
799       93,   123,   125,    59
800 };
801 # endif
802
803 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
804 static const yytype_uint8 yyr1[] =
805 {
806        0,    74,    75,    75,    75,    75,    75,    76,    76,    76,
807       76,    77,    77,    77,    78,    78,    78,    78,    78,    78,
808       78,    79,    80,    80,    80,    80,    81,    81,    83,    82,
809       85,    84,    86,    86,    87,    87,    87,    88,    88,    89,
810       89,    89,    89,    89,    89,    89,    89,    89,    89,    90,
811       90,    90,    90,    90,    91,    90,    90,    93,    92,    94,
812       92,    92,    92,    95,    95,    96,    96,    96,    97,    97,
813       98,    98,    98,    98,    98,    99,    99,   100,   100,   101,
814      102,   101,   103,   103,   104,   104,   105,   105,   106,   106,
815      107,   107,   108,   108,   108,   108,   108,   109,   109,   110,
816      110,   111,   111,   111,   111,   111,   111,   112,   112,   112,
817      112,   112,   112,   112,   112,   113,   113,   113,   114,   114,
818      115,   115,   116,   116,   116,   117,   117,   117,   117,   117,
819      117,   117,   117,   117,   117,   117,   118,   118,   118,   118,
820      118,   118,   118,   119,   119,   119,   119,   119,   119,   119,
821      119,   119,   119,   119,   119,   119,   119,   120,   120,   121,
822      122,   122,   123,   123,   124,   124,   125,   126,   127,   127,
823      128,   129,   129,   130,   130,   131,   131,   131,   132,   133,
824      134,   135,   135,   136,   137,   138
825 };
826
827 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
828 static const yytype_uint8 yyr2[] =
829 {
830        0,     2,     0,     2,     2,     2,     2,     2,     2,     2,
831        4,     1,     2,     1,     0,     1,     4,     1,     1,     1,
832        1,     5,     1,     1,     1,     2,     1,     1,     0,     7,
833        0,     3,     1,     1,     0,     2,     2,     1,     2,     2,
834        3,     1,     9,     6,     8,     8,    12,    11,     1,     2,
835        2,     2,     2,     3,     0,     4,     2,     0,     4,     0,
836        4,     4,     1,     0,     1,     0,     2,     2,     5,     4,
837        1,     2,     2,     1,     1,     1,     1,     1,     3,     0,
838        0,     3,     6,     9,     1,     2,     0,     1,     0,     2,
839        0,     1,     1,     3,     1,     2,     3,     0,     1,     0,
840        1,     1,     3,     1,     2,     3,     3,     3,     3,     3,
841        3,     3,     3,     5,     1,     1,     1,     2,     1,     1,
842        1,     1,     1,     1,     2,     1,     3,     3,     3,     3,
843        3,     3,     3,     2,     2,     5,     4,     3,     3,     3,
844        3,     3,     3,     1,     2,     3,     4,     4,     1,     1,
845        1,     2,     2,     1,     1,     2,     2,     1,     2,     4,
846        0,     1,     0,     2,     1,     2,     1,     3,     1,     2,
847        2,     1,     2,     1,     3,     1,     1,     0,     2,     2,
848        1,     0,     1,     1,     1,     2
849 };
850
851 /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
852    Performed when YYTABLE doesn't specify something else to do.  Zero
853    means the default is an error.  */
854 static const yytype_uint8 yydefact[] =
855 {
856        2,     0,     1,     6,     0,   171,   153,   154,    17,    18,
857       28,    19,    20,   160,     0,     0,     0,   148,     5,    84,
858       33,     0,     0,    32,     0,     0,     0,     0,     3,     0,
859        0,   143,    30,     4,    15,   114,   122,   123,   125,   149,
860      157,   173,   150,     0,     0,   168,     0,   172,     0,    88,
861      161,   151,   152,     0,     0,     0,   156,   150,   155,   144,
862        0,   177,   150,   103,     0,   101,     0,   158,    86,   183,
863        7,     8,    37,    34,    86,     9,     0,    85,   118,     0,
864        0,     0,     0,     0,    86,   119,   121,   120,     0,     0,
865      124,     0,     0,     0,     0,     0,     0,     0,     0,     0,
866        0,     0,     0,   116,   115,   133,   134,     0,     0,     0,
867        0,   101,     0,   170,   169,    23,    22,    26,    27,     0,
868        0,    24,     0,   132,     0,     0,     0,   175,   176,   174,
869      104,    86,   180,     0,     0,   145,    13,     0,     0,    87,
870      178,     0,    38,    31,   110,   111,   108,   109,     0,     0,
871      112,   160,   130,   131,   127,   128,   129,   126,   141,   142,
872      138,   139,   140,   137,   117,   107,   159,   167,    25,     0,
873       89,   146,   147,   105,   185,     0,   106,   102,    12,    10,
874       36,     0,    54,     0,     0,     0,    86,     0,     0,     0,
875       75,    76,     0,    97,     0,    86,    35,    48,     0,    57,
876       41,    62,    34,   181,    86,     0,    16,   136,    94,    92,
877        0,     0,   135,     0,    97,    59,     0,     0,     0,     0,
878       63,    49,    50,    51,     0,    98,    52,   179,    56,     0,
879        0,    86,   182,    39,   113,    86,    95,     0,     0,     0,
880      162,     0,     0,     0,     0,   171,    64,     0,    53,     0,
881       79,    77,    40,    21,    29,    96,    93,    86,    55,    60,
882        0,   164,   166,    61,    86,    86,     0,     0,    86,     0,
883       80,    58,     0,   163,   165,     0,     0,     0,     0,     0,
884       78,     0,    82,    65,    43,     0,    86,     0,    86,    81,
885       86,     0,    86,     0,    86,    63,     0,    67,     0,     0,
886       66,     0,    44,    45,    63,     0,    83,    70,    73,     0,
887        0,    74,     0,   184,    86,    42,     0,    86,    72,    71,
888       86,    34,    86,     0,    34,     0,     0,    47,     0,    46
889 };
890
891 /* YYDEFGOTO[NTERM-NUM].  */
892 static const yytype_int16 yydefgoto[] =
893 {
894       -1,     1,    28,   138,    29,    70,   120,   121,    30,    48,
895       31,    76,    32,   141,    71,   196,   197,   214,   198,   229,
896      240,   247,   291,   300,   312,   199,   250,   271,   281,   200,
897      139,   140,   123,   210,   211,   224,   109,   110,   201,   108,
898       87,    88,    35,    36,    37,    38,    39,    40,    49,   259,
899      260,   261,    45,    46,    47,    41,    42,   129,   202,   203,
900      135,   231,   204,   314,   134
901 };
902
903 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
904    STATE-NUM.  */
905 #define YYPACT_NINF -269
906 static const yytype_int16 yypact[] =
907 {
908     -269,   335,  -269,  -269,   -31,   -24,  -269,  -269,  -269,  -269,
909     -269,  -269,  -269,    12,    12,    12,   -19,   -12,  -269,  -269,
910     -269,   978,   978,  -269,   978,  1023,   804,    21,  -269,   115,
911      -21,  -269,  -269,     8,  1062,   952,   -20,   330,  -269,  -269,
912     -269,  -269,   246,   736,   804,  -269,     2,  -269,   205,    15,
913     -269,  -269,  -269,   736,   736,    70,    52,    80,    52,    52,
914      978,   147,  -269,  -269,    50,   308,   174,  -269,    64,  -269,
915     -269,  -269,     8,  -269,    64,  -269,   129,  -269,  -269,   978,
916      143,   978,   978,   978,    64,  -269,  -269,  -269,   978,   112,
917      -20,   978,   978,   978,   978,   978,   978,   978,   978,   978,
918      978,   978,   978,  -269,  -269,  -269,  -269,   141,   978,    90,
919      152,  1101,    48,  -269,  -269,  -269,  -269,  -269,  -269,   111,
920      105,  -269,   978,  -269,    90,    90,   308,  -269,  -269,  -269,
921      978,    64,  -269,   134,   830,  -269,  -269,    13,   -16,     8,
922     -269,   552,  -269,  -269,    53,  -269,   142,   300,  1081,   978,
923      103,    12,   185,   185,    52,    52,    52,    52,   185,   185,
924       52,    52,    52,    52,  -269,  1101,  -269,  -269,  -269,    63,
925      -20,  -269,  -269,  1101,  -269,   143,  -269,  1101,  -269,  -269,
926     -269,   121,  -269,     6,   130,   137,    64,   139,   -16,   -16,
927     -269,  -269,   -16,   978,   -16,    64,  -269,  -269,   -16,  -269,
928     -269,  1101,  -269,   127,    64,   978,  1101,  -269,  -269,  -269,
929       90,   118,  -269,   978,   978,  -269,   180,   978,   978,   665,
930      875,  -269,  -269,  -269,   -16,  1101,  -269,  -269,  -269,   598,
931      552,    64,  -269,  -269,  1101,    64,  -269,    28,   308,   -16,
932      -24,   140,   308,   308,   189,   -14,  -269,   127,  -269,   804,
933      201,  -269,  -269,  -269,  -269,  -269,  -269,    64,  -269,  -269,
934       14,  -269,  -269,  -269,    64,    64,   158,   143,    64,    50,
935     -269,  -269,   665,  -269,  -269,   -21,   665,   978,    90,   710,
936      134,   978,   198,  -269,  -269,   308,    64,  1056,    64,   952,
937       64,    60,    64,   665,    64,   907,   665,  -269,   119,   177,
938     -269,   155,  -269,  -269,   907,    90,  -269,  -269,  -269,   224,
939      228,  -269,   177,  -269,    64,  -269,    90,    64,  -269,  -269,
940       64,  -269,    64,   665,  -269,   406,   665,  -269,   479,  -269
941 };
942
943 /* YYPGOTO[NTERM-NUM].  */
944 static const yytype_int16 yypgoto[] =
945 {
946     -269,  -269,  -269,  -269,  -269,   208,  -269,  -269,  -269,  -269,
947      -58,  -269,  -269,  -193,    72,  -171,  -269,  -269,  -189,  -269,
948     -269,  -268,  -269,  -269,  -269,  -269,  -269,  -269,  -269,  -269,
949       45,    37,  -269,  -269,  -269,    38,   -48,   -23,    -1,  -269,
950     -269,  -269,   -26,    44,  -269,   217,  -269,     1,   102,  -269,
951     -269,    -3,   -39,  -269,  -269,   -72,    -2,  -269,   -28,  -213,
952      -49,  -269,   -25,   -47,    66
953 };
954
955 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
956    positive, shift that token.  If negative, reduce the rule which
957    number is the opposite.  If YYTABLE_NINF, syntax error.  */
958 #define YYTABLE_NINF -101
959 static const yytype_int16 yytable[] =
960 {
961       34,    73,    73,    64,    74,   124,   125,   114,   145,   230,
962      215,    50,    51,    52,   178,   133,     5,   252,   113,    57,
963       57,   112,    57,    62,     4,    65,   267,   305,    67,   255,
964      273,   246,   256,    57,    19,    43,   316,    91,    92,    93,
965       94,    95,   111,   111,    96,    44,    33,    53,   244,   130,
966       68,   130,   111,   111,    54,    44,    67,    69,    77,   126,
967      166,   297,    78,   -11,   208,    56,    58,   209,    59,    66,
968      122,    44,   216,     4,    72,   171,   172,    25,   144,    90,
969      146,   147,   148,    44,   298,   299,   -11,   150,   315,    57,
970       57,    57,    57,    57,    57,    57,    57,    57,    57,    57,
971       57,   282,   131,   212,   131,   284,   246,   165,    85,    86,
972       19,   142,  -101,    74,    19,   246,    96,   132,   167,   236,
973       57,   149,   303,   105,   106,   306,   307,   308,   325,   173,
974      -90,   328,   -86,   177,   143,   152,   153,   154,   155,   156,
975      157,   158,   159,   160,   161,   162,   163,     5,   206,    50,
976      151,    78,   327,   130,   164,   329,    79,   132,  -101,  -101,
977      168,   235,  -100,    74,    74,    19,   170,    74,   174,    74,
978       20,   169,   131,    74,   175,   136,   309,   310,   232,    23,
979      137,   251,    80,    72,   241,   -91,    68,   213,    69,   257,
980      127,   128,   225,   264,   265,   278,   217,    85,    86,    74,
981       69,   262,  -100,   218,   234,   220,   131,   263,   115,   116,
982      179,   270,   238,   225,    74,   266,   242,   243,   290,  -100,
983      280,   262,   268,   219,   277,  -100,   269,   195,   111,   286,
984      313,   318,   227,    72,    72,   319,   292,    72,    75,    72,
985      311,   233,    61,    72,    93,    94,    95,   283,    65,    96,
986      117,   118,   239,   207,   288,   289,   317,   274,   103,   104,
987      221,   222,   294,     0,   223,   320,   226,   322,   253,    72,
988      228,     0,   254,   119,     0,     0,   285,   237,   287,    57,
989        0,     0,     0,     0,    72,     0,     0,    57,     0,   105,
990      106,     0,     0,     0,   272,     0,   248,   107,     0,     0,
991        0,   275,   276,     0,     0,   279,     0,     0,     0,    78,
992        0,   258,     0,     0,    79,     0,     0,    78,     0,     0,
993        0,     0,    79,   293,     0,   295,     0,   296,   301,   302,
994        0,   304,     0,    90,     0,     2,     3,     0,     4,     5,
995       80,    81,     6,     7,     0,     0,     0,     0,    80,    81,
996       82,   321,     8,     9,   323,    85,    86,   324,     0,   326,
997       83,     0,     0,    85,    86,     0,     0,     0,     0,     0,
998       10,    11,    12,    13,     0,   132,     0,     0,    14,    15,
999       16,    17,    18,     0,     0,    19,    20,    97,    98,    99,
1000      100,   101,    21,    22,   102,    23,     0,    24,     0,     0,
1001       25,    26,     0,    27,     0,     0,   -14,   180,   -14,     4,
1002        5,     0,     0,     6,     7,     0,     0,     0,     0,     0,
1003        0,     0,     0,     0,     0,   181,     0,   182,   183,   184,
1004      -69,   -69,   185,   186,   187,   188,   189,   190,   191,   192,
1005      193,     0,     0,     0,    13,   194,     0,     0,     0,    14,
1006       15,    16,    17,     0,     0,     0,   -69,    20,     0,     0,
1007        0,     0,     0,    21,    22,     0,    23,     0,    24,     0,
1008        0,    25,    26,     0,    55,     0,     0,    68,   -69,    69,
1009      180,     0,     4,     5,     0,     0,     6,     7,     0,     0,
1010        0,     0,     0,     0,     0,     0,     0,     0,   181,     0,
1011      182,   183,   184,   -68,   -68,   185,   186,   187,   188,   189,
1012      190,   191,   192,   193,     0,     0,     0,    13,   194,     0,
1013        0,     0,    14,    15,    16,    17,     0,     0,     0,   -68,
1014       20,     0,     0,     0,     0,     0,    21,    22,     0,    23,
1015        0,    24,     0,     0,    25,    26,     0,    55,     0,     0,
1016       68,   -68,    69,   180,     0,     4,     5,     0,     0,     6,
1017        7,     0,     0,     0,     0,     0,     0,     0,     0,     0,
1018        0,   181,     0,   182,   183,   184,     0,     0,   185,   186,
1019      187,   188,   189,   190,   191,   192,   193,     0,     0,     0,
1020       13,   194,     0,     0,     0,    14,    15,    16,    17,    63,
1021        0,     4,     5,    20,     0,     6,     7,     0,   -99,    21,
1022       22,     0,    23,     0,    24,     0,     0,    25,    26,     0,
1023       55,     0,     0,    68,   195,    69,     0,     0,     0,     0,
1024        0,     0,     0,     0,     0,     0,    13,     0,     0,     0,
1025        0,    14,    15,    16,    17,     0,     0,     0,   -99,    20,
1026        0,     0,     0,     0,     0,    21,    22,     0,    23,     0,
1027       24,     0,     0,    25,   249,   -99,    55,     0,     4,     5,
1028        0,   -99,     6,     7,     0,     0,     0,     0,     0,     0,
1029        0,     0,     0,     0,   181,     0,   182,   183,   184,     0,
1030        0,   185,   186,   187,   188,   189,   190,   191,   192,   193,
1031        0,     0,     0,    13,   194,     0,     0,     0,    14,    15,
1032       16,    17,     0,     4,     5,     0,    20,     6,     7,     0,
1033        0,     0,    21,    22,     0,    23,     0,    24,     0,     0,
1034       25,    26,     0,    55,     0,     0,    68,    63,    69,     4,
1035        5,     0,     0,     6,     7,     0,     0,     0,    13,     0,
1036        0,     0,     0,    14,    15,    16,    17,     0,     0,     0,
1037        0,    20,     0,     0,     0,     0,     0,    21,    22,     0,
1038       23,     0,    24,     0,    13,    25,    26,     0,    55,    14,
1039       15,    16,    17,    69,     0,     0,     0,    20,     0,     0,
1040        0,     0,     0,    21,    22,     0,    23,     0,    24,     0,
1041        0,    25,    26,   -99,    55,    63,     0,     4,     5,     0,
1042        0,     6,     7,     0,     0,     0,     0,     0,     0,     0,
1043        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
1044        0,   176,     0,     4,     5,     0,     0,     6,     7,     0,
1045        0,     0,    13,     0,     0,     0,     0,    14,    15,    16,
1046       17,     0,     0,     0,     0,    20,     0,     0,     0,     0,
1047        0,    21,    22,     0,    23,     0,    24,     0,    13,    25,
1048       26,     0,    55,    14,    15,    16,    17,     0,     4,   245,
1049        0,    20,     6,     7,     0,     0,     0,    21,    22,     0,
1050       23,     0,    24,     0,     0,    25,    26,   183,    55,     0,
1051        0,     0,     0,     0,     0,     0,   190,   191,     0,     0,
1052        4,     5,     0,    13,     6,     7,     0,     0,    14,    15,
1053       16,    17,     0,     0,     0,     0,    20,     0,     0,   183,
1054        0,     0,    21,    22,     0,    23,     0,    24,   190,   191,
1055       25,    26,     0,    55,     0,    13,     0,     0,     0,     0,
1056       14,    15,    16,    17,     0,     4,     5,     0,    20,     6,
1057        7,     0,     0,    89,    21,    22,     0,    23,     0,    24,
1058        0,     0,    25,    26,     0,    55,     0,     0,     0,     0,
1059        0,     4,     5,     0,     0,     6,     7,     0,     0,     0,
1060       13,     0,     0,     0,     0,    14,    15,    16,    17,     0,
1061        0,     0,     0,    20,     0,     0,     0,     0,     0,    21,
1062       22,     0,    23,     0,    24,     0,    13,    25,    26,     0,
1063       55,    14,    15,    16,    17,     0,     4,     5,     0,    20,
1064        6,     7,     0,     0,     0,    21,    22,     0,    23,     0,
1065       24,     0,     0,    25,    26,     0,    55,     0,     0,     0,
1066        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
1067        0,     0,     0,     0,     0,    78,    14,    15,    16,    17,
1068       79,    78,     0,     0,    20,     0,    79,     0,     0,     0,
1069       21,    22,     0,    23,     0,    24,     0,     0,    25,    60,
1070       78,    55,     0,     0,     0,    79,    80,    81,    82,     0,
1071        0,     0,    80,    81,    82,     0,     0,     0,    83,     0,
1072       78,    85,    86,     0,    83,    79,    84,    85,    86,     0,
1073        0,    80,    81,    82,     0,     0,     0,     0,     0,    69,
1074        0,     0,     0,    83,   205,     0,    85,    86,     0,     0,
1075        0,    80,    81,    82,     0,     0,     0,     0,     0,     0,
1076        0,     0,     0,    83,     0,     0,    85,    86
1077 };
1078
1079 #define yypact_value_is_default(yystate) \
1080   ((yystate) == (-269))
1081
1082 #define yytable_value_is_error(yytable_value) \
1083   ((yytable_value) == (-101))
1084
1085 static const yytype_int16 yycheck[] =
1086 {
1087        1,    29,    30,    26,    29,    53,    54,    46,    80,   202,
1088        4,    13,    14,    15,     1,    64,     4,   230,    16,    21,
1089       22,    44,    24,    25,     3,    26,    40,   295,    27,     1,
1090       16,   220,     4,    35,    50,    66,   304,    57,    58,    59,
1091       60,    61,    43,    44,    64,    69,     1,    66,   219,     1,
1092       71,     1,    53,    54,    66,    69,    55,    73,    50,    60,
1093      109,     1,     9,    50,     1,    21,    22,     4,    24,    48,
1094       55,    69,    66,     3,    29,   124,   125,    65,    79,    35,
1095       81,    82,    83,    69,    24,    25,    73,    88,   301,    91,
1096       92,    93,    94,    95,    96,    97,    98,    99,   100,   101,
1097      102,   272,    54,   175,    54,   276,   295,   108,    55,    56,
1098       50,    74,     9,   138,    50,   304,    64,    67,    70,     1,
1099      122,    84,   293,    43,    44,   296,     7,     8,   321,   130,
1100       67,   324,    72,   134,     5,    91,    92,    93,    94,    95,
1101       96,    97,    98,    99,   100,   101,   102,     4,   149,   151,
1102       38,     9,   323,     1,    13,   326,    14,    67,    55,    56,
1103       49,   210,    10,   188,   189,    50,   122,   192,   131,   194,
1104       51,    66,    54,   198,    40,     1,    57,    58,   203,    60,
1105        6,   229,    40,   138,     4,    67,    71,    66,    73,   238,
1106       43,    44,   193,   242,   243,   267,    66,    55,    56,   224,
1107       73,   240,    50,    66,   205,    66,    54,    67,     3,     4,
1108      138,    10,   213,   214,   239,    26,   217,   218,    20,    67,
1109      269,   260,   247,   186,    66,    73,   249,    72,   229,   278,
1110       53,     7,   195,   188,   189,     7,   285,   192,    30,   194,
1111      298,   204,    25,   198,    59,    60,    61,   275,   249,    64,
1112       45,    46,   214,   151,   279,   281,   305,   260,    12,    13,
1113      188,   189,   287,    -1,   192,   312,   194,   316,   231,   224,
1114      198,    -1,   235,    68,    -1,    -1,   277,   211,   279,   281,
1115       -1,    -1,    -1,    -1,   239,    -1,    -1,   289,    -1,    43,
1116       44,    -1,    -1,    -1,   257,    -1,   224,    51,    -1,    -1,
1117       -1,   264,   265,    -1,    -1,   268,    -1,    -1,    -1,     9,
1118       -1,   239,    -1,    -1,    14,    -1,    -1,     9,    -1,    -1,
1119       -1,    -1,    14,   286,    -1,   288,    -1,   290,   291,   292,
1120       -1,   294,    -1,   289,    -1,     0,     1,    -1,     3,     4,
1121       40,    41,     7,     8,    -1,    -1,    -1,    -1,    40,    41,
1122       42,   314,    17,    18,   317,    55,    56,   320,    -1,   322,
1123       52,    -1,    -1,    55,    56,    -1,    -1,    -1,    -1,    -1,
1124       35,    36,    37,    38,    -1,    67,    -1,    -1,    43,    44,
1125       45,    46,    47,    -1,    -1,    50,    51,    57,    58,    59,
1126       60,    61,    57,    58,    64,    60,    -1,    62,    -1,    -1,
1127       65,    66,    -1,    68,    -1,    -1,    71,     1,    73,     3,
1128        4,    -1,    -1,     7,     8,    -1,    -1,    -1,    -1,    -1,
1129       -1,    -1,    -1,    -1,    -1,    19,    -1,    21,    22,    23,
1130       24,    25,    26,    27,    28,    29,    30,    31,    32,    33,
1131       34,    -1,    -1,    -1,    38,    39,    -1,    -1,    -1,    43,
1132       44,    45,    46,    -1,    -1,    -1,    50,    51,    -1,    -1,
1133       -1,    -1,    -1,    57,    58,    -1,    60,    -1,    62,    -1,
1134       -1,    65,    66,    -1,    68,    -1,    -1,    71,    72,    73,
1135        1,    -1,     3,     4,    -1,    -1,     7,     8,    -1,    -1,
1136       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    19,    -1,
1137       21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
1138       31,    32,    33,    34,    -1,    -1,    -1,    38,    39,    -1,
1139       -1,    -1,    43,    44,    45,    46,    -1,    -1,    -1,    50,
1140       51,    -1,    -1,    -1,    -1,    -1,    57,    58,    -1,    60,
1141       -1,    62,    -1,    -1,    65,    66,    -1,    68,    -1,    -1,
1142       71,    72,    73,     1,    -1,     3,     4,    -1,    -1,     7,
1143        8,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
1144       -1,    19,    -1,    21,    22,    23,    -1,    -1,    26,    27,
1145       28,    29,    30,    31,    32,    33,    34,    -1,    -1,    -1,
1146       38,    39,    -1,    -1,    -1,    43,    44,    45,    46,     1,
1147       -1,     3,     4,    51,    -1,     7,     8,    -1,    10,    57,
1148       58,    -1,    60,    -1,    62,    -1,    -1,    65,    66,    -1,
1149       68,    -1,    -1,    71,    72,    73,    -1,    -1,    -1,    -1,
1150       -1,    -1,    -1,    -1,    -1,    -1,    38,    -1,    -1,    -1,
1151       -1,    43,    44,    45,    46,    -1,    -1,    -1,    50,    51,
1152       -1,    -1,    -1,    -1,    -1,    57,    58,    -1,    60,    -1,
1153       62,    -1,    -1,    65,    66,    67,    68,    -1,     3,     4,
1154       -1,    73,     7,     8,    -1,    -1,    -1,    -1,    -1,    -1,
1155       -1,    -1,    -1,    -1,    19,    -1,    21,    22,    23,    -1,
1156       -1,    26,    27,    28,    29,    30,    31,    32,    33,    34,
1157       -1,    -1,    -1,    38,    39,    -1,    -1,    -1,    43,    44,
1158       45,    46,    -1,     3,     4,    -1,    51,     7,     8,    -1,
1159       -1,    -1,    57,    58,    -1,    60,    -1,    62,    -1,    -1,
1160       65,    66,    -1,    68,    -1,    -1,    71,     1,    73,     3,
1161        4,    -1,    -1,     7,     8,    -1,    -1,    -1,    38,    -1,
1162       -1,    -1,    -1,    43,    44,    45,    46,    -1,    -1,    -1,
1163       -1,    51,    -1,    -1,    -1,    -1,    -1,    57,    58,    -1,
1164       60,    -1,    62,    -1,    38,    65,    66,    -1,    68,    43,
1165       44,    45,    46,    73,    -1,    -1,    -1,    51,    -1,    -1,
1166       -1,    -1,    -1,    57,    58,    -1,    60,    -1,    62,    -1,
1167       -1,    65,    66,    67,    68,     1,    -1,     3,     4,    -1,
1168       -1,     7,     8,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
1169       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
1170       -1,     1,    -1,     3,     4,    -1,    -1,     7,     8,    -1,
1171       -1,    -1,    38,    -1,    -1,    -1,    -1,    43,    44,    45,
1172       46,    -1,    -1,    -1,    -1,    51,    -1,    -1,    -1,    -1,
1173       -1,    57,    58,    -1,    60,    -1,    62,    -1,    38,    65,
1174       66,    -1,    68,    43,    44,    45,    46,    -1,     3,     4,
1175       -1,    51,     7,     8,    -1,    -1,    -1,    57,    58,    -1,
1176       60,    -1,    62,    -1,    -1,    65,    66,    22,    68,    -1,
1177       -1,    -1,    -1,    -1,    -1,    -1,    31,    32,    -1,    -1,
1178        3,     4,    -1,    38,     7,     8,    -1,    -1,    43,    44,
1179       45,    46,    -1,    -1,    -1,    -1,    51,    -1,    -1,    22,
1180       -1,    -1,    57,    58,    -1,    60,    -1,    62,    31,    32,
1181       65,    66,    -1,    68,    -1,    38,    -1,    -1,    -1,    -1,
1182       43,    44,    45,    46,    -1,     3,     4,    -1,    51,     7,
1183        8,    -1,    -1,    11,    57,    58,    -1,    60,    -1,    62,
1184       -1,    -1,    65,    66,    -1,    68,    -1,    -1,    -1,    -1,
1185       -1,     3,     4,    -1,    -1,     7,     8,    -1,    -1,    -1,
1186       38,    -1,    -1,    -1,    -1,    43,    44,    45,    46,    -1,
1187       -1,    -1,    -1,    51,    -1,    -1,    -1,    -1,    -1,    57,
1188       58,    -1,    60,    -1,    62,    -1,    38,    65,    66,    -1,
1189       68,    43,    44,    45,    46,    -1,     3,     4,    -1,    51,
1190        7,     8,    -1,    -1,    -1,    57,    58,    -1,    60,    -1,
1191       62,    -1,    -1,    65,    66,    -1,    68,    -1,    -1,    -1,
1192       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
1193       -1,    -1,    -1,    -1,    -1,     9,    43,    44,    45,    46,
1194       14,     9,    -1,    -1,    51,    -1,    14,    -1,    -1,    -1,
1195       57,    58,    -1,    60,    -1,    62,    -1,    -1,    65,    66,
1196        9,    68,    -1,    -1,    -1,    14,    40,    41,    42,    -1,
1197       -1,    -1,    40,    41,    42,    -1,    -1,    -1,    52,    -1,
1198        9,    55,    56,    -1,    52,    14,    54,    55,    56,    -1,
1199       -1,    40,    41,    42,    -1,    -1,    -1,    -1,    -1,    73,
1200       -1,    -1,    -1,    52,    53,    -1,    55,    56,    -1,    -1,
1201       -1,    40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,
1202       -1,    -1,    -1,    52,    -1,    -1,    55,    56
1203 };
1204
1205 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
1206    symbol of state STATE-NUM.  */
1207 static const yytype_uint8 yystos[] =
1208 {
1209        0,    75,     0,     1,     3,     4,     7,     8,    17,    18,
1210       35,    36,    37,    38,    43,    44,    45,    46,    47,    50,
1211       51,    57,    58,    60,    62,    65,    66,    68,    76,    78,
1212       82,    84,    86,   104,   112,   116,   117,   118,   119,   120,
1213      121,   129,   130,    66,    69,   126,   127,   128,    83,   122,
1214      130,   130,   130,    66,    66,    68,   117,   130,   117,   117,
1215       66,   119,   130,     1,   111,   112,    48,   121,    71,    73,
1216       79,    88,   104,   132,   136,    79,    85,    50,     9,    14,
1217       40,    41,    42,    52,    54,    55,    56,   114,   115,    11,
1218      117,    57,    58,    59,    60,    61,    64,    57,    58,    59,
1219       60,    61,    64,    12,    13,    43,    44,    51,   113,   110,
1220      111,   112,   111,    16,   126,     3,     4,    45,    46,    68,
1221       80,    81,    55,   106,   110,   110,   112,    43,    44,   131,
1222        1,    54,    67,   134,   138,   134,     1,     6,    77,   104,
1223      105,    87,   105,     5,   112,   129,   112,   112,   112,   105,
1224      112,    38,   117,   117,   117,   117,   117,   117,   117,   117,
1225      117,   117,   117,   117,    13,   112,   134,    70,    49,    66,
1226      117,   134,   134,   112,   105,    40,     1,   112,     1,    88,
1227        1,    19,    21,    22,    23,    26,    27,    28,    29,    30,
1228       31,    32,    33,    34,    39,    72,    89,    90,    92,    99,
1229      103,   112,   132,   133,   136,    53,   112,   122,     1,     4,
1230      107,   108,   129,    66,    91,     4,    66,    66,    66,   105,
1231       66,    88,    88,    88,   109,   112,    88,   105,    88,    93,
1232       87,   135,   136,   105,   112,   134,     1,   138,   112,   109,
1233       94,     4,   112,   112,    89,     4,    92,    95,    88,    66,
1234      100,   110,   133,   105,   105,     1,     4,   134,    88,   123,
1235      124,   125,   126,    67,   134,   134,    26,    40,   136,   111,
1236       10,   101,   105,    16,   125,   105,   105,    66,   129,   105,
1237      134,   102,    89,   132,    89,   112,   134,   112,   136,   116,
1238       20,    96,   134,   105,   136,   105,   105,     1,    24,    25,
1239       97,   105,   105,    89,   105,    95,    89,     7,     8,    57,
1240       58,    84,    98,    53,   137,   133,    95,   134,     7,     7,
1241      137,   105,   134,   105,   105,    87,   105,    89,    87,    89
1242 };
1243
1244 #define yyerrok         (yyerrstatus = 0)
1245 #define yyclearin       (yychar = YYEMPTY)
1246 #define YYEMPTY         (-2)
1247 #define YYEOF           0
1248
1249 #define YYACCEPT        goto yyacceptlab
1250 #define YYABORT         goto yyabortlab
1251 #define YYERROR         goto yyerrorlab
1252
1253
1254 /* Like YYERROR except do call yyerror.  This remains here temporarily
1255    to ease the transition to the new meaning of YYERROR, for GCC.
1256    Once GCC version 2 has supplanted version 1, this can go.  However,
1257    YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
1258    in Bison 2.4.2's NEWS entry, where a plan to phase it out is
1259    discussed.  */
1260
1261 #define YYFAIL          goto yyerrlab
1262 #if defined YYFAIL
1263   /* This is here to suppress warnings from the GCC cpp's
1264      -Wunused-macros.  Normally we don't worry about that warning, but
1265      some users do, and we want to make it easy for users to remove
1266      YYFAIL uses, which will produce warnings from Bison 2.5.  */
1267 #endif
1268
1269 #define YYRECOVERING()  (!!yyerrstatus)
1270
1271 #define YYBACKUP(Token, Value)                                  \
1272 do                                                              \
1273   if (yychar == YYEMPTY && yylen == 1)                          \
1274     {                                                           \
1275       yychar = (Token);                                         \
1276       yylval = (Value);                                         \
1277       YYPOPSTACK (1);                                           \
1278       goto yybackup;                                            \
1279     }                                                           \
1280   else                                                          \
1281     {                                                           \
1282       yyerror (YY_("syntax error: cannot back up")); \
1283       YYERROR;                                                  \
1284     }                                                           \
1285 while (YYID (0))
1286
1287
1288 #define YYTERROR        1
1289 #define YYERRCODE       256
1290
1291
1292 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
1293    If N is 0, then set CURRENT to the empty location which ends
1294    the previous symbol: RHS[0] (always defined).  */
1295
1296 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
1297 #ifndef YYLLOC_DEFAULT
1298 # define YYLLOC_DEFAULT(Current, Rhs, N)                                \
1299     do                                                                  \
1300       if (YYID (N))                                                    \
1301         {                                                               \
1302           (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
1303           (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
1304           (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
1305           (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
1306         }                                                               \
1307       else                                                              \
1308         {                                                               \
1309           (Current).first_line   = (Current).last_line   =              \
1310             YYRHSLOC (Rhs, 0).last_line;                                \
1311           (Current).first_column = (Current).last_column =              \
1312             YYRHSLOC (Rhs, 0).last_column;                              \
1313         }                                                               \
1314     while (YYID (0))
1315 #endif
1316
1317
1318 /* This macro is provided for backward compatibility. */
1319
1320 #ifndef YY_LOCATION_PRINT
1321 # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
1322 #endif
1323
1324
1325 /* YYLEX -- calling `yylex' with the right arguments.  */
1326
1327 #ifdef YYLEX_PARAM
1328 # define YYLEX yylex (YYLEX_PARAM)
1329 #else
1330 # define YYLEX yylex ()
1331 #endif
1332
1333 /* Enable debugging if requested.  */
1334 #if YYDEBUG
1335
1336 # ifndef YYFPRINTF
1337 #  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
1338 #  define YYFPRINTF fprintf
1339 # endif
1340
1341 # define YYDPRINTF(Args)                        \
1342 do {                                            \
1343   if (yydebug)                                  \
1344     YYFPRINTF Args;                             \
1345 } while (YYID (0))
1346
1347 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \
1348 do {                                                                      \
1349   if (yydebug)                                                            \
1350     {                                                                     \
1351       YYFPRINTF (stderr, "%s ", Title);                                   \
1352       yy_symbol_print (stderr,                                            \
1353                   Type, Value); \
1354       YYFPRINTF (stderr, "\n");                                           \
1355     }                                                                     \
1356 } while (YYID (0))
1357
1358
1359 /*--------------------------------.
1360 | Print this symbol on YYOUTPUT.  |
1361 `--------------------------------*/
1362
1363 /*ARGSUSED*/
1364 #if (defined __STDC__ || defined __C99__FUNC__      || defined __cplusplus || defined _MSC_VER)
1365 static void
1366 yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
1367 #else
1368 static void
1369 yy_symbol_value_print (yyoutput, yytype, yyvaluep)
1370     FILE *yyoutput;
1371     int yytype;
1372     YYSTYPE const * const yyvaluep;
1373 #endif
1374 {
1375   if (!yyvaluep)
1376     return;
1377 # ifdef YYPRINT
1378   if (yytype < YYNTOKENS)
1379     YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
1380 # else
1381   YYUSE (yyoutput);
1382 # endif
1383   switch (yytype)
1384     {
1385       default:
1386         break;
1387     }
1388 }
1389
1390
1391 /*--------------------------------.
1392 | Print this symbol on YYOUTPUT.  |
1393 `--------------------------------*/
1394
1395 #if (defined __STDC__ || defined __C99__FUNC__      || defined __cplusplus || defined _MSC_VER)
1396 static void
1397 yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
1398 #else
1399 static void
1400 yy_symbol_print (yyoutput, yytype, yyvaluep)
1401     FILE *yyoutput;
1402     int yytype;
1403     YYSTYPE const * const yyvaluep;
1404 #endif
1405 {
1406   if (yytype < YYNTOKENS)
1407     YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
1408   else
1409     YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
1410
1411   yy_symbol_value_print (yyoutput, yytype, yyvaluep);
1412   YYFPRINTF (yyoutput, ")");
1413 }
1414
1415 /*------------------------------------------------------------------.
1416 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
1417 | TOP (included).                                                   |
1418 `------------------------------------------------------------------*/
1419
1420 #if (defined __STDC__ || defined __C99__FUNC__      || defined __cplusplus || defined _MSC_VER)
1421 static void
1422 yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
1423 #else
1424 static void
1425 yy_stack_print (yybottom, yytop)
1426     yytype_int16 *yybottom;
1427     yytype_int16 *yytop;
1428 #endif
1429 {
1430   YYFPRINTF (stderr, "Stack now");
1431   for (; yybottom <= yytop; yybottom++)
1432     {
1433       int yybot = *yybottom;
1434       YYFPRINTF (stderr, " %d", yybot);
1435     }
1436   YYFPRINTF (stderr, "\n");
1437 }
1438
1439 # define YY_STACK_PRINT(Bottom, Top)                            \
1440 do {                                                            \
1441   if (yydebug)                                                  \
1442     yy_stack_print ((Bottom), (Top));                           \
1443 } while (YYID (0))
1444
1445
1446 /*------------------------------------------------.
1447 | Report that the YYRULE is going to be reduced.  |
1448 `------------------------------------------------*/
1449
1450 #if (defined __STDC__ || defined __C99__FUNC__      || defined __cplusplus || defined _MSC_VER)
1451 static void
1452 yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
1453 #else
1454 static void
1455 yy_reduce_print (yyvsp, yyrule)
1456     YYSTYPE *yyvsp;
1457     int yyrule;
1458 #endif
1459 {
1460   int yynrhs = yyr2[yyrule];
1461   int yyi;
1462   unsigned long int yylno = yyrline[yyrule];
1463   YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
1464              yyrule - 1, yylno);
1465   /* The symbols being reduced.  */
1466   for (yyi = 0; yyi < yynrhs; yyi++)
1467     {
1468       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
1469       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
1470                        &(yyvsp[(yyi + 1) - (yynrhs)])
1471                                        );
1472       YYFPRINTF (stderr, "\n");
1473     }
1474 }
1475
1476 # define YY_REDUCE_PRINT(Rule)          \
1477 do {                                    \
1478   if (yydebug)                          \
1479     yy_reduce_print (yyvsp, Rule); \
1480 } while (YYID (0))
1481
1482 /* Nonzero means print parse trace.  It is left uninitialized so that
1483    multiple parsers can coexist.  */
1484 int yydebug;
1485 #else /* !YYDEBUG */
1486 # define YYDPRINTF(Args)
1487 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
1488 # define YY_STACK_PRINT(Bottom, Top)
1489 # define YY_REDUCE_PRINT(Rule)
1490 #endif /* !YYDEBUG */
1491
1492
1493 /* YYINITDEPTH -- initial size of the parser's stacks.  */
1494 #ifndef YYINITDEPTH
1495 # define YYINITDEPTH 200
1496 #endif
1497
1498 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
1499    if the built-in stack extension method is used).
1500
1501    Do not make this value too large; the results are undefined if
1502    YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
1503    evaluated with infinite-precision integer arithmetic.  */
1504
1505 #ifndef YYMAXDEPTH
1506 # define YYMAXDEPTH 10000
1507 #endif
1508
1509
1510 #if YYERROR_VERBOSE
1511
1512 # ifndef yystrlen
1513 #  if defined __GLIBC__ && defined _STRING_H
1514 #   define yystrlen strlen
1515 #  else
1516 /* Return the length of YYSTR.  */
1517 #if (defined __STDC__ || defined __C99__FUNC__      || defined __cplusplus || defined _MSC_VER)
1518 static YYSIZE_T
1519 yystrlen (const char *yystr)
1520 #else
1521 static YYSIZE_T
1522 yystrlen (yystr)
1523     const char *yystr;
1524 #endif
1525 {
1526   YYSIZE_T yylen;
1527   for (yylen = 0; yystr[yylen]; yylen++)
1528     continue;
1529   return yylen;
1530 }
1531 #  endif
1532 # endif
1533
1534 # ifndef yystpcpy
1535 #  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
1536 #   define yystpcpy stpcpy
1537 #  else
1538 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
1539    YYDEST.  */
1540 #if (defined __STDC__ || defined __C99__FUNC__      || defined __cplusplus || defined _MSC_VER)
1541 static char *
1542 yystpcpy (char *yydest, const char *yysrc)
1543 #else
1544 static char *
1545 yystpcpy (yydest, yysrc)
1546     char *yydest;
1547     const char *yysrc;
1548 #endif
1549 {
1550   char *yyd = yydest;
1551   const char *yys = yysrc;
1552
1553   while ((*yyd++ = *yys++) != '\0')
1554     continue;
1555
1556   return yyd - 1;
1557 }
1558 #  endif
1559 # endif
1560
1561 # ifndef yytnamerr
1562 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
1563    quotes and backslashes, so that it's suitable for yyerror.  The
1564    heuristic is that double-quoting is unnecessary unless the string
1565    contains an apostrophe, a comma, or backslash (other than
1566    backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
1567    null, do not copy; instead, return the length of what the result
1568    would have been.  */
1569 static YYSIZE_T
1570 yytnamerr (char *yyres, const char *yystr)
1571 {
1572   if (*yystr == '"')
1573     {
1574       YYSIZE_T yyn = 0;
1575       char const *yyp = yystr;
1576
1577       for (;;)
1578         switch (*++yyp)
1579           {
1580           case '\'':
1581           case ',':
1582             goto do_not_strip_quotes;
1583
1584           case '\\':
1585             if (*++yyp != '\\')
1586               goto do_not_strip_quotes;
1587             /* Fall through.  */
1588           default:
1589             if (yyres)
1590               yyres[yyn] = *yyp;
1591             yyn++;
1592             break;
1593
1594           case '"':
1595             if (yyres)
1596               yyres[yyn] = '\0';
1597             return yyn;
1598           }
1599     do_not_strip_quotes: ;
1600     }
1601
1602   if (! yyres)
1603     return yystrlen (yystr);
1604
1605   return yystpcpy (yyres, yystr) - yyres;
1606 }
1607 # endif
1608
1609 /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
1610    about the unexpected token YYTOKEN for the state stack whose top is
1611    YYSSP.
1612
1613    Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
1614    not large enough to hold the message.  In that case, also set
1615    *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
1616    required number of bytes is too large to store.  */
1617 static int
1618 yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
1619                 yytype_int16 *yyssp, int yytoken)
1620 {
1621   YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
1622   YYSIZE_T yysize = yysize0;
1623   YYSIZE_T yysize1;
1624   enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1625   /* Internationalized format string. */
1626   const char *yyformat = 0;
1627   /* Arguments of yyformat. */
1628   char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1629   /* Number of reported tokens (one for the "unexpected", one per
1630      "expected"). */
1631   int yycount = 0;
1632
1633   /* There are many possibilities here to consider:
1634      - Assume YYFAIL is not used.  It's too flawed to consider.  See
1635        <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
1636        for details.  YYERROR is fine as it does not invoke this
1637        function.
1638      - If this state is a consistent state with a default action, then
1639        the only way this function was invoked is if the default action
1640        is an error action.  In that case, don't check for expected
1641        tokens because there are none.
1642      - The only way there can be no lookahead present (in yychar) is if
1643        this state is a consistent state with a default action.  Thus,
1644        detecting the absence of a lookahead is sufficient to determine
1645        that there is no unexpected or expected token to report.  In that
1646        case, just report a simple "syntax error".
1647      - Don't assume there isn't a lookahead just because this state is a
1648        consistent state with a default action.  There might have been a
1649        previous inconsistent state, consistent state with a non-default
1650        action, or user semantic action that manipulated yychar.
1651      - Of course, the expected token list depends on states to have
1652        correct lookahead information, and it depends on the parser not
1653        to perform extra reductions after fetching a lookahead from the
1654        scanner and before detecting a syntax error.  Thus, state merging
1655        (from LALR or IELR) and default reductions corrupt the expected
1656        token list.  However, the list is correct for canonical LR with
1657        one exception: it will still contain any token that will not be
1658        accepted due to an error action in a later state.
1659   */
1660   if (yytoken != YYEMPTY)
1661     {
1662       int yyn = yypact[*yyssp];
1663       yyarg[yycount++] = yytname[yytoken];
1664       if (!yypact_value_is_default (yyn))
1665         {
1666           /* Start YYX at -YYN if negative to avoid negative indexes in
1667              YYCHECK.  In other words, skip the first -YYN actions for
1668              this state because they are default actions.  */
1669           int yyxbegin = yyn < 0 ? -yyn : 0;
1670           /* Stay within bounds of both yycheck and yytname.  */
1671           int yychecklim = YYLAST - yyn + 1;
1672           int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1673           int yyx;
1674
1675           for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1676             if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
1677                 && !yytable_value_is_error (yytable[yyx + yyn]))
1678               {
1679                 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1680                   {
1681                     yycount = 1;
1682                     yysize = yysize0;
1683                     break;
1684                   }
1685                 yyarg[yycount++] = yytname[yyx];
1686                 yysize1 = yysize + yytnamerr (0, yytname[yyx]);
1687                 if (! (yysize <= yysize1
1688                        && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1689                   return 2;
1690                 yysize = yysize1;
1691               }
1692         }
1693     }
1694
1695   switch (yycount)
1696     {
1697 # define YYCASE_(N, S)                      \
1698       case N:                               \
1699         yyformat = S;                       \
1700       break
1701       YYCASE_(0, YY_("syntax error"));
1702       YYCASE_(1, YY_("syntax error, unexpected %s"));
1703       YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
1704       YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
1705       YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
1706       YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
1707 # undef YYCASE_
1708     }
1709
1710   yysize1 = yysize + yystrlen (yyformat);
1711   if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1712     return 2;
1713   yysize = yysize1;
1714
1715   if (*yymsg_alloc < yysize)
1716     {
1717       *yymsg_alloc = 2 * yysize;
1718       if (! (yysize <= *yymsg_alloc
1719              && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
1720         *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
1721       return 1;
1722     }
1723
1724   /* Avoid sprintf, as that infringes on the user's name space.
1725      Don't have undefined behavior even if the translation
1726      produced a string with the wrong number of "%s"s.  */
1727   {
1728     char *yyp = *yymsg;
1729     int yyi = 0;
1730     while ((*yyp = *yyformat) != '\0')
1731       if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
1732         {
1733           yyp += yytnamerr (yyp, yyarg[yyi++]);
1734           yyformat += 2;
1735         }
1736       else
1737         {
1738           yyp++;
1739           yyformat++;
1740         }
1741   }
1742   return 0;
1743 }
1744 #endif /* YYERROR_VERBOSE */
1745
1746 /*-----------------------------------------------.
1747 | Release the memory associated to this symbol.  |
1748 `-----------------------------------------------*/
1749
1750 /*ARGSUSED*/
1751 #if (defined __STDC__ || defined __C99__FUNC__      || defined __cplusplus || defined _MSC_VER)
1752 static void
1753 yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1754 #else
1755 static void
1756 yydestruct (yymsg, yytype, yyvaluep)
1757     const char *yymsg;
1758     int yytype;
1759     YYSTYPE *yyvaluep;
1760 #endif
1761 {
1762   YYUSE (yyvaluep);
1763
1764   if (!yymsg)
1765     yymsg = "Deleting";
1766   YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1767
1768   switch (yytype)
1769     {
1770
1771       default:
1772         break;
1773     }
1774 }
1775
1776
1777 /* Prevent warnings from -Wmissing-prototypes.  */
1778 #ifdef YYPARSE_PARAM
1779 #if defined __STDC__ || defined __cplusplus
1780 int yyparse (void *YYPARSE_PARAM);
1781 #else
1782 int yyparse ();
1783 #endif
1784 #else /* ! YYPARSE_PARAM */
1785 #if defined __STDC__ || defined __cplusplus
1786 int yyparse (void);
1787 #else
1788 int yyparse ();
1789 #endif
1790 #endif /* ! YYPARSE_PARAM */
1791
1792
1793 /* The lookahead symbol.  */
1794 int yychar;
1795
1796 /* The semantic value of the lookahead symbol.  */
1797 YYSTYPE yylval;
1798
1799 /* Number of syntax errors so far.  */
1800 int yynerrs;
1801
1802
1803 /*----------.
1804 | yyparse.  |
1805 `----------*/
1806
1807 #ifdef YYPARSE_PARAM
1808 #if (defined __STDC__ || defined __C99__FUNC__      || defined __cplusplus || defined _MSC_VER)
1809 int
1810 yyparse (void *YYPARSE_PARAM)
1811 #else
1812 int
1813 yyparse (YYPARSE_PARAM)
1814     void *YYPARSE_PARAM;
1815 #endif
1816 #else /* ! YYPARSE_PARAM */
1817 #if (defined __STDC__ || defined __C99__FUNC__      || defined __cplusplus || defined _MSC_VER)
1818 int
1819 yyparse (void)
1820 #else
1821 int
1822 yyparse ()
1823
1824 #endif
1825 #endif
1826 {
1827     int yystate;
1828     /* Number of tokens to shift before error messages enabled.  */
1829     int yyerrstatus;
1830
1831     /* The stacks and their tools:
1832        `yyss': related to states.
1833        `yyvs': related to semantic values.
1834
1835        Refer to the stacks thru separate pointers, to allow yyoverflow
1836        to reallocate them elsewhere.  */
1837
1838     /* The state stack.  */
1839     yytype_int16 yyssa[YYINITDEPTH];
1840     yytype_int16 *yyss;
1841     yytype_int16 *yyssp;
1842
1843     /* The semantic value stack.  */
1844     YYSTYPE yyvsa[YYINITDEPTH];
1845     YYSTYPE *yyvs;
1846     YYSTYPE *yyvsp;
1847
1848     YYSIZE_T yystacksize;
1849
1850   int yyn;
1851   int yyresult;
1852   /* Lookahead token as an internal (translated) token number.  */
1853   int yytoken;
1854   /* The variables used to return semantic value and location from the
1855      action routines.  */
1856   YYSTYPE yyval;
1857
1858 #if YYERROR_VERBOSE
1859   /* Buffer for error messages, and its allocated size.  */
1860   char yymsgbuf[128];
1861   char *yymsg = yymsgbuf;
1862   YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1863 #endif
1864
1865 #define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
1866
1867   /* The number of symbols on the RHS of the reduced rule.
1868      Keep to zero when no symbol should be popped.  */
1869   int yylen = 0;
1870
1871   yytoken = 0;
1872   yyss = yyssa;
1873   yyvs = yyvsa;
1874   yystacksize = YYINITDEPTH;
1875
1876   YYDPRINTF ((stderr, "Starting parse\n"));
1877
1878   yystate = 0;
1879   yyerrstatus = 0;
1880   yynerrs = 0;
1881   yychar = YYEMPTY; /* Cause a token to be read.  */
1882
1883   /* Initialize stack pointers.
1884      Waste one element of value and location stack
1885      so that they stay on the same level as the state stack.
1886      The wasted elements are never initialized.  */
1887   yyssp = yyss;
1888   yyvsp = yyvs;
1889
1890   goto yysetstate;
1891
1892 /*------------------------------------------------------------.
1893 | yynewstate -- Push a new state, which is found in yystate.  |
1894 `------------------------------------------------------------*/
1895  yynewstate:
1896   /* In all cases, when you get here, the value and location stacks
1897      have just been pushed.  So pushing a state here evens the stacks.  */
1898   yyssp++;
1899
1900  yysetstate:
1901   *yyssp = yystate;
1902
1903   if (yyss + yystacksize - 1 <= yyssp)
1904     {
1905       /* Get the current used size of the three stacks, in elements.  */
1906       YYSIZE_T yysize = yyssp - yyss + 1;
1907
1908 #ifdef yyoverflow
1909       {
1910         /* Give user a chance to reallocate the stack.  Use copies of
1911            these so that the &'s don't force the real ones into
1912            memory.  */
1913         YYSTYPE *yyvs1 = yyvs;
1914         yytype_int16 *yyss1 = yyss;
1915
1916         /* Each stack pointer address is followed by the size of the
1917            data in use in that stack, in bytes.  This used to be a
1918            conditional around just the two extra args, but that might
1919            be undefined if yyoverflow is a macro.  */
1920         yyoverflow (YY_("memory exhausted"),
1921                     &yyss1, yysize * sizeof (*yyssp),
1922                     &yyvs1, yysize * sizeof (*yyvsp),
1923                     &yystacksize);
1924
1925         yyss = yyss1;
1926         yyvs = yyvs1;
1927       }
1928 #else /* no yyoverflow */
1929 # ifndef YYSTACK_RELOCATE
1930       goto yyexhaustedlab;
1931 # else
1932       /* Extend the stack our own way.  */
1933       if (YYMAXDEPTH <= yystacksize)
1934         goto yyexhaustedlab;
1935       yystacksize *= 2;
1936       if (YYMAXDEPTH < yystacksize)
1937         yystacksize = YYMAXDEPTH;
1938
1939       {
1940         yytype_int16 *yyss1 = yyss;
1941         union yyalloc *yyptr =
1942           (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1943         if (! yyptr)
1944           goto yyexhaustedlab;
1945         YYSTACK_RELOCATE (yyss_alloc, yyss);
1946         YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1947 #  undef YYSTACK_RELOCATE
1948         if (yyss1 != yyssa)
1949           YYSTACK_FREE (yyss1);
1950       }
1951 # endif
1952 #endif /* no yyoverflow */
1953
1954       yyssp = yyss + yysize - 1;
1955       yyvsp = yyvs + yysize - 1;
1956
1957       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1958                   (unsigned long int) yystacksize));
1959
1960       if (yyss + yystacksize - 1 <= yyssp)
1961         YYABORT;
1962     }
1963
1964   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1965
1966   if (yystate == YYFINAL)
1967     YYACCEPT;
1968
1969   goto yybackup;
1970
1971 /*-----------.
1972 | yybackup.  |
1973 `-----------*/
1974 yybackup:
1975
1976   /* Do appropriate processing given the current state.  Read a
1977      lookahead token if we need one and don't already have one.  */
1978
1979   /* First try to decide what to do without reference to lookahead token.  */
1980   yyn = yypact[yystate];
1981   if (yypact_value_is_default (yyn))
1982     goto yydefault;
1983
1984   /* Not known => get a lookahead token if don't already have one.  */
1985
1986   /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
1987   if (yychar == YYEMPTY)
1988     {
1989       YYDPRINTF ((stderr, "Reading a token: "));
1990       yychar = YYLEX;
1991     }
1992
1993   if (yychar <= YYEOF)
1994     {
1995       yychar = yytoken = YYEOF;
1996       YYDPRINTF ((stderr, "Now at end of input.\n"));
1997     }
1998   else
1999     {
2000       yytoken = YYTRANSLATE (yychar);
2001       YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
2002     }
2003
2004   /* If the proper action on seeing token YYTOKEN is to reduce or to
2005      detect an error, take that action.  */
2006   yyn += yytoken;
2007   if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
2008     goto yydefault;
2009   yyn = yytable[yyn];
2010   if (yyn <= 0)
2011     {
2012       if (yytable_value_is_error (yyn))
2013         goto yyerrlab;
2014       yyn = -yyn;
2015       goto yyreduce;
2016     }
2017
2018   /* Count tokens shifted since error; after three, turn off error
2019      status.  */
2020   if (yyerrstatus)
2021     yyerrstatus--;
2022
2023   /* Shift the lookahead token.  */
2024   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
2025
2026   /* Discard the shifted token.  */
2027   yychar = YYEMPTY;
2028
2029   yystate = yyn;
2030   *++yyvsp = yylval;
2031
2032   goto yynewstate;
2033
2034
2035 /*-----------------------------------------------------------.
2036 | yydefault -- do the default action for the current state.  |
2037 `-----------------------------------------------------------*/
2038 yydefault:
2039   yyn = yydefact[yystate];
2040   if (yyn == 0)
2041     goto yyerrlab;
2042   goto yyreduce;
2043
2044
2045 /*-----------------------------.
2046 | yyreduce -- Do a reduction.  |
2047 `-----------------------------*/
2048 yyreduce:
2049   /* yyn is the number of a rule to reduce with.  */
2050   yylen = yyr2[yyn];
2051
2052   /* If YYLEN is nonzero, implement the default value of the action:
2053      `$$ = $1'.
2054
2055      Otherwise, the following line sets YYVAL to garbage.
2056      This behavior is undocumented and Bison
2057      users should not rely upon it.  Assigning to YYVAL
2058      unconditionally makes the parser a bit smaller, and it avoids a
2059      GCC warning that YYVAL may be used uninitialized.  */
2060   yyval = yyvsp[1-yylen];
2061
2062
2063   YY_REDUCE_PRINT (yyn);
2064   switch (yyn)
2065     {
2066         case 3:
2067
2068 /* Line 1806 of yacc.c  */
2069 #line 221 "awkgram.y"
2070     {
2071                 rule = 0;
2072                 yyerrok;
2073           }
2074     break;
2075
2076   case 5:
2077
2078 /* Line 1806 of yacc.c  */
2079 #line 227 "awkgram.y"
2080     {
2081                 next_sourcefile();
2082           }
2083     break;
2084
2085   case 6:
2086
2087 /* Line 1806 of yacc.c  */
2088 #line 231 "awkgram.y"
2089     {
2090                 rule = 0;
2091                 /*
2092                  * If errors, give up, don't produce an infinite
2093                  * stream of syntax error messages.
2094                  */
2095                 /* yyerrok; */
2096           }
2097     break;
2098
2099   case 7:
2100
2101 /* Line 1806 of yacc.c  */
2102 #line 243 "awkgram.y"
2103     {
2104                 (void) append_rule((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
2105           }
2106     break;
2107
2108   case 8:
2109
2110 /* Line 1806 of yacc.c  */
2111 #line 247 "awkgram.y"
2112     {
2113                 if (rule != Rule) {
2114                         msg(_("%s blocks must have an action part"), ruletab[rule]);
2115                         errcount++;
2116                 } else if ((yyvsp[(1) - (2)]) == NULL) {
2117                         msg(_("each rule must have a pattern or an action part"));
2118                         errcount++;
2119                 } else          /* pattern rule with non-empty pattern */
2120                         (void) append_rule((yyvsp[(1) - (2)]), NULL);
2121           }
2122     break;
2123
2124   case 9:
2125
2126 /* Line 1806 of yacc.c  */
2127 #line 258 "awkgram.y"
2128     {
2129                 can_return = FALSE;
2130                 if ((yyvsp[(1) - (2)]) && func_install((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])) < 0)
2131                         YYABORT;
2132                 func_params = NULL;
2133                 yyerrok;
2134           }
2135     break;
2136
2137   case 10:
2138
2139 /* Line 1806 of yacc.c  */
2140 #line 266 "awkgram.y"
2141     {
2142                 want_source = FALSE;
2143                 yyerrok;
2144           }
2145     break;
2146
2147   case 11:
2148
2149 /* Line 1806 of yacc.c  */
2150 #line 274 "awkgram.y"
2151     {
2152                 if (include_source((yyvsp[(1) - (1)])) < 0)
2153                         YYABORT;
2154                 efree((yyvsp[(1) - (1)])->lextok);
2155                 bcfree((yyvsp[(1) - (1)]));
2156                 (yyval) = NULL;
2157           }
2158     break;
2159
2160   case 12:
2161
2162 /* Line 1806 of yacc.c  */
2163 #line 282 "awkgram.y"
2164     { (yyval) = NULL; }
2165     break;
2166
2167   case 13:
2168
2169 /* Line 1806 of yacc.c  */
2170 #line 284 "awkgram.y"
2171     { (yyval) = NULL; }
2172     break;
2173
2174   case 14:
2175
2176 /* Line 1806 of yacc.c  */
2177 #line 289 "awkgram.y"
2178     {   (yyval) = NULL; rule = Rule; }
2179     break;
2180
2181   case 15:
2182
2183 /* Line 1806 of yacc.c  */
2184 #line 291 "awkgram.y"
2185     {   (yyval) = (yyvsp[(1) - (1)]); rule = Rule; }
2186     break;
2187
2188   case 16:
2189
2190 /* Line 1806 of yacc.c  */
2191 #line 293 "awkgram.y"
2192     {
2193                 INSTRUCTION *tp;
2194
2195                 add_lint((yyvsp[(1) - (4)]), LINT_assign_in_cond);
2196                 add_lint((yyvsp[(4) - (4)]), LINT_assign_in_cond);
2197
2198                 tp = instruction(Op_no_op);
2199                 list_prepend((yyvsp[(1) - (4)]), bcalloc(Op_line_range, !!do_profiling + 1, 0));
2200                 (yyvsp[(1) - (4)])->nexti->triggered = FALSE;
2201                 (yyvsp[(1) - (4)])->nexti->target_jmp = (yyvsp[(4) - (4)])->nexti;
2202
2203                 list_append((yyvsp[(1) - (4)]), instruction(Op_cond_pair));
2204                 (yyvsp[(1) - (4)])->lasti->line_range = (yyvsp[(1) - (4)])->nexti;
2205                 (yyvsp[(1) - (4)])->lasti->target_jmp = tp;
2206
2207                 list_append((yyvsp[(4) - (4)]), instruction(Op_cond_pair));
2208                 (yyvsp[(4) - (4)])->lasti->line_range = (yyvsp[(1) - (4)])->nexti;
2209                 (yyvsp[(4) - (4)])->lasti->target_jmp = tp;
2210                 if (do_profiling) {
2211                         ((yyvsp[(1) - (4)])->nexti + 1)->condpair_left = (yyvsp[(1) - (4)])->lasti;
2212                         ((yyvsp[(1) - (4)])->nexti + 1)->condpair_right = (yyvsp[(4) - (4)])->lasti;
2213                 }
2214                 (yyval) = list_append(list_merge((yyvsp[(1) - (4)]), (yyvsp[(4) - (4)])), tp);
2215                 rule = Rule;
2216           }
2217     break;
2218
2219   case 17:
2220
2221 /* Line 1806 of yacc.c  */
2222 #line 319 "awkgram.y"
2223     {
2224                 static int begin_seen = 0;
2225                 if (do_lint_old && ++begin_seen == 2)
2226                         warning_ln((yyvsp[(1) - (1)])->source_line,
2227                                 _("old awk does not support multiple `BEGIN' or `END' rules"));
2228
2229                 (yyvsp[(1) - (1)])->in_rule = rule = BEGIN;
2230                 (yyvsp[(1) - (1)])->source_file = source;
2231                 (yyval) = (yyvsp[(1) - (1)]);
2232           }
2233     break;
2234
2235   case 18:
2236
2237 /* Line 1806 of yacc.c  */
2238 #line 330 "awkgram.y"
2239     {
2240                 static int end_seen = 0;
2241                 if (do_lint_old && ++end_seen == 2)
2242                         warning_ln((yyvsp[(1) - (1)])->source_line,
2243                                 _("old awk does not support multiple `BEGIN' or `END' rules"));
2244
2245                 (yyvsp[(1) - (1)])->in_rule = rule = END;
2246                 (yyvsp[(1) - (1)])->source_file = source;
2247                 (yyval) = (yyvsp[(1) - (1)]);
2248           }
2249     break;
2250
2251   case 19:
2252
2253 /* Line 1806 of yacc.c  */
2254 #line 341 "awkgram.y"
2255     {
2256                 (yyvsp[(1) - (1)])->in_rule = rule = BEGINFILE;
2257                 (yyvsp[(1) - (1)])->source_file = source;
2258                 (yyval) = (yyvsp[(1) - (1)]);
2259           }
2260     break;
2261
2262   case 20:
2263
2264 /* Line 1806 of yacc.c  */
2265 #line 347 "awkgram.y"
2266     {
2267                 (yyvsp[(1) - (1)])->in_rule = rule = ENDFILE;
2268                 (yyvsp[(1) - (1)])->source_file = source;
2269                 (yyval) = (yyvsp[(1) - (1)]);
2270           }
2271     break;
2272
2273   case 21:
2274
2275 /* Line 1806 of yacc.c  */
2276 #line 356 "awkgram.y"
2277     {
2278                 if ((yyvsp[(2) - (5)]) == NULL)
2279                         (yyval) = list_create(instruction(Op_no_op));
2280                 else
2281                         (yyval) = (yyvsp[(2) - (5)]);
2282           }
2283     break;
2284
2285   case 22:
2286
2287 /* Line 1806 of yacc.c  */
2288 #line 366 "awkgram.y"
2289     { (yyval) = (yyvsp[(1) - (1)]); }
2290     break;
2291
2292   case 23:
2293
2294 /* Line 1806 of yacc.c  */
2295 #line 368 "awkgram.y"
2296     { (yyval) = (yyvsp[(1) - (1)]); }
2297     break;
2298
2299   case 24:
2300
2301 /* Line 1806 of yacc.c  */
2302 #line 370 "awkgram.y"
2303     {
2304                 yyerror(_("`%s' is a built-in function, it cannot be redefined"),
2305                         tokstart);
2306                 (yyvsp[(1) - (1)])->opcode = Op_symbol; /* Op_symbol instead of Op_token so that
2307                                          * free_bc_internal does not try to free it
2308                                          */
2309                 (yyvsp[(1) - (1)])->lextok = builtin_func;
2310                 (yyval) = (yyvsp[(1) - (1)]);
2311                 /* yyerrok; */
2312           }
2313     break;
2314
2315   case 25:
2316
2317 /* Line 1806 of yacc.c  */
2318 #line 381 "awkgram.y"
2319     { (yyval) = (yyvsp[(2) - (2)]); }
2320     break;
2321
2322   case 28:
2323
2324 /* Line 1806 of yacc.c  */
2325 #line 391 "awkgram.y"
2326     {
2327                 param_counter = 0;
2328                 func_params = NULL;
2329           }
2330     break;
2331
2332   case 29:
2333
2334 /* Line 1806 of yacc.c  */
2335 #line 396 "awkgram.y"
2336     {
2337                         NODE *t;
2338
2339                         (yyvsp[(1) - (7)])->source_file = source;
2340                         t = make_param((yyvsp[(3) - (7)])->lextok);
2341                         (yyvsp[(3) - (7)])->lextok = NULL;
2342                         bcfree((yyvsp[(3) - (7)]));
2343                         t->flags |= FUNC;
2344                         t->rnode = func_params;
2345                         func_params = t;
2346                         (yyval) = (yyvsp[(1) - (7)]);
2347                         can_return = TRUE;
2348                         /* check for duplicate parameter names */
2349                         if (dup_parms((yyvsp[(1) - (7)]), t))
2350                                 errcount++;
2351                 }
2352     break;
2353
2354   case 30:
2355
2356 /* Line 1806 of yacc.c  */
2357 #line 420 "awkgram.y"
2358     { ++want_regexp; }
2359     break;
2360
2361   case 31:
2362
2363 /* Line 1806 of yacc.c  */
2364 #line 422 "awkgram.y"
2365     {
2366                   NODE *n, *exp;
2367                   char *re;
2368                   size_t len;
2369
2370                   re = (yyvsp[(3) - (3)])->lextok;
2371                   len = strlen(re);
2372                   if (do_lint) {
2373                         if (len == 0)
2374                                 lintwarn_ln((yyvsp[(3) - (3)])->source_line,
2375                                         _("regexp constant `//' looks like a C++ comment, but is not"));
2376                         else if ((re)[0] == '*' && (re)[len-1] == '*')
2377                                 /* possible C comment */
2378                                 lintwarn_ln((yyvsp[(3) - (3)])->source_line,
2379                                         _("regexp constant `/%s/' looks like a C comment, but is not"), re);
2380                   }
2381
2382                   exp = make_str_node(re, len, ALREADY_MALLOCED);
2383                   n = make_regnode(Node_regex, exp);
2384                   if (n == NULL) {
2385                         unref(exp);
2386                         YYABORT;
2387                   }
2388                   (yyval) = (yyvsp[(3) - (3)]);
2389                   (yyval)->opcode = Op_match_rec;
2390                   (yyval)->memory = n;
2391                 }
2392     break;
2393
2394   case 32:
2395
2396 /* Line 1806 of yacc.c  */
2397 #line 453 "awkgram.y"
2398     { bcfree((yyvsp[(1) - (1)])); }
2399     break;
2400
2401   case 34:
2402
2403 /* Line 1806 of yacc.c  */
2404 #line 459 "awkgram.y"
2405     {   (yyval) = NULL; }
2406     break;
2407
2408   case 35:
2409
2410 /* Line 1806 of yacc.c  */
2411 #line 461 "awkgram.y"
2412     {
2413                 if ((yyvsp[(2) - (2)]) == NULL)
2414                         (yyval) = (yyvsp[(1) - (2)]);
2415                 else {
2416                         add_lint((yyvsp[(2) - (2)]), LINT_no_effect);
2417                         if ((yyvsp[(1) - (2)]) == NULL)
2418                                 (yyval) = (yyvsp[(2) - (2)]);
2419                         else
2420                                 (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
2421                 }
2422             yyerrok;
2423           }
2424     break;
2425
2426   case 36:
2427
2428 /* Line 1806 of yacc.c  */
2429 #line 474 "awkgram.y"
2430     {   (yyval) = NULL; }
2431     break;
2432
2433   case 39:
2434
2435 /* Line 1806 of yacc.c  */
2436 #line 484 "awkgram.y"
2437     { (yyval) = NULL; }
2438     break;
2439
2440   case 40:
2441
2442 /* Line 1806 of yacc.c  */
2443 #line 486 "awkgram.y"
2444     { (yyval) = (yyvsp[(2) - (3)]); }
2445     break;
2446
2447   case 41:
2448
2449 /* Line 1806 of yacc.c  */
2450 #line 488 "awkgram.y"
2451     {
2452                 if (do_profiling)
2453                         (yyval) = list_prepend((yyvsp[(1) - (1)]), instruction(Op_exec_count));
2454                 else
2455                         (yyval) = (yyvsp[(1) - (1)]);
2456           }
2457     break;
2458
2459   case 42:
2460
2461 /* Line 1806 of yacc.c  */
2462 #line 495 "awkgram.y"
2463     {
2464                 INSTRUCTION *dflt, *curr = NULL, *cexp, *cstmt;
2465                 INSTRUCTION *ip, *nextc, *tbreak;
2466                 const char **case_values = NULL;
2467                 int maxcount = 128;
2468                 int case_count = 0;
2469                 int i;
2470
2471                 tbreak = instruction(Op_no_op); 
2472                 cstmt = list_create(tbreak);
2473                 cexp = list_create(instruction(Op_pop));
2474                 dflt = instruction(Op_jmp);
2475                 dflt->target_jmp = tbreak;      /* if no case match and no explicit default */
2476
2477                 if ((yyvsp[(7) - (9)]) != NULL) {
2478                         curr = (yyvsp[(7) - (9)])->nexti;
2479                         bcfree((yyvsp[(7) - (9)]));     /* Op_list */
2480                 } /*  else
2481                                 curr = NULL; */
2482
2483                 for(; curr != NULL; curr = nextc) {
2484                         INSTRUCTION *caseexp = curr->case_exp;
2485                         INSTRUCTION *casestmt = curr->case_stmt;
2486
2487                         nextc = curr->nexti;
2488                         if (curr->opcode == Op_K_case) {
2489                                 if (caseexp->opcode == Op_push_i) {
2490                                         /* a constant scalar */
2491                                         char *caseval;
2492                                         caseval = force_string(caseexp->memory)->stptr;
2493                                         for (i = 0; i < case_count; i++) {
2494                                                 if (strcmp(caseval, case_values[i]) == 0)
2495                                                         error_ln(curr->source_line,
2496                                                                 _("duplicate case values in switch body: %s"), caseval);
2497                                         }
2498  
2499                                         if (case_values == NULL)
2500                                                 emalloc(case_values, const char **, sizeof(char *) * maxcount, "statement");
2501                                         else if (case_count >= maxcount) {
2502                                                 maxcount += 128;
2503                                                 erealloc(case_values, const char **, sizeof(char*) * maxcount, "statement");
2504                                         }
2505                                         case_values[case_count++] = caseval;
2506                                 } else {
2507                                         /* match a constant regex against switch expression. */
2508                                         (curr + 1)->match_exp = TRUE;
2509                                 }
2510                                 curr->stmt_start = casestmt->nexti;
2511                                 curr->stmt_end  = casestmt->lasti;
2512                                 (void) list_prepend(cexp, curr);
2513                                 (void) list_prepend(cexp, caseexp);
2514                         } else {
2515                                 if (dflt->target_jmp != tbreak)
2516                                         error_ln(curr->source_line,
2517                                                 _("duplicate `default' detected in switch body"));
2518                                 else
2519                                         dflt->target_jmp = casestmt->nexti;
2520
2521                                 if (do_profiling) {
2522                                         curr->stmt_start = casestmt->nexti;
2523                                         curr->stmt_end = casestmt->lasti;
2524                                         (void) list_prepend(cexp, curr);
2525                                 } else
2526                                         bcfree(curr);
2527                         }
2528
2529                         cstmt = list_merge(casestmt, cstmt);
2530                 }
2531
2532                 if (case_values != NULL)
2533                         efree(case_values);
2534
2535                 ip = (yyvsp[(3) - (9)]);
2536                 if (do_profiling) {
2537                         (void) list_prepend(ip, (yyvsp[(1) - (9)]));
2538                         (void) list_prepend(ip, instruction(Op_exec_count));
2539                         (yyvsp[(1) - (9)])->target_break = tbreak;
2540                         ((yyvsp[(1) - (9)]) + 1)->switch_start = cexp->nexti;
2541                         ((yyvsp[(1) - (9)]) + 1)->switch_end = cexp->lasti;
2542                 }/* else
2543                                 $1 is NULL */
2544
2545                 (void) list_append(cexp, dflt);
2546                 (void) list_merge(ip, cexp);
2547                 (yyval) = list_merge(ip, cstmt);
2548
2549                 break_allowed--;                        
2550                 fix_break_continue(ip, tbreak, NULL);
2551           }
2552     break;
2553
2554   case 43:
2555
2556 /* Line 1806 of yacc.c  */
2557 #line 585 "awkgram.y"
2558     { 
2559                 /*
2560                  *    -----------------
2561                  * tc:
2562                  *         cond
2563                  *    -----------------
2564                  *    [Op_jmp_false tb   ]
2565                  *    -----------------   
2566                  *         body
2567                  *    -----------------
2568                  *    [Op_jmp      tc    ]
2569                  * tb:[Op_no_op          ]
2570                  */
2571
2572                 INSTRUCTION *ip, *tbreak, *tcont;
2573
2574                 tbreak = instruction(Op_no_op);
2575                 add_lint((yyvsp[(3) - (6)]), LINT_assign_in_cond);
2576                 tcont = (yyvsp[(3) - (6)])->nexti;
2577                 ip = list_append((yyvsp[(3) - (6)]), instruction(Op_jmp_false));
2578                 ip->lasti->target_jmp = tbreak;
2579
2580                 if (do_profiling) {
2581                         (void) list_append(ip, instruction(Op_exec_count));
2582                         (yyvsp[(1) - (6)])->target_break = tbreak;
2583                         (yyvsp[(1) - (6)])->target_continue = tcont;
2584                         ((yyvsp[(1) - (6)]) + 1)->while_body = ip->lasti;
2585                         (void) list_prepend(ip, (yyvsp[(1) - (6)]));
2586                 }/* else
2587                                 $1 is NULL */
2588
2589                 if ((yyvsp[(6) - (6)]) != NULL)
2590                         (void) list_merge(ip, (yyvsp[(6) - (6)]));
2591                 (void) list_append(ip, instruction(Op_jmp));
2592                 ip->lasti->target_jmp = tcont;
2593                 (yyval) = list_append(ip, tbreak);
2594
2595                 break_allowed--;
2596                 continue_allowed--;
2597                 fix_break_continue(ip, tbreak, tcont);
2598           }
2599     break;
2600
2601   case 44:
2602
2603 /* Line 1806 of yacc.c  */
2604 #line 627 "awkgram.y"
2605     {
2606                 /*
2607                  *    -----------------
2608                  * z:
2609                  *         body
2610                  *    -----------------
2611                  * tc: 
2612                  *         cond
2613                  *    -----------------
2614                  *    [Op_jmp_true | z  ]
2615                  * tb:[Op_no_op         ]
2616                  */
2617
2618                 INSTRUCTION *ip, *tbreak, *tcont;
2619
2620                 tbreak = instruction(Op_no_op);
2621                 tcont = (yyvsp[(6) - (8)])->nexti;
2622                 add_lint((yyvsp[(6) - (8)]), LINT_assign_in_cond);
2623                 if ((yyvsp[(3) - (8)]) != NULL)
2624                         ip = list_merge((yyvsp[(3) - (8)]), (yyvsp[(6) - (8)]));
2625                 else
2626                         ip = list_prepend((yyvsp[(6) - (8)]), instruction(Op_no_op));
2627                 if (do_profiling)
2628                         (void) list_prepend(ip, instruction(Op_exec_count));
2629                 (void) list_append(ip, instruction(Op_jmp_true));
2630                 ip->lasti->target_jmp = ip->nexti;
2631                 (yyval) = list_append(ip, tbreak);
2632
2633                 break_allowed--;
2634                 continue_allowed--;
2635                 fix_break_continue(ip, tbreak, tcont);
2636
2637                 if (do_profiling) {
2638                         (yyvsp[(1) - (8)])->target_break = tbreak;
2639                         (yyvsp[(1) - (8)])->target_continue = tcont;
2640                         ((yyvsp[(1) - (8)]) + 1)->doloop_cond = tcont;
2641                         (yyval) = list_prepend(ip, (yyvsp[(1) - (8)]));
2642                         bcfree((yyvsp[(4) - (8)]));
2643                 } /* else
2644                                 $1 and $4 are NULLs */
2645           }
2646     break;
2647
2648   case 45:
2649
2650 /* Line 1806 of yacc.c  */
2651 #line 669 "awkgram.y"
2652     {
2653                 INSTRUCTION *ip;
2654                 char *var_name = (yyvsp[(3) - (8)])->lextok;
2655
2656                 if ((yyvsp[(8) - (8)]) != NULL
2657                                 && (yyvsp[(8) - (8)])->lasti->opcode == Op_K_delete
2658                                 && (yyvsp[(8) - (8)])->lasti->expr_count == 1
2659                                 && (yyvsp[(8) - (8)])->nexti->opcode == Op_push
2660                                 && ((yyvsp[(8) - (8)])->nexti->memory->type != Node_var || !((yyvsp[(8) - (8)])->nexti->memory->var_update))
2661                                 && strcmp((yyvsp[(8) - (8)])->nexti->memory->vname, var_name) == 0
2662                 ) {
2663                 
2664                 /* Efficiency hack.  Recognize the special case of
2665                  *
2666                  *      for (iggy in foo)
2667                  *              delete foo[iggy]
2668                  *
2669                  * and treat it as if it were
2670                  *
2671                  *      delete foo
2672                  *
2673                  * Check that the body is a `delete a[i]' statement,
2674                  * and that both the loop var and array names match.
2675                  */              
2676                         NODE *arr = NULL;
2677
2678                         ip = (yyvsp[(8) - (8)])->nexti->nexti; 
2679                         if ((yyvsp[(5) - (8)])->nexti->opcode == Op_push && (yyvsp[(5) - (8)])->lasti == (yyvsp[(5) - (8)])->nexti)
2680                                 arr = (yyvsp[(5) - (8)])->nexti->memory;
2681                         if (arr != NULL
2682                                         && ip->opcode == Op_no_op
2683                                         && ip->nexti->opcode == Op_push_array
2684                                         && strcmp(ip->nexti->memory->vname, arr->vname) == 0
2685                                         && ip->nexti->nexti == (yyvsp[(8) - (8)])->lasti
2686                         ) {
2687                                 (void) make_assignable((yyvsp[(8) - (8)])->nexti);
2688                                 (yyvsp[(8) - (8)])->lasti->opcode = Op_K_delete_loop;
2689                                 (yyvsp[(8) - (8)])->lasti->expr_count = 0;
2690                                 if ((yyvsp[(1) - (8)]) != NULL)
2691                                         bcfree((yyvsp[(1) - (8)]));
2692                                 efree(var_name);
2693                                 bcfree((yyvsp[(3) - (8)]));
2694                                 bcfree((yyvsp[(4) - (8)]));
2695                                 bcfree((yyvsp[(5) - (8)]));
2696                                 (yyval) = (yyvsp[(8) - (8)]);
2697                         } else
2698                                 goto regular_loop;
2699                 } else {
2700                         INSTRUCTION *tbreak, *tcont;
2701
2702         /*    [ Op_push_array a       ]
2703          *    [ Op_arrayfor_init | ib ]
2704          * ic:[ Op_arrayfor_incr | ib ] 
2705          *    [ Op_var_assign if any  ]
2706          *
2707          *              body
2708          *
2709          *    [Op_jmp | ic            ]
2710          * ib:[Op_arrayfor_final      ]
2711          */
2712 regular_loop:
2713                         ip = (yyvsp[(5) - (8)]);
2714                         ip->nexti->opcode = Op_push_array;
2715
2716                         tbreak = instruction(Op_arrayfor_final);
2717                         (yyvsp[(4) - (8)])->opcode = Op_arrayfor_incr;
2718                         (yyvsp[(4) - (8)])->array_var = variable(var_name, Node_var);
2719                         (yyvsp[(4) - (8)])->target_jmp = tbreak;
2720                         tcont = (yyvsp[(4) - (8)]);
2721                         (yyvsp[(3) - (8)])->opcode = Op_arrayfor_init;
2722                         (yyvsp[(3) - (8)])->target_jmp = tbreak;
2723                         (void) list_append(ip, (yyvsp[(3) - (8)]));
2724
2725                         if (do_profiling) {
2726                                 (yyvsp[(1) - (8)])->opcode = Op_K_arrayfor;
2727                                 (yyvsp[(1) - (8)])->target_continue = tcont;
2728                                 (yyvsp[(1) - (8)])->target_break = tbreak;
2729                                 (void) list_append(ip, (yyvsp[(1) - (8)]));
2730                         } /* else
2731                                         $1 is NULL */
2732
2733                         /* add update_FOO instruction if necessary */ 
2734                         if ((yyvsp[(4) - (8)])->array_var->type == Node_var && (yyvsp[(4) - (8)])->array_var->var_update) {
2735                                 (void) list_append(ip, instruction(Op_var_update));
2736                                 ip->lasti->update_var = (yyvsp[(4) - (8)])->array_var->var_update;
2737                         }
2738                         (void) list_append(ip, (yyvsp[(4) - (8)]));
2739
2740                         /* add set_FOO instruction if necessary */
2741                         if ((yyvsp[(4) - (8)])->array_var->type == Node_var && (yyvsp[(4) - (8)])->array_var->var_assign) {
2742                                 (void) list_append(ip, instruction(Op_var_assign));
2743                                 ip->lasti->assign_var = (yyvsp[(4) - (8)])->array_var->var_assign;
2744                         }
2745
2746                         if (do_profiling) {
2747                                 (void) list_append(ip, instruction(Op_exec_count));
2748                                 ((yyvsp[(1) - (8)]) + 1)->forloop_cond = (yyvsp[(4) - (8)]);
2749                                 ((yyvsp[(1) - (8)]) + 1)->forloop_body = ip->lasti; 
2750                         }
2751
2752                         if ((yyvsp[(8) - (8)]) != NULL)
2753                                 (void) list_merge(ip, (yyvsp[(8) - (8)]));
2754
2755                         (void) list_append(ip, instruction(Op_jmp));
2756                         ip->lasti->target_jmp = (yyvsp[(4) - (8)]);
2757                         (yyval) = list_append(ip, tbreak);
2758                         fix_break_continue(ip, tbreak, tcont);
2759                 } 
2760
2761                 break_allowed--;
2762                 continue_allowed--;
2763           }
2764     break;
2765
2766   case 46:
2767
2768 /* Line 1806 of yacc.c  */
2769 #line 782 "awkgram.y"
2770     {
2771                 (yyval) = mk_for_loop((yyvsp[(1) - (12)]), (yyvsp[(3) - (12)]), (yyvsp[(6) - (12)]), (yyvsp[(9) - (12)]), (yyvsp[(12) - (12)]));
2772
2773                 break_allowed--;
2774                 continue_allowed--;
2775           }
2776     break;
2777
2778   case 47:
2779
2780 /* Line 1806 of yacc.c  */
2781 #line 789 "awkgram.y"
2782     {
2783                 (yyval) = mk_for_loop((yyvsp[(1) - (11)]), (yyvsp[(3) - (11)]), (INSTRUCTION *) NULL, (yyvsp[(8) - (11)]), (yyvsp[(11) - (11)]));
2784
2785                 break_allowed--;
2786                 continue_allowed--;
2787           }
2788     break;
2789
2790   case 48:
2791
2792 /* Line 1806 of yacc.c  */
2793 #line 796 "awkgram.y"
2794     {
2795                 if (do_profiling)
2796                         (yyval) = list_prepend((yyvsp[(1) - (1)]), instruction(Op_exec_count));
2797                 else
2798                         (yyval) = (yyvsp[(1) - (1)]);
2799           }
2800     break;
2801
2802   case 49:
2803
2804 /* Line 1806 of yacc.c  */
2805 #line 806 "awkgram.y"
2806     { 
2807                 if (! break_allowed)
2808                         error_ln((yyvsp[(1) - (2)])->source_line,
2809                                 _("`break' is not allowed outside a loop or switch"));
2810                 (yyvsp[(1) - (2)])->target_jmp = NULL;
2811                 (yyval) = list_create((yyvsp[(1) - (2)]));
2812
2813           }
2814     break;
2815
2816   case 50:
2817
2818 /* Line 1806 of yacc.c  */
2819 #line 815 "awkgram.y"
2820     {
2821                 if (! continue_allowed)
2822                         error_ln((yyvsp[(1) - (2)])->source_line,
2823                                 _("`continue' is not allowed outside a loop"));
2824                 (yyvsp[(1) - (2)])->target_jmp = NULL;
2825                 (yyval) = list_create((yyvsp[(1) - (2)]));
2826
2827           }
2828     break;
2829
2830   case 51:
2831
2832 /* Line 1806 of yacc.c  */
2833 #line 824 "awkgram.y"
2834     {
2835                 /* if inside function (rule = 0), resolve context at run-time */
2836                 if (rule && rule != Rule)
2837                         error_ln((yyvsp[(1) - (2)])->source_line,
2838                                 _("`next' used in %s action"), ruletab[rule]);
2839                 (yyvsp[(1) - (2)])->target_jmp = ip_rec;
2840                 (yyval) = list_create((yyvsp[(1) - (2)]));
2841           }
2842     break;
2843
2844   case 52:
2845
2846 /* Line 1806 of yacc.c  */
2847 #line 833 "awkgram.y"
2848     {
2849                 if (do_traditional)
2850                         error_ln((yyvsp[(1) - (2)])->source_line,
2851                                 _("`nextfile' is a gawk extension"));
2852
2853                 /* if inside function (rule = 0), resolve context at run-time */
2854                 if (rule == BEGIN || rule == END || rule == ENDFILE)
2855                         error_ln((yyvsp[(1) - (2)])->source_line,
2856                                 _("`nextfile' used in %s action"), ruletab[rule]);
2857
2858                 (yyvsp[(1) - (2)])->target_newfile = ip_newfile;
2859                 (yyvsp[(1) - (2)])->target_endfile = ip_endfile;
2860                 (yyval) = list_create((yyvsp[(1) - (2)]));
2861           }
2862     break;
2863
2864   case 53:
2865
2866 /* Line 1806 of yacc.c  */
2867 #line 848 "awkgram.y"
2868     {
2869                 /* Initialize the two possible jump targets, the actual target
2870                  * is resolved at run-time. 
2871                  */
2872                 (yyvsp[(1) - (3)])->target_end = ip_end;        /* first instruction in end_block */
2873                 (yyvsp[(1) - (3)])->target_atexit = ip_atexit;  /* cleanup and go home */
2874
2875                 if ((yyvsp[(2) - (3)]) == NULL) {
2876                         (yyval) = list_create((yyvsp[(1) - (3)]));
2877                         (void) list_prepend((yyval), instruction(Op_push_i));
2878                         (yyval)->nexti->memory = Nnull_string;
2879                 } else
2880                         (yyval) = list_append((yyvsp[(2) - (3)]), (yyvsp[(1) - (3)]));
2881           }
2882     break;
2883
2884   case 54:
2885
2886 /* Line 1806 of yacc.c  */
2887 #line 863 "awkgram.y"
2888     {
2889                 if (! can_return)
2890                         yyerror(_("`return' used outside function context"));
2891           }
2892     break;
2893
2894   case 55:
2895
2896 /* Line 1806 of yacc.c  */
2897 #line 866 "awkgram.y"
2898     {
2899                 if ((yyvsp[(3) - (4)]) == NULL) {
2900                         (yyval) = list_create((yyvsp[(1) - (4)]));
2901                         (void) list_prepend((yyval), instruction(Op_push_i));
2902                         (yyval)->nexti->memory = Nnull_string;
2903                 } else
2904                         (yyval) = list_append((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
2905           }
2906     break;
2907
2908   case 57:
2909
2910 /* Line 1806 of yacc.c  */
2911 #line 886 "awkgram.y"
2912     { in_print = TRUE; in_parens = 0; }
2913     break;
2914
2915   case 58:
2916
2917 /* Line 1806 of yacc.c  */
2918 #line 887 "awkgram.y"
2919     {
2920                 /*
2921                  * Optimization: plain `print' has no expression list, so $3 is null.
2922                  * If $3 is NULL or is a bytecode list for $0 use Op_K_print_rec,
2923                  * which is faster for these two cases.
2924                  */
2925
2926                 if ((yyvsp[(1) - (4)])->opcode == Op_K_print &&
2927                                 ((yyvsp[(3) - (4)]) == NULL
2928                                         || ((yyvsp[(3) - (4)])->lasti->opcode == Op_field_spec
2929                                                 && (yyvsp[(3) - (4)])->nexti->nexti->nexti == (yyvsp[(3) - (4)])->lasti
2930                                                 && (yyvsp[(3) - (4)])->nexti->nexti->opcode == Op_push_i
2931                                                 && (yyvsp[(3) - (4)])->nexti->nexti->memory->type == Node_val
2932                                                 && (yyvsp[(3) - (4)])->nexti->nexti->memory->numbr == 0.0)
2933                                 )
2934                 ) {
2935                         static short warned = FALSE;
2936                         /*   -----------------
2937                          *      output_redir
2938                          *    [ redirect exp ]
2939                          *   -----------------
2940                          *     expression_list
2941                          *   ------------------
2942                          *    [Op_K_print_rec | NULL | redir_type | expr_count]
2943                          */
2944
2945                         if ((yyvsp[(3) - (4)]) != NULL) {
2946                                 bcfree((yyvsp[(3) - (4)])->lasti);                              /* Op_field_spec */
2947                                 (yyvsp[(3) - (4)])->nexti->nexti->memory->flags &= ~PERM;
2948                                 (yyvsp[(3) - (4)])->nexti->nexti->memory->flags |= MALLOC;                      
2949                                 unref((yyvsp[(3) - (4)])->nexti->nexti->memory);        /* Node_val */
2950                                 bcfree((yyvsp[(3) - (4)])->nexti->nexti);               /* Op_push_i */
2951                                 bcfree((yyvsp[(3) - (4)])->nexti);                              /* Op_list */
2952                                 bcfree((yyvsp[(3) - (4)]));                                             /* Op_list */
2953                         } else {
2954                                 if (do_lint && (rule == BEGIN || rule == END) && ! warned) {
2955                                         warned = TRUE;
2956                                         lintwarn_ln((yyvsp[(1) - (4)])->source_line,
2957                 _("plain `print' in BEGIN or END rule should probably be `print \"\"'"));
2958                                 }
2959                         }
2960
2961                         (yyvsp[(1) - (4)])->expr_count = 0;
2962                         (yyvsp[(1) - (4)])->opcode = Op_K_print_rec;
2963                         if ((yyvsp[(4) - (4)]) == NULL) {    /* no redircetion */
2964                                 (yyvsp[(1) - (4)])->redir_type = 0;
2965                                 (yyval) = list_create((yyvsp[(1) - (4)]));
2966                         } else {
2967                                 INSTRUCTION *ip;
2968                                 ip = (yyvsp[(4) - (4)])->nexti;
2969                                 (yyvsp[(1) - (4)])->redir_type = ip->redir_type;
2970                                 (yyvsp[(4) - (4)])->nexti = ip->nexti;
2971                                 bcfree(ip);
2972                                 (yyval) = list_append((yyvsp[(4) - (4)]), (yyvsp[(1) - (4)]));
2973                         }
2974                 } else {
2975                         /*   -----------------
2976                          *    [ output_redir    ]
2977                          *    [ redirect exp    ]
2978                          *   -----------------
2979                          *    [ expression_list ]
2980                          *   ------------------
2981                          *    [$1 | NULL | redir_type | expr_count]
2982                          *
2983                          */
2984                          
2985                         if ((yyvsp[(4) - (4)]) == NULL) {               /* no redirection */
2986                                 if ((yyvsp[(3) - (4)]) == NULL) {       /* printf without arg */
2987                                         (yyvsp[(1) - (4)])->expr_count = 0;
2988                                         (yyvsp[(1) - (4)])->redir_type = 0;
2989                                         (yyval) = list_create((yyvsp[(1) - (4)]));
2990                                 } else {
2991                                         INSTRUCTION *t = (yyvsp[(3) - (4)]);
2992                                         (yyvsp[(1) - (4)])->expr_count = count_expressions(&t, FALSE);
2993                                         (yyvsp[(1) - (4)])->redir_type = 0;
2994                                         (yyval) = list_append(t, (yyvsp[(1) - (4)]));
2995                                 }
2996                         } else {
2997                                 INSTRUCTION *ip;
2998                                 ip = (yyvsp[(4) - (4)])->nexti;
2999                                 (yyvsp[(1) - (4)])->redir_type = ip->redir_type;
3000                                 (yyvsp[(4) - (4)])->nexti = ip->nexti;
3001                                 bcfree(ip);
3002                                 if ((yyvsp[(3) - (4)]) == NULL) {
3003                                         (yyvsp[(1) - (4)])->expr_count = 0;
3004                                         (yyval) = list_append((yyvsp[(4) - (4)]), (yyvsp[(1) - (4)]));
3005                                 } else {
3006                                         INSTRUCTION *t = (yyvsp[(3) - (4)]);
3007                                         (yyvsp[(1) - (4)])->expr_count = count_expressions(&t, FALSE);
3008                                         (yyval) = list_append(list_merge((yyvsp[(4) - (4)]), t), (yyvsp[(1) - (4)]));
3009                                 }
3010                         }
3011                 }
3012           }
3013     break;
3014
3015   case 59:
3016
3017 /* Line 1806 of yacc.c  */
3018 #line 982 "awkgram.y"
3019     { sub_counter = 0; }
3020     break;
3021
3022   case 60:
3023
3024 /* Line 1806 of yacc.c  */
3025 #line 983 "awkgram.y"
3026     {
3027                 char *arr = (yyvsp[(2) - (4)])->lextok;
3028
3029                 (yyvsp[(2) - (4)])->opcode = Op_push_array;
3030                 (yyvsp[(2) - (4)])->memory = variable(arr, Node_var_new);
3031
3032                 if ((yyvsp[(4) - (4)]) == NULL) {
3033                         static short warned = FALSE;
3034
3035                         if (do_lint && ! warned) {
3036                                 warned = TRUE;
3037                                 lintwarn_ln((yyvsp[(1) - (4)])->source_line,
3038                                         _("`delete array' is a gawk extension"));
3039                         }
3040                         if (do_traditional)
3041                                 error_ln((yyvsp[(1) - (4)])->source_line,
3042                                         _("`delete array' is a gawk extension"));
3043                         (yyvsp[(1) - (4)])->expr_count = 0;
3044                         (yyval) = list_append(list_create((yyvsp[(2) - (4)])), (yyvsp[(1) - (4)]));
3045                 } else {
3046                         (yyvsp[(1) - (4)])->expr_count = sub_counter;
3047                         (yyval) = list_append(list_append((yyvsp[(4) - (4)]), (yyvsp[(2) - (4)])), (yyvsp[(1) - (4)]));
3048                 }
3049           }
3050     break;
3051
3052   case 61:
3053
3054 /* Line 1806 of yacc.c  */
3055 #line 1012 "awkgram.y"
3056     {
3057                 static short warned = FALSE;
3058                 char *arr = (yyvsp[(3) - (4)])->lextok;
3059
3060                 if (do_lint && ! warned) {
3061                         warned = TRUE;
3062                         lintwarn_ln((yyvsp[(1) - (4)])->source_line,
3063                                 _("`delete(array)' is a non-portable tawk extension"));
3064                 }
3065                 if (do_traditional) {
3066                         error_ln((yyvsp[(1) - (4)])->source_line,
3067                                 _("`delete array' is a gawk extension"));
3068                 }
3069                 (yyvsp[(3) - (4)])->memory = variable(arr, Node_var_new);
3070                 (yyvsp[(3) - (4)])->opcode = Op_push_array;
3071                 (yyvsp[(1) - (4)])->expr_count = 0;
3072                 (yyval) = list_append(list_create((yyvsp[(3) - (4)])), (yyvsp[(1) - (4)]));
3073           }
3074     break;
3075
3076   case 62:
3077
3078 /* Line 1806 of yacc.c  */
3079 #line 1031 "awkgram.y"
3080     {   (yyval) = optimize_assignment((yyvsp[(1) - (1)])); }
3081     break;
3082
3083   case 63:
3084
3085 /* Line 1806 of yacc.c  */
3086 #line 1036 "awkgram.y"
3087     { (yyval) = NULL; }
3088     break;
3089
3090   case 64:
3091
3092 /* Line 1806 of yacc.c  */
3093 #line 1038 "awkgram.y"
3094     { (yyval) = (yyvsp[(1) - (1)]); }
3095     break;
3096
3097   case 65:
3098
3099 /* Line 1806 of yacc.c  */
3100 #line 1043 "awkgram.y"
3101     { (yyval) = NULL; }
3102     break;
3103
3104   case 66:
3105
3106 /* Line 1806 of yacc.c  */
3107 #line 1045 "awkgram.y"
3108     {
3109                 if ((yyvsp[(1) - (2)]) == NULL)
3110                         (yyval) = list_create((yyvsp[(2) - (2)]));
3111                 else
3112                         (yyval) = list_prepend((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
3113           }
3114     break;
3115
3116   case 67:
3117
3118 /* Line 1806 of yacc.c  */
3119 #line 1052 "awkgram.y"
3120     { (yyval) = NULL; }
3121     break;
3122
3123   case 68:
3124
3125 /* Line 1806 of yacc.c  */
3126 #line 1057 "awkgram.y"
3127     {
3128                 INSTRUCTION *casestmt = (yyvsp[(5) - (5)]);
3129                 if ((yyvsp[(5) - (5)]) == NULL)
3130                         casestmt = list_create(instruction(Op_no_op));  
3131                 if (do_profiling)
3132                         (void) list_prepend(casestmt, instruction(Op_exec_count));
3133                 (yyvsp[(1) - (5)])->case_exp = (yyvsp[(2) - (5)]);
3134                 (yyvsp[(1) - (5)])->case_stmt = casestmt;
3135                 bcfree((yyvsp[(3) - (5)]));
3136                 (yyval) = (yyvsp[(1) - (5)]);
3137           }
3138     break;
3139
3140   case 69:
3141
3142 /* Line 1806 of yacc.c  */
3143 #line 1069 "awkgram.y"
3144     {
3145                 INSTRUCTION *casestmt = (yyvsp[(4) - (4)]);
3146                 if ((yyvsp[(4) - (4)]) == NULL)
3147                         casestmt = list_create(instruction(Op_no_op));
3148                 if (do_profiling)
3149                         (void) list_prepend(casestmt, instruction(Op_exec_count));
3150                 bcfree((yyvsp[(2) - (4)]));
3151                 (yyvsp[(1) - (4)])->case_stmt = casestmt;
3152                 (yyval) = (yyvsp[(1) - (4)]);
3153           }
3154     break;
3155
3156   case 70:
3157
3158 /* Line 1806 of yacc.c  */
3159 #line 1083 "awkgram.y"
3160     {   (yyval) = (yyvsp[(1) - (1)]); }
3161     break;
3162
3163   case 71:
3164
3165 /* Line 1806 of yacc.c  */
3166 #line 1085 "awkgram.y"
3167     { 
3168                 (yyvsp[(2) - (2)])->memory->numbr = -(force_number((yyvsp[(2) - (2)])->memory));
3169                 bcfree((yyvsp[(1) - (2)]));
3170                 (yyval) = (yyvsp[(2) - (2)]);
3171           }
3172     break;
3173
3174   case 72:
3175
3176 /* Line 1806 of yacc.c  */
3177 #line 1091 "awkgram.y"
3178     {
3179                 bcfree((yyvsp[(1) - (2)]));
3180                 (yyval) = (yyvsp[(2) - (2)]);
3181           }
3182     break;
3183
3184   case 73:
3185
3186 /* Line 1806 of yacc.c  */
3187 #line 1096 "awkgram.y"
3188     {   (yyval) = (yyvsp[(1) - (1)]); }
3189     break;
3190
3191   case 74:
3192
3193 /* Line 1806 of yacc.c  */
3194 #line 1098 "awkgram.y"
3195     {
3196                 (yyvsp[(1) - (1)])->opcode = Op_push_re;
3197                 (yyval) = (yyvsp[(1) - (1)]);
3198           }
3199     break;
3200
3201   case 75:
3202
3203 /* Line 1806 of yacc.c  */
3204 #line 1106 "awkgram.y"
3205     { (yyval) = (yyvsp[(1) - (1)]); }
3206     break;
3207
3208   case 76:
3209
3210 /* Line 1806 of yacc.c  */
3211 #line 1108 "awkgram.y"
3212     { (yyval) = (yyvsp[(1) - (1)]); }
3213     break;
3214
3215   case 78:
3216
3217 /* Line 1806 of yacc.c  */
3218 #line 1118 "awkgram.y"
3219     {
3220                 (yyval) = (yyvsp[(2) - (3)]);
3221           }
3222     break;
3223
3224   case 79:
3225
3226 /* Line 1806 of yacc.c  */
3227 #line 1125 "awkgram.y"
3228     {
3229                 in_print = FALSE;
3230                 in_parens = 0;
3231                 (yyval) = NULL;
3232           }
3233     break;
3234
3235   case 80:
3236
3237 /* Line 1806 of yacc.c  */
3238 #line 1130 "awkgram.y"
3239     { in_print = FALSE; in_parens = 0; }
3240     break;
3241
3242   case 81:
3243
3244 /* Line 1806 of yacc.c  */
3245 #line 1131 "awkgram.y"
3246     {
3247                 if ((yyvsp[(1) - (3)])->redir_type == redirect_twoway
3248                         && (yyvsp[(3) - (3)])->lasti->opcode == Op_K_getline_redir
3249                                 && (yyvsp[(3) - (3)])->lasti->redir_type == redirect_twoway)
3250                         yyerror(_("multistage two-way pipelines don't work"));
3251                 (yyval) = list_prepend((yyvsp[(3) - (3)]), (yyvsp[(1) - (3)]));
3252           }
3253     break;
3254
3255   case 82:
3256
3257 /* Line 1806 of yacc.c  */
3258 #line 1142 "awkgram.y"
3259     {
3260                 (yyval) = mk_condition((yyvsp[(3) - (6)]), (yyvsp[(1) - (6)]), (yyvsp[(6) - (6)]), NULL, NULL);
3261           }
3262     break;
3263
3264   case 83:
3265
3266 /* Line 1806 of yacc.c  */
3267 #line 1147 "awkgram.y"
3268     {
3269                 (yyval) = mk_condition((yyvsp[(3) - (9)]), (yyvsp[(1) - (9)]), (yyvsp[(6) - (9)]), (yyvsp[(7) - (9)]), (yyvsp[(9) - (9)]));
3270           }
3271     break;
3272
3273   case 88:
3274
3275 /* Line 1806 of yacc.c  */
3276 #line 1164 "awkgram.y"
3277     { (yyval) = NULL; }
3278     break;
3279
3280   case 89:
3281
3282 /* Line 1806 of yacc.c  */
3283 #line 1166 "awkgram.y"
3284     {
3285                 bcfree((yyvsp[(1) - (2)]));
3286                 (yyval) = (yyvsp[(2) - (2)]);
3287           }
3288     break;
3289
3290   case 92:
3291
3292 /* Line 1806 of yacc.c  */
3293 #line 1179 "awkgram.y"
3294     {
3295                 append_param((yyvsp[(1) - (1)])->lextok);
3296                 (yyvsp[(1) - (1)])->lextok = NULL;
3297                 bcfree((yyvsp[(1) - (1)]));
3298           }
3299     break;
3300
3301   case 93:
3302
3303 /* Line 1806 of yacc.c  */
3304 #line 1185 "awkgram.y"
3305     {
3306                 append_param((yyvsp[(3) - (3)])->lextok);
3307                 (yyvsp[(3) - (3)])->lextok = NULL;
3308                 bcfree((yyvsp[(3) - (3)]));
3309                 yyerrok;
3310           }
3311     break;
3312
3313   case 94:
3314
3315 /* Line 1806 of yacc.c  */
3316 #line 1192 "awkgram.y"
3317     { /* func_params = NULL; */ }
3318     break;
3319
3320   case 95:
3321
3322 /* Line 1806 of yacc.c  */
3323 #line 1194 "awkgram.y"
3324     { /* func_params = NULL; */ }
3325     break;
3326
3327   case 96:
3328
3329 /* Line 1806 of yacc.c  */
3330 #line 1196 "awkgram.y"
3331     { /* func_params = NULL; */ }
3332     break;
3333
3334   case 97:
3335
3336 /* Line 1806 of yacc.c  */
3337 #line 1202 "awkgram.y"
3338     { (yyval) = NULL; }
3339     break;
3340
3341   case 98:
3342
3343 /* Line 1806 of yacc.c  */
3344 #line 1204 "awkgram.y"
3345     { (yyval) = (yyvsp[(1) - (1)]); }
3346     break;
3347
3348   case 99:
3349
3350 /* Line 1806 of yacc.c  */
3351 #line 1209 "awkgram.y"
3352     { (yyval) = NULL; }
3353     break;
3354
3355   case 100:
3356
3357 /* Line 1806 of yacc.c  */
3358 #line 1211 "awkgram.y"
3359     { (yyval) = (yyvsp[(1) - (1)]); }
3360     break;
3361
3362   case 101:
3363
3364 /* Line 1806 of yacc.c  */
3365 #line 1216 "awkgram.y"
3366     {   (yyval) = mk_expression_list(NULL, (yyvsp[(1) - (1)])); }
3367     break;
3368
3369   case 102:
3370
3371 /* Line 1806 of yacc.c  */
3372 #line 1218 "awkgram.y"
3373     {
3374                 (yyval) = mk_expression_list((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]));
3375                 yyerrok;
3376           }
3377     break;
3378
3379   case 103:
3380
3381 /* Line 1806 of yacc.c  */
3382 #line 1223 "awkgram.y"
3383     { (yyval) = NULL; }
3384     break;
3385
3386   case 104:
3387
3388 /* Line 1806 of yacc.c  */
3389 #line 1225 "awkgram.y"
3390     { (yyval) = NULL; }
3391     break;
3392
3393   case 105:
3394
3395 /* Line 1806 of yacc.c  */
3396 #line 1227 "awkgram.y"
3397     { (yyval) = NULL; }
3398     break;
3399
3400   case 106:
3401
3402 /* Line 1806 of yacc.c  */
3403 #line 1229 "awkgram.y"
3404     { (yyval) = NULL; }
3405     break;
3406
3407   case 107:
3408
3409 /* Line 1806 of yacc.c  */
3410 #line 1235 "awkgram.y"
3411     {
3412                 if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == Op_match_rec)
3413                         lintwarn_ln((yyvsp[(2) - (3)])->source_line,
3414                                 _("regular expression on right of assignment"));
3415                 (yyval) = mk_assignment((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)]));
3416           }
3417     break;
3418
3419   case 108:
3420
3421 /* Line 1806 of yacc.c  */
3422 #line 1242 "awkgram.y"
3423     {   (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3424     break;
3425
3426   case 109:
3427
3428 /* Line 1806 of yacc.c  */
3429 #line 1244 "awkgram.y"
3430     {   (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3431     break;
3432
3433   case 110:
3434
3435 /* Line 1806 of yacc.c  */
3436 #line 1246 "awkgram.y"
3437     {
3438                 if ((yyvsp[(1) - (3)])->lasti->opcode == Op_match_rec)
3439                         warning_ln((yyvsp[(2) - (3)])->source_line,
3440                                 _("regular expression on left of `~' or `!~' operator"));
3441
3442                 if ((yyvsp[(3) - (3)])->lasti == (yyvsp[(3) - (3)])->nexti && (yyvsp[(3) - (3)])->nexti->opcode == Op_match_rec) {
3443                         (yyvsp[(2) - (3)])->memory = (yyvsp[(3) - (3)])->nexti->memory;
3444                         bcfree((yyvsp[(3) - (3)])->nexti);      /* Op_match_rec */
3445                         bcfree((yyvsp[(3) - (3)]));                     /* Op_list */
3446                         (yyval) = list_append((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]));
3447                 } else {
3448                         (yyvsp[(2) - (3)])->memory = make_regnode(Node_dynregex, NULL);
3449                         (yyval) = list_append(list_merge((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])), (yyvsp[(2) - (3)]));
3450                 }
3451           }
3452     break;
3453
3454   case 111:
3455
3456 /* Line 1806 of yacc.c  */
3457 #line 1262 "awkgram.y"
3458     {
3459                 if (do_lint_old)
3460                   warning_ln((yyvsp[(2) - (3)])->source_line,
3461                                 _("old awk does not support the keyword `in' except after `for'"));
3462                 (yyvsp[(3) - (3)])->nexti->opcode = Op_push_array;
3463                 (yyvsp[(2) - (3)])->opcode = Op_in_array;
3464                 (yyvsp[(2) - (3)])->expr_count = 1;
3465                 (yyval) = list_append(list_merge((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])), (yyvsp[(2) - (3)]));
3466           }
3467     break;
3468
3469   case 112:
3470
3471 /* Line 1806 of yacc.c  */
3472 #line 1272 "awkgram.y"
3473     {
3474                 if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == Op_match_rec)
3475                         lintwarn_ln((yyvsp[(2) - (3)])->source_line,
3476                                 _("regular expression on right of comparison"));
3477                 (yyval) = list_append(list_merge((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])), (yyvsp[(2) - (3)]));
3478           }
3479     break;
3480
3481   case 113:
3482
3483 /* Line 1806 of yacc.c  */
3484 #line 1279 "awkgram.y"
3485     { (yyval) = mk_condition((yyvsp[(1) - (5)]), (yyvsp[(2) - (5)]), (yyvsp[(3) - (5)]), (yyvsp[(4) - (5)]), (yyvsp[(5) - (5)])); }
3486     break;
3487
3488   case 114:
3489
3490 /* Line 1806 of yacc.c  */
3491 #line 1281 "awkgram.y"
3492     { (yyval) = (yyvsp[(1) - (1)]); }
3493     break;
3494
3495   case 115:
3496
3497 /* Line 1806 of yacc.c  */
3498 #line 1286 "awkgram.y"
3499     { (yyval) = (yyvsp[(1) - (1)]); }
3500     break;
3501
3502   case 116:
3503
3504 /* Line 1806 of yacc.c  */
3505 #line 1288 "awkgram.y"
3506     { (yyval) = (yyvsp[(1) - (1)]); }
3507     break;
3508
3509   case 117:
3510
3511 /* Line 1806 of yacc.c  */
3512 #line 1290 "awkgram.y"
3513     {   
3514                 (yyvsp[(2) - (2)])->opcode = Op_assign_quotient;
3515                 (yyval) = (yyvsp[(2) - (2)]);
3516           }
3517     break;
3518
3519   case 118:
3520
3521 /* Line 1806 of yacc.c  */
3522 #line 1298 "awkgram.y"
3523     { (yyval) = (yyvsp[(1) - (1)]); }
3524     break;
3525
3526   case 119:
3527
3528 /* Line 1806 of yacc.c  */
3529 #line 1300 "awkgram.y"
3530     { (yyval) = (yyvsp[(1) - (1)]); }
3531     break;
3532
3533   case 120:
3534
3535 /* Line 1806 of yacc.c  */
3536 #line 1305 "awkgram.y"
3537     { (yyval) = (yyvsp[(1) - (1)]); }
3538     break;
3539
3540   case 121:
3541
3542 /* Line 1806 of yacc.c  */
3543 #line 1307 "awkgram.y"
3544     { (yyval) = (yyvsp[(1) - (1)]); }
3545     break;
3546
3547   case 122:
3548
3549 /* Line 1806 of yacc.c  */
3550 #line 1312 "awkgram.y"
3551     { (yyval) = (yyvsp[(1) - (1)]); }
3552     break;
3553
3554   case 123:
3555
3556 /* Line 1806 of yacc.c  */
3557 #line 1314 "awkgram.y"
3558     { (yyval) = (yyvsp[(1) - (1)]); }
3559     break;
3560
3561   case 124:
3562
3563 /* Line 1806 of yacc.c  */
3564 #line 1316 "awkgram.y"
3565     {
3566                 int count = 2;
3567                 int is_simple_var = FALSE;
3568
3569                 if ((yyvsp[(1) - (2)])->lasti->opcode == Op_concat) {
3570                         /* multiple (> 2) adjacent strings optimization */
3571                         is_simple_var = ((yyvsp[(1) - (2)])->lasti->concat_flag & CSVAR);
3572                         count = (yyvsp[(1) - (2)])->lasti->expr_count + 1;
3573                         (yyvsp[(1) - (2)])->lasti->opcode = Op_no_op;
3574                 } else {
3575                         is_simple_var = ((yyvsp[(1) - (2)])->nexti->opcode == Op_push
3576                                                 && (yyvsp[(1) - (2)])->lasti == (yyvsp[(1) - (2)])->nexti); /* first exp. is a simple
3577                                                                              * variable?; kludge for use
3578                                                                              * in Op_assign_concat.
3579                                                                              */
3580                 }
3581
3582                 if (do_optimize > 1
3583                                 && (yyvsp[(1) - (2)])->nexti == (yyvsp[(1) - (2)])->lasti && (yyvsp[(1) - (2)])->nexti->opcode == Op_push_i
3584                                 && (yyvsp[(2) - (2)])->nexti == (yyvsp[(2) - (2)])->lasti && (yyvsp[(2) - (2)])->nexti->opcode == Op_push_i
3585                 ) {
3586                         NODE *n1 = (yyvsp[(1) - (2)])->nexti->memory;
3587                         NODE *n2 = (yyvsp[(2) - (2)])->nexti->memory;
3588                         size_t nlen;
3589
3590                         (void) force_string(n1);
3591                         (void) force_string(n2);
3592                         nlen = n1->stlen + n2->stlen;
3593                         erealloc(n1->stptr, char *, nlen + 2, "constant fold");
3594                         memcpy(n1->stptr + n1->stlen, n2->stptr, n2->stlen);
3595                         n1->stlen = nlen;
3596                         n1->stptr[nlen] = '\0';
3597                         n1->flags &= ~(NUMCUR|NUMBER);
3598                         n1->flags |= (STRING|STRCUR);
3599
3600                         n2->flags &= ~PERM;
3601                         n2->flags |= MALLOC;
3602                         unref(n2);
3603                         bcfree((yyvsp[(2) - (2)])->nexti);
3604                         bcfree((yyvsp[(2) - (2)]));
3605                         (yyval) = (yyvsp[(1) - (2)]);
3606                 } else {
3607                         (yyval) = list_append(list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])), instruction(Op_concat));
3608                         (yyval)->lasti->concat_flag = (is_simple_var ? CSVAR : 0);
3609                         (yyval)->lasti->expr_count = count;
3610                         if (count > max_args)
3611                                 max_args = count;
3612                 }
3613           }
3614     break;
3615
3616   case 126:
3617
3618 /* Line 1806 of yacc.c  */
3619 #line 1371 "awkgram.y"
3620     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3621     break;
3622
3623   case 127:
3624
3625 /* Line 1806 of yacc.c  */
3626 #line 1373 "awkgram.y"
3627     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3628     break;
3629
3630   case 128:
3631
3632 /* Line 1806 of yacc.c  */
3633 #line 1375 "awkgram.y"
3634     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3635     break;
3636
3637   case 129:
3638
3639 /* Line 1806 of yacc.c  */
3640 #line 1377 "awkgram.y"
3641     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3642     break;
3643
3644   case 130:
3645
3646 /* Line 1806 of yacc.c  */
3647 #line 1379 "awkgram.y"
3648     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3649     break;
3650
3651   case 131:
3652
3653 /* Line 1806 of yacc.c  */
3654 #line 1381 "awkgram.y"
3655     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3656     break;
3657
3658   case 132:
3659
3660 /* Line 1806 of yacc.c  */
3661 #line 1383 "awkgram.y"
3662     {
3663                 /*
3664                  * In BEGINFILE/ENDFILE, allow `getline var < file'
3665                  */
3666
3667                 if (rule == BEGINFILE || rule == ENDFILE) {
3668                         if ((yyvsp[(2) - (3)]) != NULL && (yyvsp[(3) - (3)]) != NULL)
3669                                 ;        /* all  ok */
3670                         else {
3671                                 if ((yyvsp[(2) - (3)]) != NULL)
3672                                         error_ln((yyvsp[(1) - (3)])->source_line,
3673                                                 _("`getline var' invalid inside `%s' rule"), ruletab[rule]);
3674                                 else
3675                                         error_ln((yyvsp[(1) - (3)])->source_line,
3676                                                 _("`getline' invalid inside `%s' rule"), ruletab[rule]);
3677                         }
3678                 }
3679                 if (do_lint && rule == END && (yyvsp[(3) - (3)]) == NULL)
3680                         lintwarn_ln((yyvsp[(1) - (3)])->source_line,
3681                                 _("non-redirected `getline' undefined inside END action"));
3682                 (yyval) = mk_getline((yyvsp[(1) - (3)]), (yyvsp[(2) - (3)]), (yyvsp[(3) - (3)]), redirect_input);
3683           }
3684     break;
3685
3686   case 133:
3687
3688 /* Line 1806 of yacc.c  */
3689 #line 1406 "awkgram.y"
3690     {
3691                 (yyvsp[(2) - (2)])->opcode = Op_postincrement;
3692                 (yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) - (2)]));
3693           }
3694     break;
3695
3696   case 134:
3697
3698 /* Line 1806 of yacc.c  */
3699 #line 1411 "awkgram.y"
3700     {
3701                 (yyvsp[(2) - (2)])->opcode = Op_postdecrement;
3702                 (yyval) = mk_assignment((yyvsp[(1) - (2)]), NULL, (yyvsp[(2) - (2)]));
3703           }
3704     break;
3705
3706   case 135:
3707
3708 /* Line 1806 of yacc.c  */
3709 #line 1416 "awkgram.y"
3710     {
3711                 if (do_lint_old) {
3712                     warning_ln((yyvsp[(4) - (5)])->source_line,
3713                                 _("old awk does not support the keyword `in' except after `for'"));
3714                     warning_ln((yyvsp[(4) - (5)])->source_line,
3715                                 _("old awk does not support multidimensional arrays"));
3716                 }
3717                 (yyvsp[(5) - (5)])->nexti->opcode = Op_push_array;
3718                 (yyvsp[(4) - (5)])->opcode = Op_in_array;
3719                 if ((yyvsp[(2) - (5)]) == NULL) {       /* error */
3720                         errcount++;
3721                         (yyvsp[(4) - (5)])->expr_count = 0;
3722                         (yyval) = list_merge((yyvsp[(5) - (5)]), (yyvsp[(4) - (5)]));
3723                 } else {
3724                         INSTRUCTION *t = (yyvsp[(2) - (5)]);
3725                         (yyvsp[(4) - (5)])->expr_count = count_expressions(&t, FALSE);
3726                         (yyval) = list_append(list_merge(t, (yyvsp[(5) - (5)])), (yyvsp[(4) - (5)]));
3727                 }
3728           }
3729     break;
3730
3731   case 136:
3732
3733 /* Line 1806 of yacc.c  */
3734 #line 1441 "awkgram.y"
3735     {
3736                   (yyval) = mk_getline((yyvsp[(3) - (4)]), (yyvsp[(4) - (4)]), (yyvsp[(1) - (4)]), (yyvsp[(2) - (4)])->redir_type);
3737                   bcfree((yyvsp[(2) - (4)]));
3738                 }
3739     break;
3740
3741   case 137:
3742
3743 /* Line 1806 of yacc.c  */
3744 #line 1447 "awkgram.y"
3745     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3746     break;
3747
3748   case 138:
3749
3750 /* Line 1806 of yacc.c  */
3751 #line 1449 "awkgram.y"
3752     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3753     break;
3754
3755   case 139:
3756
3757 /* Line 1806 of yacc.c  */
3758 #line 1451 "awkgram.y"
3759     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3760     break;
3761
3762   case 140:
3763
3764 /* Line 1806 of yacc.c  */
3765 #line 1453 "awkgram.y"
3766     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3767     break;
3768
3769   case 141:
3770
3771 /* Line 1806 of yacc.c  */
3772 #line 1455 "awkgram.y"
3773     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3774     break;
3775
3776   case 142:
3777
3778 /* Line 1806 of yacc.c  */
3779 #line 1457 "awkgram.y"
3780     { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); }
3781     break;
3782
3783   case 143:
3784
3785 /* Line 1806 of yacc.c  */
3786 #line 1462 "awkgram.y"
3787     {
3788                 (yyval) = list_create((yyvsp[(1) - (1)]));
3789           }
3790     break;
3791
3792   case 144:
3793
3794 /* Line 1806 of yacc.c  */
3795 #line 1466 "awkgram.y"
3796     {
3797                 if ((yyvsp[(2) - (2)])->opcode == Op_match_rec) {
3798                         (yyvsp[(2) - (2)])->opcode = Op_nomatch;
3799                         (yyvsp[(1) - (2)])->opcode = Op_push_i;
3800                         (yyvsp[(1) - (2)])->memory = mk_number(0.0, (PERM|NUMCUR|NUMBER));      
3801                         (yyval) = list_append(list_append(list_create((yyvsp[(1) - (2)])),
3802                                                                 instruction(Op_field_spec)), (yyvsp[(2) - (2)]));
3803                 } else {
3804                         if (do_optimize > 1 && (yyvsp[(2) - (2)])->nexti == (yyvsp[(2) - (2)])->lasti
3805                                                         && (yyvsp[(2) - (2)])->nexti->opcode == Op_push_i
3806                         ) {
3807                                 NODE *n = (yyvsp[(2) - (2)])->nexti->memory;
3808                                 if ((n->flags & (STRCUR|STRING)) != 0) {
3809                                         n->numbr = (AWKNUM) (n->stlen == 0);
3810                                         n->flags &= ~(STRCUR|STRING);
3811                                         n->flags |= (NUMCUR|NUMBER);
3812                                         efree(n->stptr);
3813                                         n->stptr = NULL;
3814                                         n->stlen = 0;
3815                                 } else
3816                                         n->numbr = (AWKNUM) (n->numbr == 0.0);
3817                                 bcfree((yyvsp[(1) - (2)]));
3818                                 (yyval) = (yyvsp[(2) - (2)]);
3819                         } else {
3820                                 (yyvsp[(1) - (2)])->opcode = Op_not;
3821                                 add_lint((yyvsp[(2) - (2)]), LINT_assign_in_cond);
3822                                 (yyval) = list_append((yyvsp[(2) - (2)]), (yyvsp[(1) - (2)]));
3823                         }
3824                 }
3825            }
3826     break;
3827
3828   case 145:
3829
3830 /* Line 1806 of yacc.c  */
3831 #line 1497 "awkgram.y"
3832     { (yyval) = (yyvsp[(2) - (3)]); }
3833     break;
3834
3835   case 146:
3836
3837 /* Line 1806 of yacc.c  */
3838 #line 1499 "awkgram.y"
3839     {
3840                 (yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
3841                 if ((yyval) == NULL)
3842                         YYABORT;
3843           }
3844     break;
3845
3846   case 147:
3847
3848 /* Line 1806 of yacc.c  */
3849 #line 1505 "awkgram.y"
3850     {
3851                 (yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)]));
3852                 if ((yyval) == NULL)
3853                         YYABORT;
3854           }
3855     break;
3856
3857   case 148:
3858
3859 /* Line 1806 of yacc.c  */
3860 #line 1511 "awkgram.y"
3861     {
3862                 static short warned1 = FALSE;
3863
3864                 if (do_lint && ! warned1) {
3865                         warned1 = TRUE;
3866                         lintwarn_ln((yyvsp[(1) - (1)])->source_line,
3867                                 _("call of `length' without parentheses is not portable"));
3868                 }
3869                 (yyval) = snode(NULL, (yyvsp[(1) - (1)]));
3870                 if ((yyval) == NULL)
3871                         YYABORT;
3872           }
3873     break;
3874
3875   case 151:
3876
3877 /* Line 1806 of yacc.c  */
3878 #line 1526 "awkgram.y"
3879     {
3880                 (yyvsp[(1) - (2)])->opcode = Op_preincrement;
3881                 (yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) - (2)]));
3882           }
3883     break;
3884
3885   case 152:
3886
3887 /* Line 1806 of yacc.c  */
3888 #line 1531 "awkgram.y"
3889     {
3890                 (yyvsp[(1) - (2)])->opcode = Op_predecrement;
3891                 (yyval) = mk_assignment((yyvsp[(2) - (2)]), NULL, (yyvsp[(1) - (2)]));
3892           }
3893     break;
3894
3895   case 153:
3896
3897 /* Line 1806 of yacc.c  */
3898 #line 1536 "awkgram.y"
3899     {
3900                 (yyval) = list_create((yyvsp[(1) - (1)]));
3901           }
3902     break;
3903
3904   case 154:
3905
3906 /* Line 1806 of yacc.c  */
3907 #line 1540 "awkgram.y"
3908     {
3909                 (yyval) = list_create((yyvsp[(1) - (1)]));
3910           }
3911     break;
3912
3913   case 155:
3914
3915 /* Line 1806 of yacc.c  */
3916 #line 1544 "awkgram.y"
3917     {
3918                 if ((yyvsp[(2) - (2)])->lasti->opcode == Op_push_i
3919                                 && ((yyvsp[(2) - (2)])->lasti->memory->flags & (STRCUR|STRING)) == 0) {
3920                         (yyvsp[(2) - (2)])->lasti->memory->numbr = -(force_number((yyvsp[(2) - (2)])->lasti->memory));
3921                         (yyval) = (yyvsp[(2) - (2)]);
3922                         bcfree((yyvsp[(1) - (2)]));
3923                 } else {
3924                         (yyvsp[(1) - (2)])->opcode = Op_unary_minus;
3925                         (yyval) = list_append((yyvsp[(2) - (2)]), (yyvsp[(1) - (2)]));
3926                 }
3927           }
3928     break;
3929
3930   case 156:
3931
3932 /* Line 1806 of yacc.c  */
3933 #line 1556 "awkgram.y"
3934     {
3935             /*
3936              * was: $$ = $2
3937              * POSIX semantics: force a conversion to numeric type
3938              */
3939                 (yyvsp[(1) - (2)])->opcode = Op_plus_i;
3940                 (yyvsp[(1) - (2)])->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER));
3941                 (yyval) = list_append((yyvsp[(2) - (2)]), (yyvsp[(1) - (2)]));
3942           }
3943     break;
3944
3945   case 157:
3946
3947 /* Line 1806 of yacc.c  */
3948 #line 1569 "awkgram.y"
3949     {
3950                 func_use((yyvsp[(1) - (1)])->lasti->func_name, FUNC_USE);
3951                 (yyval) = (yyvsp[(1) - (1)]);
3952           }
3953     break;
3954
3955   case 158:
3956
3957 /* Line 1806 of yacc.c  */
3958 #line 1574 "awkgram.y"
3959     {
3960                 /* indirect function call */
3961                 INSTRUCTION *f, *t;
3962                 char *name;
3963                 NODE *indirect_var;
3964                 static short warned = FALSE;
3965                 const char *msg = _("indirect function calls are a gawk extension");
3966
3967                 if (do_traditional || do_posix)
3968                         yyerror("%s", msg);
3969                 else if (do_lint && ! warned) {
3970                         warned = TRUE;
3971                         lintwarn("%s", msg);
3972                 }
3973                 
3974                 f = (yyvsp[(2) - (2)])->lasti;
3975                 f->opcode = Op_indirect_func_call;
3976                 name = estrdup(f->func_name, strlen(f->func_name));
3977                 if (is_std_var(name))
3978                         yyerror(_("can not use special variable `%s' for indirect function call"), name);
3979                 indirect_var = variable(name, Node_var_new);
3980                 t = instruction(Op_push);
3981                 t->memory = indirect_var;
3982
3983                 /* prepend indirect var instead of appending to arguments (opt_expression_list),
3984                  * and pop it off in setup_frame (eval.c) (left to right evaluation order); Test case:
3985                  *              f = "fun"
3986                  *              @f(f="real_fun")
3987                  */
3988
3989                 (yyval) = list_prepend((yyvsp[(2) - (2)]), t);
3990           }
3991     break;
3992
3993   case 159:
3994
3995 /* Line 1806 of yacc.c  */
3996 #line 1610 "awkgram.y"
3997     {
3998                 param_sanity((yyvsp[(3) - (4)]));
3999                 (yyvsp[(1) - (4)])->opcode = Op_func_call;
4000                 (yyvsp[(1) - (4)])->func_body = NULL;
4001                 if ((yyvsp[(3) - (4)]) == NULL) {       /* no argument or error */
4002                         ((yyvsp[(1) - (4)]) + 1)->expr_count = 0;
4003                         (yyval) = list_create((yyvsp[(1) - (4)]));
4004                 } else {
4005                         INSTRUCTION *t = (yyvsp[(3) - (4)]);
4006                         ((yyvsp[(1) - (4)]) + 1)->expr_count = count_expressions(&t, TRUE); 
4007                         (yyval) = list_append(t, (yyvsp[(1) - (4)]));
4008                 }
4009           }
4010     break;
4011
4012   case 160:
4013
4014 /* Line 1806 of yacc.c  */
4015 #line 1627 "awkgram.y"
4016     { (yyval) = NULL; }
4017     break;
4018
4019   case 161:
4020
4021 /* Line 1806 of yacc.c  */
4022 #line 1629 "awkgram.y"
4023     { (yyval) = (yyvsp[(1) - (1)]); }
4024     break;
4025
4026   case 162:
4027
4028 /* Line 1806 of yacc.c  */
4029 #line 1634 "awkgram.y"
4030     { (yyval) = NULL; }
4031     break;
4032
4033   case 163:
4034
4035 /* Line 1806 of yacc.c  */
4036 #line 1636 "awkgram.y"
4037     { (yyval) = (yyvsp[(1) - (2)]); }
4038     break;
4039
4040   case 164:
4041
4042 /* Line 1806 of yacc.c  */
4043 #line 1641 "awkgram.y"
4044     {   (yyval) = (yyvsp[(1) - (1)]); }
4045     break;
4046
4047   case 165:
4048
4049 /* Line 1806 of yacc.c  */
4050 #line 1643 "awkgram.y"
4051     {
4052                 (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
4053           }
4054     break;
4055
4056   case 166:
4057
4058 /* Line 1806 of yacc.c  */
4059 #line 1650 "awkgram.y"
4060     {
4061                 INSTRUCTION *ip = (yyvsp[(1) - (1)])->lasti; 
4062                 int count = ip->sub_count;      /* # of SUBSEP-seperated expressions */
4063                 if (count > 1) {
4064                         /* change Op_subscript or Op_sub_array to Op_concat */
4065                         ip->opcode = Op_concat;
4066                         ip->concat_flag = CSUBSEP;
4067                         ip->expr_count = count;
4068                 } else
4069                         ip->opcode = Op_no_op;
4070                 sub_counter++;  /* count # of dimensions */
4071                 (yyval) = (yyvsp[(1) - (1)]);
4072           }
4073     break;
4074
4075   case 167:
4076
4077 /* Line 1806 of yacc.c  */
4078 #line 1667 "awkgram.y"
4079     {
4080                 INSTRUCTION *t = (yyvsp[(2) - (3)]);
4081                 if ((yyvsp[(2) - (3)]) == NULL) {
4082                         error_ln((yyvsp[(3) - (3)])->source_line,
4083                                 _("invalid subscript expression"));
4084                         /* install Null string as subscript. */
4085                         t = list_create(instruction(Op_push_i));
4086                         t->nexti->memory = Nnull_string;
4087                         (yyvsp[(3) - (3)])->sub_count = 1;                      
4088                 } else
4089                         (yyvsp[(3) - (3)])->sub_count = count_expressions(&t, FALSE);
4090                 (yyval) = list_append(t, (yyvsp[(3) - (3)]));
4091           }
4092     break;
4093
4094   case 168:
4095
4096 /* Line 1806 of yacc.c  */
4097 #line 1684 "awkgram.y"
4098     {   (yyval) = (yyvsp[(1) - (1)]); }
4099     break;
4100
4101   case 169:
4102
4103 /* Line 1806 of yacc.c  */
4104 #line 1686 "awkgram.y"
4105     {
4106                 (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)]));
4107           }
4108     break;
4109
4110   case 170:
4111
4112 /* Line 1806 of yacc.c  */
4113 #line 1693 "awkgram.y"
4114     { (yyval) = (yyvsp[(1) - (2)]); }
4115     break;
4116
4117   case 171:
4118
4119 /* Line 1806 of yacc.c  */
4120 #line 1698 "awkgram.y"
4121     {
4122                 char *var_name = (yyvsp[(1) - (1)])->lextok;
4123
4124                 (yyvsp[(1) - (1)])->opcode = Op_push;
4125                 (yyvsp[(1) - (1)])->memory = variable(var_name, Node_var_new);
4126                 (yyval) = list_create((yyvsp[(1) - (1)]));
4127           }
4128     break;
4129
4130   case 172:
4131
4132 /* Line 1806 of yacc.c  */
4133 #line 1706 "awkgram.y"
4134     {
4135                 NODE *n;
4136
4137                 char *arr = (yyvsp[(1) - (2)])->lextok;
4138                 if ((n = lookup(arr)) != NULL && ! isarray(n))
4139                         yyerror(_("use of non-array as array"));
4140                 (yyvsp[(1) - (2)])->memory = variable(arr, Node_var_new);
4141                 (yyvsp[(1) - (2)])->opcode = Op_push_array;
4142                 (yyval) = list_prepend((yyvsp[(2) - (2)]), (yyvsp[(1) - (2)]));
4143           }
4144     break;
4145
4146   case 173:
4147
4148 /* Line 1806 of yacc.c  */
4149 #line 1720 "awkgram.y"
4150     {
4151                 INSTRUCTION *ip = (yyvsp[(1) - (1)])->nexti;
4152                 if (ip->opcode == Op_push
4153                                 && ip->memory->type == Node_var
4154                                 && ip->memory->var_update
4155                 ) {
4156                         (yyval) = list_prepend((yyvsp[(1) - (1)]), instruction(Op_var_update));
4157                         (yyval)->nexti->update_var = ip->memory->var_update;
4158                 } else
4159                         (yyval) = (yyvsp[(1) - (1)]);
4160           }
4161     break;
4162
4163   case 174:
4164
4165 /* Line 1806 of yacc.c  */
4166 #line 1732 "awkgram.y"
4167     {
4168                 (yyval) = list_append((yyvsp[(2) - (3)]), (yyvsp[(1) - (3)]));
4169                 if ((yyvsp[(3) - (3)]) != NULL)
4170                   mk_assignment((yyvsp[(2) - (3)]), NULL, (yyvsp[(3) - (3)]));
4171           }
4172     break;
4173
4174   case 175:
4175
4176 /* Line 1806 of yacc.c  */
4177 #line 1741 "awkgram.y"
4178     {
4179                 (yyvsp[(1) - (1)])->opcode = Op_postincrement;
4180           }
4181     break;
4182
4183   case 176:
4184
4185 /* Line 1806 of yacc.c  */
4186 #line 1745 "awkgram.y"
4187     {
4188                 (yyvsp[(1) - (1)])->opcode = Op_postdecrement;
4189           }
4190     break;
4191
4192   case 177:
4193
4194 /* Line 1806 of yacc.c  */
4195 #line 1748 "awkgram.y"
4196     { (yyval) = NULL; }
4197     break;
4198
4199   case 179:
4200
4201 /* Line 1806 of yacc.c  */
4202 #line 1756 "awkgram.y"
4203     { yyerrok; }
4204     break;
4205
4206   case 180:
4207
4208 /* Line 1806 of yacc.c  */
4209 #line 1760 "awkgram.y"
4210     { yyerrok; }
4211     break;
4212
4213   case 183:
4214
4215 /* Line 1806 of yacc.c  */
4216 #line 1769 "awkgram.y"
4217     { yyerrok; }
4218     break;
4219
4220   case 184:
4221
4222 /* Line 1806 of yacc.c  */
4223 #line 1773 "awkgram.y"
4224     { (yyval) = (yyvsp[(1) - (1)]); yyerrok; }
4225     break;
4226
4227   case 185:
4228
4229 /* Line 1806 of yacc.c  */
4230 #line 1777 "awkgram.y"
4231     { yyerrok; }
4232     break;
4233
4234
4235
4236 /* Line 1806 of yacc.c  */
4237 #line 4250 "awkgram.c"
4238       default: break;
4239     }
4240   /* User semantic actions sometimes alter yychar, and that requires
4241      that yytoken be updated with the new translation.  We take the
4242      approach of translating immediately before every use of yytoken.
4243      One alternative is translating here after every semantic action,
4244      but that translation would be missed if the semantic action invokes
4245      YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
4246      if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
4247      incorrect destructor might then be invoked immediately.  In the
4248      case of YYERROR or YYBACKUP, subsequent parser actions might lead
4249      to an incorrect destructor call or verbose syntax error message
4250      before the lookahead is translated.  */
4251   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
4252
4253   YYPOPSTACK (yylen);
4254   yylen = 0;
4255   YY_STACK_PRINT (yyss, yyssp);
4256
4257   *++yyvsp = yyval;
4258
4259   /* Now `shift' the result of the reduction.  Determine what state
4260      that goes to, based on the state we popped back to and the rule
4261      number reduced by.  */
4262
4263   yyn = yyr1[yyn];
4264
4265   yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
4266   if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
4267     yystate = yytable[yystate];
4268   else
4269     yystate = yydefgoto[yyn - YYNTOKENS];
4270
4271   goto yynewstate;
4272
4273
4274 /*------------------------------------.
4275 | yyerrlab -- here on detecting error |
4276 `------------------------------------*/
4277 yyerrlab:
4278   /* Make sure we have latest lookahead translation.  See comments at
4279      user semantic actions for why this is necessary.  */
4280   yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
4281
4282   /* If not already recovering from an error, report this error.  */
4283   if (!yyerrstatus)
4284     {
4285       ++yynerrs;
4286 #if ! YYERROR_VERBOSE
4287       yyerror (YY_("syntax error"));
4288 #else
4289 # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
4290                                         yyssp, yytoken)
4291       {
4292         char const *yymsgp = YY_("syntax error");
4293         int yysyntax_error_status;
4294         yysyntax_error_status = YYSYNTAX_ERROR;
4295         if (yysyntax_error_status == 0)
4296           yymsgp = yymsg;
4297         else if (yysyntax_error_status == 1)
4298           {
4299             if (yymsg != yymsgbuf)
4300               YYSTACK_FREE (yymsg);
4301             yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
4302             if (!yymsg)
4303               {
4304                 yymsg = yymsgbuf;
4305                 yymsg_alloc = sizeof yymsgbuf;
4306                 yysyntax_error_status = 2;
4307               }
4308             else
4309               {
4310                 yysyntax_error_status = YYSYNTAX_ERROR;
4311                 yymsgp = yymsg;
4312               }
4313           }
4314         yyerror (yymsgp);
4315         if (yysyntax_error_status == 2)
4316           goto yyexhaustedlab;
4317       }
4318 # undef YYSYNTAX_ERROR
4319 #endif
4320     }
4321
4322
4323
4324   if (yyerrstatus == 3)
4325     {
4326       /* If just tried and failed to reuse lookahead token after an
4327          error, discard it.  */
4328
4329       if (yychar <= YYEOF)
4330         {
4331           /* Return failure if at end of input.  */
4332           if (yychar == YYEOF)
4333             YYABORT;
4334         }
4335       else
4336         {
4337           yydestruct ("Error: discarding",
4338                       yytoken, &yylval);
4339           yychar = YYEMPTY;
4340         }
4341     }
4342
4343   /* Else will try to reuse lookahead token after shifting the error
4344      token.  */
4345   goto yyerrlab1;
4346
4347
4348 /*---------------------------------------------------.
4349 | yyerrorlab -- error raised explicitly by YYERROR.  |
4350 `---------------------------------------------------*/
4351 yyerrorlab:
4352
4353   /* Pacify compilers like GCC when the user code never invokes
4354      YYERROR and the label yyerrorlab therefore never appears in user
4355      code.  */
4356   if (/*CONSTCOND*/ 0)
4357      goto yyerrorlab;
4358
4359   /* Do not reclaim the symbols of the rule which action triggered
4360      this YYERROR.  */
4361   YYPOPSTACK (yylen);
4362   yylen = 0;
4363   YY_STACK_PRINT (yyss, yyssp);
4364   yystate = *yyssp;
4365   goto yyerrlab1;
4366
4367
4368 /*-------------------------------------------------------------.
4369 | yyerrlab1 -- common code for both syntax error and YYERROR.  |
4370 `-------------------------------------------------------------*/
4371 yyerrlab1:
4372   yyerrstatus = 3;      /* Each real token shifted decrements this.  */
4373
4374   for (;;)
4375     {
4376       yyn = yypact[yystate];
4377       if (!yypact_value_is_default (yyn))
4378         {
4379           yyn += YYTERROR;
4380           if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
4381             {
4382               yyn = yytable[yyn];
4383               if (0 < yyn)
4384                 break;
4385             }
4386         }
4387
4388       /* Pop the current state because it cannot handle the error token.  */
4389       if (yyssp == yyss)
4390         YYABORT;
4391
4392
4393       yydestruct ("Error: popping",
4394                   yystos[yystate], yyvsp);
4395       YYPOPSTACK (1);
4396       yystate = *yyssp;
4397       YY_STACK_PRINT (yyss, yyssp);
4398     }
4399
4400   *++yyvsp = yylval;
4401
4402
4403   /* Shift the error token.  */
4404   YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
4405
4406   yystate = yyn;
4407   goto yynewstate;
4408
4409
4410 /*-------------------------------------.
4411 | yyacceptlab -- YYACCEPT comes here.  |
4412 `-------------------------------------*/
4413 yyacceptlab:
4414   yyresult = 0;
4415   goto yyreturn;
4416
4417 /*-----------------------------------.
4418 | yyabortlab -- YYABORT comes here.  |
4419 `-----------------------------------*/
4420 yyabortlab:
4421   yyresult = 1;
4422   goto yyreturn;
4423
4424 #if !defined(yyoverflow) || YYERROR_VERBOSE
4425 /*-------------------------------------------------.
4426 | yyexhaustedlab -- memory exhaustion comes here.  |
4427 `-------------------------------------------------*/
4428 yyexhaustedlab:
4429   yyerror (YY_("memory exhausted"));
4430   yyresult = 2;
4431   /* Fall through.  */
4432 #endif
4433
4434 yyreturn:
4435   if (yychar != YYEMPTY)
4436     {
4437       /* Make sure we have latest lookahead translation.  See comments at
4438          user semantic actions for why this is necessary.  */
4439       yytoken = YYTRANSLATE (yychar);
4440       yydestruct ("Cleanup: discarding lookahead",
4441                   yytoken, &yylval);
4442     }
4443   /* Do not reclaim the symbols of the rule which action triggered
4444      this YYABORT or YYACCEPT.  */
4445   YYPOPSTACK (yylen);
4446   YY_STACK_PRINT (yyss, yyssp);
4447   while (yyssp != yyss)
4448     {
4449       yydestruct ("Cleanup: popping",
4450                   yystos[*yyssp], yyvsp);
4451       YYPOPSTACK (1);
4452     }
4453 #ifndef yyoverflow
4454   if (yyss != yyssa)
4455     YYSTACK_FREE (yyss);
4456 #endif
4457 #if YYERROR_VERBOSE
4458   if (yymsg != yymsgbuf)
4459     YYSTACK_FREE (yymsg);
4460 #endif
4461   /* Make sure YYID is used.  */
4462   return YYID (yyresult);
4463 }
4464
4465
4466
4467 /* Line 2067 of yacc.c  */
4468 #line 1779 "awkgram.y"
4469
4470
4471 struct token {
4472         const char *operator;   /* text to match */
4473         OPCODE value;                   /*  type */
4474         int class;                              /* lexical class */
4475         unsigned flags;                 /* # of args. allowed and compatability */
4476 #       define  ARGS    0xFF    /* 0, 1, 2, 3 args allowed (any combination */
4477 #       define  A(n)    (1<<(n))
4478 #       define  VERSION_MASK    0xFF00  /* old awk is zero */
4479 #       define  NOT_OLD         0x0100  /* feature not in old awk */
4480 #       define  NOT_POSIX       0x0200  /* feature not in POSIX */
4481 #       define  GAWKX           0x0400  /* gawk extension */
4482 #       define  RESX            0x0800  /* Bell Labs Research extension */
4483 #       define  BREAK           0x1000  /* break allowed inside */
4484 #       define  CONTINUE        0x2000  /* continue allowed inside */
4485         
4486         NODE *(*ptr)(int);      /* function that implements this keyword */
4487 };
4488
4489 #if 'a' == 0x81 /* it's EBCDIC */
4490 /* tokcompare --- lexicographically compare token names for sorting */
4491
4492 static int
4493 tokcompare(const void *l, const void *r)
4494 {
4495         struct token *lhs, *rhs;
4496
4497         lhs = (struct token *) l;
4498         rhs = (struct token *) r;
4499
4500         return strcmp(lhs->operator, rhs->operator);
4501 }
4502 #endif
4503
4504 /*
4505  * Tokentab is sorted ASCII ascending order, so it can be binary searched.
4506  * See check_special(), which sorts the table on EBCDIC systems.
4507  * Function pointers come from declarations in awk.h.
4508  */
4509
4510 static const struct token tokentab[] = {
4511 {"BEGIN",       Op_rule,         LEX_BEGIN,     0,              0},
4512 {"BEGINFILE",   Op_rule,         LEX_BEGINFILE, GAWKX,          0},
4513 {"END",         Op_rule,         LEX_END,       0,              0},
4514 {"ENDFILE",             Op_rule,         LEX_ENDFILE,   GAWKX,          0},
4515 #ifdef ARRAYDEBUG
4516 {"adump",       Op_builtin,    LEX_BUILTIN,     GAWKX|A(1),     do_adump},
4517 #endif
4518 {"and",         Op_builtin,    LEX_BUILTIN,     GAWKX|A(2),     do_and},
4519 {"asort",       Op_builtin,      LEX_BUILTIN,   GAWKX|A(1)|A(2)|A(3),   do_asort},
4520 {"asorti",      Op_builtin,      LEX_BUILTIN,   GAWKX|A(1)|A(2)|A(3),   do_asorti},
4521 {"atan2",       Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(2),   do_atan2},
4522 {"bindtextdomain",      Op_builtin,      LEX_BUILTIN,   GAWKX|A(1)|A(2),        do_bindtextdomain},
4523 {"break",       Op_K_break,      LEX_BREAK,     0,              0},
4524 {"case",        Op_K_case,       LEX_CASE,      GAWKX,          0},
4525 {"close",       Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(1)|A(2),      do_close},
4526 {"compl",       Op_builtin,    LEX_BUILTIN,     GAWKX|A(1),     do_compl},
4527 {"continue",    Op_K_continue, LEX_CONTINUE,    0,              0},
4528 {"cos",         Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(1),   do_cos},
4529 {"dcgettext",   Op_builtin,      LEX_BUILTIN,   GAWKX|A(1)|A(2)|A(3),   do_dcgettext},
4530 {"dcngettext",  Op_builtin,      LEX_BUILTIN,   GAWKX|A(1)|A(2)|A(3)|A(4)|A(5), do_dcngettext},
4531 {"default",     Op_K_default,    LEX_DEFAULT,   GAWKX,          0},
4532 {"delete",      Op_K_delete,     LEX_DELETE,    NOT_OLD,        0},
4533 {"do",          Op_K_do,         LEX_DO,        NOT_OLD|BREAK|CONTINUE, 0},
4534 {"else",        Op_K_else,       LEX_ELSE,      0,              0},
4535 {"eval",        Op_symbol,       LEX_EVAL,      0,              0},
4536 {"exit",        Op_K_exit,       LEX_EXIT,      0,              0},
4537 {"exp",         Op_builtin,      LEX_BUILTIN,   A(1),           do_exp},
4538 {"extension",   Op_builtin,      LEX_BUILTIN,   GAWKX|A(2),     do_ext},
4539 {"fflush",      Op_builtin,      LEX_BUILTIN,   RESX|A(0)|A(1), do_fflush},
4540 {"for",         Op_K_for,        LEX_FOR,       BREAK|CONTINUE, 0},
4541 {"func",        Op_func, LEX_FUNCTION,  NOT_POSIX|NOT_OLD,      0},
4542 {"function",Op_func, LEX_FUNCTION,      NOT_OLD,        0},
4543 {"gensub",      Op_sub_builtin,  LEX_BUILTIN,   GAWKX|A(3)|A(4), 0},
4544 {"getline",     Op_K_getline_redir,      LEX_GETLINE,   NOT_OLD,        0},
4545 {"gsub",        Op_sub_builtin,  LEX_BUILTIN,   NOT_OLD|A(2)|A(3), 0},
4546 {"if",          Op_K_if,         LEX_IF,        0,              0},
4547 {"in",          Op_symbol,       LEX_IN,        0,              0},
4548 {"include",  Op_symbol,  LEX_INCLUDE,   GAWKX,  0},
4549 {"index",       Op_builtin,      LEX_BUILTIN,   A(2),           do_index},
4550 {"int",         Op_builtin,      LEX_BUILTIN,   A(1),           do_int},
4551 {"isarray",     Op_builtin,      LEX_BUILTIN,   GAWKX|A(1),     do_isarray},
4552 {"length",      Op_builtin,      LEX_LENGTH,    A(0)|A(1),      do_length},
4553 {"log",         Op_builtin,      LEX_BUILTIN,   A(1),           do_log},
4554 {"lshift",      Op_builtin,    LEX_BUILTIN,     GAWKX|A(2),     do_lshift},
4555 {"match",       Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(2)|A(3), do_match},
4556 {"mktime",      Op_builtin,      LEX_BUILTIN,   GAWKX|A(1),     do_mktime},
4557 {"next",        Op_K_next,       LEX_NEXT,      0,              0},
4558 {"nextfile",    Op_K_nextfile, LEX_NEXTFILE,    GAWKX,          0},
4559 {"or",          Op_builtin,    LEX_BUILTIN,     GAWKX|A(2),     do_or},
4560 {"patsplit",    Op_builtin,    LEX_BUILTIN,     GAWKX|A(2)|A(3)|A(4), do_patsplit},
4561 {"print",       Op_K_print,      LEX_PRINT,     0,              0},
4562 {"printf",      Op_K_printf,     LEX_PRINTF,    0,              0},
4563 {"rand",        Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(0),   do_rand},
4564 {"return",      Op_K_return,     LEX_RETURN,    NOT_OLD,        0},
4565 {"rshift",      Op_builtin,    LEX_BUILTIN,     GAWKX|A(2),     do_rshift},
4566 {"sin",         Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(1),   do_sin},
4567 {"split",       Op_builtin,      LEX_BUILTIN,   A(2)|A(3)|A(4), do_split},
4568 {"sprintf",     Op_builtin,      LEX_BUILTIN,   0,              do_sprintf},
4569 {"sqrt",        Op_builtin,      LEX_BUILTIN,   A(1),           do_sqrt},
4570 {"srand",       Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(0)|A(1), do_srand},
4571 #if defined(GAWKDEBUG) || defined(ARRAYDEBUG) /* || ... */
4572 {"stopme",      Op_builtin,    LEX_BUILTIN,     GAWKX|A(0),     stopme},
4573 #endif
4574 {"strftime",    Op_builtin,      LEX_BUILTIN,   GAWKX|A(0)|A(1)|A(2)|A(3), do_strftime},
4575 {"strtonum",    Op_builtin,    LEX_BUILTIN,     GAWKX|A(1),     do_strtonum},
4576 {"sub",         Op_sub_builtin,  LEX_BUILTIN,   NOT_OLD|A(2)|A(3), 0},
4577 {"substr",      Op_builtin,      LEX_BUILTIN,   A(2)|A(3),      do_substr},
4578 {"switch",      Op_K_switch,     LEX_SWITCH,    GAWKX|BREAK,    0},
4579 {"system",      Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(1),   do_system},
4580 {"systime",     Op_builtin,      LEX_BUILTIN,   GAWKX|A(0),     do_systime},
4581 {"tolower",     Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(1),   do_tolower},
4582 {"toupper",     Op_builtin,      LEX_BUILTIN,   NOT_OLD|A(1),   do_toupper},
4583 {"while",       Op_K_while,      LEX_WHILE,     BREAK|CONTINUE, 0},
4584 {"xor",         Op_builtin,    LEX_BUILTIN,     GAWKX|A(2),     do_xor},
4585 };
4586
4587 #if MBS_SUPPORT
4588 /* Variable containing the current shift state.  */
4589 static mbstate_t cur_mbstate;
4590 /* Ring buffer containing current characters.  */
4591 #define MAX_CHAR_IN_RING_BUFFER 8
4592 #define RING_BUFFER_SIZE (MAX_CHAR_IN_RING_BUFFER * MB_LEN_MAX)
4593 static char cur_char_ring[RING_BUFFER_SIZE];
4594 /* Index for ring buffers.  */
4595 static int cur_ring_idx;
4596 /* This macro means that last nextc() return a singlebyte character
4597    or 1st byte of a multibyte character.  */
4598 #define nextc_is_1stbyte (cur_char_ring[cur_ring_idx] == 1)
4599 #else /* MBS_SUPPORT */
4600 /* a dummy */
4601 #define nextc_is_1stbyte 1
4602 #endif /* MBS_SUPPORT */
4603
4604 /* getfname --- return name of a builtin function (for pretty printing) */
4605
4606 const char *
4607 getfname(NODE *(*fptr)(int))
4608 {
4609         int i, j;
4610
4611         j = sizeof(tokentab) / sizeof(tokentab[0]);
4612         /* linear search, no other way to do it */
4613         for (i = 0; i < j; i++) 
4614                 if (tokentab[i].ptr == fptr)
4615                         return tokentab[i].operator;
4616
4617         return NULL;
4618 }
4619
4620 /* print_included_from --- print `Included from ..' file names and locations */
4621
4622 static void
4623 print_included_from()
4624 {
4625         int saveline, line;
4626         SRCFILE *s;
4627
4628         /* suppress current file name, line # from `.. included from ..' msgs */ 
4629         saveline = sourceline;
4630         sourceline = 0;
4631
4632         for (s = sourcefile; s != NULL && s->stype == SRC_INC; ) {
4633                 s = s->next;
4634                 if (s == NULL || s->fd <= INVALID_HANDLE)
4635                         continue;
4636                 line = s->srclines;
4637
4638                 /* if last token is NEWLINE, line number is off by 1. */
4639                 if (s->lasttok == NEWLINE)
4640                         line--;
4641                 msg("%s %s:%d%c",
4642                         s->prev == sourcefile ? "In file included from"
4643                                                                   : "                 from",
4644                         (s->stype == SRC_INC ||
4645                                  s->stype == SRC_FILE) ? s->src : "cmd. line",
4646                         line,
4647                         s->stype == SRC_INC ? ',' : ':'
4648                 );
4649         }
4650         sourceline = saveline;
4651 }
4652
4653 /* warning_ln --- print a warning message with location */
4654
4655 static void
4656 warning_ln(int line, const char *mesg, ...)
4657 {
4658         va_list args;
4659         int saveline;
4660
4661         saveline = sourceline;
4662         sourceline = line;
4663         print_included_from();
4664         va_start(args, mesg);
4665         err(_("warning: "), mesg, args);
4666         va_end(args);
4667         sourceline = saveline;
4668 }
4669
4670 /* lintwarn_ln --- print a lint warning and location */
4671
4672 static void
4673 lintwarn_ln(int line, const char *mesg, ...)
4674 {
4675         va_list args;
4676         int saveline;
4677
4678         saveline = sourceline;
4679         sourceline = line;
4680         print_included_from();
4681         va_start(args, mesg);
4682         if (lintfunc == r_fatal)
4683                 err(_("fatal: "), mesg, args);
4684         else
4685                 err(_("warning: "), mesg, args);
4686         va_end(args);
4687         sourceline = saveline;
4688         if (lintfunc == r_fatal)
4689                 gawk_exit(EXIT_FATAL);
4690 }
4691
4692 /* error_ln --- print an error message and location */
4693
4694 static void
4695 error_ln(int line, const char *m, ...)
4696 {
4697         va_list args;
4698         int saveline;
4699
4700         saveline = sourceline;
4701         sourceline = line;
4702         print_included_from();
4703         errcount++;
4704         va_start(args, m);
4705         err("error: ", m, args);
4706         va_end(args);
4707         sourceline = saveline;
4708 }
4709
4710 /* yyerror --- print a syntax error message, show where */
4711
4712 static void
4713 yyerror(const char *m, ...)
4714 {
4715         va_list args;
4716         const char *mesg = NULL;
4717         char *bp, *cp;
4718         char *scan;
4719         char *buf;
4720         int count;
4721         static char end_of_file_line[] = "(END OF FILE)";
4722         char save;
4723
4724         print_included_from();
4725
4726         errcount++;
4727         /* Find the current line in the input file */
4728         if (lexptr && lexeme) {
4729                 if (thisline == NULL) {
4730                         cp = lexeme;
4731                         if (*cp == '\n') {
4732                                 cp--;
4733                                 mesg = _("unexpected newline or end of string");
4734                         }
4735                         for (; cp != lexptr_begin && *cp != '\n'; --cp)
4736                                 continue;
4737                         if (*cp == '\n')
4738                                 cp++;
4739                         thisline = cp;
4740                 }
4741                 /* NL isn't guaranteed */
4742                 bp = lexeme;
4743                 while (bp < lexend && *bp && *bp != '\n')
4744                         bp++;
4745         } else {
4746                 thisline = end_of_file_line;
4747                 bp = thisline + strlen(thisline);
4748         }
4749
4750         /*
4751          * Saving and restoring *bp keeps valgrind happy,
4752          * since the guts of glibc uses strlen, even though
4753          * we're passing an explict precision. Sigh.
4754          *
4755          * 8/2003: We may not need this anymore.
4756          */
4757         save = *bp;
4758         *bp = '\0';
4759
4760         msg("%.*s", (int) (bp - thisline), thisline);
4761
4762         *bp = save;
4763         va_start(args, m);
4764         if (mesg == NULL)
4765                 mesg = m;
4766
4767         count = (bp - thisline) + strlen(mesg) + 2 + 1;
4768         emalloc(buf, char *, count, "yyerror");
4769
4770         bp = buf;
4771
4772         if (lexptr != NULL) {
4773                 scan = thisline;
4774                 while (scan < lexeme)
4775                         if (*scan++ == '\t')
4776                                 *bp++ = '\t';
4777                         else
4778                                 *bp++ = ' ';
4779                 *bp++ = '^';
4780                 *bp++ = ' ';
4781         }
4782         strcpy(bp, mesg);
4783         err("", buf, args);
4784         va_end(args);
4785         efree(buf);
4786 }
4787
4788 /* mk_program --- create a single list of instructions */
4789
4790 static INSTRUCTION *
4791 mk_program()
4792 {
4793         INSTRUCTION *cp, *tmp;
4794
4795 #define begin_block         rule_block[BEGIN]
4796 #define end_block           rule_block[END]
4797 #define prog_block          rule_block[Rule]
4798 #define beginfile_block     rule_block[BEGINFILE]
4799 #define endfile_block       rule_block[ENDFILE]
4800
4801         if (end_block == NULL)
4802                 end_block = list_create(ip_end);
4803         else
4804                 (void) list_prepend(end_block, ip_end);
4805
4806         if (! in_main_context()) {
4807                 if (begin_block != NULL && prog_block != NULL)
4808                         cp = list_merge(begin_block, prog_block);
4809                 else
4810                         cp = (begin_block != NULL) ? begin_block : prog_block;
4811
4812                 if (cp != NULL)
4813                         (void) list_merge(cp, end_block);
4814                 else
4815                         cp = end_block;
4816
4817                 (void) list_append(cp, instruction(Op_stop));
4818                 goto out;
4819         }
4820
4821         if (endfile_block == NULL)
4822                 endfile_block = list_create(ip_endfile);
4823         else {
4824                 ip_rec->has_endfile = TRUE;
4825                 (void) list_prepend(endfile_block, ip_endfile);
4826         }
4827
4828         if (beginfile_block == NULL)
4829                 beginfile_block = list_create(ip_beginfile);
4830         else
4831                 (void) list_prepend(beginfile_block, ip_beginfile);
4832
4833         if (prog_block == NULL) {
4834                 if (end_block->nexti == end_block->lasti
4835                                 && beginfile_block->nexti == beginfile_block->lasti 
4836                                 && endfile_block->nexti == endfile_block->lasti
4837                 ) {
4838                         /* no pattern-action and (real) end, beginfile or endfile blocks */
4839                         bcfree(ip_rec);
4840                         bcfree(ip_newfile);
4841                         ip_rec = ip_newfile = NULL;
4842
4843                         list_append(beginfile_block, instruction(Op_after_beginfile));
4844                         (void) list_append(endfile_block, instruction(Op_after_endfile));
4845
4846                         if (begin_block == NULL)     /* no program at all */
4847                                 cp = end_block;
4848                         else
4849                                 cp = list_merge(begin_block, end_block);
4850                         (void) list_append(cp, ip_atexit);
4851                         (void) list_append(cp, instruction(Op_stop));
4852
4853                         /* append beginfile_block and endfile_block for sole use
4854                          * in getline without redirection (Op_K_getline).
4855                          */
4856
4857                         (void) list_merge(cp, beginfile_block);
4858                         (void) list_merge(cp, endfile_block);
4859
4860                         goto out;
4861
4862                 } else {
4863                         /* install a do-nothing prog block */
4864                         prog_block = list_create(instruction(Op_no_op));
4865                 }
4866         }
4867
4868         (void) list_append(endfile_block, instruction(Op_after_endfile));
4869         (void) list_prepend(prog_block, ip_rec);
4870         (void) list_append(prog_block, instruction(Op_jmp));
4871         prog_block->lasti->target_jmp = ip_rec;
4872                 
4873         list_append(beginfile_block, instruction(Op_after_beginfile));
4874
4875         cp = list_merge(beginfile_block, prog_block);
4876         (void) list_prepend(cp, ip_newfile);
4877         (void) list_merge(cp, endfile_block);
4878         (void) list_merge(cp, end_block);
4879         if (begin_block != NULL)
4880                 cp = list_merge(begin_block, cp);
4881
4882         (void) list_append(cp, ip_atexit);
4883         (void) list_append(cp, instruction(Op_stop));
4884
4885 out:
4886         /* delete the Op_list, not needed */
4887         tmp = cp->nexti;
4888         bcfree(cp);
4889         return tmp;
4890
4891 #undef begin_block
4892 #undef end_block
4893 #undef prog_block
4894 #undef beginfile_block
4895 #undef endfile_block 
4896 }
4897
4898 /* parse_program --- read in the program and convert into a list of instructions */
4899
4900 int
4901 parse_program(INSTRUCTION **pcode)
4902 {
4903         int ret;
4904
4905         /* pre-create non-local jump targets
4906          * ip_end (Op_no_op) -- used as jump target for `exit'
4907          * outside an END block.
4908          */
4909         ip_end = instruction(Op_no_op);
4910
4911         if (! in_main_context())
4912                 ip_newfile = ip_rec = ip_atexit = ip_beginfile = ip_endfile = NULL;
4913         else {
4914                 ip_endfile = instruction(Op_no_op);
4915                 ip_beginfile = instruction(Op_no_op);
4916                 ip_rec = instruction(Op_get_record); /* target for `next', also ip_newfile */
4917                 ip_newfile = bcalloc(Op_newfile, 2, 0); /* target for `nextfile' */
4918                 ip_newfile->target_jmp = ip_end;
4919                 ip_newfile->target_endfile = ip_endfile;
4920                 (ip_newfile + 1)->target_get_record = ip_rec;
4921                 ip_rec->target_newfile = ip_newfile;
4922                 ip_atexit = instruction(Op_atexit);     /* target for `exit' in END block */
4923         }
4924
4925         sourcefile = srcfiles->next;
4926         lexeof = FALSE;
4927         lexptr = NULL;
4928         lasttok = 0;
4929         memset(rule_block, 0, sizeof(ruletab) * sizeof(INSTRUCTION *));
4930         errcount = 0;
4931         tok = tokstart != NULL ? tokstart : tokexpand();
4932
4933         ret = yyparse();
4934         *pcode = mk_program();
4935
4936         /* avoid false source indications */
4937         source = NULL;
4938         sourceline = 0;
4939         if (ret == 0)   /* avoid spurious warning if parser aborted with YYABORT */
4940                 check_funcs();
4941
4942         return (ret || errcount);
4943 }
4944
4945 /* do_add_srcfile --- add one item to srcfiles */
4946
4947 static SRCFILE *
4948 do_add_srcfile(int stype, char *src, char *path, SRCFILE *thisfile)
4949 {
4950         SRCFILE *s;
4951
4952         emalloc(s, SRCFILE *, sizeof(SRCFILE), "do_add_srcfile");
4953         memset(s, 0, sizeof(SRCFILE));
4954         s->src = estrdup(src, strlen(src));
4955         s->fullpath = path;
4956         s->stype = stype;
4957         s->fd = INVALID_HANDLE;
4958         s->next = thisfile;
4959         s->prev = thisfile->prev;
4960         thisfile->prev->next = s;
4961         thisfile->prev = s;
4962         return s;
4963 }
4964
4965 /* add_srcfile --- add one item to srcfiles after checking if
4966  *                              a source file exists and not already in list.
4967  */
4968
4969 SRCFILE *
4970 add_srcfile(int stype, char *src, SRCFILE *thisfile, int *already_included, int *errcode)
4971 {
4972         SRCFILE *s;
4973         struct stat sbuf;
4974         char *path;
4975         int errno_val = 0;
4976
4977         if (already_included)
4978                 *already_included = FALSE;
4979         if (errcode)
4980                 *errcode = 0;
4981         if (stype == SRC_CMDLINE || stype == SRC_STDIN)
4982                 return do_add_srcfile(stype, src, NULL, thisfile);
4983
4984         path = find_source(src, &sbuf, &errno_val);
4985         if (path == NULL) {
4986                 if (errcode) {
4987                         *errcode = errno_val;
4988                         return NULL;
4989                 }
4990                 fatal(_("can't open source file `%s' for reading (%s)"),
4991                                 src, errno_val ? strerror(errno_val) : _("reason unknown"));
4992         }
4993
4994         for (s = srcfiles->next; s != srcfiles; s = s->next) {
4995                 if ((s->stype == SRC_FILE || s->stype == SRC_INC)
4996                                 && files_are_same(path, s)
4997                 ) {
4998                         if (do_lint) {
4999                                 int line = sourceline;
5000                                 /* Kludge: the line number may be off for `@include file'.
5001                                  * Since, this function is also used for '-f file' in main.c,
5002                                  * sourceline > 1 check ensures that the call is at
5003                                  * parse time.
5004                                  */
5005                                 if (sourceline > 1 && lasttok == NEWLINE)
5006                                         line--;
5007                                 lintwarn_ln(line, _("already included source file `%s'"), src);
5008                         }
5009                         efree(path);
5010                         if (already_included)
5011                                 *already_included = TRUE;
5012                         return NULL;
5013                 }
5014         }
5015
5016         s = do_add_srcfile(stype, src, path, thisfile);
5017         s->sbuf = sbuf;
5018         s->mtime = sbuf.st_mtime;
5019         return s;
5020 }
5021
5022 /* include_source --- read program from source included using `@include' */
5023
5024 static int
5025 include_source(INSTRUCTION *file)
5026 {
5027         SRCFILE *s;
5028         char *src = file->lextok;
5029         int errcode;
5030         int already_included;
5031
5032         if (do_traditional || do_posix) {
5033                 error_ln(file->source_line, _("@include is a gawk extension"));
5034                 return -1;
5035         }
5036
5037         if (strlen(src) == 0) {
5038                 if (do_lint)
5039                         lintwarn_ln(file->source_line, _("empty filename after @include"));
5040                 return 0;
5041         }
5042
5043         s = add_srcfile(SRC_INC, src, sourcefile, &already_included, &errcode);
5044         if (s == NULL) {
5045                 if (already_included)
5046                         return 0;
5047                 error_ln(file->source_line,
5048                         _("can't open source file `%s' for reading (%s)"),
5049                         src, errcode ? strerror(errcode) : _("reason unknown"));
5050                 return -1;
5051         }
5052
5053         /* save scanner state for the current sourcefile */
5054         sourcefile->srclines = sourceline;
5055         sourcefile->lexptr = lexptr;
5056         sourcefile->lexend = lexend;
5057         sourcefile->lexptr_begin = lexptr_begin;        
5058         sourcefile->lexeme = lexeme;
5059         sourcefile->lasttok = lasttok;
5060
5061         /* included file becomes the current source */ 
5062         sourcefile = s;
5063         lexptr = NULL;
5064         sourceline = 0;
5065         source = NULL;
5066         lasttok = 0;
5067         lexeof = FALSE;
5068         eof_warned = FALSE;
5069         return 0;
5070 }
5071
5072 /* next_sourcefile --- read program from the next source in srcfiles */
5073
5074 static void
5075 next_sourcefile()
5076 {
5077         static int (*closefunc)(int fd) = NULL;
5078
5079         if (closefunc == NULL) {
5080                 char *cp = getenv("AWKREADFUNC");
5081
5082                 /* If necessary, one day, test value for different functions.  */
5083                 if (cp == NULL)
5084                         closefunc = close;
5085                 else
5086                         closefunc = one_line_close;
5087         }
5088
5089         /*
5090          * This won't be true if there's an invalid character in
5091          * the source file or source string (e.g., user typo).
5092          * Previous versions of gawk did not core dump in such a
5093          * case.
5094          *
5095          * assert(lexeof == TRUE);
5096          */
5097         lexeof = FALSE;
5098         eof_warned = FALSE;
5099         sourcefile->srclines = sourceline;      /* total no of lines in current file */
5100         if (sourcefile->fd > INVALID_HANDLE) {
5101                 if (sourcefile->fd != fileno(stdin))  /* safety */
5102                         (*closefunc)(sourcefile->fd);
5103                 sourcefile->fd = INVALID_HANDLE;
5104         }
5105         if (sourcefile->buf != NULL) {
5106                 efree(sourcefile->buf);
5107                 sourcefile->buf = NULL;
5108                 sourcefile->lexptr_begin = NULL;
5109         }
5110
5111         sourcefile = sourcefile->next;
5112         if (sourcefile == srcfiles)
5113                 return;
5114
5115         if (sourcefile->lexptr_begin != NULL) {
5116                 /* resume reading from already opened file (postponed to process '@include') */
5117                 lexptr = sourcefile->lexptr;
5118                 lexend = sourcefile->lexend;
5119                 lasttok = sourcefile->lasttok;
5120                 lexptr_begin = sourcefile->lexptr_begin;
5121                 lexeme = sourcefile->lexeme;
5122                 sourceline = sourcefile->srclines;
5123                 source = sourcefile->src;
5124         } else {
5125                 lexptr = NULL;
5126                 sourceline = 0;
5127                 source = NULL;
5128                 lasttok = 0;
5129         }
5130 }
5131
5132 /* get_src_buf --- read the next buffer of source program */
5133
5134 static char *
5135 get_src_buf()
5136 {
5137         int n;
5138         char *scan;
5139         int newfile;
5140         int savelen;
5141         struct stat sbuf;
5142
5143         /*
5144          * No argument prototype on readfunc on purpose,
5145          * avoids problems with some ancient systems where
5146          * the types of arguments to read() aren't up to date.
5147          */
5148         static ssize_t (*readfunc)() = 0;
5149
5150         if (readfunc == NULL) {
5151                 char *cp = getenv("AWKREADFUNC");
5152
5153                 /* If necessary, one day, test value for different functions.  */
5154                 if (cp == NULL)
5155                         /*
5156                          * cast is to remove warnings on systems with
5157                          * different return types for read.
5158                          */
5159                         readfunc = ( ssize_t(*)() ) read;
5160                 else
5161                         readfunc = read_one_line;
5162         }
5163
5164         newfile = FALSE;
5165         if (sourcefile == srcfiles)
5166                 return NULL;
5167
5168         if (sourcefile->stype == SRC_CMDLINE) {
5169                 if (sourcefile->bufsize == 0) {
5170                         sourcefile->bufsize = strlen(sourcefile->src);
5171                         lexptr = lexptr_begin = lexeme = sourcefile->src;
5172                         lexend = lexptr + sourcefile->bufsize;
5173                         sourceline = 1;
5174                         if (sourcefile->bufsize == 0) {
5175                                 /*
5176                                  * Yet Another Special case:
5177                                  *      gawk '' /path/name
5178                                  * Sigh.
5179                                  */
5180                                 static short warned = FALSE;
5181
5182                                 if (do_lint && ! warned) {
5183                                         warned = TRUE;
5184                                         lintwarn(_("empty program text on command line"));
5185                                 }
5186                                 lexeof = TRUE;
5187                         }
5188                 } else if (sourcefile->buf == NULL  && *(lexptr-1) != '\n') {
5189                         /*
5190                          * The following goop is to ensure that the source
5191                          * ends with a newline and that the entire current
5192                          * line is available for error messages.
5193                          */
5194                         int offset;
5195                         char *buf;
5196
5197                         offset = lexptr - lexeme;
5198                         for (scan = lexeme; scan > lexptr_begin; scan--)
5199                                 if (*scan == '\n') {
5200                                         scan++;
5201                                         break;
5202                                 }
5203                         savelen = lexptr - scan;
5204                         emalloc(buf, char *, savelen + 1, "get_src_buf");
5205                         memcpy(buf, scan, savelen);
5206                         thisline = buf;
5207                         lexptr = buf + savelen;
5208                         *lexptr = '\n';
5209                         lexeme = lexptr - offset;
5210                         lexptr_begin = buf;
5211                         lexend = lexptr + 1;
5212                         sourcefile->buf = buf;
5213                 } else
5214                         lexeof = TRUE;
5215                 return lexptr;
5216         }
5217
5218         if (sourcefile->fd <= INVALID_HANDLE) {
5219                 int fd;
5220                 int l;
5221
5222                 source = sourcefile->src;
5223                 if (source == NULL)
5224                         return NULL;
5225                 fd = srcopen(sourcefile);
5226                 if (fd <= INVALID_HANDLE) {
5227                         char *in;
5228
5229                         /* suppress file name and line no. in error mesg */
5230                         in = source;
5231                         source = NULL;
5232                         error(_("can't open source file `%s' for reading (%s)"),
5233                                 in, strerror(errno));
5234                         errcount++;
5235                         lexeof = TRUE;
5236                         return sourcefile->src;
5237                 }
5238
5239                 sourcefile->fd = fd;
5240                 l = optimal_bufsize(fd, &sbuf);
5241                 /*
5242                  * Make sure that something silly like
5243                  *      AWKBUFSIZE=8 make check
5244                  * works ok.
5245                  */
5246 #define A_DECENT_BUFFER_SIZE    128
5247                 if (l < A_DECENT_BUFFER_SIZE)
5248                         l = A_DECENT_BUFFER_SIZE;
5249 #undef A_DECENT_BUFFER_SIZE
5250                 sourcefile->bufsize = l;
5251                 newfile = TRUE;
5252                 emalloc(sourcefile->buf, char *, sourcefile->bufsize, "get_src_buf");
5253                 lexptr = lexptr_begin = lexeme = sourcefile->buf;
5254                 savelen = 0;
5255                 sourceline = 1;
5256                 thisline = NULL;
5257         } else {
5258                 /*
5259                  * Here, we retain the current source line in the beginning of the buffer.
5260                  */
5261                 int offset;
5262                 for (scan = lexeme; scan > lexptr_begin; scan--)
5263                         if (*scan == '\n') {
5264                                 scan++;
5265                                 break;
5266                         }
5267
5268                 savelen = lexptr - scan;
5269                 offset = lexptr - lexeme;
5270
5271                 if (savelen > 0) {
5272                         /*
5273                          * Need to make sure we have room left for reading new text;
5274                          * grow the buffer (by doubling, an arbitrary choice), if the retained line
5275                          * takes up more than a certain percentage (50%, again an arbitrary figure)
5276                          * of the available space.
5277                          */
5278
5279                         if (savelen > sourcefile->bufsize / 2) { /* long line or token  */
5280                                 sourcefile->bufsize *= 2;
5281                                 erealloc(sourcefile->buf, char *, sourcefile->bufsize, "get_src_buf");
5282                                 scan = sourcefile->buf + (scan - lexptr_begin);
5283                                 lexptr_begin = sourcefile->buf;
5284                         }
5285
5286                         thisline = lexptr_begin;
5287                         memmove(thisline, scan, savelen);
5288                         lexptr = thisline + savelen;
5289                         lexeme = lexptr - offset;
5290                 } else {
5291                         savelen = 0;
5292                         lexptr = lexeme = lexptr_begin;
5293                         thisline = NULL;
5294                 }
5295         }
5296
5297         n = (*readfunc)(sourcefile->fd, lexptr, sourcefile->bufsize - savelen);
5298         if (n == -1) {
5299                 error(_("can't read sourcefile `%s' (%s)"),
5300                                 source, strerror(errno));
5301                 errcount++;
5302                 lexeof = TRUE;
5303         } else {
5304                 lexend = lexptr + n;
5305                 if (n == 0) {
5306                         static short warned = FALSE;
5307                         if (do_lint && newfile && ! warned){
5308                                 warned = TRUE;
5309                                 sourceline = 0;
5310                                 lintwarn(_("source file `%s' is empty"), source);
5311                         }
5312                         lexeof = TRUE;
5313                 }
5314         }
5315         return sourcefile->buf;
5316 }
5317
5318 /* tokadd --- add a character to the token buffer */
5319
5320 #define tokadd(x) (*tok++ = (x), tok == tokend ? tokexpand() : tok)
5321
5322 /* tokexpand --- grow the token buffer */
5323
5324 static char *
5325 tokexpand()
5326 {
5327         static int toksize;
5328         int tokoffset;
5329                         
5330         if (tokstart != NULL) {
5331                 tokoffset = tok - tokstart;
5332                 toksize *= 2;
5333                 erealloc(tokstart, char *, toksize, "tokexpand");
5334                 tok = tokstart + tokoffset;
5335         } else {
5336                 toksize = 60;
5337                 emalloc(tokstart, char *, toksize, "tokexpand");
5338                 tok = tokstart;
5339         }
5340         tokend = tokstart + toksize;
5341         return tok;
5342 }
5343
5344 /* nextc --- get the next input character */
5345
5346 #if MBS_SUPPORT
5347
5348 static int
5349 nextc(void)
5350 {
5351         if (gawk_mb_cur_max > 1) {
5352 again:
5353                 if (lexeof)
5354                         return END_FILE;
5355                 if (lexptr == NULL || lexptr >= lexend) {
5356                         if (get_src_buf())
5357                                 goto again;
5358                         return END_SRC;
5359                 }
5360
5361                 /* Update the buffer index.  */
5362                 cur_ring_idx = (cur_ring_idx == RING_BUFFER_SIZE - 1)? 0 :
5363                         cur_ring_idx + 1;
5364
5365                 /* Did we already check the current character?  */
5366                 if (cur_char_ring[cur_ring_idx] == 0) {
5367                         /* No, we need to check the next character on the buffer.  */
5368                         int idx, work_ring_idx = cur_ring_idx;
5369                         mbstate_t tmp_state;
5370                         size_t mbclen;
5371         
5372                         for (idx = 0 ; lexptr + idx < lexend ; idx++) {
5373                                 tmp_state = cur_mbstate;
5374                                 mbclen = mbrlen(lexptr, idx + 1, &tmp_state);
5375
5376                                 if (mbclen == 1 || mbclen == (size_t)-1 || mbclen == 0) {
5377                                         /* It is a singlebyte character, non-complete multibyte
5378                                            character or EOF.  We treat it as a singlebyte
5379                                            character.  */
5380                                         cur_char_ring[work_ring_idx] = 1;
5381                                         break;
5382                                 } else if (mbclen == (size_t)-2) {
5383                                         /* It is not a complete multibyte character.  */
5384                                         cur_char_ring[work_ring_idx] = idx + 1;
5385                                 } else {
5386                                         /* mbclen > 1 */
5387                                         cur_char_ring[work_ring_idx] = mbclen;
5388                                         break;
5389                                 }
5390                                 work_ring_idx = (work_ring_idx == RING_BUFFER_SIZE - 1)?
5391                                         0 : work_ring_idx + 1;
5392                         }
5393                         cur_mbstate = tmp_state;
5394
5395                         /* Put a mark on the position on which we write next character.  */
5396                         work_ring_idx = (work_ring_idx == RING_BUFFER_SIZE - 1)?
5397                                 0 : work_ring_idx + 1;
5398                         cur_char_ring[work_ring_idx] = 0;
5399                 }
5400
5401                 return (int) (unsigned char) *lexptr++;
5402         } else {
5403                 do {
5404                         if (lexeof)
5405                                 return END_FILE;
5406                         if (lexptr && lexptr < lexend)
5407                                         return ((int) (unsigned char) *lexptr++);
5408                 } while (get_src_buf());
5409                 return END_SRC;
5410         }
5411 }
5412
5413 #else /* MBS_SUPPORT */
5414
5415 int
5416 nextc()
5417 {
5418         do {
5419                 if (lexeof)
5420                         return END_FILE;
5421                 if (lexptr && lexptr < lexend)
5422                         return ((int) (unsigned char) *lexptr++);
5423         } while (get_src_buf());
5424         return END_SRC;
5425 }
5426
5427 #endif /* MBS_SUPPORT */
5428
5429 /* pushback --- push a character back on the input */
5430
5431 static inline void
5432 pushback(void)
5433 {
5434 #if MBS_SUPPORT
5435         if (gawk_mb_cur_max > 1)
5436                 cur_ring_idx = (cur_ring_idx == 0)? RING_BUFFER_SIZE - 1 :
5437                         cur_ring_idx - 1;
5438 #endif
5439         (! lexeof && lexptr && lexptr > lexptr_begin ? lexptr-- : lexptr);
5440 }
5441
5442
5443 /* allow_newline --- allow newline after &&, ||, ? and : */
5444
5445 static void
5446 allow_newline(void)
5447 {
5448         int c;
5449
5450         for (;;) {
5451                 c = nextc();
5452                 if (c == END_FILE) {
5453                         pushback();
5454                         break;
5455                 }
5456                 if (c == '#') {
5457                         while ((c = nextc()) != '\n' && c != END_FILE)
5458                                 continue;
5459                         if (c == END_FILE) {
5460                                 pushback();
5461                                 break;
5462                         }
5463                 }
5464                 if (c == '\n')
5465                         sourceline++;
5466                 if (! isspace(c)) {
5467                         pushback();
5468                         break;
5469                 }
5470         }
5471 }
5472
5473 /* newline_eof --- return newline or EOF as needed and adjust variables */
5474
5475 /*
5476  * This routine used to be a macro, however GCC 4.6.2 warned about
5477  * the result of a computation not being used.  Converting to a function
5478  * removes the warnings.
5479  */
5480
5481 static int newline_eof()
5482 {
5483         /* NB: a newline at end does not start a source line. */
5484         if (lasttok != NEWLINE) {
5485                 pushback();
5486                 if (do_lint && ! eof_warned) {
5487                         lintwarn(_("source file does not end in newline"));
5488                         eof_warned = TRUE;
5489                 }
5490                 sourceline++;
5491                 return NEWLINE;
5492         }
5493
5494         sourceline--;
5495         eof_warned = FALSE;
5496         return LEX_EOF;
5497 }
5498
5499 /* yylex --- Read the input and turn it into tokens. */
5500
5501 static int
5502 yylex(void)
5503 {
5504         int c;
5505         int seen_e = FALSE;             /* These are for numbers */
5506         int seen_point = FALSE;
5507         int esc_seen;           /* for literal strings */
5508         int mid;
5509         static int did_newline = FALSE;
5510         char *tokkey;
5511         int inhex = FALSE;
5512         int intlstr = FALSE;
5513
5514 #define GET_INSTRUCTION(op) bcalloc(op, 1, sourceline)
5515
5516 #define NEWLINE_EOF newline_eof()
5517
5518         yylval = (INSTRUCTION *) NULL;
5519         if (lasttok == SUBSCRIPT) {
5520                 lasttok = 0;
5521                 return SUBSCRIPT;
5522         }
5523  
5524         if (lasttok == LEX_EOF)         /* error earlier in current source, must give up !! */
5525                 return 0;
5526
5527         c = nextc();
5528         if (c == END_SRC)
5529                 return 0;
5530         if (c == END_FILE)
5531                 return lasttok = NEWLINE_EOF;
5532         pushback();
5533
5534 #if defined __EMX__
5535         /*
5536          * added for OS/2's extproc feature of cmd.exe
5537          * (like #! in BSD sh)
5538          */
5539         if (strncasecmp(lexptr, "extproc ", 8) == 0) {
5540                 while (*lexptr && *lexptr != '\n')
5541                         lexptr++;
5542         }
5543 #endif
5544
5545         lexeme = lexptr;
5546         thisline = NULL;
5547         if (want_regexp) {
5548                 int in_brack = 0;       /* count brackets, [[:alnum:]] allowed */
5549                 /*
5550                  * Counting brackets is non-trivial. [[] is ok,
5551                  * and so is [\]], with a point being that /[/]/ as a regexp
5552                  * constant has to work.
5553                  *
5554                  * Do not count [ or ] if either one is preceded by a \.
5555                  * A `[' should be counted if
5556                  *  a) it is the first one so far (in_brack == 0)
5557                  *  b) it is the `[' in `[:'
5558                  * A ']' should be counted if not preceded by a \, since
5559                  * it is either closing `:]' or just a plain list.
5560                  * According to POSIX, []] is how you put a ] into a set.
5561                  * Try to handle that too.
5562                  *
5563                  * The code for \ handles \[ and \].
5564                  */
5565
5566                 want_regexp = FALSE;
5567                 tok = tokstart;
5568                 for (;;) {
5569                         c = nextc();
5570
5571                         if (gawk_mb_cur_max == 1 || nextc_is_1stbyte) switch (c) {
5572                         case '[':
5573                                 /* one day check for `.' and `=' too */
5574                                 if (nextc() == ':' || in_brack == 0)
5575                                         in_brack++;
5576                                 pushback();
5577                                 break;
5578                         case ']':
5579                                 if (tokstart[0] == '['
5580                                     && (tok == tokstart + 1
5581                                         || (tok == tokstart + 2
5582                                             && tokstart[1] == '^')))
5583                                         /* do nothing */;
5584                                 else
5585                                         in_brack--;
5586                                 break;
5587                         case '\\':
5588                                 if ((c = nextc()) == END_FILE) {
5589                                         pushback();
5590                                         yyerror(_("unterminated regexp ends with `\\' at end of file"));
5591                                         goto end_regexp; /* kludge */
5592                                 } else if (c == '\n') {
5593                                         sourceline++;
5594                                         continue;
5595                                 } else {
5596                                         tokadd('\\');
5597                                         tokadd(c);
5598                                         continue;
5599                                 }
5600                                 break;
5601                         case '/':       /* end of the regexp */
5602                                 if (in_brack > 0)
5603                                         break;
5604 end_regexp:
5605                                 yylval = GET_INSTRUCTION(Op_token);
5606                                 yylval->lextok = estrdup(tokstart, tok - tokstart);
5607                                 if (do_lint) {
5608                                         int peek = nextc();
5609
5610                                         pushback();
5611                                         if (peek == 'i' || peek == 's') {
5612                                                 if (source)
5613                                                         lintwarn(
5614                                                 _("%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"),
5615                                                                 source, sourceline, peek);
5616                                                 else
5617                                                         lintwarn(
5618                                                 _("tawk regex modifier `/.../%c' doesn't work in gawk"),
5619                                                                 peek);
5620                                         }
5621                                 }
5622                                 return lasttok = REGEXP;
5623                         case '\n':
5624                                 pushback();
5625                                 yyerror(_("unterminated regexp"));
5626                                 goto end_regexp;        /* kludge */
5627                         case END_FILE:
5628                                 pushback();
5629                                 yyerror(_("unterminated regexp at end of file"));
5630                                 goto end_regexp;        /* kludge */
5631                         }
5632                         tokadd(c);
5633                 }
5634         }
5635 retry:
5636
5637         /* skipping \r is a hack, but windows is just too pervasive. sigh. */
5638         while ((c = nextc()) == ' ' || c == '\t' || c == '\r')
5639                 continue;
5640
5641         lexeme = lexptr ? lexptr - 1 : lexptr;
5642         thisline = NULL;
5643         tok = tokstart;
5644
5645 #if MBS_SUPPORT
5646         if (gawk_mb_cur_max == 1 || nextc_is_1stbyte)
5647 #endif
5648         switch (c) {
5649         case END_SRC:
5650                 return 0;
5651
5652         case END_FILE:
5653                 return lasttok = NEWLINE_EOF;
5654
5655         case '\n':
5656                 sourceline++;
5657                 return lasttok = NEWLINE;
5658
5659         case '#':               /* it's a comment */
5660                 while ((c = nextc()) != '\n') {
5661                         if (c == END_FILE)
5662                                 return lasttok = NEWLINE_EOF;
5663                 }
5664                 sourceline++;
5665                 return lasttok = NEWLINE;
5666
5667         case '@':
5668                 return lasttok = '@';
5669
5670         case '\\':
5671 #ifdef RELAXED_CONTINUATION
5672                 /*
5673                  * This code puports to allow comments and/or whitespace
5674                  * after the `\' at the end of a line used for continuation.
5675                  * Use it at your own risk. We think it's a bad idea, which
5676                  * is why it's not on by default.
5677                  */
5678                 if (! do_traditional) {
5679                         /* strip trailing white-space and/or comment */
5680                         while ((c = nextc()) == ' ' || c == '\t' || c == '\r')
5681                                 continue;
5682                         if (c == '#') {
5683                                 static short warned = FALSE;
5684
5685                                 if (do_lint && ! warned) {
5686                                         warned = TRUE;
5687                                         lintwarn(
5688                 _("use of `\\ #...' line continuation is not portable"));
5689                                 }
5690                                 while ((c = nextc()) != '\n')
5691                                         if (c == END_FILE)
5692                                                 break;
5693                         }
5694                         pushback();
5695                 }
5696 #endif /* RELAXED_CONTINUATION */
5697                 c = nextc();
5698                 if (c == '\r')  /* allow MS-DOS files. bleah */
5699                         c = nextc();
5700                 if (c == '\n') {
5701                         sourceline++;
5702                         goto retry;
5703                 } else {
5704                         yyerror(_("backslash not last character on line"));
5705                         return lasttok = LEX_EOF;
5706                 }
5707                 break;
5708
5709         case ':':
5710         case '?':
5711                 yylval = GET_INSTRUCTION(Op_cond_exp);
5712                 if (! do_posix)
5713                         allow_newline();
5714                 return lasttok = c;
5715
5716                 /*
5717                  * in_parens is undefined unless we are parsing a print
5718                  * statement (in_print), but why bother with a check?
5719                  */
5720         case ')':
5721                 in_parens--;
5722                 return lasttok = c;
5723
5724         case '(':       
5725                 in_parens++;
5726                 return lasttok = c;
5727         case '$':
5728                 yylval = GET_INSTRUCTION(Op_field_spec);
5729                 return lasttok = c;
5730         case '{':
5731                 if (++in_braces == 1)
5732                         firstline = sourceline;
5733         case ';':
5734         case ',':
5735         case '[':
5736                         return lasttok = c;
5737         case ']':
5738                 c = nextc();
5739                 pushback();
5740                 if (c == '[') {
5741                         yylval = GET_INSTRUCTION(Op_sub_array);
5742                         lasttok = ']';
5743                 } else {
5744                         yylval = GET_INSTRUCTION(Op_subscript);
5745                         lasttok = SUBSCRIPT;    /* end of subscripts */
5746                 }
5747                 return ']';
5748
5749         case '*':
5750                 if ((c = nextc()) == '=') {
5751                         yylval = GET_INSTRUCTION(Op_assign_times);
5752                         return lasttok = ASSIGNOP;
5753                 } else if (do_posix) {
5754                         pushback();
5755                         yylval = GET_INSTRUCTION(Op_times);
5756                         return lasttok = '*';
5757                 } else if (c == '*') {
5758                         /* make ** and **= aliases for ^ and ^= */
5759                         static int did_warn_op = FALSE, did_warn_assgn = FALSE;
5760
5761                         if (nextc() == '=') {
5762                                 if (! did_warn_assgn) {
5763                                         did_warn_assgn = TRUE;
5764                                         if (do_lint)
5765                                                 lintwarn(_("POSIX does not allow operator `**='"));
5766                                         if (do_lint_old)
5767                                                 warning(_("old awk does not support operator `**='"));
5768                                 }
5769                                 yylval = GET_INSTRUCTION(Op_assign_exp);
5770                                 return ASSIGNOP;
5771                         } else {
5772                                 pushback();
5773                                 if (! did_warn_op) {
5774                                         did_warn_op = TRUE;
5775                                         if (do_lint)
5776                                                 lintwarn(_("POSIX does not allow operator `**'"));
5777                                         if (do_lint_old)
5778                                                 warning(_("old awk does not support operator `**'"));
5779                                 }
5780                                 yylval = GET_INSTRUCTION(Op_exp);
5781                                 return lasttok = '^';
5782                         }
5783                 }
5784                 pushback();
5785                 yylval = GET_INSTRUCTION(Op_times);
5786                 return lasttok = '*';
5787
5788         case '/':
5789                 if (nextc() == '=') {
5790                         pushback();
5791                         return lasttok = SLASH_BEFORE_EQUAL;
5792                 }
5793                 pushback();
5794                 yylval = GET_INSTRUCTION(Op_quotient);
5795                 return lasttok = '/';
5796
5797         case '%':
5798                 if (nextc() == '=') {
5799                         yylval = GET_INSTRUCTION(Op_assign_mod);
5800                         return lasttok = ASSIGNOP;
5801                 }
5802                 pushback();
5803                 yylval = GET_INSTRUCTION(Op_mod);
5804                 return lasttok = '%';
5805
5806         case '^':
5807         {
5808                 static int did_warn_op = FALSE, did_warn_assgn = FALSE;
5809
5810                 if (nextc() == '=') {
5811                         if (do_lint_old && ! did_warn_assgn) {
5812                                 did_warn_assgn = TRUE;
5813                                 warning(_("operator `^=' is not supported in old awk"));
5814                         }
5815                         yylval = GET_INSTRUCTION(Op_assign_exp);
5816                         return lasttok = ASSIGNOP;
5817                 }
5818                 pushback();
5819                 if (do_lint_old && ! did_warn_op) {
5820                         did_warn_op = TRUE;
5821                         warning(_("operator `^' is not supported in old awk"));
5822                 }
5823                 yylval = GET_INSTRUCTION(Op_exp);       
5824                 return lasttok = '^';
5825         }
5826
5827         case '+':
5828                 if ((c = nextc()) == '=') {
5829                         yylval = GET_INSTRUCTION(Op_assign_plus);
5830                         return lasttok = ASSIGNOP;
5831                 }
5832                 if (c == '+') {
5833                         yylval = GET_INSTRUCTION(Op_symbol);
5834                         return lasttok = INCREMENT;
5835                 }
5836                 pushback();
5837                 yylval = GET_INSTRUCTION(Op_plus);
5838                 return lasttok = '+';
5839
5840         case '!':
5841                 if ((c = nextc()) == '=') {
5842                         yylval = GET_INSTRUCTION(Op_notequal);
5843                         return lasttok = RELOP;
5844                 }
5845                 if (c == '~') {
5846                         yylval = GET_INSTRUCTION(Op_nomatch);
5847                         return lasttok = MATCHOP;
5848                 }
5849                 pushback();
5850                 yylval = GET_INSTRUCTION(Op_symbol);
5851                 return lasttok = '!';
5852
5853         case '<':
5854                 if (nextc() == '=') {
5855                         yylval = GET_INSTRUCTION(Op_leq);
5856                         return lasttok = RELOP;
5857                 }
5858                 yylval = GET_INSTRUCTION(Op_less);
5859                 pushback();
5860                 return lasttok = '<';
5861
5862         case '=':
5863                 if (nextc() == '=') {
5864                         yylval = GET_INSTRUCTION(Op_equal);
5865                         return lasttok = RELOP;
5866                 }
5867                 yylval = GET_INSTRUCTION(Op_assign);
5868                 pushback();
5869                 return lasttok = ASSIGN;
5870
5871         case '>':
5872                 if ((c = nextc()) == '=') {
5873                         yylval = GET_INSTRUCTION(Op_geq);
5874                         return lasttok = RELOP;
5875                 } else if (c == '>') {
5876                         yylval = GET_INSTRUCTION(Op_symbol);
5877                         yylval->redir_type = redirect_append;
5878                         return lasttok = IO_OUT;
5879                 }
5880                 pushback();
5881                 if (in_print && in_parens == 0) {
5882                         yylval = GET_INSTRUCTION(Op_symbol);
5883                         yylval->redir_type = redirect_output;
5884                         return lasttok = IO_OUT;
5885                 }
5886                 yylval = GET_INSTRUCTION(Op_greater);
5887                 return lasttok = '>';
5888
5889         case '~':
5890                 yylval = GET_INSTRUCTION(Op_match);
5891                 return lasttok = MATCHOP;
5892
5893         case '}':
5894                 /*
5895                  * Added did newline stuff.  Easier than
5896                  * hacking the grammar.
5897                  */
5898                 if (did_newline) {
5899                         did_newline = FALSE;
5900                         if (--in_braces == 0)
5901                                 lastline = sourceline;
5902                         return lasttok = c;
5903                 }
5904                 did_newline++;
5905                 --lexptr;       /* pick up } next time */
5906                 return lasttok = NEWLINE;
5907
5908         case '"':
5909         string:
5910                 esc_seen = FALSE;
5911                 while ((c = nextc()) != '"') {
5912                         if (c == '\n') {
5913                                 pushback();
5914                                 yyerror(_("unterminated string"));
5915                                 return lasttok = LEX_EOF;
5916                         }
5917                         if ((gawk_mb_cur_max == 1 || nextc_is_1stbyte) &&
5918                             c == '\\') {
5919                                 c = nextc();
5920                                 if (c == '\n') {
5921                                         sourceline++;
5922                                         continue;
5923                                 }
5924                                 esc_seen = TRUE;
5925                                 if (! want_source || c != '"')
5926                                         tokadd('\\');
5927                         }
5928                         if (c == END_FILE) {
5929                                 pushback();
5930                                 yyerror(_("unterminated string"));
5931                                 return lasttok = LEX_EOF;
5932                         }
5933                         tokadd(c);
5934                 }
5935                 yylval = GET_INSTRUCTION(Op_token);
5936                 if (want_source) {
5937                         yylval->lextok = estrdup(tokstart, tok - tokstart);
5938                         return lasttok = FILENAME;
5939                 }
5940                 
5941                 yylval->opcode = Op_push_i;
5942                 yylval->memory = make_str_node(tokstart,
5943                                                 tok - tokstart, esc_seen ? SCAN : 0);
5944                 yylval->memory->flags &= ~MALLOC;
5945                 yylval->memory->flags |= PERM;
5946                 if (intlstr) {
5947                         yylval->memory->flags |= INTLSTR;
5948                         intlstr = FALSE;
5949                         if (do_intl)
5950                                 dumpintlstr(yylval->memory->stptr, yylval->memory->stlen);
5951                 }
5952                 return lasttok = YSTRING;
5953
5954         case '-':
5955                 if ((c = nextc()) == '=') {
5956                         yylval = GET_INSTRUCTION(Op_assign_minus);
5957                         return lasttok = ASSIGNOP;
5958                 }
5959                 if (c == '-') {
5960                         yylval = GET_INSTRUCTION(Op_symbol);
5961                         return lasttok = DECREMENT;
5962                 }
5963                 pushback();
5964                 yylval = GET_INSTRUCTION(Op_minus);
5965                 return lasttok = '-';
5966
5967         case '.':
5968                 c = nextc();
5969                 pushback();
5970                 if (! isdigit(c))
5971                         return lasttok = '.';
5972                 else
5973                         c = '.';
5974                 /* FALL THROUGH */
5975         case '0':
5976         case '1':
5977         case '2':
5978         case '3':
5979         case '4':
5980         case '5':
5981         case '6':
5982         case '7':
5983         case '8':
5984         case '9':
5985                 /* It's a number */
5986                 for (;;) {
5987                         int gotnumber = FALSE;
5988
5989                         tokadd(c);
5990                         switch (c) {
5991                         case 'x':
5992                         case 'X':
5993                                 if (do_traditional)
5994                                         goto done;
5995                                 if (tok == tokstart + 2) {
5996                                         int peek = nextc();
5997
5998                                         if (isxdigit(peek)) {
5999                                                 inhex = TRUE;
6000                                                 pushback();     /* following digit */
6001                                         } else {
6002                                                 pushback();     /* x or X */
6003                                                 goto done;
6004                                         }
6005                                 }
6006                                 break;
6007                         case '.':
6008                                 /* period ends exponent part of floating point number */
6009                                 if (seen_point || seen_e) {
6010                                         gotnumber = TRUE;
6011                                         break;
6012                                 }
6013                                 seen_point = TRUE;
6014                                 break;
6015                         case 'e':
6016                         case 'E':
6017                                 if (inhex)
6018                                         break;
6019                                 if (seen_e) {
6020                                         gotnumber = TRUE;
6021                                         break;
6022                                 }
6023                                 seen_e = TRUE;
6024                                 if ((c = nextc()) == '-' || c == '+') {
6025                                         int c2 = nextc();
6026
6027                                         if (isdigit(c2)) {
6028                                                 tokadd(c);
6029                                                 tokadd(c2);
6030                                         } else {
6031                                                 pushback();     /* non-digit after + or - */
6032                                                 pushback();     /* + or - */
6033                                                 pushback();     /* e or E */
6034                                         }
6035                                 } else if (! isdigit(c)) {
6036                                         pushback();     /* character after e or E */
6037                                         pushback();     /* e or E */
6038                                 } else {
6039                                         pushback();     /* digit */
6040                                 }
6041                                 break;
6042                         case 'a':
6043                         case 'A':
6044                         case 'b':
6045                         case 'B':
6046                         case 'c':
6047                         case 'C':
6048                         case 'D':
6049                         case 'd':
6050                         case 'f':
6051                         case 'F':
6052                                 if (do_traditional || ! inhex)
6053                                         goto done;
6054                                 /* fall through */
6055                         case '0':
6056                         case '1':
6057                         case '2':
6058                         case '3':
6059                         case '4':
6060                         case '5':
6061                         case '6':
6062                         case '7':
6063                         case '8':
6064                         case '9':
6065                                 break;
6066                         default:
6067                         done:
6068                                 gotnumber = TRUE;
6069                         }
6070                         if (gotnumber)
6071                                 break;
6072                         c = nextc();
6073                 }
6074                 pushback();
6075
6076                 tokadd('\0');
6077                 yylval = GET_INSTRUCTION(Op_push_i);
6078                 if (! do_traditional && isnondecimal(tokstart, FALSE)) {
6079                         if (do_lint) {
6080                                 if (isdigit((unsigned char) tokstart[1]))       /* not an 'x' or 'X' */
6081                                         lintwarn("numeric constant `%.*s' treated as octal",
6082                                                 (int) strlen(tokstart)-1, tokstart);
6083                                 else if (tokstart[1] == 'x' || tokstart[1] == 'X')
6084                                         lintwarn("numeric constant `%.*s' treated as hexadecimal",
6085                                                 (int) strlen(tokstart)-1, tokstart);
6086                         }
6087                         yylval->memory = mk_number(nondec2awknum(tokstart, strlen(tokstart)),
6088                                                                                         PERM|NUMCUR|NUMBER);
6089                 } else
6090                         yylval->memory = mk_number(atof(tokstart), PERM|NUMCUR|NUMBER);
6091                 return lasttok = YNUMBER;
6092
6093         case '&':
6094                 if ((c = nextc()) == '&') {
6095                         yylval = GET_INSTRUCTION(Op_and);
6096                         allow_newline();
6097                         return lasttok = LEX_AND;
6098                 }
6099                 pushback();
6100                 yylval = GET_INSTRUCTION(Op_symbol);
6101                 return lasttok = '&';
6102
6103         case '|':
6104                 if ((c = nextc()) == '|') {
6105                         yylval = GET_INSTRUCTION(Op_or);
6106                         allow_newline();
6107                         return lasttok = LEX_OR;
6108                 } else if (! do_traditional && c == '&') {
6109                         yylval = GET_INSTRUCTION(Op_symbol);
6110                         yylval->redir_type = redirect_twoway;
6111                         return lasttok = (in_print && in_parens == 0 ? IO_OUT : IO_IN);
6112                 }
6113                 pushback();
6114                 if (in_print && in_parens == 0) {
6115                         yylval = GET_INSTRUCTION(Op_symbol);
6116                         yylval->redir_type = redirect_pipe;
6117                         return lasttok = IO_OUT;
6118                 } else {
6119                         yylval = GET_INSTRUCTION(Op_symbol);
6120                         yylval->redir_type = redirect_pipein;
6121                         return lasttok = IO_IN;
6122                 }
6123         }
6124
6125         if (c != '_' && ! isalpha(c)) {
6126                 yyerror(_("invalid char '%c' in expression"), c);
6127                 return lasttok = LEX_EOF;
6128         }
6129
6130         /*
6131          * Lots of fog here.  Consider:
6132          *
6133          * print "xyzzy"$_"foo"
6134          *
6135          * Without the check for ` lasttok != '$' ', this is parsed as
6136          *
6137          * print "xxyzz" $(_"foo")
6138          *
6139          * With the check, it is "correctly" parsed as three
6140          * string concatenations.  Sigh.  This seems to be
6141          * "more correct", but this is definitely one of those
6142          * occasions where the interactions are funny.
6143          */
6144         if (! do_traditional && c == '_' && lasttok != '$') {
6145                 if ((c = nextc()) == '"') {
6146                         intlstr = TRUE;
6147                         goto string;
6148                 }
6149                 pushback();
6150                 c = '_';
6151         }
6152
6153         /* it's some type of name-type-thing.  Find its length. */
6154         tok = tokstart;
6155         while (c != END_FILE && is_identchar(c)) {
6156                 tokadd(c);
6157                 c = nextc();
6158         }
6159         tokadd('\0');
6160         pushback();
6161
6162         /* See if it is a special token. */
6163         if ((mid = check_special(tokstart)) >= 0) {
6164                 static int warntab[sizeof(tokentab) / sizeof(tokentab[0])];
6165                 int class = tokentab[mid].class;
6166
6167                 if ((class == LEX_INCLUDE || class == LEX_EVAL)
6168                                 && lasttok != '@')
6169                         goto out;
6170
6171                 if (do_lint) {
6172                         if ((tokentab[mid].flags & GAWKX) && ! (warntab[mid] & GAWKX)) {
6173                                 lintwarn(_("`%s' is a gawk extension"),
6174                                         tokentab[mid].operator);
6175                                 warntab[mid] |= GAWKX;
6176                         }
6177                         if ((tokentab[mid].flags & RESX) && ! (warntab[mid] & RESX)) {
6178                                 lintwarn(_("`%s' is a Bell Labs extension"),
6179                                         tokentab[mid].operator);
6180                                 warntab[mid] |= RESX;
6181                         }
6182                         if ((tokentab[mid].flags & NOT_POSIX) && ! (warntab[mid] & NOT_POSIX)) {
6183                                 lintwarn(_("POSIX does not allow `%s'"),
6184                                         tokentab[mid].operator);
6185                                 warntab[mid] |= NOT_POSIX;
6186                         }
6187                 }
6188                 if (do_lint_old && (tokentab[mid].flags & NOT_OLD)
6189                                  && ! (warntab[mid] & NOT_OLD)
6190                 ) {
6191                         warning(_("`%s' is not supported in old awk"),
6192                                         tokentab[mid].operator);
6193                         warntab[mid] |= NOT_OLD;
6194                 }
6195
6196                 if (tokentab[mid].flags & BREAK)
6197                         break_allowed++;
6198                 if (tokentab[mid].flags & CONTINUE)
6199                         continue_allowed++;
6200
6201                 switch (class) {
6202                 case LEX_INCLUDE:
6203                         want_source = TRUE;
6204                         break;
6205                 case LEX_EVAL:
6206                         if (in_main_context())
6207                                 goto out;
6208                         emalloc(tokkey, char *, tok - tokstart + 1, "yylex");
6209                         tokkey[0] = '@';
6210                         memcpy(tokkey + 1, tokstart, tok - tokstart);
6211                         yylval = GET_INSTRUCTION(Op_token);
6212                         yylval->lextok = tokkey;
6213                         break;
6214
6215                 case LEX_FUNCTION:
6216                 case LEX_BEGIN:
6217                 case LEX_END:
6218                 case LEX_BEGINFILE:
6219                 case LEX_ENDFILE:               
6220                         yylval = bcalloc(tokentab[mid].value, 3, sourceline);
6221                         break;
6222
6223                 case LEX_FOR:
6224                 case LEX_WHILE:
6225                 case LEX_DO:
6226                 case LEX_SWITCH:
6227                         if (! do_profiling)
6228                                 return lasttok = class;
6229                         /* fall through */
6230                 case LEX_CASE:
6231                         yylval = bcalloc(tokentab[mid].value, 2, sourceline);
6232                         break;
6233
6234                 default:
6235                         yylval = GET_INSTRUCTION(tokentab[mid].value);
6236                         if (class == LEX_BUILTIN || class == LEX_LENGTH)
6237                                 yylval->builtin_idx = mid;
6238                         break;
6239                 }
6240                 return lasttok = class;
6241         }
6242 out:
6243         tokkey = estrdup(tokstart, tok - tokstart);
6244         if (*lexptr == '(') {
6245                 yylval = bcalloc(Op_token, 2, sourceline);
6246                 yylval->lextok = tokkey;        
6247                 return lasttok = FUNC_CALL;
6248         } else {
6249                 static short goto_warned = FALSE;
6250
6251                 yylval = GET_INSTRUCTION(Op_token);
6252                 yylval->lextok = tokkey;
6253
6254 #define SMART_ALECK     1
6255                 if (SMART_ALECK && do_lint
6256                     && ! goto_warned && strcasecmp(tokkey, "goto") == 0) {
6257                         goto_warned = TRUE;
6258                         lintwarn(_("`goto' considered harmful!\n"));
6259                 }
6260                 return lasttok = NAME;
6261         }
6262
6263 #undef GET_INSTRUCTION
6264 #undef NEWLINE_EOF
6265 }
6266
6267 /* mk_symbol --- allocates a symbol for the symbol table. */
6268
6269 NODE *
6270 mk_symbol(NODETYPE type, NODE *value)
6271 {
6272         NODE *r;
6273
6274         getnode(r);
6275         r->type = type;
6276         r->flags = MALLOC;
6277         r->lnode = value;
6278         r->rnode = NULL;
6279         r->parent_array = NULL;
6280         r->var_assign = (Func_ptr) 0;
6281         return r;
6282 }
6283
6284 /* snode --- instructions for builtin functions. Checks for arg. count
6285              and supplies defaults where possible. */
6286
6287 static INSTRUCTION *
6288 snode(INSTRUCTION *subn, INSTRUCTION *r)
6289 {
6290         INSTRUCTION *arg;
6291         INSTRUCTION *ip;
6292         NODE *n;
6293         int nexp = 0;
6294         int args_allowed;
6295         int idx = r->builtin_idx;
6296
6297         if (subn != NULL) {
6298                 INSTRUCTION *tp;
6299                 for (tp = subn->nexti; tp; tp = tp->nexti) {
6300                         tp = tp->lasti;
6301                         nexp++;
6302                 }
6303                 assert(nexp > 0);
6304         }               
6305
6306         /* check against how many args. are allowed for this builtin */
6307         args_allowed = tokentab[idx].flags & ARGS;
6308         if (args_allowed && (args_allowed & A(nexp)) == 0) {
6309                 yyerror(_("%d is invalid as number of arguments for %s"),
6310                                 nexp, tokentab[idx].operator);
6311                 return NULL;
6312         }
6313
6314         /* special processing for sub, gsub and gensub */
6315
6316         if (tokentab[idx].value == Op_sub_builtin) {
6317                 const char *operator = tokentab[idx].operator;
6318
6319                 r->sub_flags = 0;
6320
6321                 arg = subn->nexti;              /* first arg list */
6322                 (void) mk_rexp(arg);
6323
6324                 if (strcmp(operator, "gensub") != 0) {
6325                         /* sub and gsub */
6326
6327                         if (strcmp(operator, "gsub") == 0)
6328                                 r->sub_flags |= GSUB;
6329
6330                         arg = arg->lasti->nexti;        /* 2nd arg list */
6331                         if (nexp == 2) {
6332                                 INSTRUCTION *expr;
6333
6334                                 expr = list_create(instruction(Op_push_i));
6335                                 expr->nexti->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER));
6336                                 (void) mk_expression_list(subn,
6337                                                 list_append(expr, instruction(Op_field_spec)));
6338                         }
6339
6340                         arg = arg->lasti->nexti;        /* third arg list */
6341                         ip = arg->lasti;
6342                         if (ip->opcode == Op_push_i) {
6343                                 if (do_lint)
6344                                         lintwarn(_("%s: string literal as last arg of substitute has no effect"),
6345                                                 operator);
6346                                 r->sub_flags |= LITERAL;
6347                         } else {
6348                                 if (make_assignable(ip) == NULL)
6349                                         yyerror(_("%s third parameter is not a changeable object"),
6350                                                 operator);
6351                                 else
6352                                         ip->do_reference = TRUE;
6353                         }
6354
6355                         r->expr_count = count_expressions(&subn, FALSE);
6356                         ip = subn->lasti;
6357
6358                         (void) list_append(subn, r);
6359
6360                         /* add after_assign code */
6361                         if (ip->opcode == Op_push_lhs && ip->memory->type == Node_var && ip->memory->var_assign) {
6362                                 (void) list_append(subn, instruction(Op_var_assign));
6363                                 subn->lasti->assign_ctxt = Op_sub_builtin;
6364                                 subn->lasti->assign_var = ip->memory->var_assign;
6365                         } else if (ip->opcode == Op_field_spec_lhs) {
6366                                 (void) list_append(subn, instruction(Op_field_assign));
6367                                 subn->lasti->assign_ctxt = Op_sub_builtin;
6368                                 subn->lasti->field_assign = (Func_ptr) 0;
6369                                 ip->target_assign = subn->lasti;
6370                         }
6371                         return subn;    
6372
6373                 } else {
6374                         /* gensub */
6375
6376                         r->sub_flags |= GENSUB;
6377                         if (nexp == 3) {
6378                                 ip = instruction(Op_push_i);
6379                                 ip->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER));
6380                                 (void) mk_expression_list(subn,
6381                                                 list_append(list_create(ip), instruction(Op_field_spec)));
6382                         }
6383
6384                         r->expr_count = count_expressions(&subn, FALSE);
6385                         return list_append(subn, r);
6386                 }
6387         }
6388
6389         r->builtin = tokentab[idx].ptr;
6390
6391         /* special case processing for a few builtins */
6392
6393         if (r->builtin == do_length) {
6394                 if (nexp == 0) {                
6395                     /* no args. Use $0 */
6396
6397                         INSTRUCTION *list;
6398                         r->expr_count = 1;                      
6399                         list = list_create(r);
6400                         (void) list_prepend(list, instruction(Op_field_spec));
6401                         (void) list_prepend(list, instruction(Op_push_i));
6402                         list->nexti->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER));
6403                         return list; 
6404                 } else {
6405                         arg = subn->nexti;
6406                         if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push)
6407                                 arg->nexti->opcode = Op_push_arg;       /* argument may be array */
6408                 }
6409         } else if (r->builtin == do_isarray) {
6410                 arg = subn->nexti;
6411                 if (arg->nexti == arg->lasti && arg->nexti->opcode == Op_push)
6412                         arg->nexti->opcode = Op_push_arg;       /* argument may be array */
6413         } else if (r->builtin == do_match) {
6414                 static short warned = FALSE;
6415
6416                 arg = subn->nexti->lasti->nexti;        /* 2nd arg list */
6417                 (void) mk_rexp(arg);
6418
6419                 if (nexp == 3) {        /* 3rd argument there */
6420                         if (do_lint && ! warned) {
6421                                 warned = TRUE;
6422                                 lintwarn(_("match: third argument is a gawk extension"));
6423                         }
6424                         if (do_traditional) {
6425                                 yyerror(_("match: third argument is a gawk extension"));
6426                                 return NULL;
6427                         }
6428
6429                         arg = arg->lasti->nexti;        /* third arg list */
6430                         ip = arg->lasti;
6431                         if (/*ip == arg->nexti  && */ ip->opcode == Op_push)
6432                                 ip->opcode = Op_push_array;
6433                 }
6434         } else if (r->builtin == do_split) {
6435                 arg = subn->nexti->lasti->nexti;        /* 2nd arg list */
6436                 ip = arg->lasti;
6437                 if (ip->opcode == Op_push)
6438                         ip->opcode = Op_push_array;
6439                 if (nexp == 2) {
6440                         INSTRUCTION *expr;
6441                         expr = list_create(instruction(Op_push));
6442                         expr->nexti->memory = FS_node;
6443                         (void) mk_expression_list(subn, expr);
6444                 }
6445                 arg = arg->lasti->nexti;
6446                 n = mk_rexp(arg);
6447                 if (nexp == 2)
6448                         n->re_flags |= FS_DFLT;
6449                 if (nexp == 4) {
6450                         arg = arg->lasti->nexti;
6451                         ip = arg->lasti;
6452                         if (ip->opcode == Op_push)
6453                                 ip->opcode = Op_push_array;
6454                 }
6455         } else if (r->builtin == do_patsplit) {
6456                 arg = subn->nexti->lasti->nexti;        /* 2nd arg list */
6457                 ip = arg->lasti;
6458                 if (ip->opcode == Op_push)
6459                         ip->opcode = Op_push_array;
6460                 if (nexp == 2) {
6461                         INSTRUCTION *expr;
6462                         expr = list_create(instruction(Op_push));
6463                         expr->nexti->memory = FPAT_node;
6464                         (void) mk_expression_list(subn, expr);
6465                 }
6466                 arg = arg->lasti->nexti;
6467                 n = mk_rexp(arg);
6468                 if (nexp == 4) {
6469                         arg = arg->lasti->nexti;
6470                         ip = arg->lasti;
6471                         if (ip->opcode == Op_push)
6472                                 ip->opcode = Op_push_array;
6473                 }
6474         } else if (r->builtin == do_close) {
6475                 static short warned = FALSE;
6476                 if (nexp == 2) {
6477                         if (do_lint && ! warned) {
6478                                 warned = TRUE;
6479                                 lintwarn(_("close: second argument is a gawk extension"));
6480                         }
6481                         if (do_traditional) {
6482                                 yyerror(_("close: second argument is a gawk extension"));
6483                                 return NULL;
6484                         }
6485                 }
6486         } else if (do_intl                                      /* --gen-po */
6487                         && r->builtin == do_dcgettext           /* dcgettext(...) */
6488                         && subn->nexti->lasti->opcode == Op_push_i      /* 1st arg is constant */
6489                         && (subn->nexti->lasti->memory->flags & STRCUR) != 0) { /* it's a string constant */
6490                 /* ala xgettext, dcgettext("some string" ...) dumps the string */
6491                 NODE *str = subn->nexti->lasti->memory;
6492
6493                 if ((str->flags & INTLSTR) != 0)
6494                         warning(_("use of dcgettext(_\"...\") is incorrect: remove leading underscore"));
6495                         /* don't dump it, the lexer already did */
6496                 else
6497                         dumpintlstr(str->stptr, str->stlen);
6498         } else if (do_intl                                      /* --gen-po */
6499                         && r->builtin == do_dcngettext          /* dcngettext(...) */
6500                         && subn->nexti->lasti->opcode == Op_push_i      /* 1st arg is constant */
6501                         && (subn->nexti->lasti->memory->flags & STRCUR) != 0    /* it's a string constant */
6502                         && subn->nexti->lasti->nexti->lasti->opcode == Op_push_i        /* 2nd arg is constant too */
6503                         && (subn->nexti->lasti->nexti->lasti->memory->flags & STRCUR) != 0) {   /* it's a string constant */
6504                 /* ala xgettext, dcngettext("some string", "some plural" ...) dumps the string */
6505                 NODE *str1 = subn->nexti->lasti->memory;
6506                 NODE *str2 = subn->nexti->lasti->nexti->lasti->memory;
6507
6508                 if (((str1->flags | str2->flags) & INTLSTR) != 0)
6509                         warning(_("use of dcngettext(_\"...\") is incorrect: remove leading underscore"));
6510                 else
6511                         dumpintlstr2(str1->stptr, str1->stlen, str2->stptr, str2->stlen);
6512         } else if (r->builtin == do_asort || r->builtin == do_asorti) {
6513                 arg = subn->nexti;      /* 1st arg list */
6514                 ip = arg->lasti;
6515                 if (ip->opcode == Op_push)
6516                         ip->opcode = Op_push_array;
6517                 if (nexp >= 2) {
6518                         arg = ip->nexti;
6519                         ip = arg->lasti;
6520                         if (ip->opcode == Op_push)
6521                                 ip->opcode = Op_push_array;
6522                 }
6523         }
6524 #ifdef ARRAYDEBUG
6525         else if (r->builtin == do_adump) {
6526                 ip = subn->nexti->lasti;
6527                 if (ip->opcode == Op_push)
6528                         ip->opcode = Op_push_array;
6529         }
6530 #endif          
6531
6532         if (subn != NULL) {
6533                 r->expr_count = count_expressions(&subn, FALSE);
6534                 return list_append(subn, r);
6535         }
6536
6537         r->expr_count = 0;
6538         return list_create(r);
6539 }
6540
6541 /* append_param --- append PNAME to the list of parameters
6542  *                  for the current function.
6543  */
6544
6545 static void
6546 append_param(char *pname)
6547 {
6548         static NODE *savetail = NULL;
6549         NODE *p;
6550
6551         p = make_param(pname);
6552         if (func_params == NULL) {
6553                 func_params = p;
6554                 savetail = p;
6555         } else if (savetail != NULL) {
6556                 savetail->rnode = p;
6557                 savetail = p;
6558         }
6559 }
6560
6561 /* dup_parms --- return TRUE if there are duplicate parameters */
6562
6563 static int
6564 dup_parms(INSTRUCTION *fp, NODE *func)
6565 {
6566         NODE *np;
6567         const char *fname, **names;
6568         int count, i, j, dups;
6569         NODE *params;
6570
6571         if (func == NULL)       /* error earlier */
6572                 return TRUE;
6573
6574         fname = func->param;
6575         count = func->param_cnt;
6576         params = func->rnode;
6577
6578         if (count == 0)         /* no args, no problem */
6579                 return FALSE;
6580
6581         if (params == NULL)     /* error earlier */
6582                 return TRUE;
6583
6584         emalloc(names, const char **, count * sizeof(char *), "dup_parms");
6585
6586         i = 0;
6587         for (np = params; np != NULL; np = np->rnode) {
6588                 if (np->param == NULL) { /* error earlier, give up, go home */
6589                         efree(names);
6590                         return TRUE;
6591                 }
6592                 names[i++] = np->param;
6593         }
6594
6595         dups = 0;
6596         for (i = 1; i < count; i++) {
6597                 for (j = 0; j < i; j++) {
6598                         if (strcmp(names[i], names[j]) == 0) {
6599                                 dups++;
6600                                 error_ln(fp->source_line,
6601         _("function `%s': parameter #%d, `%s', duplicates parameter #%d"),
6602                                         fname, i + 1, names[j], j+1);
6603                         }
6604                 }
6605         }
6606
6607         efree(names);
6608         return (dups > 0 ? TRUE : FALSE);
6609 }
6610
6611 /* parms_shadow --- check if parameters shadow globals */
6612
6613 static int
6614 parms_shadow(INSTRUCTION *pc, int *shadow)
6615 {
6616         int pcount, i;
6617         int ret = FALSE;
6618         NODE *func;
6619         char *fname;
6620
6621         func = pc->func_body;
6622         fname = func->lnode->param;
6623         
6624 #if 0   /* can't happen, already exited if error ? */
6625         if (fname == NULL || func == NULL)      /* error earlier */
6626                 return FALSE;
6627 #endif
6628
6629         pcount = func->lnode->param_cnt;
6630
6631         if (pcount == 0)                /* no args, no problem */
6632                 return 0;
6633
6634         source = pc->source_file;
6635         sourceline = pc->source_line;
6636         /*
6637          * Use warning() and not lintwarn() so that can warn
6638          * about all shadowed parameters.
6639          */
6640         for (i = 0; i < pcount; i++) {
6641                 if (lookup(func->parmlist[i]) != NULL) {
6642                         warning(
6643         _("function `%s': parameter `%s' shadows global variable"),
6644                                         fname, func->parmlist[i]);
6645                         ret = TRUE;
6646                 }
6647         }
6648
6649         *shadow |= ret;
6650         return 0;
6651 }
6652
6653
6654 /*
6655  * install_symbol:
6656  * Install a name in the symbol table, even if it is already there.
6657  * Caller must check against redefinition if that is desired. 
6658  */
6659
6660
6661 NODE *
6662 install_symbol(char *name, NODE *value)
6663 {
6664         NODE *hp;
6665         size_t len;
6666         int bucket;
6667
6668         if (install_func)
6669                 (*install_func)(name);
6670
6671         var_count++;
6672         len = strlen(name);
6673         bucket = hash(name, len, (unsigned long) HASHSIZE, NULL);
6674         getnode(hp);
6675         hp->type = Node_hashnode;
6676         hp->hnext = variables[bucket];
6677         variables[bucket] = hp;
6678         hp->hlength = len;
6679         hp->hvalue = value;
6680         hp->hname = name;
6681         hp->hvalue->vname = name;
6682         return hp->hvalue;
6683 }
6684
6685 /* lookup --- find the most recent hash node for name installed by install_symbol */
6686
6687 NODE *
6688 lookup(const char *name)
6689 {
6690         NODE *bucket;
6691         size_t len;
6692
6693         len = strlen(name);
6694         for (bucket = variables[hash(name, len, (unsigned long) HASHSIZE, NULL)];
6695                         bucket != NULL; bucket = bucket->hnext)
6696                 if (bucket->hlength == len && strncmp(bucket->hname, name, len) == 0)
6697                         return bucket->hvalue;
6698         return NULL;
6699 }
6700
6701 /* sym_comp --- compare two symbol (variable or function) names */
6702
6703 static int
6704 sym_comp(const void *v1, const void *v2)
6705 {
6706         const NODE *const *npp1, *const *npp2;
6707         const NODE *n1, *n2;
6708         int minlen;
6709
6710         npp1 = (const NODE *const *) v1;
6711         npp2 = (const NODE *const *) v2;
6712         n1 = *npp1;
6713         n2 = *npp2;
6714
6715         if (n1->hlength > n2->hlength)
6716                 minlen = n1->hlength;
6717         else
6718                 minlen = n2->hlength;
6719
6720         return strncmp(n1->hname, n2->hname, minlen);
6721 }
6722
6723 /* valinfo --- dump var info */
6724
6725 void
6726 valinfo(NODE *n, int (*print_func)(FILE *, const char *, ...), FILE *fp)
6727 {
6728         if (n == Nnull_string)
6729                 print_func(fp, "uninitialized scalar\n");
6730         else if (n->flags & STRING) {
6731                 pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', FALSE);
6732                 print_func(fp, "\n");
6733         } else if (n->flags & NUMBER)
6734                 print_func(fp, "%.17g\n", n->numbr);
6735         else if (n->flags & STRCUR) {
6736                 pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', FALSE);
6737                 print_func(fp, "\n");
6738         } else if (n->flags & NUMCUR)
6739                 print_func(fp, "%.17g\n", n->numbr);
6740         else
6741                 print_func(fp, "?? flags %s\n", flags2str(n->flags));
6742 }
6743
6744 /* get_varlist --- list of global variables */
6745
6746 NODE **
6747 get_varlist()
6748 {
6749         int i, j;
6750         NODE **table;
6751         NODE *p;
6752
6753         emalloc(table, NODE **, (var_count + 1) * sizeof(NODE *), "get_varlist");
6754         update_global_values();
6755         for (i = j = 0; i < HASHSIZE; i++)
6756                 for (p = variables[i]; p != NULL; p = p->hnext)
6757                         table[j++] = p;
6758         assert(j == var_count);
6759
6760         /* Shazzam! */
6761         qsort(table, j, sizeof(NODE *), sym_comp);
6762
6763         table[j] = NULL;
6764         return table;
6765 }
6766
6767 /* print_vars --- print names and values of global variables */ 
6768
6769 void
6770 print_vars(int (*print_func)(FILE *, const char *, ...), FILE *fp)
6771 {
6772         int i;
6773         NODE **table;
6774         NODE *p;
6775
6776         table = get_varlist();
6777         for (i = 0; (p = table[i]) != NULL; i++) {
6778                 if (p->hvalue->type == Node_func)
6779                         continue;
6780                 print_func(fp, "%.*s: ", (int) p->hlength, p->hname);
6781                 if (p->hvalue->type == Node_var_array)
6782                         print_func(fp, "array, %ld elements\n", p->hvalue->table_size);
6783                 else if (p->hvalue->type == Node_var_new)
6784                         print_func(fp, "untyped variable\n");
6785                 else if (p->hvalue->type == Node_var)
6786                         valinfo(p->hvalue->var_value, print_func, fp);
6787         }
6788         efree(table);
6789 }
6790
6791 /* dump_vars --- dump the symbol table */
6792
6793 void
6794 dump_vars(const char *fname)
6795 {
6796         FILE *fp;
6797
6798         if (fname == NULL)
6799                 fp = stderr;
6800         else if ((fp = fopen(fname, "w")) == NULL) {
6801                 warning(_("could not open `%s' for writing (%s)"), fname, strerror(errno));
6802                 warning(_("sending variable list to standard error"));
6803                 fp = stderr;
6804         }
6805
6806         print_vars(fprintf, fp);
6807         if (fp != stderr && fclose(fp) != 0)
6808                 warning(_("%s: close failed (%s)"), fname, strerror(errno));
6809 }
6810
6811 /* release_all_vars --- free all variable memory */
6812
6813 void
6814 release_all_vars()
6815 {
6816         int i;
6817         NODE *p, *next;
6818         
6819         for (i = 0; i < HASHSIZE; i++) {
6820                 for (p = variables[i]; p != NULL; p = next) {
6821                         next = p->hnext;
6822
6823                         if (p->hvalue->type == Node_func)
6824                                 continue;
6825                         else if (p->hvalue->type == Node_var_array)
6826                                 assoc_clear(p->hvalue);
6827                         else if (p->hvalue->type != Node_var_new)
6828                                 unref(p->hvalue->var_value);
6829
6830                         efree(p->hname);
6831                         freenode(p->hvalue);
6832                         freenode(p);
6833                 }
6834         }                                                                    
6835 }
6836
6837 /* dump_funcs --- print all functions */
6838
6839 void
6840 dump_funcs()
6841 {
6842         if (func_count <= 0)
6843                 return;
6844
6845         (void) foreach_func((int (*)(INSTRUCTION *, void *)) pp_func, TRUE, (void *) 0);
6846 }
6847
6848 /* shadow_funcs --- check all functions for parameters that shadow globals */
6849
6850 void
6851 shadow_funcs()
6852 {
6853         static int calls = 0;
6854         int shadow = FALSE;
6855
6856         if (func_count <= 0)
6857                 return;
6858
6859         if (calls++ != 0)
6860                 fatal(_("shadow_funcs() called twice!"));
6861
6862         (void) foreach_func((int (*)(INSTRUCTION *, void *)) parms_shadow, TRUE, &shadow);
6863
6864         /* End with fatal if the user requested it.  */
6865         if (shadow && lintfunc != warning)
6866                 lintwarn(_("there were shadowed variables."));
6867 }
6868
6869 /*
6870  * func_install:
6871  * check if name is already installed;  if so, it had better have Null value,
6872  * in which case def is added as the value. Otherwise, install name with def
6873  * as value. 
6874  *
6875  * Extra work, build up and save a list of the parameter names in a table
6876  * and hang it off params->parmlist. This is used to set the `vname' field
6877  * of each function parameter during a function call. See eval.c.
6878  */
6879
6880 static int
6881 func_install(INSTRUCTION *func, INSTRUCTION *def)
6882 {
6883         NODE *params;
6884         NODE *r, *n, *thisfunc, *hp;
6885         char **pnames = NULL;
6886         char *fname;
6887         int pcount = 0;
6888         int i;
6889
6890         params = func_params;
6891
6892         /* check for function foo(foo) { ... }.  bleah. */
6893         for (n = params->rnode; n != NULL; n = n->rnode) {
6894                 if (strcmp(n->param, params->param) == 0) {
6895                         error_ln(func->source_line,
6896                                 _("function `%s': can't use function name as parameter name"), params->param);
6897                         return -1;
6898                 } else if (is_std_var(n->param)) {
6899                         error_ln(func->source_line,
6900                                 _("function `%s': can't use special variable `%s' as a function parameter"),
6901                                         params->param, n->param);
6902                         return -1;
6903                 }
6904         }
6905
6906         thisfunc = NULL;        /* turn off warnings */
6907
6908         fname = params->param;
6909         /* symbol table management */
6910         hp = remove_symbol(params->param);  /* remove function name out of symbol table */ 
6911         if (hp != NULL)
6912                 freenode(hp);
6913         r = lookup(fname);
6914         if (r != NULL) {
6915                 error_ln(func->source_line,
6916                          _("function name `%s' previously defined"), fname);
6917                 return -1;
6918         } else if (fname == builtin_func)       /* not a valid function name */
6919                 goto remove_params;
6920
6921         /* add an implicit return at end;
6922          * also used by 'return' command in debugger
6923          */
6924       
6925         (void) list_append(def, instruction(Op_push_i));
6926         def->lasti->memory = Nnull_string;
6927         (void) list_append(def, instruction(Op_K_return));
6928
6929         if (do_profiling)
6930                 (void) list_prepend(def, instruction(Op_exec_count));
6931
6932         /* func->opcode is Op_func */
6933         (func + 1)->firsti = def->nexti;
6934         (func + 1)->lasti = def->lasti;
6935         (func + 2)->first_line = func->source_line;
6936         (func + 2)->last_line = lastline;
6937
6938         func->nexti = def->nexti;
6939         bcfree(def);
6940
6941         (void) list_append(rule_list, func + 1);        /* debugging */
6942
6943         /* install the function */
6944         thisfunc = mk_symbol(Node_func, params);
6945         (void) install_symbol(fname, thisfunc);
6946         thisfunc->code_ptr = func;
6947         func->func_body = thisfunc;
6948
6949         for (n = params->rnode; n != NULL; n = n->rnode)
6950                 pcount++;
6951
6952         if (pcount != 0) {
6953                 emalloc(pnames, char **, (pcount + 1) * sizeof(char *), "func_install");
6954                 for (i = 0, n = params->rnode; i < pcount; i++, n = n->rnode)
6955                         pnames[i] = n->param;
6956                 pnames[pcount] = NULL;
6957         }
6958         thisfunc->parmlist = pnames;
6959
6960         /* update lint table info */
6961         func_use(fname, FUNC_DEFINE);
6962
6963         func_count++;   /* used in profiler / pretty printer */
6964
6965 remove_params:
6966         /* remove params from symbol table */
6967         pop_params(params->rnode);
6968         return 0;
6969 }
6970
6971 /* remove_symbol --- remove a variable from the symbol table */
6972
6973 NODE *
6974 remove_symbol(char *name)
6975 {
6976         NODE *bucket, **save;
6977         size_t len;
6978
6979         len = strlen(name);
6980         save = &(variables[hash(name, len, (unsigned long) HASHSIZE, NULL)]);
6981         for (bucket = *save; bucket != NULL; bucket = bucket->hnext) {
6982                 if (len == bucket->hlength && strncmp(bucket->hname, name, len) == 0) {
6983                         var_count--;
6984                         *save = bucket->hnext;
6985                         return bucket;
6986                 }
6987                 save = &(bucket->hnext);
6988         }
6989         return NULL;
6990 }
6991
6992 /* pop_params --- remove list of function parameters from symbol table */
6993
6994 /*
6995  * pop parameters out of the symbol table. do this in reverse order to
6996  * avoid reading freed memory if there were duplicated parameters.
6997  */
6998 static void
6999 pop_params(NODE *params)
7000 {
7001         NODE *hp;
7002         if (params == NULL)
7003                 return;
7004         pop_params(params->rnode);
7005         hp = remove_symbol(params->param);
7006         if (hp != NULL)
7007                 freenode(hp);
7008 }
7009
7010 /* make_param --- make NAME into a function parameter */
7011
7012 static NODE *
7013 make_param(char *name)
7014 {
7015         NODE *r;
7016
7017         getnode(r);
7018         r->type = Node_param_list;
7019         r->rnode = NULL;
7020         r->param_cnt = param_counter++;
7021         return (install_symbol(name, r));
7022 }
7023
7024 static struct fdesc {
7025         char *name;
7026         short used;
7027         short defined;
7028         struct fdesc *next;
7029 } *ftable[HASHSIZE];
7030
7031 /* func_use --- track uses and definitions of functions */
7032
7033 static void
7034 func_use(const char *name, enum defref how)
7035 {
7036         struct fdesc *fp;
7037         int len;
7038         int ind;
7039
7040         len = strlen(name);
7041         ind = hash(name, len, HASHSIZE, NULL);
7042
7043         for (fp = ftable[ind]; fp != NULL; fp = fp->next) {
7044                 if (strcmp(fp->name, name) == 0) {
7045                         if (how == FUNC_DEFINE)
7046                                 fp->defined++;
7047                         else
7048                                 fp->used++;
7049                         return;
7050                 }
7051         }
7052
7053         /* not in the table, fall through to allocate a new one */
7054
7055         emalloc(fp, struct fdesc *, sizeof(struct fdesc), "func_use");
7056         memset(fp, '\0', sizeof(struct fdesc));
7057         emalloc(fp->name, char *, len + 1, "func_use");
7058         strcpy(fp->name, name);
7059         if (how == FUNC_DEFINE)
7060                 fp->defined++;
7061         else
7062                 fp->used++;
7063         fp->next = ftable[ind];
7064         ftable[ind] = fp;
7065 }
7066
7067 /* check_funcs --- verify functions that are called but not defined */
7068
7069 static void
7070 check_funcs()
7071 {
7072         struct fdesc *fp, *next;
7073         int i;
7074
7075         if (! in_main_context())
7076                 goto free_mem;
7077  
7078         for (i = 0; i < HASHSIZE; i++) {
7079                 for (fp = ftable[i]; fp != NULL; fp = fp->next) {
7080 #ifdef REALLYMEAN
7081                         /* making this the default breaks old code. sigh. */
7082                         if (fp->defined == 0) {
7083                                 error(
7084                 _("function `%s' called but never defined"), fp->name);
7085                                 errcount++;
7086                         }
7087 #else
7088                         if (do_lint && fp->defined == 0)
7089                                 lintwarn(
7090                 _("function `%s' called but never defined"), fp->name);
7091 #endif
7092                         if (do_lint && fp->used == 0) {
7093                                 lintwarn(_("function `%s' defined but never called directly"),
7094                                         fp->name);
7095                         }
7096                 }
7097         }
7098
7099 free_mem:
7100         /* now let's free all the memory */
7101         for (i = 0; i < HASHSIZE; i++) {
7102                 for (fp = ftable[i]; fp != NULL; fp = next) {
7103                         next = fp->next;
7104                         efree(fp->name);
7105                         efree(fp);
7106                 }
7107                 ftable[i] = NULL;
7108         }
7109 }
7110
7111 /* param_sanity --- look for parameters that are regexp constants */
7112
7113 static void
7114 param_sanity(INSTRUCTION *arglist)
7115 {
7116         INSTRUCTION *argl, *arg;
7117         int i = 1;
7118
7119         if (arglist == NULL)
7120                 return;
7121         for (argl = arglist->nexti; argl; ) {
7122                 arg = argl->lasti;
7123                 if (arg->opcode == Op_match_rec)
7124                         warning_ln(arg->source_line,
7125                                 _("regexp constant for parameter #%d yields boolean value"), i);
7126                 argl = arg->nexti;
7127                 i++;
7128         }
7129 }
7130
7131 /* foreach_func --- execute given function for each awk function in symbol table. */
7132
7133 int
7134 foreach_func(int (*pfunc)(INSTRUCTION *, void *), int sort, void *data)
7135 {
7136         int i, j;
7137         NODE *p;
7138         int ret = 0;
7139
7140         if (sort) {
7141                 NODE **tab;
7142
7143                 /*
7144                  * Walk through symbol table counting functions.
7145                  * Could be more than func_count if there are
7146                  * extension functions.
7147                  */
7148                 for (i = j = 0; i < HASHSIZE; i++) {
7149                         for (p = variables[i]; p != NULL; p = p->hnext) {
7150                                 if (p->hvalue->type == Node_func) {
7151                                         j++;
7152                                 }
7153                         }
7154                 }
7155
7156                 if (j == 0)
7157                         return 0;
7158
7159                 emalloc(tab, NODE **, j * sizeof(NODE *), "foreach_func");
7160
7161                 /* now walk again, copying info */
7162                 for (i = j = 0; i < HASHSIZE; i++) {
7163                         for (p = variables[i]; p != NULL; p = p->hnext) {
7164                                 if (p->hvalue->type == Node_func) {
7165                                         tab[j] = p;
7166                                         j++;
7167                                 }
7168                         }
7169                 }
7170
7171                 /* Shazzam! */
7172                 qsort(tab, j, sizeof(NODE *), sym_comp);
7173
7174                 for (i = 0; i < j; i++) {
7175                         if ((ret = pfunc(tab[i]->hvalue->code_ptr, data)) != 0)
7176                                 break;
7177                 }
7178
7179                 efree(tab);
7180                 return ret;
7181         }
7182
7183         /* unsorted */
7184         for (i = 0; i < HASHSIZE; i++) {
7185                 for (p = variables[i]; p != NULL; p = p->hnext) {
7186                         if (p->hvalue->type == Node_func
7187                                         && (ret = pfunc(p->hvalue->code_ptr, data)) != 0)
7188                                 return ret;
7189                 }
7190         }
7191         return 0;
7192 }
7193
7194 /* deferred variables --- those that are only defined if needed. */
7195
7196 /*
7197  * Is there any reason to use a hash table for deferred variables?  At the
7198  * moment, there are only 1 to 3 such variables, so it may not be worth
7199  * the overhead.  If more modules start using this facility, it should
7200  * probably be converted into a hash table.
7201  */
7202
7203 static struct deferred_variable {
7204         NODE *(*load_func)(void);
7205         struct deferred_variable *next;
7206         char name[1];   /* variable-length array */
7207 } *deferred_variables;
7208
7209 /* register_deferred_variable --- add a var name and loading function to the list */
7210
7211 void
7212 register_deferred_variable(const char *name, NODE *(*load_func)(void))
7213 {
7214         struct deferred_variable *dv;
7215         size_t sl = strlen(name);
7216
7217         emalloc(dv, struct deferred_variable *, sizeof(*dv)+sl,
7218                 "register_deferred_variable");
7219         dv->load_func = load_func;
7220         dv->next = deferred_variables;
7221         memcpy(dv->name, name, sl+1);
7222         deferred_variables = dv;
7223 }
7224
7225 /* variable --- make sure NAME is in the symbol table */
7226
7227 NODE *
7228 variable(char *name, NODETYPE type)
7229 {
7230         NODE *r;
7231
7232         if ((r = lookup(name)) != NULL) {
7233                 if (r->type == Node_func) {
7234                         error(_("function `%s' called with space between name and `(',\nor used as a variable or an array"),
7235                                 r->vname);
7236                         errcount++;
7237                         r->type = Node_var_new; /* continue parsing instead of exiting */
7238                 }
7239         } else {
7240                 /* not found */
7241                 struct deferred_variable *dv;
7242
7243                 for (dv = deferred_variables; TRUE; dv = dv->next) {
7244                         if (dv == NULL) {
7245                         /*
7246                          * This is the only case in which we may not free the string.
7247                          */
7248                                 if (type == Node_var)
7249                                         r = mk_symbol(type, Nnull_string);
7250                                 else
7251                                         r = mk_symbol(type, (NODE *) NULL);
7252                                 return install_symbol(name, r);
7253                         }
7254                         if (strcmp(name, dv->name) == 0) {
7255                                 r = (*dv->load_func)();
7256                                 break;
7257                         }
7258                 }
7259         }
7260         efree(name);
7261         return r;
7262 }
7263
7264 /* make_regnode --- make a regular expression node */
7265
7266 static NODE *
7267 make_regnode(int type, NODE *exp)
7268 {
7269         NODE *n;
7270
7271         getnode(n);
7272         memset(n, 0, sizeof(NODE));
7273         n->type = type;
7274         n->re_cnt = 1;
7275
7276         if (type == Node_regex) {
7277                 n->re_reg = make_regexp(exp->stptr, exp->stlen, FALSE, TRUE, FALSE);
7278                 if (n->re_reg == NULL) {
7279                         freenode(n);
7280                         return NULL;
7281                 }
7282                 n->re_exp = exp;
7283                 n->re_flags = CONSTANT;
7284         }
7285         return n;
7286 }
7287
7288
7289 /* mk_rexp --- make a regular expression constant */
7290
7291 static NODE *
7292 mk_rexp(INSTRUCTION *list)
7293 {
7294         INSTRUCTION *ip;
7295
7296         ip = list->nexti;
7297         if (ip == list->lasti && ip->opcode == Op_match_rec)
7298                 ip->opcode = Op_push_re;
7299         else {
7300                 ip = instruction(Op_push_re);
7301                 ip->memory = make_regnode(Node_dynregex, NULL);
7302                 ip->nexti = list->lasti->nexti;
7303                 list->lasti->nexti = ip;
7304                 list->lasti = ip;
7305         }
7306         return ip->memory;
7307 }
7308
7309 /* isnoeffect --- when used as a statement, has no side effects */
7310
7311 static int
7312 isnoeffect(OPCODE type)
7313 {
7314         switch (type) {
7315         case Op_times:
7316         case Op_times_i:
7317         case Op_quotient:
7318         case Op_quotient_i:
7319         case Op_mod:
7320         case Op_mod_i:
7321         case Op_plus:
7322         case Op_plus_i:
7323         case Op_minus:
7324         case Op_minus_i:
7325         case Op_subscript:
7326         case Op_concat:
7327         case Op_exp:
7328         case Op_exp_i:
7329         case Op_unary_minus:
7330         case Op_field_spec:
7331         case Op_and_final:
7332         case Op_or_final:
7333         case Op_equal:
7334         case Op_notequal:
7335         case Op_less:
7336         case Op_greater:
7337         case Op_leq:
7338         case Op_geq:
7339         case Op_match:
7340         case Op_nomatch:
7341         case Op_match_rec:
7342         case Op_not:
7343         case Op_in_array:
7344                 return TRUE;
7345         default:
7346                 break;  /* keeps gcc -Wall happy */
7347         }
7348
7349         return FALSE;
7350 }
7351
7352 /* make_assignable --- make this operand an assignable one if posiible */
7353
7354 static INSTRUCTION *
7355 make_assignable(INSTRUCTION *ip)
7356 {
7357         switch (ip->opcode) {
7358         case Op_push:
7359                 if (ip->memory->type == Node_param_list
7360                                 && (ip->memory->flags & FUNC) != 0)
7361                         return NULL;
7362                 ip->opcode = Op_push_lhs;
7363                 return ip;
7364         case Op_field_spec:
7365                 ip->opcode = Op_field_spec_lhs;
7366                 return ip;
7367         case Op_subscript:
7368                 ip->opcode = Op_subscript_lhs;
7369                 return ip;
7370         default:
7371                 break;  /* keeps gcc -Wall happy */
7372         }
7373         return NULL;
7374 }
7375
7376 /* stopme --- for debugging */
7377
7378 NODE *
7379 stopme(int nargs ATTRIBUTE_UNUSED)
7380 {
7381         return (NODE *) 0;
7382 }
7383
7384 /* dumpintlstr --- write out an initial .po file entry for the string */
7385
7386 static void
7387 dumpintlstr(const char *str, size_t len)
7388 {
7389         char *cp;
7390
7391         /* See the GNU gettext distribution for details on the file format */
7392
7393         if (source != NULL) {
7394                 /* ala the gettext sources, remove leading `./'s */
7395                 for (cp = source; cp[0] == '.' && cp[1] == '/'; cp += 2)
7396                         continue;
7397                 printf("#: %s:%d\n", cp, sourceline);
7398         }
7399
7400         printf("msgid ");
7401         pp_string_fp(fprintf, stdout, str, len, '"', TRUE);
7402         putchar('\n');
7403         printf("msgstr \"\"\n\n");
7404         fflush(stdout);
7405 }
7406
7407 /* dumpintlstr2 --- write out an initial .po file entry for the string and its plural */
7408
7409 static void
7410 dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2)
7411 {
7412         char *cp;
7413
7414         /* See the GNU gettext distribution for details on the file format */
7415
7416         if (source != NULL) {
7417                 /* ala the gettext sources, remove leading `./'s */
7418                 for (cp = source; cp[0] == '.' && cp[1] == '/'; cp += 2)
7419                         continue;
7420                 printf("#: %s:%d\n", cp, sourceline);
7421         }
7422
7423         printf("msgid ");
7424         pp_string_fp(fprintf, stdout, str1, len1, '"', TRUE);
7425         putchar('\n');
7426         printf("msgid_plural ");
7427         pp_string_fp(fprintf, stdout, str2, len2, '"', TRUE);
7428         putchar('\n');
7429         printf("msgstr[0] \"\"\nmsgstr[1] \"\"\n\n");
7430         fflush(stdout);
7431 }
7432
7433 /* isarray --- can this type be subscripted? */
7434
7435 static int
7436 isarray(NODE *n)
7437 {
7438         switch (n->type) {
7439         case Node_var_new:
7440         case Node_var_array:
7441                 return TRUE;
7442         case Node_param_list:
7443                 return (n->flags & FUNC) == 0;
7444         case Node_array_ref:
7445                 cant_happen();
7446                 break;
7447         default:
7448                 break;  /* keeps gcc -Wall happy */
7449         }
7450
7451         return FALSE;
7452 }
7453
7454 /* mk_binary --- instructions for binary operators */
7455
7456 static INSTRUCTION *
7457 mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op)
7458 {
7459         INSTRUCTION *ip1,*ip2;
7460         AWKNUM res;
7461
7462         ip2 = s2->nexti;
7463         if (s2->lasti == ip2 && ip2->opcode == Op_push_i) {
7464         /* do any numeric constant folding */
7465                 ip1 = s1->nexti;
7466                 if (do_optimize > 1
7467                                 && ip1 == s1->lasti && ip1->opcode == Op_push_i
7468                                 && (ip1->memory->flags & (STRCUR|STRING)) == 0
7469                                 && (ip2->memory->flags & (STRCUR|STRING)) == 0
7470                 ) {
7471                         NODE *n1 = ip1->memory, *n2 = ip2->memory;
7472                         res = force_number(n1);
7473                         (void) force_number(n2);
7474                         switch (op->opcode) {
7475                         case Op_times:
7476                                 res *= n2->numbr;
7477                                 break;
7478                         case Op_quotient:
7479                                 if (n2->numbr == 0.0) {
7480                                         /* don't fatalize, allow parsing rest of the input */
7481                                         error_ln(op->source_line, _("division by zero attempted"));
7482                                         goto regular;
7483                                 }
7484
7485                                 res /= n2->numbr;
7486                                 break;
7487                         case Op_mod:
7488                                 if (n2->numbr == 0.0) {
7489                                         /* don't fatalize, allow parsing rest of the input */
7490                                         error_ln(op->source_line, _("division by zero attempted in `%%'"));
7491                                         goto regular;
7492                                 }
7493 #ifdef HAVE_FMOD
7494                                 res = fmod(res, n2->numbr);
7495 #else   /* ! HAVE_FMOD */
7496                                 (void) modf(res / n2->numbr, &res);
7497                                 res = n1->numbr - res * n2->numbr;
7498 #endif  /* ! HAVE_FMOD */
7499                                 break;
7500                         case Op_plus:
7501                                 res += n2->numbr;
7502                                 break;
7503                         case Op_minus:
7504                                 res -= n2->numbr;
7505                                 break;
7506                         case Op_exp:
7507                                 res = calc_exp(res, n2->numbr);
7508                                 break;
7509                         default:
7510                                 goto regular;
7511                         }
7512
7513                         op->opcode = Op_push_i;
7514                         op->memory = mk_number(res, (PERM|NUMCUR|NUMBER));
7515                         n1->flags &= ~PERM;
7516                         n1->flags |= MALLOC;
7517                         n2->flags &= ~PERM;
7518                         n2->flags |= MALLOC;
7519                         unref(n1);
7520                         unref(n2);
7521                         bcfree(ip1);
7522                         bcfree(ip2);
7523                         bcfree(s1);
7524                         bcfree(s2);
7525                         return list_create(op);
7526                 } else {
7527                 /* do basic arithmetic optimisation */
7528                 /* convert (Op_push_i Node_val) + (Op_plus) to (Op_plus_i Node_val) */
7529                         switch (op->opcode) {
7530                         case Op_times:
7531                                 op->opcode = Op_times_i;
7532                                 break;
7533                         case Op_quotient:
7534                                 op->opcode = Op_quotient_i;
7535                                 break;
7536                         case Op_mod:
7537                                 op->opcode = Op_mod_i;
7538                                 break;
7539                         case Op_plus:
7540                                 op->opcode = Op_plus_i;
7541                                 break;
7542                         case Op_minus:
7543                                 op->opcode = Op_minus_i;
7544                                 break;
7545                         case Op_exp:
7546                                 op->opcode = Op_exp_i;
7547                                 break;
7548                         default:
7549                                 goto regular;
7550                         }       
7551
7552                         op->memory = ip2->memory;
7553                         bcfree(ip2);
7554                         bcfree(s2);     /* Op_list */
7555                         return list_append(s1, op);
7556                 }
7557         }
7558
7559 regular:
7560         /* append lists s1, s2 and add `op' bytecode */
7561         (void) list_merge(s1, s2);
7562         return list_append(s1, op);
7563 }
7564
7565 /* mk_boolean --- instructions for boolean and, or */
7566  
7567 static INSTRUCTION *
7568 mk_boolean(INSTRUCTION *left, INSTRUCTION *right, INSTRUCTION *op)
7569 {
7570         INSTRUCTION *tp;
7571         OPCODE opc, final_opc;
7572
7573         opc = op->opcode;               /* Op_and or Op_or */
7574         final_opc = (opc == Op_or) ? Op_or_final : Op_and_final;
7575
7576         add_lint(right, LINT_assign_in_cond);
7577
7578         tp = left->lasti;
7579
7580         if (tp->opcode != final_opc) {  /* x || y */
7581                 list_append(right, instruction(final_opc));
7582                 add_lint(left, LINT_assign_in_cond);
7583                 (void) list_append(left, op);
7584                 left->lasti->target_jmp = right->lasti;
7585
7586                 /* NB: target_stmt points to previous Op_and(Op_or) in a chain;
7587                  *     target_stmt only used in the parser (see below).
7588                  */
7589
7590                 left->lasti->target_stmt = left->lasti;
7591                 right->lasti->target_stmt = left->lasti;
7592         } else {                /* optimization for x || y || z || ... */
7593                 INSTRUCTION *ip;
7594                 
7595                 op->opcode = final_opc;
7596                 (void) list_append(right, op);
7597                 op->target_stmt = tp;
7598                 tp->opcode = opc;
7599                 tp->target_jmp = op;
7600
7601                 /* update jump targets */
7602                 for (ip = tp->target_stmt; ; ip = ip->target_stmt) {
7603                         assert(ip->opcode == opc);
7604                         assert(ip->target_jmp == tp);
7605                         /* if (ip->opcode == opc &&  ip->target_jmp == tp) */
7606                         ip->target_jmp = op;
7607                         if (ip->target_stmt == ip)
7608                                 break;
7609                 }
7610         }
7611
7612         return list_merge(left, right);
7613 }
7614
7615 /* mk_condition --- if-else and conditional */
7616
7617 static INSTRUCTION *
7618 mk_condition(INSTRUCTION *cond, INSTRUCTION *ifp, INSTRUCTION *true_branch,
7619                 INSTRUCTION *elsep, INSTRUCTION *false_branch)
7620 {
7621         /*
7622          *    ----------------
7623          *       cond
7624          *    ----------------
7625          * t: [Op_jmp_false f ]
7626          *    ----------------
7627          *       true_branch
7628          *
7629          *    ----------------
7630          *    [Op_jmp y]
7631          *    ---------------- 
7632          * f:
7633          *      false_branch
7634          *    ----------------
7635          * y: [Op_no_op]
7636          *    ----------------
7637          */
7638
7639         INSTRUCTION *ip;
7640
7641         if (false_branch == NULL) {
7642                 false_branch = list_create(instruction(Op_no_op));
7643                 if (elsep != NULL) {            /* else { } */
7644                         if (do_profiling)
7645                                 (void) list_prepend(false_branch, elsep);
7646                         else
7647                                 bcfree(elsep);
7648                 }
7649         } else {
7650                 /* assert(elsep != NULL); */
7651
7652                 /* avoid a series of no_op's: if .. else if .. else if .. */
7653                 if (false_branch->lasti->opcode != Op_no_op)
7654                         (void) list_append(false_branch, instruction(Op_no_op));
7655                 if (do_profiling) {
7656                         (void) list_prepend(false_branch, elsep);
7657                         false_branch->nexti->branch_end = false_branch->lasti;
7658                         (void) list_prepend(false_branch, instruction(Op_exec_count));
7659                 } else
7660                         bcfree(elsep);
7661         }
7662
7663         (void) list_prepend(false_branch, instruction(Op_jmp));
7664         false_branch->nexti->target_jmp = false_branch->lasti;
7665
7666         add_lint(cond, LINT_assign_in_cond);
7667         ip = list_append(cond, instruction(Op_jmp_false));
7668         ip->lasti->target_jmp = false_branch->nexti->nexti;
7669
7670         if (do_profiling) {
7671                 (void) list_prepend(ip, ifp);
7672                 (void) list_append(ip, instruction(Op_exec_count));
7673                 ip->nexti->branch_if = ip->lasti;
7674                 ip->nexti->branch_else = false_branch->nexti;
7675         } else
7676                 bcfree(ifp);
7677
7678         if (true_branch != NULL)
7679                 list_merge(ip, true_branch);
7680         return list_merge(ip, false_branch);
7681 }
7682
7683 enum defline { FIRST_LINE, LAST_LINE };
7684
7685 /* find_line -- find the first(last) line in a list of (pattern) instructions */
7686
7687 static int
7688 find_line(INSTRUCTION *pattern, enum defline what)
7689 {
7690         INSTRUCTION *ip;
7691         int lineno = 0;
7692
7693         for (ip = pattern->nexti; ip; ip = ip->nexti) {
7694                 if (what == LAST_LINE) {
7695                         if (ip->source_line > lineno)
7696                                 lineno = ip->source_line;
7697                 } else {        /* FIRST_LINE */
7698                         if (ip->source_line > 0
7699                                         && (lineno == 0 || ip->source_line < lineno))
7700                                 lineno = ip->source_line;
7701                 }
7702                 if (ip == pattern->lasti)
7703                         break;
7704         }
7705         assert(lineno > 0);
7706         return lineno;
7707 }
7708
7709 /* append_rule --- pattern-action instructions */
7710
7711 static INSTRUCTION *
7712 append_rule(INSTRUCTION *pattern, INSTRUCTION *action)
7713 {
7714         /*
7715          *    ----------------
7716          *       pattern
7717          *    ----------------
7718          *    [Op_jmp_false f ]
7719          *    ----------------
7720          *       action
7721          *    ----------------
7722          * f: [Op_no_op       ]
7723          *    ----------------
7724          */
7725
7726         INSTRUCTION *rp;
7727         INSTRUCTION *tp;
7728         INSTRUCTION *ip;
7729
7730         if (rule != Rule) {
7731                 rp = pattern;
7732                 if (do_profiling)
7733                         (void) list_append(action, instruction(Op_no_op));
7734                 (rp + 1)->firsti = action->nexti;
7735                 (rp + 1)->lasti = action->lasti;
7736                 (rp + 2)->first_line = pattern->source_line;
7737                 (rp + 2)->last_line = lastline;
7738                 ip = list_prepend(action, rp);
7739
7740         } else {
7741                 rp = bcalloc(Op_rule, 3, 0);
7742                 rp->in_rule = Rule;
7743                 rp->source_file = source;
7744                 tp = instruction(Op_no_op);
7745
7746                 if (pattern == NULL) {
7747                         /* assert(action != NULL); */
7748                         if (do_profiling)
7749                                 (void) list_prepend(action, instruction(Op_exec_count));
7750                         (rp + 1)->firsti = action->nexti;
7751                         (rp + 1)->lasti = tp;
7752                         (rp + 2)->first_line = firstline;
7753                         (rp + 2)->last_line = lastline;
7754                         rp->source_line = firstline;
7755                         ip = list_prepend(list_append(action, tp), rp);
7756                 } else {
7757                         (void) list_append(pattern, instruction(Op_jmp_false));
7758                         pattern->lasti->target_jmp = tp;
7759                         (rp + 2)->first_line = find_line(pattern, FIRST_LINE);
7760                         rp->source_line = (rp + 2)->first_line;
7761                         if (action == NULL) {
7762                                 (rp + 2)->last_line = find_line(pattern, LAST_LINE);
7763                                 action = list_create(instruction(Op_K_print_rec));
7764                                 if (do_profiling)
7765                                         (void) list_prepend(action, instruction(Op_exec_count));
7766                         } else
7767                                 (rp + 2)->last_line = lastline;
7768
7769                         if (do_profiling) {
7770                                 (void) list_prepend(pattern, instruction(Op_exec_count));
7771                                 (void) list_prepend(action, instruction(Op_exec_count));
7772                         }
7773                         (rp + 1)->firsti = action->nexti;
7774                         (rp + 1)->lasti = tp;
7775                         ip = list_append(
7776                                         list_merge(list_prepend(pattern, rp),
7777                                                 action),
7778                                         tp);
7779                 }
7780
7781         }
7782
7783         list_append(rule_list, rp + 1);
7784
7785         if (rule_block[rule] == NULL)
7786                 rule_block[rule] = ip;
7787         else
7788                 (void) list_merge(rule_block[rule], ip);
7789         
7790         return rule_block[rule];
7791 }
7792
7793 /* mk_assignment --- assignment bytecodes */
7794
7795 static INSTRUCTION *
7796 mk_assignment(INSTRUCTION *lhs, INSTRUCTION *rhs, INSTRUCTION *op)
7797 {
7798         INSTRUCTION *tp;
7799         INSTRUCTION *ip;
7800
7801         tp = lhs->lasti;
7802         switch (tp->opcode) {
7803         case Op_field_spec:
7804                 tp->opcode = Op_field_spec_lhs;
7805                 break;
7806         case Op_subscript:
7807                 tp->opcode = Op_subscript_lhs;
7808                 break;
7809         case Op_push:
7810         case Op_push_array:
7811                 tp->opcode = Op_push_lhs; 
7812                 break;
7813         default:
7814                 cant_happen();
7815         }
7816
7817         tp->do_reference = (op->opcode != Op_assign);   /* check for uninitialized reference */
7818
7819         if (rhs != NULL)
7820                 ip = list_merge(rhs, lhs);
7821         else
7822                 ip = lhs;
7823
7824         (void) list_append(ip, op);
7825
7826         if (tp->opcode == Op_push_lhs
7827                         && tp->memory->type == Node_var
7828                         && tp->memory->var_assign
7829         ) {
7830                 tp->do_reference = FALSE; /* no uninitialized reference checking
7831                                            * for a special variable.
7832                                            */
7833                 (void) list_append(ip, instruction(Op_var_assign));
7834                 ip->lasti->assign_var = tp->memory->var_assign;
7835         } else if (tp->opcode == Op_field_spec_lhs) {
7836                 (void) list_append(ip, instruction(Op_field_assign));
7837                 ip->lasti->field_assign = (Func_ptr) 0;
7838                 tp->target_assign = ip->lasti;
7839         }
7840
7841         return ip;
7842 }
7843
7844 /* optimize_assignment --- peephole optimization for assignment */
7845
7846 static INSTRUCTION *
7847 optimize_assignment(INSTRUCTION *exp)
7848 {
7849         INSTRUCTION *i1;
7850         INSTRUCTION *i2;
7851         INSTRUCTION *i3;
7852
7853         /*
7854          * Optimize assignment statements array[subs] = x; var = x; $n = x;
7855          * string concatenation of the form s = s t.
7856          *
7857          * 1) Array element assignment array[subs] = x:
7858          *   Replaces Op_push_array + Op_subscript_lhs + Op_assign + Op_pop
7859          *   with single instruction Op_store_sub.
7860          *       Limitation: 1 dimension and sub is simple var/value.
7861          * 
7862          * 2) Simple variable assignment var = x:
7863          *   Replaces Op_push_lhs + Op_assign + Op_pop with Op_store_var.
7864          *
7865          * 3) Field assignment $n = x:
7866          *   Replaces Op_field_spec_lhs + Op_assign + Op_field_assign + Op_pop
7867          *   with Op_store_field.
7868          *
7869          * 4) Optimization for string concatenation:
7870          *   For cases like x = x y, uses realloc to include y in x;
7871          *   also eliminates instructions Op_push_lhs and Op_pop.
7872          */
7873
7874         /*
7875          * N.B.: do not append Op_pop instruction to the returned
7876          * instruction list if optimized. None of these
7877          * optimized instructions pushes the r-value of assignment
7878          * onto the runtime stack.
7879          */
7880
7881         i2 = NULL;
7882         i1 = exp->lasti;
7883
7884         if (   ! do_optimize
7885             || (   i1->opcode != Op_assign
7886                 && i1->opcode != Op_field_assign)
7887         )
7888                 return list_append(exp, instruction(Op_pop));
7889
7890         for (i2 = exp->nexti; i2 != i1; i2 = i2->nexti) {
7891                 switch (i2->opcode) {
7892                 case Op_concat:
7893                         if (i2->nexti->opcode == Op_push_lhs    /* l.h.s is a simple variable */
7894                                 && (i2->concat_flag & CSVAR)        /* 1st exp in r.h.s is a simple variable;
7895                                                                      * see Op_concat in the grammer above.
7896                                                                      */
7897                                 && i2->nexti->memory == exp->nexti->memory       /* and the same as in l.h.s */
7898                                 && i2->nexti->nexti == i1
7899                                 && i1->opcode == Op_assign
7900                         ) {
7901                                 /* s = s ... optimization */
7902
7903                                 /* avoid stuff like x = x (x = y) or x = x gsub(/./, "b", x);
7904                                  * check for l-value reference to this variable in the r.h.s.
7905                                  * Also, avoid function calls in general to guard against
7906                                  * global variable assignment.
7907                                  */
7908
7909                                 for (i3 = exp->nexti->nexti; i3 != i2; i3 = i3->nexti) {
7910                                         if ((i3->opcode == Op_push_lhs && i3->memory == i2->nexti->memory)
7911                                                         || i3->opcode == Op_func_call)
7912                                                 return list_append(exp, instruction(Op_pop)); /* no optimization */
7913                                 }
7914
7915                                 /* remove the variable from r.h.s */
7916                                 i3 = exp->nexti;
7917                                 exp->nexti = i3->nexti;
7918                                 bcfree(i3);
7919
7920                                 if (--i2->expr_count == 1)      /* one less expression in Op_concat */
7921                                         i2->opcode = Op_no_op;
7922
7923                                 i3 = i2->nexti;
7924                                 assert(i3->opcode == Op_push_lhs);
7925                                 i3->opcode = Op_assign_concat;  /* change Op_push_lhs to Op_assign_concat */
7926                                 i3->nexti = NULL;
7927                                 bcfree(i1);          /* Op_assign */
7928                                 exp->lasti = i3;     /* update Op_list */
7929                                 return exp;
7930                         }
7931                         break;
7932
7933                 case Op_field_spec_lhs:
7934                         if (i2->nexti->opcode == Op_assign
7935                                         && i2->nexti->nexti == i1
7936                                         && i1->opcode == Op_field_assign
7937                         ) {
7938                                 /* $n = .. */
7939                                 i2->opcode = Op_store_field;
7940                                 bcfree(i2->nexti);  /* Op_assign */
7941                                 i2->nexti = NULL;
7942                                 bcfree(i1);          /* Op_field_assign */
7943                                 exp->lasti = i2;    /* update Op_list */
7944                                 return exp;
7945                         }
7946                         break;
7947
7948                 case Op_push_array:
7949                         if (i2->nexti->nexti->opcode == Op_subscript_lhs) {
7950                                 i3 = i2->nexti->nexti;
7951                                 if (i3->sub_count == 1
7952                                                 && i3->nexti == i1
7953                                                 && i1->opcode == Op_assign
7954                                 ) {
7955                                         /* array[sub] = .. */
7956                                         i3->opcode = Op_store_sub;
7957                                         i3->memory = i2->memory;
7958                                         i3->expr_count = 1;  /* sub_count shadows memory,
7959                                           * so use expr_count instead.
7960                                                           */
7961                                         i3->nexti = NULL;
7962                                         i2->opcode = Op_no_op;                                  
7963                                         bcfree(i1);          /* Op_assign */
7964                                         exp->lasti = i3;     /* update Op_list */
7965                                         return exp;
7966                                 }
7967                         }
7968                         break;
7969
7970                 case Op_push_lhs:
7971                         if (i2->nexti == i1
7972                                                 && i1->opcode == Op_assign
7973                         ) {
7974                                 /* var = .. */
7975                                 i2->opcode = Op_store_var;
7976                                 i2->nexti = NULL;
7977                                 bcfree(i1);          /* Op_assign */
7978                                 exp->lasti = i2;     /* update Op_list */
7979                                 return exp;
7980                         }
7981                         break;
7982
7983                 default:
7984                         break;
7985                 }
7986         }
7987
7988         /* no optimization  */
7989         return list_append(exp, instruction(Op_pop));
7990 }
7991
7992
7993 /* mk_getline --- make instructions for getline */
7994
7995 static INSTRUCTION *
7996 mk_getline(INSTRUCTION *op, INSTRUCTION *var, INSTRUCTION *redir, int redirtype)
7997 {
7998         INSTRUCTION *ip;
7999         INSTRUCTION *tp;
8000         INSTRUCTION *asgn = NULL;
8001
8002         /*
8003          *  getline [var] < [file]
8004          *
8005          *  [ file (simp_exp)]
8006          *  [ [ var ] ]
8007          *  [ Op_K_getline_redir|NULL|redir_type|into_var]
8008          *  [ [var_assign] ] 
8009          *
8010          */
8011
8012         if (redir == NULL) {
8013                 int sline = op->source_line;
8014                 bcfree(op);
8015                 op = bcalloc(Op_K_getline, 2, sline);
8016                 (op + 1)->target_endfile = ip_endfile;
8017                 (op + 1)->target_beginfile = ip_beginfile;      
8018         }
8019
8020         if (var != NULL) {
8021                 tp = make_assignable(var->lasti);
8022                 assert(tp != NULL);
8023
8024                 /* check if we need after_assign bytecode */
8025                 if (tp->opcode == Op_push_lhs
8026                                 && tp->memory->type == Node_var
8027                                 && tp->memory->var_assign
8028                 ) {
8029                         asgn = instruction(Op_var_assign);
8030                         asgn->assign_ctxt = op->opcode;
8031                         asgn->assign_var = tp->memory->var_assign;
8032                 } else if (tp->opcode == Op_field_spec_lhs) {
8033                         asgn = instruction(Op_field_assign);
8034                         asgn->assign_ctxt = op->opcode;
8035                         asgn->field_assign = (Func_ptr) 0;   /* determined at run time */
8036                         tp->target_assign = asgn;
8037                 }
8038                 if (redir != NULL) {
8039                         ip = list_merge(redir, var);
8040                         (void) list_append(ip, op);
8041                 } else
8042                         ip = list_append(var, op);
8043         } else if (redir != NULL)
8044                 ip = list_append(redir, op);
8045         else
8046                 ip = list_create(op);
8047         op->into_var = (var != NULL);
8048         op->redir_type = (redir != NULL) ? redirtype : 0;
8049
8050         return (asgn == NULL ? ip : list_append(ip, asgn));
8051 }
8052
8053
8054 /* mk_for_loop --- for loop bytecodes */
8055
8056 static INSTRUCTION *
8057 mk_for_loop(INSTRUCTION *forp, INSTRUCTION *init, INSTRUCTION *cond,
8058                                 INSTRUCTION *incr, INSTRUCTION *body)
8059 {
8060         /*
8061          *   ------------------------
8062          *        init                 (may be NULL)
8063          *   ------------------------
8064          * x:
8065          *        cond                 (Op_no_op if NULL)
8066          *   ------------------------
8067          *    [ Op_jmp_false tb      ]
8068          *   ------------------------
8069          *        body                 (may be NULL)
8070          *   ------------------------
8071          * tc: 
8072          *    incr                      (may be NULL)
8073          *    [ Op_jmp x             ] 
8074          *   ------------------------
8075          * tb:[ Op_no_op             ] 
8076          */
8077
8078         INSTRUCTION *ip, *tbreak, *tcont;
8079         INSTRUCTION *jmp;
8080         INSTRUCTION *pp_cond;
8081         INSTRUCTION *ret;
8082
8083         tbreak = instruction(Op_no_op);
8084
8085         if (cond != NULL) {
8086                 add_lint(cond, LINT_assign_in_cond);
8087                 pp_cond = cond->nexti;
8088                 ip = cond;
8089                 (void) list_append(ip, instruction(Op_jmp_false));
8090                 ip->lasti->target_jmp = tbreak;
8091         } else {
8092                 pp_cond = instruction(Op_no_op);
8093                 ip = list_create(pp_cond);
8094         }
8095
8096         if (init != NULL)
8097                 ip = list_merge(init, ip);
8098
8099         if (do_profiling) {
8100                 (void) list_append(ip, instruction(Op_exec_count));
8101                 (forp + 1)->forloop_cond = pp_cond;
8102                 (forp + 1)->forloop_body = ip->lasti;
8103         }
8104
8105         if (body != NULL)
8106                 (void) list_merge(ip, body);
8107
8108         jmp = instruction(Op_jmp);
8109         jmp->target_jmp = pp_cond;
8110         if (incr == NULL)
8111                 tcont = jmp;
8112         else {
8113                 tcont = incr->nexti;
8114                 (void) list_merge(ip, incr);
8115         }
8116
8117         (void) list_append(ip, jmp);
8118         ret = list_append(ip, tbreak);
8119         fix_break_continue(ret, tbreak, tcont);
8120
8121         if (do_profiling) {
8122                 forp->target_break = tbreak;
8123                 forp->target_continue = tcont;
8124                 ret = list_prepend(ret, forp);
8125         } /* else
8126                         forp is NULL */
8127
8128         return ret;
8129 }
8130
8131 /* add_lint --- add lint warning bytecode if needed */
8132
8133 static void
8134 add_lint(INSTRUCTION *list, LINTTYPE linttype)
8135 {
8136 #ifndef NO_LINT
8137         INSTRUCTION *ip;
8138
8139         switch (linttype) {
8140         case LINT_assign_in_cond:
8141                 ip = list->lasti;
8142                 if (ip->opcode == Op_var_assign || ip->opcode == Op_field_assign) {
8143                         assert(ip != list->nexti);
8144                         for (ip = list->nexti; ip->nexti != list->lasti; ip = ip->nexti)
8145                                 ;
8146                 }
8147
8148                 if (ip->opcode == Op_assign || ip->opcode == Op_assign_concat) {
8149                         list_append(list, instruction(Op_lint));
8150                         list->lasti->lint_type = linttype;
8151                 }
8152                 break;
8153
8154         case LINT_no_effect:
8155                 if (list->lasti->opcode == Op_pop && list->nexti != list->lasti) {
8156                         for (ip = list->nexti; ip->nexti != list->lasti; ip = ip->nexti)
8157                                 ;
8158
8159                         if (do_lint) {          /* compile-time warning */
8160                                 if (isnoeffect(ip->opcode))
8161                                         lintwarn_ln(ip->source_line, ("statement may have no effect"));
8162                         }
8163
8164                         if (ip->opcode == Op_push) {            /* run-time warning */
8165                                 list_append(list, instruction(Op_lint));
8166                                 list->lasti->lint_type = linttype;
8167                         }
8168                 }
8169                 break;
8170
8171         default:
8172                 break;
8173         }
8174 #endif
8175 }
8176
8177 /* mk_expression_list --- list of bytecode lists */
8178
8179 static INSTRUCTION *
8180 mk_expression_list(INSTRUCTION *list, INSTRUCTION *s1)
8181 {
8182         INSTRUCTION *r;
8183
8184         /* we can't just combine all bytecodes, since we need to
8185          * process individual expressions for a few builtins in snode() (-:
8186          */
8187         
8188         /* -- list of lists     */
8189         /* [Op_list| ... ]------
8190          *                       |
8191          * [Op_list| ... ]   --  |
8192          *  ...               |  |
8193          *  ...       <-------   |
8194          * [Op_list| ... ]   --  |
8195          *  ...               |  |
8196          *  ...               |  |
8197          *  ...       <------- --
8198          */
8199
8200         assert(s1 != NULL && s1->opcode == Op_list);
8201         if (list == NULL) {
8202                 list = instruction(Op_list);
8203                 list->nexti = s1;
8204                 list->lasti = s1->lasti;
8205                 return list;
8206         }
8207
8208         /* append expression to the end of the list */
8209
8210         r = list->lasti;
8211         r->nexti = s1;
8212         list->lasti = s1->lasti;
8213         return list;
8214 }
8215
8216 /* count_expressions --- fixup expression_list from mk_expression_list.
8217  *                       returns no of expressions in list. isarg is true
8218  *                       for function arguments.
8219  */
8220
8221 static int
8222 count_expressions(INSTRUCTION **list, int isarg)
8223 {
8224         INSTRUCTION *expr;
8225         INSTRUCTION *r = NULL;
8226         int count = 0;
8227
8228         if (*list == NULL)      /* error earlier */
8229                 return 0;
8230
8231         for (expr = (*list)->nexti; expr; ) {
8232                 INSTRUCTION *t1, *t2;
8233                 t1 = expr->nexti;
8234                 t2 = expr->lasti;
8235                 if (isarg && t1 == t2 && t1->opcode == Op_push)
8236                         t1->opcode = Op_push_param;
8237                 if (++count == 1)
8238                         r = expr;
8239                 else
8240                         (void) list_merge(r, expr);
8241                 expr = t2->nexti;
8242         }
8243  
8244         assert(count > 0);
8245         if (! isarg && count > max_args)
8246                 max_args = count;
8247         bcfree(*list);
8248         *list = r;
8249         return count;
8250 }
8251
8252 /* fix_break_continue --- fix up break & continue codes in loop bodies */
8253
8254 static void
8255 fix_break_continue(INSTRUCTION *list, INSTRUCTION *b_target, INSTRUCTION *c_target)
8256 {
8257         INSTRUCTION *ip;
8258
8259         list->lasti->nexti = NULL;      /* just to make sure */
8260
8261         for (ip = list->nexti; ip != NULL; ip = ip->nexti) {
8262                 switch (ip->opcode) {
8263                 case Op_K_break:
8264                         if (ip->target_jmp == NULL)
8265                                 ip->target_jmp = b_target;
8266                         break;
8267
8268                 case Op_K_continue:
8269                         if (ip->target_jmp == NULL)
8270                                 ip->target_jmp = c_target;
8271                         break;
8272
8273                 default:
8274                         /* this is to keep the compiler happy. sheesh. */
8275                         break;
8276                 }
8277         }
8278 }
8279
8280
8281 /* append_symbol --- append symbol to the list of symbols
8282  *                  installed in the symbol table.
8283  */
8284
8285 void
8286 append_symbol(char *name)
8287 {
8288         NODE *hp;
8289
8290         /* N.B.: func_install removes func name and reinstalls it;
8291          * and we get two entries for it here!. destroy_symbol()
8292          * will find and destroy the Node_func which is what we want.
8293          */
8294
8295         getnode(hp);
8296         hp->hname = name;       /* shallow copy */
8297         hp->hnext = symbol_list->hnext;
8298         symbol_list->hnext = hp;
8299 }
8300
8301 /* release_symbol --- free symbol list and optionally remove symbol from symbol table */
8302
8303 void
8304 release_symbols(NODE *symlist, int keep_globals)
8305 {
8306         NODE *hp, *n;
8307
8308         for (hp = symlist->hnext; hp != NULL; hp = n) {
8309                 if (! keep_globals) {
8310                         /* destroys globals, function, and params
8311                          * if still in symbol table and not removed by func_install
8312                          * due to syntax error.
8313                          */
8314                         destroy_symbol(hp->hname);
8315                 }
8316                 n = hp->hnext;
8317                 freenode(hp);
8318         }
8319         symlist->hnext = NULL;
8320 }
8321
8322 /* destroy_symbol --- remove a symbol from symbol table
8323 *                     and free all associated memory.
8324 */
8325
8326 void
8327 destroy_symbol(char *name)
8328 {
8329         NODE *symbol, *hp;
8330
8331         symbol = lookup(name);
8332         if (symbol == NULL)
8333                 return;
8334
8335         if (symbol->type == Node_func) {
8336                 char **varnames;
8337                 NODE *func, *n;
8338                                 
8339                 func = symbol;
8340                 varnames = func->parmlist;
8341                 if (varnames != NULL)
8342                         efree(varnames);
8343
8344                 /* function parameters of type Node_param_list */                               
8345                 for (n = func->lnode->rnode; n != NULL; ) {
8346                         NODE *np;
8347                         np = n->rnode;
8348                         efree(n->param);
8349                         freenode(n);
8350                         n = np;
8351                 }               
8352                 freenode(func->lnode);
8353                 func_count--;
8354
8355         } else if (symbol->type == Node_var_array)
8356                 assoc_clear(symbol);
8357         else if (symbol->type == Node_var) 
8358                 unref(symbol->var_value);
8359
8360         /* remove from symbol table */
8361         hp = remove_symbol(name);
8362         efree(hp->hname);
8363         freenode(hp->hvalue);
8364         freenode(hp);
8365 }
8366
8367 #define pool_size       d.dl
8368 #define freei           x.xi
8369 static INSTRUCTION *pool_list;
8370 static AWK_CONTEXT *curr_ctxt = NULL;
8371
8372 /* new_context --- create a new execution context. */
8373
8374 AWK_CONTEXT *
8375 new_context()
8376 {
8377         AWK_CONTEXT *ctxt;
8378
8379         emalloc(ctxt, AWK_CONTEXT *, sizeof(AWK_CONTEXT), "new_context");
8380         memset(ctxt, 0, sizeof(AWK_CONTEXT));
8381         ctxt->srcfiles.next = ctxt->srcfiles.prev = &ctxt->srcfiles;
8382         ctxt->rule_list.opcode = Op_list;
8383         ctxt->rule_list.lasti = &ctxt->rule_list;
8384         return ctxt;
8385 }
8386
8387 /* set_context --- change current execution context. */
8388
8389 static void
8390 set_context(AWK_CONTEXT *ctxt)
8391 {
8392         pool_list = &ctxt->pools;
8393         symbol_list = &ctxt->symbols;
8394         srcfiles = &ctxt->srcfiles;
8395         rule_list = &ctxt->rule_list;
8396         install_func = ctxt->install_func;
8397         curr_ctxt = ctxt;
8398 }
8399
8400 /*
8401  * push_context:
8402  *
8403  * Switch to the given context after saving the current one. The set
8404  * of active execution contexts forms a stack; the global or main context
8405  * is at the bottom of the stack.
8406  */
8407
8408 void
8409 push_context(AWK_CONTEXT *ctxt)
8410 {
8411         ctxt->prev = curr_ctxt;
8412         /* save current source and sourceline */
8413         if (curr_ctxt != NULL) {
8414                 curr_ctxt->sourceline = sourceline;
8415                 curr_ctxt->source = source;
8416         }
8417         sourceline = 0;
8418         source = NULL;
8419         set_context(ctxt);
8420 }
8421
8422 /* pop_context --- switch to previous execution context. */ 
8423
8424 void
8425 pop_context()
8426 {
8427         AWK_CONTEXT *ctxt;
8428
8429         assert(curr_ctxt != NULL);
8430         ctxt = curr_ctxt->prev;
8431         /* restore source and sourceline */
8432         sourceline = ctxt->sourceline;
8433         source = ctxt->source;
8434         set_context(ctxt);
8435 }
8436
8437 /* in_main_context --- are we in the main context ? */
8438
8439 int
8440 in_main_context()
8441 {
8442         assert(curr_ctxt != NULL);
8443         return (curr_ctxt->prev == NULL);
8444 }
8445
8446 /* free_context --- free context structure and related data. */ 
8447
8448 void
8449 free_context(AWK_CONTEXT *ctxt, int keep_globals)
8450 {
8451         SRCFILE *s, *sn;
8452
8453         if (ctxt == NULL)
8454                 return;
8455
8456         assert(curr_ctxt != ctxt);
8457
8458         /* free all code including function codes */
8459         free_bcpool(&ctxt->pools);
8460         /* free symbols */
8461         release_symbols(&ctxt->symbols, keep_globals);
8462         /* free srcfiles */
8463         for (s = &ctxt->srcfiles; s != &ctxt->srcfiles; s = sn) {
8464                 sn = s->next;
8465                 if (s->stype != SRC_CMDLINE && s->stype != SRC_STDIN)
8466                         efree(s->fullpath);
8467                 efree(s->src);
8468                 efree(s);
8469         }
8470         efree(ctxt);
8471 }
8472
8473 /* free_bc_internal --- free internal memory of an instruction. */ 
8474
8475 static void
8476 free_bc_internal(INSTRUCTION *cp)
8477 {
8478         NODE *m;
8479
8480         switch(cp->opcode) {
8481         case Op_func_call:
8482                 if (cp->func_name != NULL
8483                                 && cp->func_name != builtin_func
8484                 )
8485                         efree(cp->func_name);
8486                 break;
8487         case Op_push_re:
8488         case Op_match_rec:
8489         case Op_match:
8490         case Op_nomatch:
8491                 m = cp->memory;
8492                 if (m->re_reg != NULL)
8493                         refree(m->re_reg);
8494                 if (m->re_exp != NULL)
8495                         unref(m->re_exp);
8496                 if (m->re_text != NULL)
8497                         unref(m->re_text);
8498                 freenode(m);
8499                 break;                  
8500         case Op_token:  /* token lost during error recovery in yyparse */
8501                 if (cp->lextok != NULL)
8502                         efree(cp->lextok);
8503                 break;
8504         case Op_illegal:
8505                 cant_happen();
8506         default:
8507                 break;  
8508         }
8509 }
8510
8511
8512 /* INSTR_CHUNK must be > largest code size (3) */
8513 #define INSTR_CHUNK 127
8514
8515 /* bcfree --- deallocate instruction */
8516
8517 void
8518 bcfree(INSTRUCTION *cp)
8519 {
8520         cp->opcode = 0;
8521         cp->nexti = pool_list->freei;
8522         pool_list->freei = cp;
8523 }       
8524
8525 /* bcalloc --- allocate a new instruction */
8526
8527 INSTRUCTION *
8528 bcalloc(OPCODE op, int size, int srcline)
8529 {
8530         INSTRUCTION *cp;
8531
8532         if (size > 1) {
8533                 /* wide instructions Op_rule, Op_func_call .. */
8534                 emalloc(cp, INSTRUCTION *, (size + 1) * sizeof(INSTRUCTION), "bcalloc");
8535                 cp->pool_size = size;
8536                 cp->nexti = pool_list->nexti;
8537                 pool_list->nexti = cp++;
8538         } else {
8539                 INSTRUCTION *pool;
8540
8541                 pool = pool_list->freei;
8542                 if (pool == NULL) {
8543                         INSTRUCTION *last;
8544                         emalloc(cp, INSTRUCTION *, (INSTR_CHUNK + 1) * sizeof(INSTRUCTION), "bcalloc");
8545
8546                         cp->pool_size = INSTR_CHUNK;
8547                         cp->nexti = pool_list->nexti;
8548                         pool_list->nexti = cp;
8549                         pool = ++cp;
8550                         last = &pool[INSTR_CHUNK - 1];
8551                         for (; cp <= last; cp++) {
8552                                 cp->opcode = 0;
8553                                 cp->nexti = cp + 1;
8554                         }
8555                         --cp;
8556                         cp->nexti = NULL;
8557                 }
8558                 cp = pool;
8559                 pool_list->freei = cp->nexti;
8560         }
8561
8562         memset(cp, 0, size * sizeof(INSTRUCTION));
8563         cp->opcode = op;
8564         cp->source_line = srcline;
8565         return cp;
8566 }
8567
8568 /* free_bcpool --- free list of instruction memory pools */
8569
8570 static void
8571 free_bcpool(INSTRUCTION *pl)
8572 {
8573         INSTRUCTION *pool, *tmp;
8574
8575         for (pool = pl->nexti; pool != NULL; pool = tmp) {
8576                 INSTRUCTION *cp, *last;
8577                 long psiz;
8578                 psiz = pool->pool_size;
8579                 if (psiz == INSTR_CHUNK)
8580                         last = pool + psiz;
8581                 else
8582                         last = pool + 1;
8583                 for (cp = pool + 1; cp <= last ; cp++) {
8584                         if (cp->opcode != 0)
8585                                 free_bc_internal(cp);
8586                 }
8587                 tmp = pool->nexti;
8588                 efree(pool);
8589         }
8590         memset(pl, 0, sizeof(INSTRUCTION));
8591 }
8592
8593
8594 static inline INSTRUCTION *
8595 list_create(INSTRUCTION *x)
8596 {
8597         INSTRUCTION *l;
8598
8599         l = instruction(Op_list);
8600         l->nexti = x;
8601         l->lasti = x;
8602         return l;
8603 }
8604
8605 static inline INSTRUCTION *
8606 list_append(INSTRUCTION *l, INSTRUCTION *x)
8607 {
8608 #ifdef GAWKDEBUG
8609         if (l->opcode != Op_list)
8610                 cant_happen();
8611 #endif
8612         l->lasti->nexti = x;
8613         l->lasti = x;
8614         return l;
8615 }
8616
8617 static inline INSTRUCTION *
8618 list_prepend(INSTRUCTION *l, INSTRUCTION *x)
8619 {
8620 #ifdef GAWKDEBUG
8621         if (l->opcode != Op_list)
8622                 cant_happen();
8623 #endif
8624         x->nexti = l->nexti;
8625         l->nexti = x;
8626         return l;
8627 }
8628
8629 static inline INSTRUCTION *
8630 list_merge(INSTRUCTION *l1, INSTRUCTION *l2)
8631 {
8632 #ifdef GAWKDEBUG
8633         if (l1->opcode != Op_list)
8634                 cant_happen();
8635         if (l2->opcode != Op_list)
8636                 cant_happen();
8637 #endif
8638         l1->lasti->nexti = l2->nexti;
8639         l1->lasti = l2->lasti;
8640         bcfree(l2);
8641         return l1;
8642 }
8643
8644 /* See if name is a special token. */
8645
8646 int
8647 check_special(const char *name)
8648 {
8649         int low, high, mid;
8650         int i;
8651 #if 'a' == 0x81 /* it's EBCDIC */
8652         static int did_sort = FALSE;
8653
8654         if (! did_sort) {
8655                 qsort((void *) tokentab,
8656                                 sizeof(tokentab) / sizeof(tokentab[0]),
8657                                 sizeof(tokentab[0]), tokcompare);
8658                 did_sort = TRUE;
8659         }
8660 #endif
8661
8662         low = 0;
8663         high = (sizeof(tokentab) / sizeof(tokentab[0])) - 1;
8664         while (low <= high) {
8665                 mid = (low + high) / 2;
8666                 i = *name - tokentab[mid].operator[0];
8667                 if (i == 0)
8668                         i = strcmp(name, tokentab[mid].operator);
8669
8670                 if (i < 0)              /* token < mid */
8671                         high = mid - 1;
8672                 else if (i > 0)         /* token > mid */
8673                         low = mid + 1;
8674                 else {
8675                         if ((do_traditional && (tokentab[mid].flags & GAWKX))
8676                                         || (do_posix && (tokentab[mid].flags & NOT_POSIX)))
8677                                 return -1;
8678                         return mid;
8679                 }
8680         }
8681         return -1;
8682 }
8683
8684 /*
8685  * This provides a private version of functions that act like VMS's
8686  * variable-length record filesystem, where there was a bug on
8687  * certain source files.
8688  */
8689
8690 static FILE *fp = NULL;
8691
8692 /* read_one_line --- return one input line at a time. mainly for debugging. */
8693
8694 static ssize_t
8695 read_one_line(int fd, void *buffer, size_t count)
8696 {
8697         char buf[BUFSIZ];
8698
8699         /* Minor potential memory leak here. Too bad. */
8700         if (fp == NULL) {
8701                 fp = fdopen(fd, "r");
8702                 if (fp == NULL) {
8703                         fprintf(stderr, "ugh. fdopen: %s\n", strerror(errno));
8704                         gawk_exit(EXIT_FAILURE);
8705                 }
8706         }
8707
8708         if (fgets(buf, sizeof buf, fp) == NULL)
8709                 return 0;
8710
8711         memcpy(buffer, buf, strlen(buf));
8712         return strlen(buf);
8713 }
8714
8715 /* one_line_close --- close the open file being read with read_one_line() */
8716
8717 static int
8718 one_line_close(int fd)
8719 {
8720         int ret;
8721
8722         if (fp == NULL || fd != fileno(fp))
8723                 fatal("debugging read/close screwed up!");
8724
8725         ret = fclose(fp);
8726         fp = NULL;
8727         return ret;
8728 }
8729
8730