1 package org.metricshub.jawk.intermediate;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import java.io.PrintStream;
26 import java.io.Serializable;
27 import java.util.ArrayDeque;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.Deque;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.Map;
34 import java.util.Set;
35 import java.util.function.Supplier;
36 import org.metricshub.jawk.ext.ExtensionFunction;
37
38
39
40
41
42
43
44
45 public class AwkTuples implements Serializable {
46
47 private static final long serialVersionUID = 2L;
48
49
50 private VersionManager versionManager = new VersionManager();
51
52
53 private final AddressManager addressManager = new AddressManager();
54
55
56
57
58
59
60
61
62
63
64 private java.util.List<Tuple> queue = new ArrayList<Tuple>(100) {
65 private static final long serialVersionUID = -6334362156408598578L;
66
67 @Override
68 public boolean add(Tuple t) {
69 t.setLineNumber(linenoStack.peek());
70 return super.add(t);
71 }
72 };
73
74
75
76
77
78
79
80
81
82 public static String toOpcodeString(int opcode) {
83 return Opcode.fromId(opcode).name();
84 }
85
86
87
88
89
90
91 public void pop() {
92 queue.add(new Tuple(Opcode.POP));
93 }
94
95
96
97
98
99
100
101
102 public void push(Object o) {
103 assert (o instanceof String) || (o instanceof Long) || (o instanceof Integer) || (o instanceof Double);
104
105
106 if (o instanceof String) {
107 queue.add(new Tuple(Opcode.PUSH, o.toString()));
108 } else if (o instanceof Integer) {
109 queue.add(new Tuple(Opcode.PUSH, (Integer) o));
110 } else if (o instanceof Long) {
111 queue.add(new Tuple(Opcode.PUSH, (Long) o));
112 } else if (o instanceof Double) {
113 queue.add(new Tuple(Opcode.PUSH, (Double) o));
114 } else {
115 assert false : "Invalid type for " + o + ", " + o.getClass();
116 }
117 }
118
119
120
121
122
123
124
125
126 public void ifFalse(Address address) {
127 queue.add(new Tuple(Opcode.IFFALSE, address));
128 }
129
130
131
132
133
134
135 public void toNumber() {
136 queue.add(new Tuple(Opcode.TO_NUMBER));
137 }
138
139
140
141
142
143
144
145
146 public void ifTrue(Address address) {
147 queue.add(new Tuple(Opcode.IFTRUE, address));
148 }
149
150
151
152
153
154
155
156
157 public void gotoAddress(Address address) {
158 queue.add(new Tuple(Opcode.GOTO, address));
159 }
160
161
162
163
164
165
166
167
168
169 public Address createAddress(String label) {
170 return addressManager.createAddress(label);
171 }
172
173
174
175
176
177
178
179
180
181 public AwkTuples address(Address address) {
182 addressManager.resolveAddress(address, queue.size());
183 return this;
184 }
185
186
187
188
189
190
191 public void nop() {
192 queue.add(new Tuple(Opcode.NOP));
193 }
194
195
196
197
198
199
200
201
202 public void print(int numExprs) {
203 queue.add(new Tuple(Opcode.PRINT, numExprs));
204 }
205
206
207
208
209
210
211
212
213
214 public void printToFile(int numExprs, boolean append) {
215 queue.add(new Tuple(Opcode.PRINT_TO_FILE, numExprs, append));
216 }
217
218
219
220
221
222
223
224
225 public void printToPipe(int numExprs) {
226 queue.add(new Tuple(Opcode.PRINT_TO_PIPE, numExprs));
227 }
228
229
230
231
232
233
234
235
236 public void printf(int numExprs) {
237 queue.add(new Tuple(Opcode.PRINTF, numExprs));
238 }
239
240
241
242
243
244
245
246
247
248 public void printfToFile(int numExprs, boolean append) {
249 queue.add(new Tuple(Opcode.PRINTF_TO_FILE, numExprs, append));
250 }
251
252
253
254
255
256
257
258
259 public void printfToPipe(int numExprs) {
260 queue.add(new Tuple(Opcode.PRINTF_TO_PIPE, numExprs));
261 }
262
263
264
265
266
267
268
269
270 public void sprintf(int numExprs) {
271 queue.add(new Tuple(Opcode.SPRINTF, numExprs));
272 }
273
274
275
276
277
278
279
280
281 public void length(int numExprs) {
282 queue.add(new Tuple(Opcode.LENGTH, numExprs));
283 }
284
285
286
287
288
289
290 public void concat() {
291 queue.add(new Tuple(Opcode.CONCAT));
292 }
293
294
295
296
297
298
299
300
301
302 public void assign(int offset, boolean isGlobal) {
303 queue.add(new Tuple(Opcode.ASSIGN, offset, isGlobal));
304 }
305
306
307
308
309
310
311
312
313
314 public void assignArray(int offset, boolean isGlobal) {
315 queue.add(new Tuple(Opcode.ASSIGN_ARRAY, offset, isGlobal));
316 }
317
318
319
320
321
322
323 public void assignAsInput() {
324 queue.add(new Tuple(Opcode.ASSIGN_AS_INPUT));
325 }
326
327
328
329
330 public void setInputForEval() {
331 queue.add(new Tuple(Opcode.SET_INPUT_FOR_EVAL));
332 }
333
334
335
336
337
338
339 public void assignAsInputField() {
340 queue.add(new Tuple(Opcode.ASSIGN_AS_INPUT_FIELD));
341 }
342
343
344
345
346
347
348
349
350
351
352 public void dereference(int offset, boolean isArray, boolean isGlobal) {
353 queue.add(new Tuple(Opcode.DEREFERENCE, offset, isArray, isGlobal));
354 }
355
356
357
358
359
360
361
362
363
364 public void plusEq(int offset, boolean isGlobal) {
365 queue.add(new Tuple(Opcode.PLUS_EQ, offset, isGlobal));
366 }
367
368
369
370
371
372
373
374
375
376 public void minusEq(int offset, boolean isGlobal) {
377 queue.add(new Tuple(Opcode.MINUS_EQ, offset, isGlobal));
378 }
379
380
381
382
383
384
385
386
387
388 public void multEq(int offset, boolean isGlobal) {
389 queue.add(new Tuple(Opcode.MULT_EQ, offset, isGlobal));
390 }
391
392
393
394
395
396
397
398
399
400 public void divEq(int offset, boolean isGlobal) {
401 queue.add(new Tuple(Opcode.DIV_EQ, offset, isGlobal));
402 }
403
404
405
406
407
408
409
410
411
412 public void modEq(int offset, boolean isGlobal) {
413 queue.add(new Tuple(Opcode.MOD_EQ, offset, isGlobal));
414 }
415
416
417
418
419
420
421
422
423
424 public void powEq(int offset, boolean isGlobal) {
425 queue.add(new Tuple(Opcode.POW_EQ, offset, isGlobal));
426 }
427
428
429
430
431
432
433
434
435
436 public void plusEqArray(int offset, boolean isGlobal) {
437 queue.add(new Tuple(Opcode.PLUS_EQ_ARRAY, offset, isGlobal));
438 }
439
440
441
442
443
444
445
446
447
448 public void minusEqArray(int offset, boolean isGlobal) {
449 queue.add(new Tuple(Opcode.MINUS_EQ_ARRAY, offset, isGlobal));
450 }
451
452
453
454
455
456
457
458
459
460 public void multEqArray(int offset, boolean isGlobal) {
461 queue.add(new Tuple(Opcode.MULT_EQ_ARRAY, offset, isGlobal));
462 }
463
464
465
466
467
468
469
470
471
472 public void divEqArray(int offset, boolean isGlobal) {
473 queue.add(new Tuple(Opcode.DIV_EQ_ARRAY, offset, isGlobal));
474 }
475
476
477
478
479
480
481
482
483
484 public void modEqArray(int offset, boolean isGlobal) {
485 queue.add(new Tuple(Opcode.MOD_EQ_ARRAY, offset, isGlobal));
486 }
487
488
489
490
491
492
493
494
495
496 public void powEqArray(int offset, boolean isGlobal) {
497 queue.add(new Tuple(Opcode.POW_EQ_ARRAY, offset, isGlobal));
498 }
499
500
501
502
503
504
505 public void plusEqInputField() {
506 queue.add(new Tuple(Opcode.PLUS_EQ_INPUT_FIELD));
507 }
508
509
510
511
512
513
514 public void minusEqInputField() {
515 queue.add(new Tuple(Opcode.MINUS_EQ_INPUT_FIELD));
516 }
517
518
519
520
521
522
523 public void multEqInputField() {
524 queue.add(new Tuple(Opcode.MULT_EQ_INPUT_FIELD));
525 }
526
527
528
529
530
531
532 public void divEqInputField() {
533 queue.add(new Tuple(Opcode.DIV_EQ_INPUT_FIELD));
534 }
535
536
537
538
539
540
541 public void modEqInputField() {
542 queue.add(new Tuple(Opcode.MOD_EQ_INPUT_FIELD));
543 }
544
545
546
547
548
549
550 public void powEqInputField() {
551 queue.add(new Tuple(Opcode.POW_EQ_INPUT_FIELD));
552 }
553
554
555
556
557
558
559
560
561 public void srand(int num) {
562 queue.add(new Tuple(Opcode.SRAND, num));
563 }
564
565
566
567
568
569
570 public void rand() {
571 queue.add(new Tuple(Opcode.RAND));
572 }
573
574
575
576
577
578
579 public void intFunc() {
580 queue.add(new Tuple(Opcode.INTFUNC));
581 }
582
583
584
585
586
587
588 public void sqrt() {
589 queue.add(new Tuple(Opcode.SQRT));
590 }
591
592
593
594
595
596
597 public void log() {
598 queue.add(new Tuple(Opcode.LOG));
599 }
600
601
602
603
604
605
606 public void exp() {
607 queue.add(new Tuple(Opcode.EXP));
608 }
609
610
611
612
613
614
615 public void sin() {
616 queue.add(new Tuple(Opcode.SIN));
617 }
618
619
620
621
622
623
624 public void cos() {
625 queue.add(new Tuple(Opcode.COS));
626 }
627
628
629
630
631
632
633 public void atan2() {
634 queue.add(new Tuple(Opcode.ATAN2));
635 }
636
637
638
639
640
641
642 public void match() {
643 queue.add(new Tuple(Opcode.MATCH));
644 }
645
646
647
648
649
650
651 public void index() {
652 queue.add(new Tuple(Opcode.INDEX));
653 }
654
655
656
657
658
659
660
661
662 public void subForDollar0(boolean isGsub) {
663 queue.add(new Tuple(Opcode.SUB_FOR_DOLLAR_0, isGsub));
664 }
665
666
667
668
669
670
671
672
673 public void subForDollarReference(boolean isGsub) {
674 queue.add(new Tuple(Opcode.SUB_FOR_DOLLAR_REFERENCE, isGsub));
675 }
676
677
678
679
680
681
682
683
684
685
686 public void subForVariable(int offset, boolean isGlobal, boolean isGsub) {
687 queue.add(new Tuple(Opcode.SUB_FOR_VARIABLE, offset, isGlobal, isGsub));
688 }
689
690
691
692
693
694
695
696
697
698
699 public void subForArrayReference(int offset, boolean isGlobal, boolean isGsub) {
700 queue.add(new Tuple(Opcode.SUB_FOR_ARRAY_REFERENCE, offset, isGlobal, isGsub));
701 }
702
703
704
705
706
707
708
709
710 public void split(int numargs) {
711 queue.add(new Tuple(Opcode.SPLIT, numargs));
712 }
713
714
715
716
717
718
719
720
721 public void substr(int numargs) {
722 queue.add(new Tuple(Opcode.SUBSTR, numargs));
723 }
724
725
726
727
728
729
730 public void tolower() {
731 queue.add(new Tuple(Opcode.TOLOWER));
732 }
733
734
735
736
737
738
739 public void toupper() {
740 queue.add(new Tuple(Opcode.TOUPPER));
741 }
742
743
744
745
746
747
748 public void system() {
749 queue.add(new Tuple(Opcode.SYSTEM));
750 }
751
752
753
754
755
756
757 public void exec() {
758 queue.add(new Tuple(Opcode.EXEC));
759 }
760
761
762
763
764
765
766 public void swap() {
767 queue.add(new Tuple(Opcode.SWAP));
768 }
769
770
771
772
773
774
775 public void add() {
776 queue.add(new Tuple(Opcode.ADD));
777 }
778
779
780
781
782
783
784 public void subtract() {
785 queue.add(new Tuple(Opcode.SUBTRACT));
786 }
787
788
789
790
791
792
793 public void multiply() {
794 queue.add(new Tuple(Opcode.MULTIPLY));
795 }
796
797
798
799
800
801
802 public void divide() {
803 queue.add(new Tuple(Opcode.DIVIDE));
804 }
805
806
807
808
809
810
811 public void mod() {
812 queue.add(new Tuple(Opcode.MOD));
813 }
814
815
816
817
818
819
820 public void pow() {
821 queue.add(new Tuple(Opcode.POW));
822 }
823
824
825
826
827
828
829
830
831
832 public void inc(int offset, boolean isGlobal) {
833 queue.add(new Tuple(Opcode.INC, offset, isGlobal));
834 }
835
836
837
838
839
840
841
842
843
844 public void dec(int offset, boolean isGlobal) {
845 queue.add(new Tuple(Opcode.DEC, offset, isGlobal));
846 }
847
848
849
850
851
852
853
854
855
856 public void postInc(int offset, boolean isGlobal) {
857 queue.add(new Tuple(Opcode.POSTINC, offset, isGlobal));
858 }
859
860
861
862
863
864
865
866
867
868 public void postDec(int offset, boolean isGlobal) {
869 queue.add(new Tuple(Opcode.POSTDEC, offset, isGlobal));
870 }
871
872
873
874
875
876
877
878
879
880 public void incArrayRef(int offset, boolean isGlobal) {
881 queue.add(new Tuple(Opcode.INC_ARRAY_REF, offset, isGlobal));
882 }
883
884
885
886
887
888
889
890
891
892 public void decArrayRef(int offset, boolean isGlobal) {
893 queue.add(new Tuple(Opcode.DEC_ARRAY_REF, offset, isGlobal));
894 }
895
896
897
898
899
900
901 public void incDollarRef() {
902 queue.add(new Tuple(Opcode.INC_DOLLAR_REF));
903 }
904
905
906
907
908
909
910 public void decDollarRef() {
911 queue.add(new Tuple(Opcode.DEC_DOLLAR_REF));
912 }
913
914
915
916
917
918
919 public void dup() {
920 queue.add(new Tuple(Opcode.DUP));
921 }
922
923
924
925
926
927
928 public void not() {
929 queue.add(new Tuple(Opcode.NOT));
930 }
931
932
933
934
935
936
937 public void negate() {
938 queue.add(new Tuple(Opcode.NEGATE));
939 }
940
941
942
943
944
945
946 public void unaryPlus() {
947 queue.add(new Tuple(Opcode.UNARY_PLUS));
948 }
949
950
951
952
953
954
955 public void cmpEq() {
956 queue.add(new Tuple(Opcode.CMP_EQ));
957 }
958
959
960
961
962
963
964 public void cmpLt() {
965 queue.add(new Tuple(Opcode.CMP_LT));
966 }
967
968
969
970
971
972
973 public void cmpGt() {
974 queue.add(new Tuple(Opcode.CMP_GT));
975 }
976
977
978
979
980
981
982 public void matches() {
983 queue.add(new Tuple(Opcode.MATCHES));
984 }
985
986
987
988
989
990
991 public void dereferenceArray() {
992 queue.add(new Tuple(Opcode.DEREF_ARRAY));
993 }
994
995
996
997
998
999
1000 public void keylist() {
1001 queue.add(new Tuple(Opcode.KEYLIST));
1002 }
1003
1004
1005
1006
1007
1008
1009
1010
1011 public void isEmptyList(Address address) {
1012 queue.add(new Tuple(Opcode.IS_EMPTY_KEYLIST, address));
1013 }
1014
1015
1016
1017
1018
1019
1020 public void getFirstAndRemoveFromList() {
1021 queue.add(new Tuple(Opcode.GET_FIRST_AND_REMOVE_FROM_KEYLIST));
1022 }
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032 public boolean checkClass(Class<?> cls) {
1033 queue.add(new Tuple(Opcode.CHECK_CLASS, cls));
1034 return true;
1035 }
1036
1037
1038
1039
1040
1041
1042 public void getInputField() {
1043 queue.add(new Tuple(Opcode.GET_INPUT_FIELD));
1044 }
1045
1046
1047
1048
1049
1050
1051
1052
1053 public void consumeInput(Address address) {
1054 queue.add(new Tuple(Opcode.CONSUME_INPUT, address));
1055 }
1056
1057
1058
1059
1060
1061
1062 public void getlineInput() {
1063 queue.add(new Tuple(Opcode.GETLINE_INPUT));
1064 }
1065
1066
1067
1068
1069
1070
1071 public void useAsFileInput() {
1072 queue.add(new Tuple(Opcode.USE_AS_FILE_INPUT));
1073 }
1074
1075
1076
1077
1078
1079
1080 public void useAsCommandInput() {
1081 queue.add(new Tuple(Opcode.USE_AS_COMMAND_INPUT));
1082 }
1083
1084
1085
1086
1087
1088
1089
1090
1091 public void nfOffset(int offset) {
1092 queue.add(new Tuple(Opcode.NF_OFFSET, offset));
1093 }
1094
1095
1096
1097
1098
1099
1100
1101
1102 public void nrOffset(int offset) {
1103 queue.add(new Tuple(Opcode.NR_OFFSET, offset));
1104 }
1105
1106
1107
1108
1109
1110
1111
1112
1113 public void fnrOffset(int offset) {
1114 queue.add(new Tuple(Opcode.FNR_OFFSET, offset));
1115 }
1116
1117
1118
1119
1120
1121
1122
1123
1124 public void fsOffset(int offset) {
1125 queue.add(new Tuple(Opcode.FS_OFFSET, offset));
1126 }
1127
1128
1129
1130
1131
1132
1133
1134
1135 public void rsOffset(int offset) {
1136 queue.add(new Tuple(Opcode.RS_OFFSET, offset));
1137 }
1138
1139
1140
1141
1142
1143
1144
1145
1146 public void ofsOffset(int offset) {
1147 queue.add(new Tuple(Opcode.OFS_OFFSET, offset));
1148 }
1149
1150
1151
1152
1153
1154
1155
1156
1157 public void orsOffset(int offset) {
1158 queue.add(new Tuple(Opcode.ORS_OFFSET, offset));
1159 }
1160
1161
1162
1163
1164
1165
1166
1167
1168 public void rstartOffset(int offset) {
1169 queue.add(new Tuple(Opcode.RSTART_OFFSET, offset));
1170 }
1171
1172
1173
1174
1175
1176
1177
1178
1179 public void rlengthOffset(int offset) {
1180 queue.add(new Tuple(Opcode.RLENGTH_OFFSET, offset));
1181 }
1182
1183
1184
1185
1186
1187
1188
1189
1190 public void filenameOffset(int offset) {
1191 queue.add(new Tuple(Opcode.FILENAME_OFFSET, offset));
1192 }
1193
1194
1195
1196
1197
1198
1199
1200
1201 public void subsepOffset(int offset) {
1202 queue.add(new Tuple(Opcode.SUBSEP_OFFSET, offset));
1203 }
1204
1205
1206
1207
1208
1209
1210
1211
1212 public void convfmtOffset(int offset) {
1213 queue.add(new Tuple(Opcode.CONVFMT_OFFSET, offset));
1214 }
1215
1216
1217
1218
1219
1220
1221
1222
1223 public void ofmtOffset(int offset) {
1224 queue.add(new Tuple(Opcode.OFMT_OFFSET, offset));
1225 }
1226
1227
1228
1229
1230
1231
1232
1233
1234 public void environOffset(int offset) {
1235 queue.add(new Tuple(Opcode.ENVIRON_OFFSET, offset));
1236 }
1237
1238
1239
1240
1241
1242
1243
1244
1245 public void argcOffset(int offset) {
1246 queue.add(new Tuple(Opcode.ARGC_OFFSET, offset));
1247 }
1248
1249
1250
1251
1252
1253
1254
1255
1256 public void argvOffset(int offset) {
1257 queue.add(new Tuple(Opcode.ARGV_OFFSET, offset));
1258 }
1259
1260
1261
1262
1263
1264
1265 public void applyRS() {
1266 queue.add(new Tuple(Opcode.APPLY_RS));
1267 }
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277 public void function(String funcName, int numFormalParams) {
1278 queue.add(new Tuple(Opcode.FUNCTION, funcName, numFormalParams));
1279 }
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294 public void callFunction(
1295 Supplier<Address> addressSupplier,
1296 String funcName,
1297 int numFormalParams,
1298 int numActualParams) {
1299 queue.add(new Tuple(Opcode.CALL_FUNCTION, addressSupplier, funcName, numFormalParams, numActualParams));
1300 }
1301
1302
1303
1304
1305
1306
1307 public void setReturnResult() {
1308 queue.add(new Tuple(Opcode.SET_RETURN_RESULT));
1309 }
1310
1311
1312
1313
1314
1315
1316 public void returnFromFunction() {
1317 queue.add(new Tuple(Opcode.RETURN_FROM_FUNCTION));
1318 }
1319
1320
1321
1322
1323
1324
1325
1326
1327 public void setNumGlobals(int numGlobals) {
1328 queue.add(new Tuple(Opcode.SET_NUM_GLOBALS, numGlobals));
1329 }
1330
1331
1332
1333
1334
1335
1336 public void close() {
1337 queue.add(new Tuple(Opcode.CLOSE));
1338 }
1339
1340
1341
1342
1343
1344
1345
1346
1347 public void applySubsep(int count) {
1348 queue.add(new Tuple(Opcode.APPLY_SUBSEP, count));
1349 }
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359 public void deleteArrayElement(int offset, boolean isGlobal) {
1360 queue.add(new Tuple(Opcode.DELETE_ARRAY_ELEMENT, offset, isGlobal));
1361 }
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371 public void deleteArray(int offset, boolean isGlobal) {
1372 queue.add(new Tuple(Opcode.DELETE_ARRAY, offset, isGlobal));
1373 }
1374
1375
1376
1377
1378
1379
1380
1381
1382 public void setExitAddress(Address addr) {
1383 queue.add(new Tuple(Opcode.SET_EXIT_ADDRESS, addr));
1384 }
1385
1386
1387
1388
1389
1390
1391
1392
1393 public void setWithinEndBlocks(boolean b) {
1394 queue.add(new Tuple(Opcode.SET_WITHIN_END_BLOCKS, b));
1395 }
1396
1397
1398
1399
1400
1401
1402 public void exitWithCode() {
1403 queue.add(new Tuple(Opcode.EXIT_WITH_CODE));
1404 }
1405
1406
1407
1408
1409
1410
1411 public void exitWithoutCode() {
1412 queue.add(new Tuple(Opcode.EXIT_WITHOUT_CODE));
1413 }
1414
1415
1416
1417
1418
1419
1420
1421
1422 public void regexp(String regexpStr) {
1423 queue.add(new Tuple(Opcode.REGEXP, regexpStr));
1424 }
1425
1426
1427
1428
1429
1430
1431 public void conditionPair() {
1432 queue.add(new Tuple(Opcode.CONDITION_PAIR));
1433 }
1434
1435
1436
1437
1438
1439
1440 public void isIn() {
1441 queue.add(new Tuple(Opcode.IS_IN));
1442 }
1443
1444
1445
1446
1447 public void scriptThis() {
1448 queue.add(new Tuple(Opcode.THIS));
1449 }
1450
1451
1452
1453
1454
1455
1456
1457
1458 public void extension(ExtensionFunction function, int paramCount, boolean isInitial) {
1459 queue.add(new Tuple(Opcode.EXTENSION, function, paramCount, isInitial));
1460 }
1461
1462
1463
1464
1465
1466
1467 public void dump(PrintStream ps) {
1468 ps.println("(" + versionManager + ")");
1469 ps.println();
1470 for (int i = 0; i < queue.size(); i++) {
1471 Address address = addressManager.getAddress(i);
1472 if (address == null) {
1473 ps.println(i + " : " + queue.get(i));
1474 } else {
1475 ps.println(i + " : [" + address + "] : " + queue.get(i));
1476 }
1477 }
1478 }
1479
1480
1481
1482
1483
1484
1485
1486
1487 public PositionTracker top() {
1488 return new PositionTracker(queue);
1489 }
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500 public void postProcess() {
1501 assert queue.isEmpty() || !queue.get(0).hasNext() : "postProcess() already executed";
1502
1503 for (int i = 0; i < queue.size() - 1; i++) {
1504 queue.get(i).setNext(queue.get(i + 1));
1505 }
1506
1507 for (Tuple tuple : queue) {
1508 tuple.touch(queue);
1509 }
1510 }
1511
1512
1513 private Map<String, Integer> globalVarOffsetMap = new HashMap<String, Integer>();
1514
1515
1516 private Map<String, Boolean> globalVarAarrayMap = new HashMap<String, Boolean>();
1517
1518
1519 private Set<String> functionNames = null;
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529 public void addGlobalVariableNameToOffsetMapping(String varname, int offset, boolean isArray) {
1530 if (globalVarOffsetMap.get(varname) != null) {
1531 assert globalVarAarrayMap.get(varname) != null;
1532 return;
1533 }
1534 globalVarOffsetMap.put(varname, offset);
1535 globalVarAarrayMap.put(varname, isArray);
1536 }
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546 public void setFunctionNameSet(Set<String> names) {
1547
1548
1549
1550
1551
1552
1553
1554
1555 this.functionNames = new HashSet<String>(names);
1556 }
1557
1558
1559
1560
1561
1562
1563
1564
1565 public Map<String, Integer> getGlobalVariableOffsetMap() {
1566 return Collections.unmodifiableMap(globalVarOffsetMap);
1567 }
1568
1569
1570
1571
1572
1573
1574
1575
1576 public Map<String, Boolean> getGlobalVariableAarrayMap() {
1577 return Collections.unmodifiableMap(globalVarAarrayMap);
1578 }
1579
1580
1581
1582
1583
1584
1585
1586
1587 public Set<String> getFunctionNameSet() {
1588 assert functionNames != null;
1589 return Collections.unmodifiableSet(functionNames);
1590 }
1591
1592
1593 private Deque<Integer> linenoStack = new ArrayDeque<Integer>();
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605 public void pushSourceLineNumber(int lineno) {
1606 linenoStack.push(lineno);
1607 }
1608
1609
1610
1611
1612
1613
1614
1615
1616 public void popSourceLineNumber(int lineno) {
1617 int tos = linenoStack.pop();
1618 assert lineno == tos;
1619 }
1620
1621 }