1 package io.jawk.intermediate;
2
3 /*-
4 * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
5 * Jawk
6 * ჻჻჻჻჻჻
7 * Copyright (C) 2006 - 2026 MetricsHub
8 * ჻჻჻჻჻჻
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation, either version 3 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Lesser Public License for more details.
18 *
19 * You should have received a copy of the GNU General Lesser Public
20 * License along with this program. If not, see
21 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22 * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
23 */
24
25 /**
26 * Instruction set of the AVM: the opcode of every tuple that {@link AwkTuples}
27 * produces and {@link io.jawk.backend.AVM} executes.
28 * <p>
29 * Each enum constant describes one tuple opcode understood by the AVM.
30 * </p>
31 *
32 * @see AwkTuples
33 * @see Tuple
34 */
35 public enum Opcode {
36 /**
37 * Pops an item off the operand stack.
38 * <p>
39 * Stack before: x ...<br/>
40 * Stack after: ...
41 */
42 POP,
43 /**
44 * Pushes a long constant onto the operand stack.
45 * <p>
46 * Argument: the long value<br/>
47 * Stack before: ...<br/>
48 * Stack after: x ...
49 */
50 PUSH_LONG,
51 /**
52 * Pushes a double constant onto the operand stack.
53 * <p>
54 * Argument: the double value<br/>
55 * Stack before: ...<br/>
56 * Stack after: x ...
57 */
58 PUSH_DOUBLE,
59 /**
60 * Pushes a string constant onto the operand stack.
61 * <p>
62 * Argument: the string value<br/>
63 * Stack before: ...<br/>
64 * Stack after: x ...
65 */
66 PUSH_STRING,
67 /**
68 * Pops and evaluates the top-of-stack; if
69 * false, it jumps to a specified address.
70 * <p>
71 * Argument: address
72 * <p>
73 * Stack before: x ...<br/>
74 * Stack after: ...
75 */
76 IFFALSE,
77 /**
78 * Converts the top-of-stack to a number.
79 * <p>
80 * Stack before: x ...<br/>
81 * Stack after: x (as a number)
82 */
83 TO_NUMBER,
84 /**
85 * Pops and evaluates the top-of-stack; if
86 * true, it jumps to a specified address.
87 * <p>
88 * Argument: address
89 * <p>
90 * Stack before: x ...<br/>
91 * Stack after: ...
92 */
93 IFTRUE,
94 /**
95 * Jumps to a specified address. The operand stack contents
96 * are unaffected.
97 */
98 GOTO,
99 /**
100 * A no-operation. The operand stack contents are
101 * unaffected.
102 */
103 NOP,
104 /**
105 * Prints N number of items that are on the operand stack.
106 * The number of items are passed in as a tuple argument.
107 * <p>
108 * Argument: # of items (N)
109 * <p>
110 * Stack before: x1 x2 x3 .. xN ...<br/>
111 * Stack after: ...
112 */
113 PRINT,
114 /**
115 * Prints N number of items that are on the operand stack to
116 * a specified file. The file is passed in on the stack.
117 * The number of items are passed in as a tuple argument,
118 * as well as whether to overwrite the file or not (append mode).
119 * <p>
120 * Argument 1: # of items (N)<br/>
121 * Argument 2: true = append, false = overwrite
122 * <p>
123 * Stack before: x1 x2 x3 .. xN filename ...<br/>
124 * Stack after: ...
125 */
126 PRINT_TO_FILE,
127 /**
128 * Prints N number of items that are on the operand stack to
129 * a process executing a specified command (via a pipe).
130 * The command string is passed in on the stack.
131 * The number of items are passed in as a tuple argument.
132 * <p>
133 * Argument: # of items (N)
134 * <p>
135 * Stack before: x1 x2 x3 .. xN command-string ...<br/>
136 * Stack after: ...
137 */
138 PRINT_TO_PIPE,
139 /**
140 * Performs a formatted print of N items that are on the operand stack.
141 * The number of items are passed in as a tuple argument.
142 * <p>
143 * Argument: # of items (N)
144 * <p>
145 * Stack before: x1 x2 x3 .. xN ...<br/>
146 * Stack after: ...
147 */
148 PRINTF,
149 /**
150 * Performs a formatted print of N items that are on the operand stack to
151 * a specified file. The file is passed in on the stack.
152 * The number of items are passed in as a tuple argument,
153 * as well as whether to overwrite the file or not (append mode).
154 * <p>
155 * Argument 1: # of items (N)<br/>
156 * Argument 2: true = append, false = overwrite
157 * <p>
158 * Stack before: x1 x2 x3 .. xN filename ...<br/>
159 * Stack after: ...
160 */
161 PRINTF_TO_FILE,
162 /**
163 * Performs a formatted print of N items that are on the operand stack to
164 * a process executing a specified command (via a pipe).
165 * The command string is passed in on the stack.
166 * The number of items are passed in as a tuple argument.
167 * <p>
168 * Argument: # of items (N)
169 * <p>
170 * Stack before: x1 x2 x3 .. xN command-string ...<br/>
171 * Stack after: ...
172 */
173 PRINTF_TO_PIPE,
174 /** Constant <code>SPRINTF=270</code> */
175 SPRINTF,
176 /**
177 * Depending on the argument, pop and evaluate the string length of the top-of-stack
178 * or evaluate the string length of $0; in either case, push the result onto
179 * the stack.
180 * <p>
181 * The input field length evaluation mode is provided to support backward
182 * compatibility with the deprecated usage of length (i.e., no arguments).
183 * <p>
184 * Argument: 0 to use $0, use top-of-stack otherwise
185 * <p>
186 * If argument is 0:
187 * <blockquote>
188 * Stack before: ...<br/>
189 * Stack after: length-of-$0 ...
190 * </blockquote>
191 * else
192 * <blockquote>
193 * Stack before: x ...<br/>
194 * Stack after: length-of-x ...
195 * </blockquote>
196 */
197 LENGTH,
198 /**
199 * Pop and concatenate two strings from the top-of-stack; push the result onto
200 * the stack.
201 * <p>
202 * Stack before: x y ...<br/>
203 * Stack after: x-concatenated-with-y ...
204 */
205 CONCAT,
206 /**
207 * Pops and concatenates N values from the top-of-stack after AWK string
208 * conversion; pushes the result onto the stack. The number of items is passed
209 * in as a tuple argument.
210 * <p>
211 * Argument: # of items (N)
212 * <p>
213 * Stack before: x1 x2 x3 .. xN ...<br/>
214 * Stack after: x1-concatenated-through-xN ...
215 */
216 MULTI_CONCAT,
217 /**
218 * Assigns the top-of-stack to a variable and pushes the assigned value back
219 * onto the stack.
220 * <p>
221 * Argument 1: offset of the particular variable into the variable manager<br/>
222 * Argument 2: whether the variable is global or local
223 * <p>
224 * Stack before: x ...<br/>
225 * Stack after: x ...
226 */
227 ASSIGN,
228 /**
229 * Assigns the top-of-stack to a variable without pushing the assigned value
230 * back onto the stack.
231 * <p>
232 * Argument 1: offset of the particular variable into the variable manager<br/>
233 * Argument 2: whether the variable is global or local
234 * <p>
235 * Stack before: x ...<br/>
236 * Stack after: ...
237 */
238 ASSIGN_NOPUSH,
239 /**
240 * Assigns an item to an array element. The item remains on the stack.
241 * <p>
242 * Argument 1: offset of the particular associative array into the variable manager<br/>
243 * Argument 2: whether the associative array is global or local
244 * <p>
245 * Stack before: index-into-array item ...<br/>
246 * Stack after: item ...
247 */
248 ASSIGN_ARRAY,
249 /**
250 * Assigns an item to an element of the associative array currently on the stack.
251 * The item remains on the stack.
252 * <p>
253 * Stack before: array-index associative-array item ...<br/>
254 * Stack after: item ...
255 */
256 ASSIGN_MAP_ELEMENT,
257 /**
258 * Assigns the top-of-stack to $0. The contents of the stack are unaffected.
259 * Upon assignment, individual field variables are recalculated.
260 * <p>
261 * Stack before: x ...<br/>
262 * Stack after: x ...
263 */
264 ASSIGN_AS_INPUT,
265 /**
266 * Assigns an item as a particular input field; the field number can be 0.
267 * Upon assignment, associating input fields are affected. For example, if
268 * the following assignment were made:
269 * <blockquote>
270 *
271 * <pre>
272 * $3 = "hi"
273 * </pre>
274 *
275 * </blockquote>
276 * $0 would be recalculated. Likewise, if the following assignment were made:
277 * <blockquote>
278 *
279 * <pre>
280 * $0 = "hello there"
281 * </pre>
282 *
283 * </blockquote>
284 * $1, $2, ... would be recalculated.
285 * <p>
286 * Stack before: field-num x ...<br/>
287 * Stack after: x ...
288 */
289 ASSIGN_AS_INPUT_FIELD,
290 /**
291 * Obtains an item from the variable manager and push it onto the stack.
292 * <p>
293 * Argument 1: offset of the particular variable into the variable manager<br/>
294 * Argument 2: whether the variable is global or local
295 * <p>
296 * Stack before: ...<br/>
297 * Stack after: x ...
298 */
299 DEREFERENCE,
300 /**
301 * Obtains an item from the variable manager without assigning a blank value
302 * when the variable is still untyped.
303 * <p>
304 * This differs from {@link #DEREFERENCE} only for introspection paths that
305 * must observe an unassigned scalar-or-array state without changing it.
306 * </p>
307 * <p>
308 * Argument 1: offset of the particular variable into the variable manager<br/>
309 * Argument 2: whether the variable is global or local
310 * <p>
311 * Stack before: ...<br/>
312 * Stack after: x ...
313 */
314 PEEK_DEREFERENCE,
315 /**
316 * Increase the contents of the variable by an adjustment value;
317 * assigns the result to the variable and pushes the result onto the stack.
318 * <p>
319 * Argument 1: offset of the particular variable into the variable manager<br/>
320 * Argument 2: whether the variable is global or local
321 * <p>
322 * Stack before: n ...<br/>
323 * Stack after: x+n ...
324 */
325 PLUS_EQ,
326 /**
327 * Decreases the contents of the variable by an adjustment value;
328 * assigns the result to the variable and pushes the result onto the stack.
329 * <p>
330 * Argument 1: offset of the particular variable into the variable manager<br/>
331 * Argument 2: whether the variable is global or local
332 * <p>
333 * Stack before: n ...<br/>
334 * Stack after: x-n ...
335 */
336 MINUS_EQ,
337 /**
338 * Multiplies the contents of the variable by an adjustment value;
339 * assigns the result to the variable and pushes the result onto the stack.
340 * <p>
341 * Argument 1: offset of the particular variable into the variable manager<br/>
342 * Argument 2: whether the variable is global or local
343 * <p>
344 * Stack before: n ...<br/>
345 * Stack after: x*n ...
346 */
347 MULT_EQ,
348 /**
349 * Divides the contents of the variable by an adjustment value;
350 * assigns the result to the variable and pushes the result onto the stack.
351 * <p>
352 * Argument 1: offset of the particular variable into the variable manager<br/>
353 * Argument 2: whether the variable is global or local
354 * <p>
355 * Stack before: n ...<br/>
356 * Stack after: x/n ...
357 */
358 DIV_EQ,
359 /**
360 * Takes the modules of the contents of the variable by an adjustment value;
361 * assigns the result to the variable and pushes the result onto the stack.
362 * <p>
363 * Argument 1: offset of the particular variable into the variable manager<br/>
364 * Argument 2: whether the variable is global or local
365 * <p>
366 * Stack before: n ...<br/>
367 * Stack after: x%n ...
368 */
369 MOD_EQ,
370 /**
371 * Raises the contents of the variable to the power of the adjustment value;
372 * assigns the result to the variable and pushes the result onto the stack.
373 * <p>
374 * Argument 1: offset of the particular variable into the variable manager<br/>
375 * Argument 2: whether the variable is global or local
376 * <p>
377 * Stack before: n ...<br/>
378 * Stack after: x^n ...
379 */
380 POW_EQ,
381 /**
382 * Increase the contents of an indexed array by an adjustment value;
383 * assigns the result to the array and pushes the result onto the stack.
384 * <p>
385 * Argument 1: offset of the associative array into the variable manager<br/>
386 * Argument 2: whether the associative array is global or local
387 * <p>
388 * Stack before: array-idx n ...<br/>
389 * Stack after: x+n ...
390 */
391 PLUS_EQ_ARRAY,
392 /**
393 * Decreases the contents of an indexed array by an adjustment value;
394 * assigns the result to the array and pushes the result onto the stack.
395 * <p>
396 * Argument 1: offset of the associative array into the variable manager<br/>
397 * Argument 2: whether the associative array is global or local
398 * <p>
399 * Stack before: array-idx n ...<br/>
400 * Stack after: x-n ...
401 */
402 MINUS_EQ_ARRAY,
403 /**
404 * Multiplies the contents of an indexed array by an adjustment value;
405 * assigns the result to the array and pushes the result onto the stack.
406 * <p>
407 * Argument 1: offset of the associative array into the variable manager<br/>
408 * Argument 2: whether the associative array is global or local
409 * <p>
410 * Stack before: array-idx n ...<br/>
411 * Stack after: x*n ...
412 */
413 MULT_EQ_ARRAY,
414 /**
415 * Divides the contents of an indexed array by an adjustment value;
416 * assigns the result to the array and pushes the result onto the stack.
417 * <p>
418 * Argument 1: offset of the associative array into the variable manager<br/>
419 * Argument 2: whether the associative array is global or local
420 * <p>
421 * Stack before: array-idx n ...<br/>
422 * Stack after: x/n ...
423 */
424 DIV_EQ_ARRAY,
425 /**
426 * Takes the modulus of the contents of an indexed array by an adjustment value;
427 * assigns the result to the array and pushes the result onto the stack.
428 * <p>
429 * Argument 1: offset of the associative array into the variable manager<br/>
430 * Argument 2: whether the associative array is global or local
431 * <p>
432 * Stack before: array-idx n ...<br/>
433 * Stack after: x%n ...
434 */
435 MOD_EQ_ARRAY,
436 /**
437 * Raises the contents of an indexed array to the power of an adjustment value;
438 * assigns the result to the array and pushes the result onto the stack.
439 * <p>
440 * Argument 1: offset of the associative array into the variable manager<br/>
441 * Argument 2: whether the associative array is global or local
442 * <p>
443 * Stack before: array-idx n ...<br/>
444 * Stack after: x^n ...
445 */
446 POW_EQ_ARRAY,
447 /**
448 * Increase the contents of a stack-provided associative-array element by an
449 * adjustment value; assigns the result to the array and pushes the result onto
450 * the stack.
451 * <p>
452 * Stack before: array-idx associative-array n ...<br/>
453 * Stack after: x+n ...
454 */
455 PLUS_EQ_MAP_ELEMENT,
456 /**
457 * Decreases the contents of a stack-provided associative-array element by an
458 * adjustment value; assigns the result to the array and pushes the result onto
459 * the stack.
460 * <p>
461 * Stack before: array-idx associative-array n ...<br/>
462 * Stack after: x-n ...
463 */
464 MINUS_EQ_MAP_ELEMENT,
465 /**
466 * Multiplies the contents of a stack-provided associative-array element by an
467 * adjustment value; assigns the result to the array and pushes the result onto
468 * the stack.
469 * <p>
470 * Stack before: array-idx associative-array n ...<br/>
471 * Stack after: x*n ...
472 */
473 MULT_EQ_MAP_ELEMENT,
474 /**
475 * Divides the contents of a stack-provided associative-array element by an
476 * adjustment value; assigns the result to the array and pushes the result onto
477 * the stack.
478 * <p>
479 * Stack before: array-idx associative-array n ...<br/>
480 * Stack after: x/n ...
481 */
482 DIV_EQ_MAP_ELEMENT,
483 /**
484 * Takes the modulus of the contents of a stack-provided associative-array
485 * element by an adjustment value; assigns the result to the array and pushes the
486 * result onto the stack.
487 * <p>
488 * Stack before: array-idx associative-array n ...<br/>
489 * Stack after: x%n ...
490 */
491 MOD_EQ_MAP_ELEMENT,
492 /**
493 * Raises the contents of a stack-provided associative-array element to the
494 * power of an adjustment value; assigns the result to the array and pushes the
495 * result onto the stack.
496 * <p>
497 * Stack before: array-idx associative-array n ...<br/>
498 * Stack after: x^n ...
499 */
500 POW_EQ_MAP_ELEMENT,
501 /**
502 * Increases the contents of an input field by an adjustment value;
503 * assigns the result to the input field and pushes the result onto the stack.
504 * <p>
505 * Stack before: input-field_number n ...<br/>
506 * Stack after: x+n ...
507 */
508 PLUS_EQ_INPUT_FIELD,
509 /**
510 * Decreases the contents of an input field by an adjustment value;
511 * assigns the result to the input field and pushes the result onto the stack.
512 * <p>
513 * Stack before: input-field_number n ...<br/>
514 * Stack after: x-n ...
515 */
516 MINUS_EQ_INPUT_FIELD,
517 /**
518 * Multiplies the contents of an input field by an adjustment value;
519 * assigns the result to the input field and pushes the result onto the stack.
520 * <p>
521 * Stack before: input-field_number n ...<br/>
522 * Stack after: x*n ...
523 */
524 MULT_EQ_INPUT_FIELD,
525 /**
526 * Divides the contents of an input field by an adjustment value;
527 * assigns the result to the input field and pushes the result onto the stack.
528 * <p>
529 * Stack before: input-field_number n ...<br/>
530 * Stack after: x/n ...
531 */
532 DIV_EQ_INPUT_FIELD,
533 /**
534 * Takes the modulus of the contents of an input field by an adjustment value;
535 * assigns the result to the input field and pushes the result onto the stack.
536 * <p>
537 * Stack before: input-field_number n ...<br/>
538 * Stack after: x%n ...
539 */
540 MOD_EQ_INPUT_FIELD,
541 /**
542 * Raises the contents of an input field to the power of an adjustment value;
543 * assigns the result to the input field and pushes the result onto the stack.
544 * <p>
545 * Stack before: input-field_number n ...<br/>
546 * Stack after: x^n ...
547 */
548 POW_EQ_INPUT_FIELD,
549
550 /**
551 * Seeds the random number generator. If there are no arguments, the current
552 * time (as a long value) is used as the seed. Otherwise, the top-of-stack is
553 * popped and used as the seed value.
554 * <p>
555 * Argument: # of arguments
556 * <p>
557 * If # of arguments is 0:
558 * <blockquote>
559 * Stack before: ...<br/>
560 * Stack after: old-seed ...
561 * </blockquote>
562 * else
563 * <blockquote>
564 * Stack before: x ...<br/>
565 * Stack after: old-seed ...
566 * </blockquote>
567 */
568 SRAND,
569 /**
570 * Obtains the next random number from the random number generator
571 * and push it onto the stack.
572 * <p>
573 * Stack before: ...<br/>
574 * Stack after: random-number ...
575 */
576 RAND,
577 /**
578 * Built-in function that pops the top-of-stack, removes its fractional part,
579 * if any, and places the result onto the stack.
580 * <p>
581 * Stack before: x ...<br/>
582 * Stack after: (int)x ...
583 */
584 INTFUNC,
585 /**
586 * Built-in function that pops the top-of-stack, takes its square root,
587 * and places the result onto the stack.
588 * <p>
589 * Stack before: x ...<br/>
590 * Stack after: sqrt(x) ...
591 */
592 SQRT,
593 /**
594 * Built-in function that pops the top-of-stack, calls the java.lang.Math.log method
595 * with the top-of-stack as the argument, and places the result onto the stack.
596 * <p>
597 * Stack before: x ...<br/>
598 * Stack after: log(x) ...
599 */
600 LOG,
601 /**
602 * Built-in function that pops the top-of-stack, calls the java.lang.Math.exp method
603 * with the top-of-stack as the argument, and places the result onto the stack.
604 * <p>
605 * Stack before: x ...<br/>
606 * Stack after: exp(x) ...
607 */
608 EXP,
609 /**
610 * Built-in function that pops the top-of-stack, calls the java.lang.Math.sin method
611 * with the top-of-stack as the argument, and places the result onto the stack.
612 * <p>
613 * Stack before: x ...<br/>
614 * Stack after: sin(x) ...
615 */
616 SIN,
617 /**
618 * Built-in function that pops the top-of-stack, calls the java.lang.Math.cos method
619 * with the top-of-stack as the argument, and places the result onto the stack.
620 * <p>
621 * Stack before: x ...<br/>
622 * Stack after: cos(x) ...
623 */
624 COS,
625 /**
626 * Built-in function that pops the first two items off the stack,
627 * calls the java.lang.Math.atan2 method
628 * with these as arguments, and places the result onto the stack.
629 * <p>
630 * Stack before: x1 x2 ...<br/>
631 * Stack after: atan2(x1,x2) ...
632 */
633 ATAN2,
634 /**
635 * Built-in function that searches a string as input to a regular expression,
636 * the location of the match is pushed onto the stack.
637 * The RSTART and RLENGTH variables are set as a side effect.
638 * If a match is found, RSTART and function return value are set
639 * to the location of the match and RLENGTH is set to the length
640 * of the substring matched against the regular expression.
641 * If no match is found, RSTART (and return value) is set to
642 * 0 and RLENGTH is set to -1.
643 * <p>
644 * Stack before: string regexp ...<br/>
645 * Stack after: RSTART ...
646 */
647 MATCH,
648 /**
649 * Built-in function that locates a substring within a source string
650 * and pushes the location onto the stack. If the substring is
651 * not found, 0 is pushed onto the stack.
652 * <p>
653 * Stack before: string substring ...<br/>
654 * Stack after: location-index ...
655 */
656 INDEX,
657 /**
658 * Built-in function that substitutes an occurrence (or all occurrences)
659 * of a string in $0 and replaces it with another.
660 * <p>
661 * Argument: true if global sub, false otherwise.
662 * <p>
663 * Stack before: regexp replacement-string ...<br/>
664 * Stack after: ...
665 */
666 SUB_FOR_DOLLAR_0,
667 /**
668 * Built-in function that substitutes an occurrence (or all occurrences)
669 * of a string in a field reference and replaces it with another.
670 * <p>
671 * Argument: true if global sub, false otherwise.
672 * <p>
673 * Stack before: field-num regexp replacement-string ...<br/>
674 * Stack after: ...
675 */
676 SUB_FOR_DOLLAR_REFERENCE,
677 /**
678 * Built-in function that substitutes an occurrence (or all occurrences)
679 * of a string in a particular variable and replaces it with another.
680 * <p>
681 * Argument 1: variable offset in variable manager<br/>
682 * Argument 2: is global variable<br/>
683 * Argument 3: is global sub
684 * <p>
685 * Stack before: regexp replacement-string orig-string ...<br/>
686 * Stack after: ...
687 */
688 SUB_FOR_VARIABLE,
689 /**
690 * Built-in function that substitutes an occurrence (or all occurrences)
691 * of a string in a particular array cell and replaces it with another.
692 * <p>
693 * Argument 1: array map offset in variable manager<br/>
694 * Argument 2: is global array map<br/>
695 * Argument 3: is global sub
696 * <p>
697 * Stack before: array-index regexp replacement-string orig-string ...<br/>
698 * Stack after: ...
699 */
700 SUB_FOR_ARRAY_REFERENCE,
701 /**
702 * Built-in function that substitutes an occurrence (or all occurrences) of a
703 * string in a particular stack-provided array cell and replaces it with another.
704 * <p>
705 * Argument 1: is global sub
706 * <p>
707 * Stack before: array-index associative-array orig-string replacement-string regexp ...<br/>
708 * Stack after: ...
709 */
710 SUB_FOR_MAP_REFERENCE,
711 /**
712 * Built-in function to split a string by a regexp and put the
713 * components into an array.
714 * <p>
715 * Argument: # of arguments (parameters on stack)
716 * <p>
717 * If # of arguments is 2:
718 * <blockquote>
719 * Stack before: string array ...<br/>
720 * Stack after: n ...
721 * </blockquote>
722 * else
723 * <blockquote>
724 * Stack before: string array regexp ...<br/>
725 * Stack after: n ...
726 * </blockquote>
727 */
728 SPLIT,
729 /**
730 * Built-in function that pushes a substring of the top-of-stack
731 * onto the stack.
732 * The tuple argument indicates whether to limit the substring
733 * to a particular end position, or to take the substring
734 * up to the end-of-string.
735 * <p>
736 * Argument: # of arguments
737 * <p>
738 * If # of arguments is 2:
739 * <blockquote>
740 * Stack before: string start-pos ...<br/>
741 * Stack after: substring ...
742 * </blockquote>
743 * else
744 * <blockquote>
745 * Stack before: string start-pos end-pos ...<br/>
746 * Stack after: substring ...
747 * </blockquote>
748 */
749 SUBSTR,
750 /**
751 * Built-in function that converts all the letters in the top-of-stack
752 * to lower case and pushes the result onto the stack.
753 * <p>
754 * Stack before: STRING-ARGUMENT ...<br/>
755 * Stack after: string-argument ...
756 */
757 TOLOWER,
758 /**
759 * Built-in function that converts all the letters in the top-of-stack
760 * to upper case and pushes the result onto the stack.
761 * <p>
762 * Stack before: string-argument ...<br/>
763 * Stack after: STRING-ARGUMENT ...
764 */
765 TOUPPER,
766 /**
767 * Built-in function that executes the top-of-stack as a system command
768 * and pushes the return code onto the stack.
769 * <p>
770 * Stack before: cmd ...<br/>
771 * Stack after: return-code ...
772 */
773 SYSTEM,
774
775 /**
776 * Swaps the top two elements of the stack.
777 * <p>
778 * Stack before: x1 x2 ...<br/>
779 * Stack after: x2 x1 ...
780 */
781 SWAP,
782
783 /**
784 * Numerically adds the top two elements of the stack with the result
785 * pushed onto the stack.
786 * <p>
787 * Stack before: x1 x2 ...<br/>
788 * Stack after: x1+x2 ...
789 */
790 ADD,
791 /**
792 * Numerically subtracts the top two elements of the stack with the result
793 * pushed onto the stack.
794 * <p>
795 * Stack before: x1 x2 ...<br/>
796 * Stack after: x1-x2 ...
797 */
798 SUBTRACT,
799 /**
800 * Numerically multiplies the top two elements of the stack with the result
801 * pushed onto the stack.
802 * <p>
803 * Stack before: x1 x2 ...<br/>
804 * Stack after: x1*x2 ...
805 */
806 MULTIPLY,
807 /**
808 * Numerically divides the top two elements of the stack with the result
809 * pushed onto the stack.
810 * <p>
811 * Stack before: x1 x2 ...<br/>
812 * Stack after: x1/x2 ...
813 */
814 DIVIDE,
815 /**
816 * Numerically takes the modulus of the top two elements of the stack with the result
817 * pushed onto the stack.
818 * <p>
819 * Stack before: x1 x2 ...<br/>
820 * Stack after: x1%x2 ...
821 */
822 MOD,
823 /**
824 * Numerically raises the top element to the power of the next element with the result
825 * pushed onto the stack.
826 * <p>
827 * Stack before: x1 x2 ...<br/>
828 * Stack after: x1^x2 ...
829 */
830 POW,
831
832 /**
833 * Increases the variable reference by one; pushes the result
834 * onto the stack.
835 * <p>
836 * Argument 1: offset of the particular variable into the variable manager<br/>
837 * Argument 2: whether the variable is global or local
838 * <p>
839 * Stack before: ...<br/>
840 * Stack after: x+1 ...
841 */
842 INC,
843 /**
844 * Decreases the variable reference by one; pushes the result
845 * onto the stack.
846 * <p>
847 * Argument 1: offset of the particular variable into the variable manager<br/>
848 * Argument 2: whether the variable is global or local
849 * <p>
850 * Stack before: ...<br/>
851 * Stack after: x-1 ...
852 */
853 DEC,
854 /**
855 * Increases the array element reference by one; pushes the result
856 * onto the stack.
857 * <p>
858 * Argument 1: offset of the associative array into the variable manager<br/>
859 * Argument 2: whether the associative array is global or local
860 * <p>
861 * Stack before: array-idx ...<br/>
862 * Stack after: x+1 ...
863 */
864 INC_ARRAY_REF,
865 /**
866 * Decreases the array element reference by one; pushes the result
867 * onto the stack.
868 * <p>
869 * Argument 1: offset of the associative array into the variable manager<br/>
870 * Argument 2: whether the associative array is global or local
871 * <p>
872 * Stack before: array-idx ...<br/>
873 * Stack after: x-1 ...
874 */
875 DEC_ARRAY_REF,
876 /**
877 * Increases the stack-provided array element reference by one.
878 * <p>
879 * Stack before: array-idx associative-array ...<br/>
880 * Stack after: x+1 ...
881 */
882 INC_MAP_REF,
883 /**
884 * Decreases the stack-provided array element reference by one.
885 * <p>
886 * Stack before: array-idx associative-array ...<br/>
887 * Stack after: x-1 ...
888 */
889 DEC_MAP_REF,
890 /**
891 * Increases the input field variable by one; pushes the result
892 * onto the stack.
893 * <p>
894 * Stack before: field-idx ...<br/>
895 * Stack after: x+1
896 */
897 INC_DOLLAR_REF,
898 /**
899 * Decreases the input field variable by one; pushes the result
900 * onto the stack.
901 * <p>
902 * Stack before: field-idx ...<br/>
903 * Stack after: x-1
904 */
905 DEC_DOLLAR_REF,
906
907 /**
908 * Duplicates the top-of-stack on the stack.
909 * <p>
910 * Stack before: x ...<br/>
911 * Stack after: x x ...
912 */
913 DUP,
914 /**
915 * Evaluates the logical NOT of the top stack element;
916 * pushes the result onto the stack.
917 * <p>
918 * Stack before: x ...<br/>
919 * Stack after: !x ...
920 */
921 NOT,
922 /**
923 * Evaluates the numerical NEGATION of the top stack element;
924 * pushes the result onto the stack.
925 * <p>
926 * Stack before: x ...<br/>
927 * Stack after: -x ...
928 */
929 NEGATE,
930
931 /**
932 * Compares the top two stack elements; pushes 1 onto the stack if equal, 0 if not equal.
933 * <p>
934 * Stack before: x1 x2 ...<br/>
935 * Stack after: x1==x2
936 */
937 CMP_EQ,
938 /**
939 * Compares the top two stack elements; pushes 1 onto the stack if x1 < x2, 0 if not equal.
940 * <p>
941 * Stack before: x1 x2 ...<br/>
942 * Stack after: x1<x2
943 */
944 CMP_LT,
945 /**
946 * Compares the top two stack elements; pushes 1 onto the stack if x1 > x2, 0 if not equal.
947 * <p>
948 * Stack before: x1 x2 ...<br/>
949 * Stack after: x1>x2
950 */
951 CMP_GT,
952 /**
953 * Applies a regular expression to the top stack element; pushes 1 if it matches,
954 * 0 if it does not match.
955 * <p>
956 * Stack before: x1 x2 ...<br/>
957 * Stack after: (x1 ~ /x2/) ...
958 */
959 MATCHES,
960
961 /** Constant <code>DEREF_ARRAY=336</code> */
962 DEREF_ARRAY,
963
964 // for (x in y) {keyset} support
965 /**
966 * Retrieves and pushes a set of keys from an associative array onto the stack.
967 * The set is stored in a {@link java.util.Deque} for iteration.
968 * <p>
969 * Stack before: associative-array ...<br/>
970 * Stack after: key-list-set ...
971 */
972 KEYLIST,
973 /**
974 * Tests whether the key list (deque) is empty; jumps to the argument
975 * address if empty, steps to the next instruction if not.
976 * <p>
977 * Argument: jump-address-if-empty
978 * <p>
979 * Stack before: key-list ...<br/>
980 * Stack after: ...
981 */
982 IS_EMPTY_KEYLIST,
983 /**
984 * Removes an item from the key list (deque) and pushes it onto the operand stack.
985 * <p>
986 * Stack before: key-list ...<br/>
987 * Stack after: 1st-item ...
988 */
989 GET_FIRST_AND_REMOVE_FROM_KEYLIST,
990
991 // assertions
992 /**
993 * Checks whether the top-of-stack is of a particular class type;
994 * if not, an AwkRuntimeException is thrown.
995 * The stack remains unchanged upon a successful check.
996 * <p>
997 * Argument: class-type (i.e., java.util.Deque.class)
998 * <p>
999 * Stack before: obj ...<br/>
1000 * Stack after: obj ...
1001 */
1002 CHECK_CLASS,
1003
1004 // input
1005 // * Obtain an input string from stdin; push the result onto the stack.
1006 /**
1007 * Push an input field onto the stack.
1008 * <p>
1009 * Stack before: field-id ...<br/>
1010 * Stack after: x ...
1011 */
1012 GET_INPUT_FIELD,
1013 /**
1014 * Pushes an input field onto the stack using an embedded field index.
1015 * <p>
1016 * Argument: field-id
1017 * <p>
1018 * Stack before: ...<br/>
1019 * Stack after: x ...
1020 */
1021 GET_INPUT_FIELD_CONST,
1022 /**
1023 * Consume next line of input; assigning $0 and recalculating $1, $2, etc.
1024 * The input can come from the following sources:
1025 * <ul>
1026 * <li>stdin
1027 * <li>filename arguments
1028 * </ul>
1029 * The operand stack is unaffected.
1030 */
1031 CONSUME_INPUT,
1032 /**
1033 * Obtains input from stdin/filename-args, stores it into
1034 * {@code $0}, {@code $1..$NF}, and pushes only the status code
1035 * onto the stack.
1036 * The input is partitioned into records based on the RS variable
1037 * assignment as a regular expression.
1038 * <p>
1039 * If there is input available, a return code of 1 is pushed.
1040 * If EOF is reached, a 0 return code is pushed.
1041 * Upon an IO error, the exception is propagated.
1042 * <p>
1043 * Stack before: ...<br/>
1044 * Stack after: return-code ...
1045 */
1046 GETLINE_INPUT,
1047 /**
1048 * Obtains input from stdin/filename-args and pushes
1049 * the input line and status code onto the stack without
1050 * updating {@code $0}, {@code $1..$NF}.
1051 * The input is partitioned into records based on the RS variable
1052 * assignment as a regular expression.
1053 * <p>
1054 * If there is input available, the input string and a return code
1055 * of 1 is pushed and execution falls through. If EOF is reached,
1056 * only a 0 return code is pushed and execution jumps to the
1057 * argument address, so that the target of the read keeps its
1058 * previous value. Upon an IO error, the exception is propagated.
1059 * <p>
1060 * Argument: address to jump to when no record was read.
1061 * <p>
1062 * Stack before: ...<br/>
1063 * Stack after: input-string return-code ... (or return-code ...
1064 * when no record was read)
1065 */
1066 GETLINE_INPUT_TO_TARGET,
1067 /**
1068 * Obtains input from a file and pushes
1069 * input line and status code onto the stack.
1070 * The input is partitioned into records based on the RS variable
1071 * assignment as a regular expression.
1072 * <p>
1073 * Upon initial execution, the file is opened and the handle
1074 * is maintained until it is explicitly closed, or until
1075 * the VM exits. Subsequent calls will obtain subsequent
1076 * lines (records) of input until no more records are available.
1077 * {@code $0}, {@code $1..$NF}, NR, FNR, and FILENAME are left
1078 * untouched.
1079 * <p>
1080 * If there is input available, the input string and a return code
1081 * of 1 is pushed and execution falls through. If EOF is reached,
1082 * only a 0 return code is pushed and execution jumps to the
1083 * argument address. When the file cannot be opened or read, a -1
1084 * return code is pushed instead, ERRNO is set to the error
1085 * description, and execution jumps to the argument address. Either
1086 * way the target of the read keeps its previous value.
1087 * <p>
1088 * Argument: address to jump to when no record was read.
1089 * <p>
1090 * Stack before: filename ...<br/>
1091 * Stack after: input-string return-code ... (or return-code ...
1092 * when no record was read)
1093 */
1094 USE_AS_FILE_INPUT,
1095 /**
1096 * Obtains input from a command (process) and pushes
1097 * input line and status code onto the stack.
1098 * The input is partitioned into records based on the RS variable
1099 * assignment as a regular expression.
1100 * <p>
1101 * Upon initial execution, the a process is spawned to execute
1102 * the specified command and the process reference
1103 * is maintained until it is explicitly closed, or until
1104 * the VM exits. Subsequent calls will obtain subsequent
1105 * lines (records) of input until no more records are available.
1106 * {@code $0}, {@code $1..$NF}, NR, FNR, and FILENAME are left
1107 * untouched.
1108 * <p>
1109 * If there is input available, the input string and a return code
1110 * of 1 is pushed and execution falls through. If EOF is reached,
1111 * only a 0 return code is pushed and execution jumps to the
1112 * argument address. When the process cannot be spawned, a -1
1113 * return code is pushed instead, ERRNO is set to the error
1114 * description, and execution jumps to the argument address. Either
1115 * way the target of the read keeps its previous value.
1116 * <p>
1117 * Argument: address to jump to when no record was read.
1118 * <p>
1119 * Stack before: command-line ...<br/>
1120 * Stack after: input-string return-code ... (or return-code ...
1121 * when no record was read)
1122 */
1123 USE_AS_COMMAND_INPUT,
1124
1125 // variable housekeeping
1126 /**
1127 * Assign the NF variable offset. This is important for the
1128 * AVM to set the variables as new input lines are processed.
1129 * <p>
1130 * The operand stack is unaffected.
1131 */
1132 NF_OFFSET,
1133 /**
1134 * Assign the NR variable offset. This is important for the
1135 * AVM to increase the record number as new input lines received.
1136 * <p>
1137 * The operand stack is unaffected.
1138 */
1139 NR_OFFSET,
1140 /**
1141 * Assign the FNR variable offset. This is important for the
1142 * AVM to increase the "file" record number as new input lines are received.
1143 * <p>
1144 * The operand stack is unaffected.
1145 */
1146 FNR_OFFSET,
1147 /**
1148 * Assign the FS variable offset. This is important for the
1149 * AVM to know how to split fields upon incoming records of input.
1150 * <p>
1151 * The operand stack is unaffected.
1152 */
1153 FS_OFFSET,
1154 /**
1155 * Assign the RS variable offset. This is important for the
1156 * AVM to know how to create records from the stream(s) of input.
1157 * <p>
1158 * The operand stack is unaffected.
1159 */
1160 RS_OFFSET,
1161 /**
1162 * Assign the OFS variable offset. This is important for the
1163 * AVM to use when outputting expressions via PRINT.
1164 * <p>
1165 * The operand stack is unaffected.
1166 */
1167 OFS_OFFSET,
1168 /**
1169 * Assign the RSTART variable offset. The AVM sets this variable while
1170 * executing the match() builtin function.
1171 * <p>
1172 * The operand stack is unaffected.
1173 */
1174 RSTART_OFFSET,
1175 /**
1176 * Assign the RLENGTH variable offset. The AVM sets this variable while
1177 * executing the match() builtin function.
1178 * <p>
1179 * The operand stack is unaffected.
1180 */
1181 RLENGTH_OFFSET,
1182 /**
1183 * Assign the FILENAME variable offset. The AVM sets this variable while
1184 * processing files from the command-line for input.
1185 * <p>
1186 * The operand stack is unaffected.
1187 */
1188 FILENAME_OFFSET,
1189 /**
1190 * Assign the SUBSEP variable offset. The AVM uses this variable while
1191 * building an index of a multi-dimensional array.
1192 * <p>
1193 * The operand stack is unaffected.
1194 */
1195 SUBSEP_OFFSET,
1196 /**
1197 * Assign the CONVFMT variable offset. The AVM uses this variable while
1198 * converting numbers to strings.
1199 * <p>
1200 * The operand stack is unaffected.
1201 */
1202 CONVFMT_OFFSET,
1203 /**
1204 * Assign the OFMT variable offset. The AVM uses this variable while
1205 * converting numbers to strings for printing.
1206 * <p>
1207 * The operand stack is unaffected.
1208 */
1209 OFMT_OFFSET,
1210 /**
1211 * Assign the ENVIRON variable offset. The AVM provides environment
1212 * variables through this array.
1213 * <p>
1214 * The operand stack is unaffected.
1215 */
1216 ENVIRON_OFFSET,
1217 /**
1218 * Assign the ARGC variable offset. The AVM provides the number of
1219 * arguments via this variable.
1220 * <p>
1221 * The operand stack is unaffected.
1222 */
1223 ARGC_OFFSET,
1224 /**
1225 * Assign the ARGV variable offset. The AVM provides command-line
1226 * arguments via this variable.
1227 * <p>
1228 * The operand stack is unaffected.
1229 */
1230 ARGV_OFFSET,
1231
1232 /**
1233 * Apply the RS variable by notifying the partitioning reader that
1234 * there is a new regular expression to use when partitioning input
1235 * records.
1236 * <p>
1237 * The stack remains unaffected.
1238 */
1239 APPLY_RS,
1240
1241 /**
1242 * Call a user function.
1243 * <p>
1244 * Stack before: x1, x2, ..., xn <br>
1245 * Stack after: f(x1, x2, ..., xn)
1246 */
1247 CALL_FUNCTION,
1248
1249 /**
1250 * Define a user function.
1251 * <p>
1252 * Stack remains unchanged
1253 */
1254 FUNCTION,
1255
1256 /**
1257 * Sets the return value of a user function.
1258 * <p>
1259 * Stack before: x <br>
1260 * Stack after: ...
1261 */
1262 SET_RETURN_RESULT,
1263
1264 /**
1265 * Get the return value of the user function that was called
1266 * <p>
1267 * Stack before: ... <br>
1268 * Stack after: x
1269 */
1270 RETURN_FROM_FUNCTION,
1271
1272 /**
1273 * Internal: sets the number of global variables
1274 */
1275 SET_NUM_GLOBALS,
1276
1277 /**
1278 * Close the specified file.
1279 * <p>
1280 * Stack before: file name <br>
1281 * Stack after: result of the close operation
1282 */
1283 CLOSE,
1284
1285 /**
1286 * Convert a list of array indices to a concatenated string with SUBSEP.
1287 * This is used for multidimensional arrays.
1288 * <p>
1289 * Stack before: i1, i2, ..., in <br>
1290 * Stack after: "i1SUBSEPi2SUBSEP...in"
1291 */
1292 APPLY_SUBSEP,
1293
1294 /**
1295 * Deletes an entry in an array.
1296 * <p>
1297 * Stack before: i <br>
1298 * Stack after: ...
1299 */
1300 DELETE_ARRAY_ELEMENT,
1301 /**
1302 * Deletes an entry in a stack-provided associative array.
1303 * <p>
1304 * Stack before: array-index associative-array <br/>
1305 * Stack after: ...
1306 */
1307 DELETE_MAP_ELEMENT,
1308
1309 /**
1310 * Internal.
1311 * <p>
1312 * Stack remains unchanged.
1313 */
1314 SET_WITHIN_END_BLOCKS,
1315
1316 /**
1317 * Terminates execution and returns specified exit code.
1318 * <p>
1319 * Stack before: integer <br>
1320 * Stack after: N/A
1321 */
1322 EXIT_WITH_CODE,
1323
1324 /**
1325 * Returns a regex pattern.
1326 * <p>
1327 * Stack before: ... <br>
1328 * Stack after: the regex pattern object
1329 */
1330 REGEXP,
1331
1332 /**
1333 * Returns a pair of regex patterns.
1334 * <p>
1335 * Stack before: pattern1, pattern2 <br>
1336 * Stack after: regex pair object
1337 */
1338 CONDITION_PAIR,
1339
1340 /**
1341 * Returns whether the specified key is in the array.
1342 * <p>
1343 * Stack before: key, array <br>
1344 * Stack after: true|false
1345 */
1346 IS_IN,
1347
1348 /**
1349 * Deprecated.
1350 */
1351 THIS,
1352
1353 /**
1354 * Call a function from an extension
1355 * <p>
1356 * Stack before: x1, x2, ..., xn <br>
1357 * Stack after: f(x1, x2, ..., xn)
1358 */
1359 EXTENSION,
1360
1361 /**
1362 * Delete the specified array.
1363 * <p>
1364 * Stack remains unchanged.
1365 */
1366 DELETE_ARRAY,
1367
1368 /**
1369 * Converts the top stack element to a number;
1370 * pushes the result onto the stack.
1371 * <p>
1372 * Stack before: x ...<br/>
1373 * Stack after: x ... (as a number)
1374 */
1375 UNARY_PLUS,
1376
1377 /**
1378 * Terminates execution without specifying an exit code.
1379 * <p>
1380 * Stack before: N/A <br>
1381 * Stack after: N/A
1382 */
1383 EXIT_WITHOUT_CODE,
1384
1385 /**
1386 * Assign to the special variable NF via JRT and push the assigned value.
1387 * <p>
1388 * Stack before: value ...<br/>
1389 * Stack after: value ...
1390 */
1391 ASSIGN_NF,
1392 /**
1393 * Push the current value of the special variable NF via JRT.
1394 * <p>
1395 * Stack before: ...<br/>
1396 * Stack after: NF ...
1397 */
1398 PUSH_NF,
1399
1400 /** Assign to NR via JRT and push the assigned value. */
1401 ASSIGN_NR,
1402 /** Push the current NR via JRT. */
1403 PUSH_NR,
1404
1405 /** Assign to FNR via JRT and push the assigned value. */
1406 ASSIGN_FNR,
1407 /** Push the current FNR via JRT. */
1408 PUSH_FNR,
1409
1410 /** Assign to FS via JRT and push the assigned value. */
1411 ASSIGN_FS,
1412 /** Push the current FS via JRT. */
1413 PUSH_FS,
1414
1415 /** Assign to RS via JRT and push the assigned value. */
1416 ASSIGN_RS,
1417 /** Push the current RS via JRT. */
1418 PUSH_RS,
1419
1420 /** Assign to OFS via JRT and push the assigned value. */
1421 ASSIGN_OFS,
1422 /** Push the current OFS via JRT. */
1423 PUSH_OFS,
1424
1425 /** Assign to ORS via JRT and push the assigned value. */
1426 ASSIGN_ORS,
1427 /** Push the current ORS via JRT. */
1428 PUSH_ORS,
1429
1430 /** Assign to RSTART via JRT and push the assigned value. */
1431 ASSIGN_RSTART,
1432 /** Push the current RSTART via JRT. */
1433 PUSH_RSTART,
1434
1435 /** Assign to RLENGTH via JRT and push the assigned value. */
1436 ASSIGN_RLENGTH,
1437 /** Push the current RLENGTH via JRT. */
1438 PUSH_RLENGTH,
1439
1440 /** Assign to FILENAME via JRT and push the assigned value. */
1441 ASSIGN_FILENAME,
1442 /** Push the current FILENAME via JRT. */
1443 PUSH_FILENAME,
1444
1445 /** Assign to SUBSEP via JRT and push the assigned value. */
1446 ASSIGN_SUBSEP,
1447 /** Push the current SUBSEP via JRT. */
1448 PUSH_SUBSEP,
1449
1450 /** Assign to CONVFMT via JRT and push the assigned value. */
1451 ASSIGN_CONVFMT,
1452 /** Push the current CONVFMT via JRT. */
1453 PUSH_CONVFMT,
1454
1455 /** Assign to OFMT via JRT and push the assigned value. */
1456 ASSIGN_OFMT,
1457 /** Push the current OFMT via JRT. */
1458 PUSH_OFMT,
1459
1460 /** Assign to ARGC via JRT and push the assigned value. */
1461 ASSIGN_ARGC,
1462 /** Push the current ARGC via JRT. */
1463 PUSH_ARGC,
1464
1465 /**
1466 * Assign the ORS variable offset. This is important for the
1467 * AVM to use when outputting expressions via PRINT.
1468 * <p>
1469 * The operand stack is unaffected.
1470 */
1471 ORS_OFFSET,
1472
1473 /**
1474 * Increases the variable reference by one; pushes the original value
1475 * onto the stack.
1476 * <p>
1477 * Argument 1: offset of the particular variable into the variable manager<br/>
1478 * Argument 2: whether the variable is global or local
1479 * <p>
1480 * Stack before: ...<br/>
1481 * Stack after: x ... or 0 if uninitialized
1482 */
1483 POSTINC,
1484
1485 /**
1486 * Decreases the variable reference by one; pushes the original value
1487 * onto the stack.
1488 * <p>
1489 * Argument 1: offset of the particular variable into the variable manager<br/>
1490 * Argument 2: whether the variable is global or local
1491 * <p>
1492 * Stack before: ...<br/>
1493 * Stack after: x ... or 0 if uninitialized
1494 */
1495 POSTDEC,
1496
1497 /**
1498 * Dereferences an associative-array element as an array, creating a nested
1499 * array when the element is currently blank or uninitialized.
1500 * <p>
1501 * Stack before: array-index associative-array ...<br/>
1502 * Stack after: nested-associative-array ...
1503 */
1504 ENSURE_ARRAY_ELEMENT,
1505
1506 /**
1507 * Looks up an associative-array element without creating a blank entry when
1508 * the key is missing.
1509 * <p>
1510 * Stack before: array-index associative-array ...<br/>
1511 * Stack after: item ...
1512 */
1513 PEEK_ARRAY_ELEMENT,
1514
1515 /**
1516 * Assigns the top of the stack to IGNORECASE, managed by the JRT.
1517 * <p>
1518 * Stack before: value ...<br/>
1519 * Stack after: value ...
1520 */
1521 ASSIGN_IGNORECASE,
1522
1523 /**
1524 * Pushes the value of IGNORECASE, managed by the JRT.
1525 * <p>
1526 * Stack before: ...<br/>
1527 * Stack after: ignorecase-value ...
1528 */
1529 PUSH_IGNORECASE,
1530
1531 /**
1532 * Prints a diagnostic message to the warning stream.
1533 * <p>
1534 * Stack unchanged.
1535 */
1536 WARNING,
1537
1538 /**
1539 * Runs the extension beforeStart hooks. Emitted by the parser at the end
1540 * of the preamble; executed at most once per AVM instance.
1541 * <p>
1542 * Stack unchanged.
1543 */
1544 BEFORE_START_HOOKS,
1545
1546 /**
1547 * Populates the SYMTAB array with the names and values of the program's
1548 * symbols. Emitted only when the script references SYMTAB outside POSIX
1549 * mode.
1550 * <p>
1551 * Argument: offset of the SYMTAB global<br/>
1552 * Stack unchanged.
1553 */
1554 UPDATE_SYMTAB,
1555
1556 /**
1557 * Populates the FUNCTAB array with the names of the program's functions.
1558 * Emitted only when the script references FUNCTAB outside POSIX mode.
1559 * <p>
1560 * Argument: offset of the FUNCTAB global<br/>
1561 * Stack unchanged.
1562 */
1563 UPDATE_FUNCTAB,
1564
1565 /**
1566 * Advances the main input to the next input file, applying pending
1567 * {@code name=value} command-line assignments along the way. On success,
1568 * FILENAME, FNR, ARGIND, and ERRNO are updated and execution falls through
1569 * to the BEGINFILE rules. When no input file remains, it jumps to the
1570 * specified address. Emitted only when BEGINFILE/ENDFILE rules or a
1571 * {@code nextfile} statement require per-file input stepping.
1572 * <p>
1573 * Argument: address to jump to when no more input files remain
1574 * <p>
1575 * Stack unchanged.
1576 */
1577 NEXT_FILE,
1578
1579 /**
1580 * Consume the next record of the current input file only; assigning $0 and
1581 * recalculating $1, $2, etc. Unlike {@link #CONSUME_INPUT}, it never
1582 * advances to the next input file: at end of the current file it jumps to
1583 * the specified address so the ENDFILE rules can run.
1584 * <p>
1585 * Argument: address to jump to at end of the current input file
1586 * <p>
1587 * Stack unchanged.
1588 */
1589 CONSUME_FILE_INPUT,
1590
1591 /**
1592 * Executes the {@code nextfile} statement: abandons the current input
1593 * file and resumes the per-file input loop. The runtime jumps to the
1594 * ENDFILE rules when the current file was opened successfully, or
1595 * directly past them when the file could not be opened (BEGINFILE error
1596 * handling). The jump targets are carried as properties of the tuple
1597 * stream, not as tuples. The runtime stack and operand stack are
1598 * cleared, allowing {@code nextfile} to be invoked from user-defined
1599 * functions.
1600 * <p>
1601 * Stack after: (empty)
1602 */
1603 EXEC_NEXTFILE,
1604
1605 /**
1606 * Assigns the top of the stack to ERRNO, managed by the JRT.
1607 * <p>
1608 * Stack before: value ...<br/>
1609 * Stack after: value ...
1610 */
1611 ASSIGN_ERRNO,
1612
1613 /**
1614 * Pushes the value of ERRNO, managed by the JRT.
1615 * <p>
1616 * Stack before: ...<br/>
1617 * Stack after: errno-value ...
1618 */
1619 PUSH_ERRNO,
1620
1621 /**
1622 * Assigns the top of the stack to ARGIND, managed by the JRT.
1623 * <p>
1624 * Stack before: value ...<br/>
1625 * Stack after: value ...
1626 */
1627 ASSIGN_ARGIND,
1628
1629 /**
1630 * Pushes the value of ARGIND, managed by the JRT.
1631 * <p>
1632 * Stack before: ...<br/>
1633 * Stack after: argind-value ...
1634 */
1635 PUSH_ARGIND,
1636
1637 /**
1638 * Call a user-defined, built-in, or extension function selected by name at
1639 * runtime. New opcodes are appended to preserve serialized numeric identifiers.
1640 */
1641 INDIRECT_CALL,
1642
1643 /**
1644 * Push an indirect-call argument that snapshots its scalar value while retaining
1645 * its variable location. The target selected at runtime determines whether to
1646 * use the scalar snapshot or materialize/read an array at that location.
1647 */
1648 PUSH_INDIRECT_ARGUMENT,
1649
1650 /**
1651 * Push an indirect-call subarray argument that snapshots its scalar value while
1652 * retaining its containing map and key for a runtime-selected array parameter.
1653 */
1654 PUSH_INDIRECT_ARRAY_ARGUMENT,
1655
1656 /**
1657 * Pushes whether the range pattern identified by the tuple's operand is
1658 * currently active (i.e. its start condition matched a previous record and its
1659 * end condition has not matched yet).
1660 * <p>
1661 * Stack before: ... <br>
1662 * Stack after: 1|0 ...
1663 */
1664 CONDITION_PAIR_IN_RANGE,
1665
1666 /**
1667 * Marks the range pattern identified by the tuple's operand as active, after
1668 * its start condition matched the current record.
1669 * <p>
1670 * Stack before: ... <br>
1671 * Stack after: ...
1672 */
1673 CONDITION_PAIR_ENTER,
1674
1675 /**
1676 * Marks the range pattern identified by the tuple's operand as inactive, after
1677 * its end condition matched the current record.
1678 * <p>
1679 * Stack before: ... <br>
1680 * Stack after: ...
1681 */
1682 CONDITION_PAIR_LEAVE,
1683
1684 /**
1685 * Convert a list of array indices located under the top stack element to
1686 * their concatenated SUBSEP key, leaving the top element in place. Used by
1687 * the "in" operator, whose key must be converted with the CONVFMT and
1688 * SUBSEP in effect after the array operand has been evaluated.
1689 * <p>
1690 * Stack before: i1, i2, ..., in, top <br>
1691 * Stack after: "i1SUBSEPi2SUBSEP...in", top
1692 */
1693 APPLY_SUBSEP_UNDER_TOP,
1694
1695 /**
1696 * Executes the {@code next} statement at runtime, when it is reached
1697 * through a user-defined function call: abandons the current input record
1698 * and resumes the main input loop, whose address is carried as a property
1699 * of the tuple stream, not as a tuple. The runtime stack and operand
1700 * stack are cleared, unwinding the active user-defined function calls.
1701 * When no input rule is active (BEGIN, END, BEGINFILE, or ENDFILE
1702 * callers), the runtime reports a fatal error instead. A {@code next}
1703 * written directly inside an input rule compiles to a plain {@code GOTO}.
1704 * <p>
1705 * Stack after: (empty)
1706 */
1707 EXEC_NEXT;
1708
1709 private static final Opcode[] VALUES = values();
1710
1711 /**
1712 * Resolves an opcode enum constant from its serialized numeric identifier.
1713 *
1714 * @param id Numeric opcode identifier
1715 * @return Matching {@link Opcode}
1716 * @throws IllegalArgumentException If the identifier is outside the valid
1717 * opcode range
1718 */
1719 public static Opcode fromId(int id) {
1720 if (id < 0 || id >= VALUES.length) {
1721 throw new IllegalArgumentException("Unknown opcode: " + id);
1722 }
1723 return VALUES[id];
1724 }
1725 }