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