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 * <p>
25 * Each enum constant describes one tuple opcode understood by the AVM.
26 * </p>
27 */
28 public enum Opcode {
29 /**
30 * Pops an item off the operand stack.
31 * <p>
32 * Stack before: x ...<br/>
33 * Stack after: ...
34 */
35 POP,
36 /**
37 * Pushes a long constant onto the operand stack.
38 * <p>
39 * Argument: the long value<br/>
40 * Stack before: ...<br/>
41 * Stack after: x ...
42 */
43 PUSH_LONG,
44 /**
45 * Pushes a double constant onto the operand stack.
46 * <p>
47 * Argument: the double value<br/>
48 * Stack before: ...<br/>
49 * Stack after: x ...
50 */
51 PUSH_DOUBLE,
52 /**
53 * Pushes a string constant onto the operand stack.
54 * <p>
55 * Argument: the string value<br/>
56 * Stack before: ...<br/>
57 * Stack after: x ...
58 */
59 PUSH_STRING,
60 /**
61 * Pops and evaluates the top-of-stack; if
62 * false, it jumps to a specified address.
63 * <p>
64 * Argument: address
65 * <p>
66 * Stack before: x ...<br/>
67 * Stack after: ...
68 */
69 IFFALSE,
70 /**
71 * Converts the top-of-stack to a number.
72 * <p>
73 * Stack before: x ...<br/>
74 * Stack after: x (as a number)
75 */
76 TO_NUMBER,
77 /**
78 * Pops and evaluates the top-of-stack; if
79 * true, it jumps to a specified address.
80 * <p>
81 * Argument: address
82 * <p>
83 * Stack before: x ...<br/>
84 * Stack after: ...
85 */
86 IFTRUE,
87 /**
88 * Jumps to a specified address. The operand stack contents
89 * are unaffected.
90 */
91 GOTO,
92 /**
93 * A no-operation. The operand stack contents are
94 * unaffected.
95 */
96 NOP,
97 /**
98 * Prints N number of items that are on the operand stack.
99 * The number of items are passed in as a tuple argument.
100 * <p>
101 * Argument: # of items (N)
102 * <p>
103 * Stack before: x1 x2 x3 .. xN ...<br/>
104 * Stack after: ...
105 */
106 PRINT,
107 /**
108 * Prints N number of items that are on the operand stack to
109 * a specified file. The file is passed in on the stack.
110 * The number of items are passed in as a tuple argument,
111 * as well as whether to overwrite the file or not (append mode).
112 * <p>
113 * Argument 1: # of items (N)<br/>
114 * Argument 2: true = append, false = overwrite
115 * <p>
116 * Stack before: x1 x2 x3 .. xN filename ...<br/>
117 * Stack after: ...
118 */
119 PRINT_TO_FILE,
120 /**
121 * Prints N number of items that are on the operand stack to
122 * a process executing a specified command (via a pipe).
123 * The command string is passed in on the stack.
124 * The number of items are passed in as a tuple argument.
125 * <p>
126 * Argument: # of items (N)
127 * <p>
128 * Stack before: x1 x2 x3 .. xN command-string ...<br/>
129 * Stack after: ...
130 */
131 PRINT_TO_PIPE,
132 /**
133 * Performs a formatted print of N items that are on the operand stack.
134 * The number of items are passed in as a tuple argument.
135 * <p>
136 * Argument: # of items (N)
137 * <p>
138 * Stack before: x1 x2 x3 .. xN ...<br/>
139 * Stack after: ...
140 */
141 PRINTF,
142 /**
143 * Performs a formatted print of N items that are on the operand stack to
144 * a specified file. The file is passed in on the stack.
145 * The number of items are passed in as a tuple argument,
146 * as well as whether to overwrite the file or not (append mode).
147 * <p>
148 * Argument 1: # of items (N)<br/>
149 * Argument 2: true = append, false = overwrite
150 * <p>
151 * Stack before: x1 x2 x3 .. xN filename ...<br/>
152 * Stack after: ...
153 */
154 PRINTF_TO_FILE,
155 /**
156 * Performs a formatted print of N items that are on the operand stack to
157 * a process executing a specified command (via a pipe).
158 * The command string is passed in on the stack.
159 * The number of items are passed in as a tuple argument.
160 * <p>
161 * Argument: # of items (N)
162 * <p>
163 * Stack before: x1 x2 x3 .. xN command-string ...<br/>
164 * Stack after: ...
165 */
166 PRINTF_TO_PIPE,
167 /** Constant <code>SPRINTF=270</code> */
168 SPRINTF,
169 /**
170 * Depending on the argument, pop and evaluate the string length of the top-of-stack
171 * or evaluate the string length of $0; in either case, push the result onto
172 * the stack.
173 * <p>
174 * The input field length evaluation mode is provided to support backward
175 * compatibility with the deprecated usage of length (i.e., no arguments).
176 * <p>
177 * Argument: 0 to use $0, use top-of-stack otherwise
178 * <p>
179 * If argument is 0:
180 * <blockquote>
181 * Stack before: ...<br/>
182 * Stack after: length-of-$0 ...
183 * </blockquote>
184 * else
185 * <blockquote>
186 * Stack before: x ...<br/>
187 * Stack after: length-of-x ...
188 * </blockquote>
189 */
190 LENGTH,
191 /**
192 * Pop and concatenate two strings from the top-of-stack; push the result onto
193 * the stack.
194 * <p>
195 * Stack before: x y ...<br/>
196 * Stack after: x-concatenated-with-y ...
197 */
198 CONCAT,
199 /**
200 * Assigns the top-of-stack to a variable. The contents of the stack
201 * are unaffected.
202 * <p>
203 * Argument 1: offset of the particular variable into the variable manager<br/>
204 * Argument 2: whether the variable is global or local
205 * <p>
206 * Stack before: x ...<br/>
207 * Stack after: x ...
208 */
209 ASSIGN,
210 /**
211 * Assigns an item to an array element. The item remains on the stack.
212 * <p>
213 * Argument 1: offset of the particular associative array into the variable manager<br/>
214 * Argument 2: whether the associative array is global or local
215 * <p>
216 * Stack before: index-into-array item ...<br/>
217 * Stack after: item ...
218 */
219 ASSIGN_ARRAY,
220 /**
221 * Assigns an item to an element of the associative array currently on the stack.
222 * The item remains on the stack.
223 * <p>
224 * Stack before: array-index associative-array item ...<br/>
225 * Stack after: item ...
226 */
227 ASSIGN_MAP_ELEMENT,
228 /**
229 * Assigns the top-of-stack to $0. The contents of the stack are unaffected.
230 * Upon assignment, individual field variables are recalculated.
231 * <p>
232 * Stack before: x ...<br/>
233 * Stack after: x ...
234 */
235 ASSIGN_AS_INPUT,
236 /**
237 * Assigns an item as a particular input field; the field number can be 0.
238 * Upon assignment, associating input fields are affected. For example, if
239 * the following assignment were made:
240 * <blockquote>
241 *
242 * <pre>
243 * $3 = "hi"
244 * </pre>
245 *
246 * </blockquote>
247 * $0 would be recalculated. Likewise, if the following assignment were made:
248 * <blockquote>
249 *
250 * <pre>
251 * $0 = "hello there"
252 * </pre>
253 *
254 * </blockquote>
255 * $1, $2, ... would be recalculated.
256 * <p>
257 * Stack before: field-num x ...<br/>
258 * Stack after: x ...
259 */
260 ASSIGN_AS_INPUT_FIELD,
261 /**
262 * Obtains an item from the variable manager and push it onto the stack.
263 * <p>
264 * Argument 1: offset of the particular variable into the variable manager<br/>
265 * Argument 2: whether the variable is global or local
266 * <p>
267 * Stack before: ...<br/>
268 * Stack after: x ...
269 */
270 DEREFERENCE,
271 /**
272 * Increase the contents of the variable by an adjustment value;
273 * assigns the result to the variable and pushes the result onto the stack.
274 * <p>
275 * Argument 1: offset of the particular variable into the variable manager<br/>
276 * Argument 2: whether the variable is global or local
277 * <p>
278 * Stack before: n ...<br/>
279 * Stack after: x+n ...
280 */
281 PLUS_EQ,
282 /**
283 * Decreases the contents of the variable by an adjustment value;
284 * assigns the result to the variable and pushes the result onto the stack.
285 * <p>
286 * Argument 1: offset of the particular variable into the variable manager<br/>
287 * Argument 2: whether the variable is global or local
288 * <p>
289 * Stack before: n ...<br/>
290 * Stack after: x-n ...
291 */
292 MINUS_EQ,
293 /**
294 * Multiplies the contents of the variable by an adjustment value;
295 * assigns the result to the variable and pushes the result onto the stack.
296 * <p>
297 * Argument 1: offset of the particular variable into the variable manager<br/>
298 * Argument 2: whether the variable is global or local
299 * <p>
300 * Stack before: n ...<br/>
301 * Stack after: x*n ...
302 */
303 MULT_EQ,
304 /**
305 * Divides the contents of the variable by an adjustment value;
306 * assigns the result to the variable and pushes the result onto the stack.
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: n ...<br/>
312 * Stack after: x/n ...
313 */
314 DIV_EQ,
315 /**
316 * Takes the modules of 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 MOD_EQ,
326 /**
327 * Raises the contents of the variable to the power of the 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 POW_EQ,
337 /**
338 * Increase the contents of an indexed array by an adjustment value;
339 * assigns the result to the array and pushes the result onto the stack.
340 * <p>
341 * Argument 1: offset of the associative array into the variable manager<br/>
342 * Argument 2: whether the associative array is global or local
343 * <p>
344 * Stack before: array-idx n ...<br/>
345 * Stack after: x+n ...
346 */
347 PLUS_EQ_ARRAY,
348 /**
349 * Decreases the contents of an indexed array by an adjustment value;
350 * assigns the result to the array and pushes the result onto the stack.
351 * <p>
352 * Argument 1: offset of the associative array into the variable manager<br/>
353 * Argument 2: whether the associative array is global or local
354 * <p>
355 * Stack before: array-idx n ...<br/>
356 * Stack after: x-n ...
357 */
358 MINUS_EQ_ARRAY,
359 /**
360 * Multiplies the contents of an indexed array by an adjustment value;
361 * assigns the result to the array and pushes the result onto the stack.
362 * <p>
363 * Argument 1: offset of the associative array into the variable manager<br/>
364 * Argument 2: whether the associative array is global or local
365 * <p>
366 * Stack before: array-idx n ...<br/>
367 * Stack after: x*n ...
368 */
369 MULT_EQ_ARRAY,
370 /**
371 * Divides the contents of an indexed array by an adjustment value;
372 * assigns the result to the array and pushes the result onto the stack.
373 * <p>
374 * Argument 1: offset of the associative array into the variable manager<br/>
375 * Argument 2: whether the associative array is global or local
376 * <p>
377 * Stack before: array-idx n ...<br/>
378 * Stack after: x/n ...
379 */
380 DIV_EQ_ARRAY,
381 /**
382 * Takes the modulus of 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 MOD_EQ_ARRAY,
392 /**
393 * Raises the contents of an indexed array to the power of 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 POW_EQ_ARRAY,
403 /**
404 * Increase the contents of a stack-provided associative-array element by an
405 * adjustment value; assigns the result to the array and pushes the result onto
406 * the stack.
407 * <p>
408 * Stack before: array-idx associative-array n ...<br/>
409 * Stack after: x+n ...
410 */
411 PLUS_EQ_MAP_ELEMENT,
412 /**
413 * Decreases the contents of a stack-provided associative-array element by an
414 * adjustment value; assigns the result to the array and pushes the result onto
415 * the stack.
416 * <p>
417 * Stack before: array-idx associative-array n ...<br/>
418 * Stack after: x-n ...
419 */
420 MINUS_EQ_MAP_ELEMENT,
421 /**
422 * Multiplies the contents of a stack-provided associative-array element by an
423 * adjustment value; assigns the result to the array and pushes the result onto
424 * the stack.
425 * <p>
426 * Stack before: array-idx associative-array n ...<br/>
427 * Stack after: x*n ...
428 */
429 MULT_EQ_MAP_ELEMENT,
430 /**
431 * Divides the contents of a stack-provided associative-array element by an
432 * adjustment value; assigns the result to the array and pushes the result onto
433 * the stack.
434 * <p>
435 * Stack before: array-idx associative-array n ...<br/>
436 * Stack after: x/n ...
437 */
438 DIV_EQ_MAP_ELEMENT,
439 /**
440 * Takes the modulus of the contents of a stack-provided associative-array
441 * element by an adjustment value; assigns the result to the array and pushes the
442 * result onto the stack.
443 * <p>
444 * Stack before: array-idx associative-array n ...<br/>
445 * Stack after: x%n ...
446 */
447 MOD_EQ_MAP_ELEMENT,
448 /**
449 * Raises the contents of a stack-provided associative-array element to the
450 * power of an adjustment value; assigns the result to the array and pushes the
451 * result onto the stack.
452 * <p>
453 * Stack before: array-idx associative-array n ...<br/>
454 * Stack after: x^n ...
455 */
456 POW_EQ_MAP_ELEMENT,
457 /**
458 * Increases the contents of an input field by an adjustment value;
459 * assigns the result to the input field and pushes the result onto the stack.
460 * <p>
461 * Stack before: input-field_number n ...<br/>
462 * Stack after: x+n ...
463 */
464 PLUS_EQ_INPUT_FIELD,
465 /**
466 * Decreases the contents of an input field by an adjustment value;
467 * assigns the result to the input field and pushes the result onto the stack.
468 * <p>
469 * Stack before: input-field_number n ...<br/>
470 * Stack after: x-n ...
471 */
472 MINUS_EQ_INPUT_FIELD,
473 /**
474 * Multiplies the contents of an input field by an adjustment value;
475 * assigns the result to the input field and pushes the result onto the stack.
476 * <p>
477 * Stack before: input-field_number n ...<br/>
478 * Stack after: x*n ...
479 */
480 MULT_EQ_INPUT_FIELD,
481 /**
482 * Divides the contents of an input field by an adjustment value;
483 * assigns the result to the input field and pushes the result onto the stack.
484 * <p>
485 * Stack before: input-field_number n ...<br/>
486 * Stack after: x/n ...
487 */
488 DIV_EQ_INPUT_FIELD,
489 /**
490 * Takes the modulus of the contents of an input field by an adjustment value;
491 * assigns the result to the input field and pushes the result onto the stack.
492 * <p>
493 * Stack before: input-field_number n ...<br/>
494 * Stack after: x%n ...
495 */
496 MOD_EQ_INPUT_FIELD,
497 /**
498 * Raises the contents of an input field to the power of an adjustment value;
499 * assigns the result to the input field and pushes the result onto the stack.
500 * <p>
501 * Stack before: input-field_number n ...<br/>
502 * Stack after: x^n ...
503 */
504 POW_EQ_INPUT_FIELD,
505
506 /**
507 * Seeds the random number generator. If there are no arguments, the current
508 * time (as a long value) is used as the seed. Otherwise, the top-of-stack is
509 * popped and used as the seed value.
510 * <p>
511 * Argument: # of arguments
512 * <p>
513 * If # of arguments is 0:
514 * <blockquote>
515 * Stack before: ...<br/>
516 * Stack after: old-seed ...
517 * </blockquote>
518 * else
519 * <blockquote>
520 * Stack before: x ...<br/>
521 * Stack after: old-seed ...
522 * </blockquote>
523 */
524 SRAND,
525 /**
526 * Obtains the next random number from the random number generator
527 * and push it onto the stack.
528 * <p>
529 * Stack before: ...<br/>
530 * Stack after: random-number ...
531 */
532 RAND,
533 /**
534 * Built-in function that pops the top-of-stack, removes its fractional part,
535 * if any, and places the result onto the stack.
536 * <p>
537 * Stack before: x ...<br/>
538 * Stack after: (int)x ...
539 */
540 INTFUNC,
541 /**
542 * Built-in function that pops the top-of-stack, takes its square root,
543 * and places the result onto the stack.
544 * <p>
545 * Stack before: x ...<br/>
546 * Stack after: sqrt(x) ...
547 */
548 SQRT,
549 /**
550 * Built-in function that pops the top-of-stack, calls the java.lang.Math.log method
551 * with the top-of-stack as the argument, and places the result onto the stack.
552 * <p>
553 * Stack before: x ...<br/>
554 * Stack after: log(x) ...
555 */
556 LOG,
557 /**
558 * Built-in function that pops the top-of-stack, calls the java.lang.Math.exp method
559 * with the top-of-stack as the argument, and places the result onto the stack.
560 * <p>
561 * Stack before: x ...<br/>
562 * Stack after: exp(x) ...
563 */
564 EXP,
565 /**
566 * Built-in function that pops the top-of-stack, calls the java.lang.Math.sin method
567 * with the top-of-stack as the argument, and places the result onto the stack.
568 * <p>
569 * Stack before: x ...<br/>
570 * Stack after: sin(x) ...
571 */
572 SIN,
573 /**
574 * Built-in function that pops the top-of-stack, calls the java.lang.Math.cos method
575 * with the top-of-stack as the argument, and places the result onto the stack.
576 * <p>
577 * Stack before: x ...<br/>
578 * Stack after: cos(x) ...
579 */
580 COS,
581 /**
582 * Built-in function that pops the first two items off the stack,
583 * calls the java.lang.Math.atan2 method
584 * with these as arguments, and places the result onto the stack.
585 * <p>
586 * Stack before: x1 x2 ...<br/>
587 * Stack after: atan2(x1,x2) ...
588 */
589 ATAN2,
590 /**
591 * Built-in function that searches a string as input to a regular expression,
592 * the location of the match is pushed onto the stack.
593 * The RSTART and RLENGTH variables are set as a side effect.
594 * If a match is found, RSTART and function return value are set
595 * to the location of the match and RLENGTH is set to the length
596 * of the substring matched against the regular expression.
597 * If no match is found, RSTART (and return value) is set to
598 * 0 and RLENGTH is set to -1.
599 * <p>
600 * Stack before: string regexp ...<br/>
601 * Stack after: RSTART ...
602 */
603 MATCH,
604 /**
605 * Built-in function that locates a substring within a source string
606 * and pushes the location onto the stack. If the substring is
607 * not found, 0 is pushed onto the stack.
608 * <p>
609 * Stack before: string substring ...<br/>
610 * Stack after: location-index ...
611 */
612 INDEX,
613 /**
614 * Built-in function that substitutes an occurrence (or all occurrences)
615 * of a string in $0 and replaces it with another.
616 * <p>
617 * Argument: true if global sub, false otherwise.
618 * <p>
619 * Stack before: regexp replacement-string ...<br/>
620 * Stack after: ...
621 */
622 SUB_FOR_DOLLAR_0,
623 /**
624 * Built-in function that substitutes an occurrence (or all occurrences)
625 * of a string in a field reference and replaces it with another.
626 * <p>
627 * Argument: true if global sub, false otherwise.
628 * <p>
629 * Stack before: field-num regexp replacement-string ...<br/>
630 * Stack after: ...
631 */
632 SUB_FOR_DOLLAR_REFERENCE,
633 /**
634 * Built-in function that substitutes an occurrence (or all occurrences)
635 * of a string in a particular variable and replaces it with another.
636 * <p>
637 * Argument 1: variable offset in variable manager<br/>
638 * Argument 2: is global variable<br/>
639 * Argument 3: is global sub
640 * <p>
641 * Stack before: regexp replacement-string orig-string ...<br/>
642 * Stack after: ...
643 */
644 SUB_FOR_VARIABLE,
645 /**
646 * Built-in function that substitutes an occurrence (or all occurrences)
647 * of a string in a particular array cell and replaces it with another.
648 * <p>
649 * Argument 1: array map offset in variable manager<br/>
650 * Argument 2: is global array map<br/>
651 * Argument 3: is global sub
652 * <p>
653 * Stack before: array-index regexp replacement-string orig-string ...<br/>
654 * Stack after: ...
655 */
656 SUB_FOR_ARRAY_REFERENCE,
657 /**
658 * Built-in function that substitutes an occurrence (or all occurrences) of a
659 * string in a particular stack-provided array cell and replaces it with another.
660 * <p>
661 * Argument 1: is global sub
662 * <p>
663 * Stack before: array-index associative-array orig-string replacement-string regexp ...<br/>
664 * Stack after: ...
665 */
666 SUB_FOR_MAP_REFERENCE,
667 /**
668 * Built-in function to split a string by a regexp and put the
669 * components into an array.
670 * <p>
671 * Argument: # of arguments (parameters on stack)
672 * <p>
673 * If # of arguments is 2:
674 * <blockquote>
675 * Stack before: string array ...<br/>
676 * Stack after: n ...
677 * </blockquote>
678 * else
679 * <blockquote>
680 * Stack before: string array regexp ...<br/>
681 * Stack after: n ...
682 * </blockquote>
683 */
684 SPLIT,
685 /**
686 * Built-in function that pushes a substring of the top-of-stack
687 * onto the stack.
688 * The tuple argument indicates whether to limit the substring
689 * to a particular end position, or to take the substring
690 * up to the end-of-string.
691 * <p>
692 * Argument: # of arguments
693 * <p>
694 * If # of arguments is 2:
695 * <blockquote>
696 * Stack before: string start-pos ...<br/>
697 * Stack after: substring ...
698 * </blockquote>
699 * else
700 * <blockquote>
701 * Stack before: string start-pos end-pos ...<br/>
702 * Stack after: substring ...
703 * </blockquote>
704 */
705 SUBSTR,
706 /**
707 * Built-in function that converts all the letters in the top-of-stack
708 * to lower case and pushes the result onto the stack.
709 * <p>
710 * Stack before: STRING-ARGUMENT ...<br/>
711 * Stack after: string-argument ...
712 */
713 TOLOWER,
714 /**
715 * Built-in function that converts all the letters in the top-of-stack
716 * to upper case and pushes the result onto the stack.
717 * <p>
718 * Stack before: string-argument ...<br/>
719 * Stack after: STRING-ARGUMENT ...
720 */
721 TOUPPER,
722 /**
723 * Built-in function that executes the top-of-stack as a system command
724 * and pushes the return code onto the stack.
725 * <p>
726 * Stack before: cmd ...<br/>
727 * Stack after: return-code ...
728 */
729 SYSTEM,
730
731 /**
732 * Swaps the top two elements of the stack.
733 * <p>
734 * Stack before: x1 x2 ...<br/>
735 * Stack after: x2 x1 ...
736 */
737 SWAP,
738
739 /**
740 * Numerically adds the top two elements of the stack with the result
741 * pushed onto the stack.
742 * <p>
743 * Stack before: x1 x2 ...<br/>
744 * Stack after: x1+x2 ...
745 */
746 ADD,
747 /**
748 * Numerically subtracts the top two elements of the stack with the result
749 * pushed onto the stack.
750 * <p>
751 * Stack before: x1 x2 ...<br/>
752 * Stack after: x1-x2 ...
753 */
754 SUBTRACT,
755 /**
756 * Numerically multiplies the top two elements of the stack with the result
757 * pushed onto the stack.
758 * <p>
759 * Stack before: x1 x2 ...<br/>
760 * Stack after: x1*x2 ...
761 */
762 MULTIPLY,
763 /**
764 * Numerically divides the top two elements of the stack with the result
765 * pushed onto the stack.
766 * <p>
767 * Stack before: x1 x2 ...<br/>
768 * Stack after: x1/x2 ...
769 */
770 DIVIDE,
771 /**
772 * Numerically takes the modulus of the top two elements of the stack with the result
773 * pushed onto the stack.
774 * <p>
775 * Stack before: x1 x2 ...<br/>
776 * Stack after: x1%x2 ...
777 */
778 MOD,
779 /**
780 * Numerically raises the top element to the power of the next element with the result
781 * pushed onto the stack.
782 * <p>
783 * Stack before: x1 x2 ...<br/>
784 * Stack after: x1^x2 ...
785 */
786 POW,
787
788 /**
789 * Increases the variable reference by one; pushes the result
790 * onto the stack.
791 * <p>
792 * Argument 1: offset of the particular variable into the variable manager<br/>
793 * Argument 2: whether the variable is global or local
794 * <p>
795 * Stack before: ...<br/>
796 * Stack after: x+1 ...
797 */
798 INC,
799 /**
800 * Decreases the variable reference by one; pushes the result
801 * onto the stack.
802 * <p>
803 * Argument 1: offset of the particular variable into the variable manager<br/>
804 * Argument 2: whether the variable is global or local
805 * <p>
806 * Stack before: ...<br/>
807 * Stack after: x-1 ...
808 */
809 DEC,
810 /**
811 * Increases the array element reference by one; pushes the result
812 * onto the stack.
813 * <p>
814 * Argument 1: offset of the associative array into the variable manager<br/>
815 * Argument 2: whether the associative array is global or local
816 * <p>
817 * Stack before: array-idx ...<br/>
818 * Stack after: x+1 ...
819 */
820 INC_ARRAY_REF,
821 /**
822 * Decreases the array element reference by one; pushes the result
823 * onto the stack.
824 * <p>
825 * Argument 1: offset of the associative array into the variable manager<br/>
826 * Argument 2: whether the associative array is global or local
827 * <p>
828 * Stack before: array-idx ...<br/>
829 * Stack after: x-1 ...
830 */
831 DEC_ARRAY_REF,
832 /**
833 * Increases the stack-provided array element reference by one.
834 * <p>
835 * Stack before: array-idx associative-array ...<br/>
836 * Stack after: x+1 ...
837 */
838 INC_MAP_REF,
839 /**
840 * Decreases the stack-provided array element reference by one.
841 * <p>
842 * Stack before: array-idx associative-array ...<br/>
843 * Stack after: x-1 ...
844 */
845 DEC_MAP_REF,
846 /**
847 * Increases the input field variable by one; pushes the result
848 * onto the stack.
849 * <p>
850 * Stack before: field-idx ...<br/>
851 * Stack after: x+1
852 */
853 INC_DOLLAR_REF,
854 /**
855 * Decreases the input field variable by one; pushes the result
856 * onto the stack.
857 * <p>
858 * Stack before: field-idx ...<br/>
859 * Stack after: x-1
860 */
861 DEC_DOLLAR_REF,
862
863 /**
864 * Duplicates the top-of-stack on the stack.
865 * <p>
866 * Stack before: x ...<br/>
867 * Stack after: x x ...
868 */
869 DUP,
870 /**
871 * Evaluates the logical NOT of the top stack element;
872 * pushes the result onto the stack.
873 * <p>
874 * Stack before: x ...<br/>
875 * Stack after: !x ...
876 */
877 NOT,
878 /**
879 * Evaluates the numerical NEGATION of the top stack element;
880 * pushes the result onto the stack.
881 * <p>
882 * Stack before: x ...<br/>
883 * Stack after: -x ...
884 */
885 NEGATE,
886
887 /**
888 * Compares the top two stack elements; pushes 1 onto the stack if equal, 0 if not equal.
889 * <p>
890 * Stack before: x1 x2 ...<br/>
891 * Stack after: x1==x2
892 */
893 CMP_EQ,
894 /**
895 * Compares the top two stack elements; pushes 1 onto the stack if x1 < x2, 0 if not equal.
896 * <p>
897 * Stack before: x1 x2 ...<br/>
898 * Stack after: x1<x2
899 */
900 CMP_LT,
901 /**
902 * Compares the top two stack elements; pushes 1 onto the stack if x1 > x2, 0 if not equal.
903 * <p>
904 * Stack before: x1 x2 ...<br/>
905 * Stack after: x1>x2
906 */
907 CMP_GT,
908 /**
909 * Applies a regular expression to the top stack element; pushes 1 if it matches,
910 * 0 if it does not match.
911 * <p>
912 * Stack before: x1 x2 ...<br/>
913 * Stack after: (x1 ~ /x2/) ...
914 */
915 MATCHES,
916
917 /** Constant <code>DEREF_ARRAY=336</code> */
918 DEREF_ARRAY,
919
920 // for (x in y) {keyset} support
921 /**
922 * Retrieves and pushes a set of keys from an associative array onto the stack.
923 * The set is stored in a {@link java.util.Deque} for iteration.
924 * <p>
925 * Stack before: associative-array ...<br/>
926 * Stack after: key-list-set ...
927 */
928 KEYLIST,
929 /**
930 * Tests whether the key list (deque) is empty; jumps to the argument
931 * address if empty, steps to the next instruction if not.
932 * <p>
933 * Argument: jump-address-if-empty
934 * <p>
935 * Stack before: key-list ...<br/>
936 * Stack after: ...
937 */
938 IS_EMPTY_KEYLIST,
939 /**
940 * Removes an item from the key list (deque) and pushes it onto the operand stack.
941 * <p>
942 * Stack before: key-list ...<br/>
943 * Stack after: 1st-item ...
944 */
945 GET_FIRST_AND_REMOVE_FROM_KEYLIST,
946
947 // assertions
948 /**
949 * Checks whether the top-of-stack is of a particular class type;
950 * if not, an AwkRuntimeException is thrown.
951 * The stack remains unchanged upon a successful check.
952 * <p>
953 * Argument: class-type (i.e., java.util.Deque.class)
954 * <p>
955 * Stack before: obj ...<br/>
956 * Stack after: obj ...
957 */
958 CHECK_CLASS,
959
960 // input
961 // * Obtain an input string from stdin; push the result onto the stack.
962 /**
963 * Push an input field onto the stack.
964 * <p>
965 * Stack before: field-id ...<br/>
966 * Stack after: x ...
967 */
968 GET_INPUT_FIELD,
969 /**
970 * Pushes an input field onto the stack using an embedded field index.
971 * <p>
972 * Argument: field-id
973 * <p>
974 * Stack before: ...<br/>
975 * Stack after: x ...
976 */
977 GET_INPUT_FIELD_CONST,
978 /**
979 * Consume next line of input; assigning $0 and recalculating $1, $2, etc.
980 * The input can come from the following sources:
981 * <ul>
982 * <li>stdin
983 * <li>filename arguments
984 * </ul>
985 * The operand stack is unaffected.
986 */
987 CONSUME_INPUT,
988 /**
989 * Obtains input from stdin/filename-args, stores it into
990 * {@code $0}, {@code $1..$NF}, and pushes only the status code
991 * onto the stack.
992 * The input is partitioned into records based on the RS variable
993 * assignment as a regular expression.
994 * <p>
995 * If there is input available, a return code of 1 is pushed.
996 * If EOF is reached, a 0 return code is pushed.
997 * Upon an IO error, the exception is propagated.
998 * <p>
999 * Stack before: ...<br/>
1000 * Stack after: return-code ...
1001 */
1002 GETLINE_INPUT,
1003 /**
1004 * Obtains input from stdin/filename-args and pushes
1005 * the input line and status code onto the stack without
1006 * updating {@code $0}, {@code $1..$NF}.
1007 * The input is partitioned into records based on the RS variable
1008 * assignment as a regular expression.
1009 * <p>
1010 * If there is input available, the input string and a return code
1011 * of 1 is pushed. If EOF is reached, an empty string ("")
1012 * is pushed along with a 0 return code. Upon an IO error,
1013 * the exception is propagated.
1014 * <p>
1015 * Stack before: ...<br/>
1016 * Stack after: input-string return-code ...
1017 */
1018 GETLINE_INPUT_TO_TARGET,
1019 /**
1020 * Obtains input from a file and pushes
1021 * input line and status code onto the stack.
1022 * The input is partitioned into records based on the RS variable
1023 * assignment as a regular expression.
1024 * <p>
1025 * Upon initial execution, the file is opened and the handle
1026 * is maintained until it is explicitly closed, or until
1027 * the VM exits. Subsequent calls will obtain subsequent
1028 * lines (records) of input until no more records are available.
1029 * <p>
1030 * If there is input available, the input string and a return code
1031 * of 1 is pushed. If EOF is reached, an empty string ("")
1032 * is pushed along with a 0 return code. Upon an IO error,
1033 * a blank string and a -1 is pushed onto the operand stack.
1034 * <p>
1035 * Stack before: filename ...<br/>
1036 * Stack after: input-string return-code ...
1037 */
1038 USE_AS_FILE_INPUT,
1039 /**
1040 * Obtains input from a command (process) and pushes
1041 * input line and status code onto the stack.
1042 * The input is partitioned into records based on the RS variable
1043 * assignment as a regular expression.
1044 * <p>
1045 * Upon initial execution, the a process is spawned to execute
1046 * the specified command and the process reference
1047 * is maintained until it is explicitly closed, or until
1048 * the VM exits. Subsequent calls will obtain subsequent
1049 * lines (records) of input until no more records are available.
1050 * <p>
1051 * If there is input available, the input string and a return code
1052 * of 1 is pushed. If EOF is reached, an empty string ("")
1053 * is pushed along with a 0 return code. Upon an IO error,
1054 * a blank string and a -1 is pushed onto the operand stack.
1055 * <p>
1056 * Stack before: command-line ...<br/>
1057 * Stack after: input-string return-code ...
1058 */
1059 USE_AS_COMMAND_INPUT,
1060
1061 // variable housekeeping
1062 /**
1063 * Assign the NF variable offset. This is important for the
1064 * AVM to set the variables as new input lines are processed.
1065 * <p>
1066 * The operand stack is unaffected.
1067 */
1068 NF_OFFSET,
1069 /**
1070 * Assign the NR variable offset. This is important for the
1071 * AVM to increase the record number as new input lines received.
1072 * <p>
1073 * The operand stack is unaffected.
1074 */
1075 NR_OFFSET,
1076 /**
1077 * Assign the FNR variable offset. This is important for the
1078 * AVM to increase the "file" record number as new input lines are received.
1079 * <p>
1080 * The operand stack is unaffected.
1081 */
1082 FNR_OFFSET,
1083 /**
1084 * Assign the FS variable offset. This is important for the
1085 * AVM to know how to split fields upon incoming records of input.
1086 * <p>
1087 * The operand stack is unaffected.
1088 */
1089 FS_OFFSET,
1090 /**
1091 * Assign the RS variable offset. This is important for the
1092 * AVM to know how to create records from the stream(s) of input.
1093 * <p>
1094 * The operand stack is unaffected.
1095 */
1096 RS_OFFSET,
1097 /**
1098 * Assign the OFS variable offset. This is important for the
1099 * AVM to use when outputting expressions via PRINT.
1100 * <p>
1101 * The operand stack is unaffected.
1102 */
1103 OFS_OFFSET,
1104 /**
1105 * Assign the RSTART variable offset. The AVM sets this variable while
1106 * executing the match() builtin function.
1107 * <p>
1108 * The operand stack is unaffected.
1109 */
1110 RSTART_OFFSET,
1111 /**
1112 * Assign the RLENGTH variable offset. The AVM sets this variable while
1113 * executing the match() builtin function.
1114 * <p>
1115 * The operand stack is unaffected.
1116 */
1117 RLENGTH_OFFSET,
1118 /**
1119 * Assign the FILENAME variable offset. The AVM sets this variable while
1120 * processing files from the command-line for input.
1121 * <p>
1122 * The operand stack is unaffected.
1123 */
1124 FILENAME_OFFSET,
1125 /**
1126 * Assign the SUBSEP variable offset. The AVM uses this variable while
1127 * building an index of a multi-dimensional array.
1128 * <p>
1129 * The operand stack is unaffected.
1130 */
1131 SUBSEP_OFFSET,
1132 /**
1133 * Assign the CONVFMT variable offset. The AVM uses this variable while
1134 * converting numbers to strings.
1135 * <p>
1136 * The operand stack is unaffected.
1137 */
1138 CONVFMT_OFFSET,
1139 /**
1140 * Assign the OFMT variable offset. The AVM uses this variable while
1141 * converting numbers to strings for printing.
1142 * <p>
1143 * The operand stack is unaffected.
1144 */
1145 OFMT_OFFSET,
1146 /**
1147 * Assign the ENVIRON variable offset. The AVM provides environment
1148 * variables through this array.
1149 * <p>
1150 * The operand stack is unaffected.
1151 */
1152 ENVIRON_OFFSET,
1153 /**
1154 * Assign the ARGC variable offset. The AVM provides the number of
1155 * arguments via this variable.
1156 * <p>
1157 * The operand stack is unaffected.
1158 */
1159 ARGC_OFFSET,
1160 /**
1161 * Assign the ARGV variable offset. The AVM provides command-line
1162 * arguments via this variable.
1163 * <p>
1164 * The operand stack is unaffected.
1165 */
1166 ARGV_OFFSET,
1167
1168 /**
1169 * Apply the RS variable by notifying the partitioning reader that
1170 * there is a new regular expression to use when partitioning input
1171 * records.
1172 * <p>
1173 * The stack remains unaffected.
1174 */
1175 APPLY_RS,
1176
1177 /**
1178 * Call a user function.
1179 * <p>
1180 * Stack before: x1, x2, ..., xn <br>
1181 * Stack after: f(x1, x2, ..., xn)
1182 */
1183 CALL_FUNCTION,
1184
1185 /**
1186 * Define a user function.
1187 * <p>
1188 * Stack remains unchanged
1189 */
1190 FUNCTION,
1191
1192 /**
1193 * Sets the return value of a user function.
1194 * <p>
1195 * Stack before: x <br>
1196 * Stack after: ...
1197 */
1198 SET_RETURN_RESULT,
1199
1200 /**
1201 * Get the return value of the user function that was called
1202 * <p>
1203 * Stack before: ... <br>
1204 * Stack after: x
1205 */
1206 RETURN_FROM_FUNCTION,
1207
1208 /**
1209 * Internal: sets the number of global variables
1210 */
1211 SET_NUM_GLOBALS,
1212
1213 /**
1214 * Close the specified file.
1215 * <p>
1216 * Stack before: file name <br>
1217 * Stack after: result of the close operation
1218 */
1219 CLOSE,
1220
1221 /**
1222 * Convert a list of array indices to a concatenated string with SUBSEP.
1223 * This is used for multidimensional arrays.
1224 * <p>
1225 * Stack before: i1, i2, ..., in <br>
1226 * Stack after: "i1SUBSEPi2SUBSEP...in"
1227 */
1228 APPLY_SUBSEP,
1229
1230 /**
1231 * Deletes an entry in an array.
1232 * <p>
1233 * Stack before: i <br>
1234 * Stack after: ...
1235 */
1236 DELETE_ARRAY_ELEMENT,
1237 /**
1238 * Deletes an entry in a stack-provided associative array.
1239 * <p>
1240 * Stack before: array-index associative-array <br/>
1241 * Stack after: ...
1242 */
1243 DELETE_MAP_ELEMENT,
1244
1245 /**
1246 * Internal.
1247 * <p>
1248 * Stack remains unchanged.
1249 */
1250 SET_EXIT_ADDRESS,
1251
1252 /**
1253 * Internal.
1254 * <p>
1255 * Stack remains unchanged.
1256 */
1257 SET_WITHIN_END_BLOCKS,
1258
1259 /**
1260 * Terminates execution and returns specified exit code.
1261 * <p>
1262 * Stack before: integer <br>
1263 * Stack after: N/A
1264 */
1265 EXIT_WITH_CODE,
1266
1267 /**
1268 * Returns a regex pattern.
1269 * <p>
1270 * Stack before: ... <br>
1271 * Stack after: the regex pattern object
1272 */
1273 REGEXP,
1274
1275 /**
1276 * Returns a pair of regex patterns.
1277 * <p>
1278 * Stack before: pattern1, pattern2 <br>
1279 * Stack after: regex pair object
1280 */
1281 CONDITION_PAIR,
1282
1283 /**
1284 * Returns whether the specified key is in the array.
1285 * <p>
1286 * Stack before: key, array <br>
1287 * Stack after: true|false
1288 */
1289 IS_IN,
1290
1291 /**
1292 * Deprecated.
1293 */
1294 THIS,
1295
1296 /**
1297 * Call a function from an extension
1298 * <p>
1299 * Stack before: x1, x2, ..., xn <br>
1300 * Stack after: f(x1, x2, ..., xn)
1301 */
1302 EXTENSION,
1303
1304 /**
1305 * Delete the specified array.
1306 * <p>
1307 * Stack remains unchanged.
1308 */
1309 DELETE_ARRAY,
1310
1311 /**
1312 * Converts the top stack element to a number;
1313 * pushes the result onto the stack.
1314 * <p>
1315 * Stack before: x ...<br/>
1316 * Stack after: x ... (as a number)
1317 */
1318 UNARY_PLUS,
1319
1320 /**
1321 * Terminates execution without specifying an exit code.
1322 * <p>
1323 * Stack before: N/A <br>
1324 * Stack after: N/A
1325 */
1326 EXIT_WITHOUT_CODE,
1327
1328 /**
1329 * Assign to the special variable NF via JRT and push the assigned value.
1330 * <p>
1331 * Stack before: value ...<br/>
1332 * Stack after: value ...
1333 */
1334 ASSIGN_NF,
1335 /**
1336 * Push the current value of the special variable NF via JRT.
1337 * <p>
1338 * Stack before: ...<br/>
1339 * Stack after: NF ...
1340 */
1341 PUSH_NF,
1342
1343 /** Assign to NR via JRT and push the assigned value. */
1344 ASSIGN_NR,
1345 /** Push the current NR via JRT. */
1346 PUSH_NR,
1347
1348 /** Assign to FNR via JRT and push the assigned value. */
1349 ASSIGN_FNR,
1350 /** Push the current FNR via JRT. */
1351 PUSH_FNR,
1352
1353 /** Assign to FS via JRT and push the assigned value. */
1354 ASSIGN_FS,
1355 /** Push the current FS via JRT. */
1356 PUSH_FS,
1357
1358 /** Assign to RS via JRT and push the assigned value. */
1359 ASSIGN_RS,
1360 /** Push the current RS via JRT. */
1361 PUSH_RS,
1362
1363 /** Assign to OFS via JRT and push the assigned value. */
1364 ASSIGN_OFS,
1365 /** Push the current OFS via JRT. */
1366 PUSH_OFS,
1367
1368 /** Assign to ORS via JRT and push the assigned value. */
1369 ASSIGN_ORS,
1370 /** Push the current ORS via JRT. */
1371 PUSH_ORS,
1372
1373 /** Assign to RSTART via JRT and push the assigned value. */
1374 ASSIGN_RSTART,
1375 /** Push the current RSTART via JRT. */
1376 PUSH_RSTART,
1377
1378 /** Assign to RLENGTH via JRT and push the assigned value. */
1379 ASSIGN_RLENGTH,
1380 /** Push the current RLENGTH via JRT. */
1381 PUSH_RLENGTH,
1382
1383 /** Assign to FILENAME via JRT and push the assigned value. */
1384 ASSIGN_FILENAME,
1385 /** Push the current FILENAME via JRT. */
1386 PUSH_FILENAME,
1387
1388 /** Assign to SUBSEP via JRT and push the assigned value. */
1389 ASSIGN_SUBSEP,
1390 /** Push the current SUBSEP via JRT. */
1391 PUSH_SUBSEP,
1392
1393 /** Assign to CONVFMT via JRT and push the assigned value. */
1394 ASSIGN_CONVFMT,
1395 /** Push the current CONVFMT via JRT. */
1396 PUSH_CONVFMT,
1397
1398 /** Assign to OFMT via JRT and push the assigned value. */
1399 ASSIGN_OFMT,
1400 /** Push the current OFMT via JRT. */
1401 PUSH_OFMT,
1402
1403 /** Assign to ARGC via JRT and push the assigned value. */
1404 ASSIGN_ARGC,
1405 /** Push the current ARGC via JRT. */
1406 PUSH_ARGC,
1407
1408 /**
1409 * Assign the ORS variable offset. This is important for the
1410 * AVM to use when outputting expressions via PRINT.
1411 * <p>
1412 * The operand stack is unaffected.
1413 */
1414 ORS_OFFSET,
1415
1416 /**
1417 * Increases the variable reference by one; pushes the original value
1418 * onto the stack.
1419 * <p>
1420 * Argument 1: offset of the particular variable into the variable manager<br/>
1421 * Argument 2: whether the variable is global or local
1422 * <p>
1423 * Stack before: ...<br/>
1424 * Stack after: x ... or 0 if uninitialized
1425 */
1426 POSTINC,
1427
1428 /**
1429 * Decreases the variable reference by one; pushes the original value
1430 * onto the stack.
1431 * <p>
1432 * Argument 1: offset of the particular variable into the variable manager<br/>
1433 * Argument 2: whether the variable is global or local
1434 * <p>
1435 * Stack before: ...<br/>
1436 * Stack after: x ... or 0 if uninitialized
1437 */
1438 POSTDEC,
1439
1440 /**
1441 * Dereferences an associative-array element as an array, creating a nested
1442 * array when the element is currently blank or uninitialized.
1443 * <p>
1444 * Stack before: array-index associative-array ...<br/>
1445 * Stack after: nested-associative-array ...
1446 */
1447 ENSURE_ARRAY_ELEMENT,
1448
1449 /**
1450 * Looks up an associative-array element without creating a blank entry when
1451 * the key is missing.
1452 * <p>
1453 * Stack before: array-index associative-array ...<br/>
1454 * Stack after: item ...
1455 */
1456 PEEK_ARRAY_ELEMENT;
1457
1458 private static final Opcode[] VALUES = values();
1459
1460 /**
1461 * Resolves an opcode enum constant from its serialized numeric identifier.
1462 *
1463 * @param id Numeric opcode identifier
1464 * @return Matching {@link Opcode}
1465 * @throws IllegalArgumentException If the identifier is outside the valid
1466 * opcode range
1467 */
1468 public static Opcode fromId(int id) {
1469 if (id < 0 || id >= VALUES.length) {
1470 throw new IllegalArgumentException("Unknown opcode: " + id);
1471 }
1472 return VALUES[id];
1473 }
1474 }