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