~vcs-imports/gawk/master

« back to all changes in this revision

Viewing changes to awkgram.c

  • Committer: Arnold D. Robbins
  • Date: 2010-11-18 21:00:31 UTC
  • Revision ID: git-v1:6f3612539c425da2bc1d34db621696e6a273b01c
Bring latest byte code gawk into git. Hurray!

Show diffs side-by-side

added added

removed removed

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