-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDebug File Parsing.i7x
2948 lines (2402 loc) · 175 KB
/
Debug File Parsing.i7x
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Version 2 of Debug File Parsing (for Glulx only) by Brady Garvin begins here.
"Loads debug information produced by the Inform compilers."
Include Compiler Version Checks by Brady Garvin.
Include Runtime Checks by Brady Garvin.
Include Low-Level Operations by Brady Garvin.
Include Low-Level Text by Brady Garvin.
Include Low-Level Linked Lists by Brady Garvin.
Include Low-Level Hash Tables by Brady Garvin.
Include Punctuated Word Parsing Engine by Brady Garvin.
Include Human-Friendly Function Names by Brady Garvin.
Include I6 Routine Names by Brady Garvin.
Include Binary Input Files by Brady Garvin.
Use authorial modesty.
Book "Copyright and License"
[Copyright 2013 Brady J. Garvin]
[This extension is released under the Creative Commons Attribution 3.0 Unported License (CC BY 3.0) so that it can qualify as a public Inform extension. See the LICENSE file included in the release for further details.]
Book "Extension Information"
[We assume a single I6 source file.]
[We ignore column numbers, mostly because the client extensions don't need them, and also because the code here becomes simpler (and a tad faster starting up) when they aren't stored. Also, accounting for their overflow is tricky business.]
[We use one-based line numbers throughout, even though zero-based would be a little more convenient. Most text editors use a one-based numbering, so one-based is what we want to show to authors, and there are just too many opportunities for silly mistakes if we have to convert back and forth.]
[As a consequence, line number zero usually means ``no line at all.'']
[For each of the kinds defined by Glk Interception you will see a sentence like
A routine record is an invalid routine record.
This bewildering statement actually sets up routine records as a qualitative value with default value the routine record at address one, which, as we say, is invalid. (We could have gone with a quantitative kind for default zero, but then we would open up the possibility for arithmetic on the pointers.) I wish it weren't necessary, but at least in this build Inform doesn't let us provide a default value any other way, and, moreover, we need a default value or else only I6 substitutions are allowed to decide on routine records.]
Chapter "Forced Use Options"
Include action creations in the debugging log.
Include assertions in the debugging log.
Include constructed plurals in the debugging log.
Include kind creations in the debugging log.
Include object creations in the debugging log.
Include rulebook compilation in the debugging log.
Include variable creations in the debugging log.
Chapter "Use Options"
Use a routine record hash table size of at least 2311 translates as (- Constant DFP_ROUTINE_HASH_SIZE = {N}; -).
Use a source line record hash table size of at least 11213 translates as (- Constant DFP_SOURCE_LINE_HASH_SIZE = {N}; -).
Use a sequence point hash table size of at least 11213 translates as (- Constant DFP_SEQUENCE_POINT_HASH_SIZE = {N}; -).
Use a global record hash table size of at least 311 translates as (- Constant DFP_GLOBAL_HASH_SIZE = {N}; -).
Use a memory stack variable record hash table size of at least 311 translates as (- Constant DFP_MSV_HASH_SIZE = {N}; -).
Use a memory stack frame hash table size of at least 31 translates as (- Constant DFP_MEMORY_STACK_FRAME_HASH_SIZE = {N}; -).
Use a debug plural hash table size of at least 1123 translates as (- Constant DFP_PLURAL_HASH_SIZE = {N}; -).
Use a kind hash table size of at least 131 translates as (- Constant DFP_KIND_HASH_SIZE = {N}; -).
Use a source line position hash table size of at least 11213 translates as (- Constant DFP_LINE_POSITION_HASH_SIZE = {N}; -).
Use an object hash table size of at least 1123 translates as (- Constant DFP_OBJECT_HASH_SIZE = {N}; -).
To decide what number is the routine record hash table size: (- DFP_ROUTINE_HASH_SIZE -).
To decide what number is the source line record hash table size: (- DFP_SOURCE_LINE_HASH_SIZE -).
To decide what number is the sequence point hash table size: (- DFP_SEQUENCE_POINT_HASH_SIZE -).
To decide what number is the global record hash table size: (- DFP_GLOBAL_HASH_SIZE -).
To decide what number is the memory stack variable hash table size: (- DFP_MSV_HASH_SIZE -).
To decide what number is the memory stack frame hash table size: (- DFP_MEMORY_STACK_FRAME_HASH_SIZE -).
To decide what number is the debug plural hash table size: (- DFP_PLURAL_HASH_SIZE -).
To decide what number is the kind hash table size: (- DFP_KIND_HASH_SIZE -).
To decide what number is the source line position hash table size: (- DFP_LINE_POSITION_HASH_SIZE -).
To decide what number is the object hash table size: (- DFP_OBJECT_HASH_SIZE -).
Use blorb resources in lieu of external debug files translates as (- Constant DFP_USE_BLORB; -).
Chapter "Other Options"
[These are not use options, but we treat them almost as if they were.]
The name of the symbolic link to the intermediate I6 file is some text that varies.
The name of the symbolic link to the debug information file is some text that varies.
The name of the symbolic link to the debugging log file is some text that varies.
Chapter "Rulebooks"
The debug file setup rulebook is a rulebook.
Book "Runtime Checks"
Chapter "Messages" - unindexed
To fail at loading debug files twice (this is failing to load debug files twice):
say "[low-level runtime failure in]Debug File Parsing[with explanation]I was asked to load debug files a second time, but they can only be loaded once.[terminating the story]".
To fail at opening an unnamed debug information file (this is failing to open an unnamed debug information file):
say "[low-level runtime failure in]Debug File Parsing[with explanation]I wasn't given the name of a symbolic link to the debug information file ([fixed letter spacing]gameinfo.dbg[variable letter spacing][warning type]). Add a line like[line break][line break][fixed letter spacing] The name of the symbolic link to the debug information file is 'debuginfo'.[variable letter spacing][warning type][line break][line break]or[line break][line break][fixed letter spacing] Use blorb resources in lieu of external debug files.[variable letter spacing][warning type][line break][line break]to the source text. (The i7grip download contains a JAR file that does this automatically.)[terminating the story]".
To fail at recognizing the debug information file's format (this is failing to recognize the debug information file's format):
say "[low-level runtime failure in]Debug File Parsing[with explanation]The debug information file appears to have the wrong format; the first magic number doesn't match my expectations.[terminating the story]".
To fail at recognizing the debug information file's version (this is failing to recognize the debug information file's version):
say "[low-level runtime failure in]Debug File Parsing[with explanation]The debug information file has a version number that is newer than any of the versions that I know about.[terminating the story]".
To fail at recognizing the debug record type (Y - a number) (this is failing to recognize a debug record type):
say "[low-level runtime failure in]Debug File Parsing[with explanation]The debug information file contains a record of type [Y converted to a number], but that isn't a valid record type for the version of the file format the file claims to use.[terminating the story]".
To fail at matching the header of the debug information file (this is failing to match the header of the debug information file):
say "[low-level runtime failure in]Debug File Parsing[with explanation]I need the debug information file to match the story, but the headers are different, so they can't possibly go together.[terminating the story]".
To fail at opening an unnamed intermediate I6 file (this is failing to open an unnamed intermediate I6 file):
say "[low-level runtime failure in]Debug File Parsing[with explanation]I wasn't given the name of a symbolic link to the intermediate I6 file ([fixed letter spacing]gameinfo.dbg[variable letter spacing][warning type]). Add a line like[line break][line break][fixed letter spacing] The name of the symbolic link to the intermediate I6 file is 'debugI6'.[variable letter spacing][warning type][line break][line break]or[line break][line break][fixed letter spacing] Use blorb resources in lieu of external debug files.[variable letter spacing][warning type][line break][line break]to the source text. (The i7grip download contains a JAR file that does this automatically.)[terminating the story]".
To fail at handling a second I6 source file named (F - some text) (this is failing to handle a second I6 source file):
say "[low-level runtime failure in]Debug File Parsing[with explanation]I assume that every project is reduced to a single I6 source file before the final compilation. But the debug information file mentions at least one other source of I6 code, '[F converted to some text]', and I'm not prepared to handle it.[terminating the story]".
To fail at finding a cached line position for the I6 line number (L - a number) (this is failing to find a cached line position for an I6 line):
say "[low-level runtime failure in]Debug File Parsing[with explanation]I should have a cached stream position for the I6 line number [L converted to a number], but I can't find it. Maybe the I6 source file doesn't match this story?[terminating the story]".
To fail at keeping routine records in order (this is failing to keep routine records in order):
say "[low-level runtime failure in]Debug File Parsing[with explanation]I expected that at most the last routine on a line could extend beyond that line, but my bookkeeping says otherwise.[terminating the story]".
To fail at opening an unnamed debugging log file (this is failing to open an unnamed debugging log file):
say "[low-level runtime failure in]Debug File Parsing[with explanation]I wasn't given the name of a symbolic link to the debugging log file ([fixed letter spacing]Debug log.txt[variable letter spacing][warning type]). Add a line like[line break][line break][fixed letter spacing] The name of the symbolic link to the debugging log file is 'debuglog'.[variable letter spacing][warning type][line break][line break]or[line break][line break][fixed letter spacing] Use blorb resources in lieu of external debug files.[variable letter spacing][warning type][line break][line break]to the source text. (The i7grip download contains a JAR file that does this automatically.)[terminating the story]".
To fail at finding a reference point for finding the declaration of I7 globals (this is failing to find a reference point for finding the declaration of I7 globals):
say "[low-level runtime failure in]Debug File Parsing[with explanation]I tried to find the declaration of the I6 array [fixed letter spacing]Global_Vars[variable letter spacing], which stores I7 global variables. To do so, I normally work my way backwards from the kind information for table columns, but because I couldn't find the latter, I had no way to locate the former.[terminating the story]".
To fail at finding the base address for I6 globals (this is failing to find the base address for I6 globals):
say "[low-level runtime failure in]Debug File Parsing[with explanation]I tried to find the location of I6 globals in memory, a location that should exist for all story files, but the debug information files never told me where it is.[terminating the story]".
To fail at associating I7 object names with object numbers (this is failing to associate I7 object names with object numbers):
say "[low-level runtime failure in]Debug File Parsing[with explanation]I tried to associate I7 object names with object numbers, but found more object names than there are objects in the object tree. My parsing of the debug information must be wrong.[terminating the story]".
Book "Data Structures"
Chapter "Routine Records"
Section "The Routine Record Kind"
A routine record is a kind of value.
A routine record is an invalid routine record. [See the note in the book "Extension Information."]
The specification of a routine record is "A routine record represents everything that Debug File Parsing knows about a routine."
Section "The Routine Record Structure" - unindexed
[Layout:
4 bytes for the function address
4 bytes for the local count [-1 if the local count and names have not been loaded]
64 bytes for the I6 local names [null if the local count and names have not been loaded, "<invalid-local-#>" for nonexistent locals]
64 bytes for the sample I7 local names [null if the local count and names have not been loaded, "<invalid-local-#>" for nonexistent or non-I7 locals]
64 bytes for the I7 local kind names [null if the I7 locals have not been loaded, "<no kind>" for nonexistent locals and locals without kinds]
4 bytes for the source version [zero if the source language has not been determined, six for I6, seven for I7]
4 bytes for the beginning stream position
4 bytes for the sequence point stream position
4 bytes for the end stream position
4 bytes for the preamble line number [a line number for the I6 source, zero if the source version has not been set to seven]
4 bytes for the beginning line number [a line number for the I6 source, zero if there are no lines]
4 bytes for the end line number [likewise; note that the beginning and end line numbers are adjusted so that the beginning is inclusive, but the end is exclusive]
4 bytes for the sequence point linked list [an invalid linked list if the sequence points have not been loaded]
4 bytes for the sequence point linked list tail [an invalid linked list tail if the sequence points have not been loaded]]
[All stream positions are in the debug information file, not the I6 source.]
To decide what number is the assumed maximum local count: (- 16 -).
To decide what number is the size in memory of a routine record: (- 236 -).
Section "Routine Record Construction" - unindexed
To decide what routine record is a new routine record with function address (A - a number) and beginning line number (N - a number) and beginning stream position (P - a number) (this is creating a routine record):
let the result be a permanent memory allocation of the size in memory of a routine record bytes converted to a routine record;
zero the size in memory of a routine record bytes at address result converted to a number;
write the function address A to the result;
write the local count -1 to the result;
write the beginning stream position P to the result;
write the beginning line number N to the result;
write the sequence point linked list an invalid permanent linked list to the result;
write the sequence point linked list tail an invalid permanent linked list tail to the result;
decide on the result.
Section "Private Routine Record Accessors and Mutators" - unindexed
To write the function address (X - a number) to (A - a routine record): (- llo_setInt({A}, {X}); -).
To decide what number is the possibly invalid local count of (A - a routine record): (- llo_getField({A}, 1) -).
To write the local count (X - a number) to (A - a routine record): (- llo_setField({A}, 1, {X}); -).
To decide what text is the possibly invalid I6 local name number (I - a number) of (A - a routine record): (- llo_getField({A}, 2 + {I}) -).
To write (X - some text) to I6 local name number (I - a number) of (A - a routine record): (- llo_setField({A}, 2 + {I}, {X}); -).
To decide what text is the possibly invalid sample I7 local name number (I - a number) of (A - a routine record): (- llo_getField({A}, 18 + {I}) -).
To write (X - some text) to sample I7 local name number (I - a number) of (A - a routine record): (- llo_setField({A}, 18 + {I}, {X}); -).
To decide what text is the possibly invalid I7 local kind name number (I - a number) of (A - a routine record): (- llo_getField({A}, 34 + {I}) -).
To write (X - some text) to I7 local kind name number (I - a number) of (A - a routine record): (- llo_setField({A}, 34 + {I}, {X}); -).
To decide what number is the possibly invalid source version of (A - a routine record): (- llo_getField({A}, 50) -).
To write the source version (X - a number) to (A - a routine record): (- llo_setField({A}, 50, {X}); -).
To decide what number is the beginning stream position of (A - a routine record): (- llo_getField({A}, 51) -).
To write the beginning stream position (X - a number) to (A - a routine record): (- llo_setField({A}, 51, {X}); -).
To decide what number is the sequence point stream position of (A - a routine record): (- llo_getField({A}, 52) -).
To write the sequence point stream position (X - a number) to (A - a routine record): (- llo_setField({A}, 52, {X}); -).
To decide what number is the end stream position of (A - a routine record): (- llo_getField({A}, 53) -).
To write the end stream position (X - a number) to (A - a routine record): (- llo_setField({A}, 53, {X}); -).
To decide what number is the possibly invalid preamble line number of (A - a routine record): (- llo_getField({A}, 54) -).
To write the preamble line number (X - a number) to (A - a routine record): (- llo_setField({A}, 54, {X}); -).
To write the beginning line number (X - a number) to (A - a routine record): (- llo_setField({A}, 55, {X}); -).
To write the end line number (X - a number) to (A - a routine record): (- llo_setField({A}, 56, {X}); -).
To decide what permanent linked list is the possibly invalid sequence point linked list of (A - a routine record): (- ({A}-->57) -).
To write the sequence point linked list (X - a permanent linked list) to (A - a routine record): (- llo_setField({A}, 57, {X}); -).
To decide what permanent linked list tail is the possibly invalid sequence point linked list tail of (A - a routine record): (- ({A}-->58) -).
To write the sequence point linked list tail (X - a permanent linked list tail) to (A - a routine record): (- llo_setField({A}, 58, {X}); -).
Section "Direct Public Routine Record Accessors"
To decide what number is the function address of (A - a routine record): (- llo_getInt({A}) -).
To decide what number is the beginning line number of (A - a routine record): (- llo_getField({A}, 55) -).
To decide what number is the end line number of (A - a routine record): (- llo_getField({A}, 56) -).
Section "Lazy Public Routine Record Accessors"
To decide what number is the local count of (A - a routine record) (this is determining the local count of a routine record):
let the result be the possibly invalid local count of A;
if the result is not -1:
decide on the result;
load I6 locals into A;
decide on the possibly invalid local count of A.
To decide what text is I6 local name number (I - a number) of (A - a routine record) (this is determining an I6 local name in a routine record):
let the result be the possibly invalid I6 local name number I of A;
if the result is not zero converted to a text:
decide on the result;
load I6 locals into A;
decide on the possibly invalid I6 local name number I of A.
To decide what text is sample I7 local name number (I - a number) of (A - a routine record) (this is determining a sample I7 local name in a routine record):
let the result be the possibly invalid sample I7 local name number I of A;
if the result is not zero converted to a text:
decide on the result;
load I7 locals into A;
decide on the possibly invalid sample I7 local name number I of A.
To decide what text is I7 local kind name number (I - a number) of (A - a routine record) (this is determining a I7 local kind in a routine record):
let the result be the possibly invalid I7 local kind name number I of A;
if the result is not zero converted to a text:
decide on the result;
load I7 kinds into A;
decide on the possibly invalid I7 local kind name number I of A.
To decide what number is the source version of (A - a routine record) (this is determining the source version of a routine record):
let the result be the possibly invalid source version of A;
if the result is not zero:
decide on the result;
load the source version and preamble line number into A;
decide on the possibly invalid source version of A.
To decide what number is the preamble line number of (A - a routine record) (this is determining the preamble line number of a routine record):
let the discarded value be the source version of A;
decide on the possibly invalid preamble line number of A.
[We intentionally return an r-value, not an l-value.]
To decide what permanent linked list is the sequence point linked list of (A - a routine record) (this is determining the sequence point linked list of a routine record):
let the result be the possibly invalid sequence point linked list of A;
if the result is not an invalid permanent linked list:
decide on the result;
load the sequence point list into A;
decide on the possibly invalid sequence point linked list of A.
Chapter "Source Line Records"
Section "The Source Line Record Kind"
A source line record is a kind of value.
A source line record is an invalid source line record. [See the note in the book "Extension Information."]
The specification of a source line record is "A source line record represents everything that Debug File Parsing knows about a single line in the intermediate I6 file auto.inf."
Section "The Source Line Record Structure" - unindexed
[Layout:
4 bytes for the line number
4 bytes for the I6
4 bytes for the I7 [null if the I7 has not yet been determined, the empty string if we have determined that there is no I7 on this line]
4 bytes for the I7 indentation [zero if the I7 has not yet been determined, but possibly zero anyway]
4 bytes for the I7 coda flag [false if the I7 has not yet been determined, but usually false anyway (the coda flag is true when we are still in a routine but past the end of the last I7 line's translation)]
4 bytes for the routine record linked list
4 bytes for the sequence point linked list [an invalid permanent linked list if the sequence points have not yet been determined]
64 bytes for the I7 local names [null if the I7 has not yet been determined, "<invalid-local-#>" for nonexistent locals and locals out of scope]]
To decide what number is the size in memory of a source line record: (- 92 -).
Section "Source Line Record Construction" - unindexed
To decide what source line record is a new source line record for line number (N - a number) and the I6 (T - some text) and the routine record list (R - a permanent linked list) (this is creating a source line record):
let the result be a permanent memory allocation of the size in memory of a source line record bytes converted to a source line record;
zero the size in memory of a source line record bytes at address result converted to a number;
write the line number N to the result;
write the I6 T to the result;
write the routine record list R to the result;
write the sequence point linked list an invalid permanent linked list to the result;
decide on the result.
Section "Private Source Line Record Accessors and Mutators" - unindexed
To write the line number (X - a number) to (A - a source line record): (- llo_setInt({A}, {X}); -).
To write the I6 (X - some text) to (A - a source line record): (- llo_setField({A}, 1, {X}); -).
To decide what text is the possibly invalid I7 of (A - a source line record): (- llo_getField({A}, 2) -).
To write the I7 (X - some text) to (A - a source line record): (- llo_setField({A}, 2, {X}); -).
To decide what number is the possibly invalid I7 indentation of (A - a source line record): (- llo_getField({A}, 3) -).
To write the I7 indentation (X - a number) to (A - a source line record): (- llo_setField({A}, 3, {X}); -).
To decide whether the possibly invalid I7 coda flag is set in (A - a source line record): (- llo_getField({A}, 4) -).
To set the I7 coda flag in (A - a source line record): (- llo_setField({A}, 4, 1); -).
To write the routine record list (X - a permanent linked list) to (A - a source line record): (- llo_setField({A}, 5, {X}); -).
To decide what permanent linked list is the possibly invalid sequence point linked list of (A - a source line record): (- ({A}-->6) -).
To write the sequence point linked list (X - a permanent linked list) to (A - a source line record): (- llo_setField({A}, 6, {X}); -).
To decide what text is the possibly invalid I7 local name number (I - a number) of (A - a source line record): (- llo_getField({A}, 7 + {I}) -).
To write (X - some text) to I7 local name number (I - a number) of (A - a source line record): (- llo_setField({A}, 7 + {I}, {X}); -).
Section "Direct Public Source Line Record Accessors"
To decide what number is the line number of (A - a source line record): (- llo_getInt({A}) -).
To decide what text is the I6 of (A - a source line record): (- llo_getField({A}, 1) -).
To decide what permanent linked list is the routine record list of (A - a source line record): (- ({A}-->5) -).
To decide what routine record is the sole routine record of (A - a source line record):
let the routine record list be the routine record list of A;
if the routine record list is unit:
decide on the routine record key of the routine record list converted to a permanent linked list vertex;
decide on an invalid routine record.
Section "Lazy Public Source Line Record Accessors"
To decide what text is the I7 of (A - a source line record) (this is determining the I7 of a source line record):
let the result be the possibly invalid I7 of A;
if the result is not zero converted to a text:
decide on the result;
load I7 into A;
decide on the possibly invalid I7 of A.
To decide what number is the I7 indentation of (A - a source line record) (this is determining the I7 indentation of a source line record):
let the discarded value be the I7 of A;
decide on the possibly invalid I7 indentation of A.
To decide whether the I7 coda flag is set in (A - a source line record) (this is determining the I7 coda flag of a source line record):
let the discarded value be the I7 of A;
decide on whether or not the possibly invalid I7 coda flag is set in A.
To decide what permanent linked list is the sequence point linked list of (A - a source line record) (this is determining the sequence point linked list of a source line record):
let the result be the possibly invalid sequence point linked list of A;
if the result is not an invalid permanent linked list:
decide on the result;
load sequence points into A;
decide on the possibly invalid sequence point linked list of A.
To decide what text is I7 local name number (I - a number) of (A - a source line record) (this is determining an I7 local name in a source line record):
let the result be the possibly invalid I7 local name number I of A;
if the result is not zero converted to a text:
decide on the result;
load I7 locals into A;
decide on the possibly invalid I7 local name number I of A.
Chapter "Global Records"
Section "The Global Record Kind"
A global record is a kind of value.
A global record is an invalid global record. [See the note in the book "Extension Information."]
The specification of a global record is "A global record represents everything that Debug File Parsing knows about a global variable---either a 'true' I6 global or an I7 global stored in the Global_Vars array."
Section "The Global Record Structure" - unindexed
[Layout:
4 bytes for the global index [either an I6 index (into the globals space) or an I7 index (into the Global_Vars array)]
4 bytes for the address [-2 for an I6 global (in which case scale and shift the [I6] global index), -1 if the address has not yet been determined, zero if an address cannot be found]
4 bytes for the human-friendly name
4 bytes for the kind name]
To decide what number is the size in memory of a global record: (- 16 -).
Section "Global Record Construction" - unindexed
To decide what global record is a new I7 global record with index (I - a number) and human-friendly name (T - some text) and kind name (K - some text) (this is creating a global record with a kind):
let the result be a permanent memory allocation of the size in memory of a global record bytes converted to a global record;
write the global index I to the result;
write the address -1 to the result;
write the human-friendly name T to the result;
write the kind name K to the result;
decide on the result.
To decide what global record is a new I6 global record with index (I - a number) and human-friendly name (T - some text) (this is creating a global record without a kind):
let the result be a permanent memory allocation of the size in memory of a global record bytes converted to a global record;
write the global index I to the result;
write the address -2 to the result;
write the human-friendly name T to the result;
write the kind name "<no kind>" to the result;
decide on the result.
Section "Private Global Record Accessors and Mutators"
To write the global index (X - a number) to (A - a global record): (- llo_setInt({A}, {X}); -).
To decide what number is the possibly invalid address of (A - a global record): (- llo_getField({A}, 1) -).
To write the address (X - a number) to (A - a global record): (- llo_setField({A}, 1, {X}); -).
To write the human-friendly name (X - some text) to (A - a global record): (- llo_setField({A}, 2, {X}); -).
To write the kind name (X - some text) to (A - a global record): (- llo_setField({A}, 3, {X}); -).
Section "Direct Public Global Record Accessors"
To decide what number is the global index of (A - a global record): (- llo_getInt({A}) -).
To decide what text is the human-friendly name of (A - a global record): (- llo_getField({A}, 2) -).
To decide what text is the kind name of (A - a global record): (- llo_getField({A}, 3) -).
To decide what number is the source version of (A - a global record):
if the possibly invalid address of A is -2:
decide on six;
decide on seven.
Section "Uninstrumented Global Record Address Accessor" (for use without Glulx Runtime Instrumentation Framework by Brady Garvin)
To decide what number is the address of (A - a global record) (this is determining the address of a global record):
let the result be the possibly invalid address of A;
if the result is:
-- -1:
load addresses into the global records;
decide on the possibly invalid address of A;
-- -2:
always check that the base address for I6 globals is not zero or else fail at finding the base address for I6 globals;
decide on four times the global index of A plus the base address for I6 globals;
-- otherwise:
decide on the result.
Section "Instrumented Global Record Address Accessor" (for use with Glulx Runtime Instrumentation Framework by Brady Garvin)
[GRIF relocates the I6 temporary space (which comprises low-indexed globals); the global addresses should reflect that relocation.]
To decide what number is the address of (A - a global record) (this is determining the address of a global record):
let the result be the possibly invalid address of A;
if the result is:
-- -1:
load addresses into the global records;
decide on the possibly invalid address of A;
-- -2:
always check that the base address for I6 globals is not zero or else fail at finding the base address for I6 globals;
let the index be the global index of A;
if the index is less than the variable count of the temporary space:
decide on four times the index plus the address of the alternative temporary space;
decide on four times the index plus the base address for I6 globals;
-- otherwise:
decide on the result.
Chapter "Memory Stack Variable Records"
Section "The Memory Stack Variable Record Kind"
A memory stack variable record is a kind of value.
A memory stack variable record is an invalid memory stack variable record. [See the note in the book "Extension Information."]
The specification of a memory stack variable record is "A memory stack variable record represents everything that Debug File Parsing knows about a rulebook, activity, or action variable."
Section "The Memory Stack Variable Record Structure" - unindexed
[Layout:
4 bytes for the memory stack identifier [@] [defined by Inform as a rulebook number for rulebook variables, 10000 plus the activity number (that is, the zero-based index in creation order) for activity variables, or 20000 plus the action number (again, the zero-based index in creation order) for action variables; we use -1 for unresolved rulebook variables, -10001 for unresolved activity variables, and -20001 for unresolved action variables]
4 bytes for the memory stack offset [the zero-based index of the variable among all variables sharing the same memory stack identifier]
4 bytes for the owner name [the name of the owning rulebook, activity, or action]
4 bytes for the human-friendly name
4 bytes for the kind name]
To decide what number is the size in memory of a memory stack variable record: (- 20 -).
Section "Memory Stack Variable Record Construction" - unindexed
To decide what memory stack variable record is a new rulebook variable record for variable (I - a number) owned by (O - some text) with human-friendly name (T - some text) and kind name (K - some text) (this is creating a rulebook variable record):
let the result be a permanent memory allocation of the size in memory of a memory stack variable record bytes converted to a memory stack variable record;
write the memory stack identifier -1 to the result;
write the memory stack offset I to the result;
write the owner name O to the result;
write the human-friendly name T to the result;
write the kind name K to the result;
decide on the result.
To decide what memory stack variable record is a new activity variable record for variable (I - a number) owned by (O - some text) with human-friendly name (T - some text) and kind name (K - some text) (this is creating an activity variable record):
let the result be a permanent memory allocation of the size in memory of a memory stack variable record bytes converted to a memory stack variable record;
write the memory stack identifier -10001 to the result;
write the memory stack offset I to the result;
write the owner name O to the result;
write the human-friendly name T to the result;
write the kind name K to the result;
decide on the result.
To decide what memory stack variable record is a new action variable record for variable (I - a number) owned by (O - some text) with human-friendly name (T - some text) and kind name (K - some text) (this is creating an action variable record):
let the result be a permanent memory allocation of the size in memory of a memory stack variable record bytes converted to a memory stack variable record;
write the memory stack identifier -20001 to the result;
write the memory stack offset I to the result;
write the owner name O to the result;
write the human-friendly name T to the result;
write the kind name K to the result;
decide on the result.
Section "Private Memory Stack Variable Record Accessors and Mutators"
To decide what number is the possibly invalid memory stack identifier of (A - a memory stack variable record): (- llo_getInt({A}) -).
To write the memory stack identifier (X - a number) to (A - a memory stack variable record): (- llo_setInt({A}, {X}); -).
To write the memory stack offset (X - a number) to (A - a memory stack variable record): (- llo_setField({A}, 1, {X}); -).
To write the owner name (X - some text) to (A - a memory stack variable record): (- llo_setField({A}, 2, {X}); -).
To write the human-friendly name (X - some text) to (A - a memory stack variable record): (- llo_setField({A}, 3, {X}); -).
To write the kind name (X - some text) to (A - a memory stack variable record): (- llo_setField({A}, 4, {X}); -).
Section "Direct Public Memory Stack Variable Record Accessors"
To decide what number is the memory stack offset of (A - a memory stack variable record): (- llo_getField({A}, 1) -).
To decide what text is the owner name of (A - a memory stack variable record): (- llo_getField({A}, 2) -).
To decide what text is the human-friendly name of (A - a memory stack variable record): (- llo_getField({A}, 3) -).
To decide what text is the kind name of (A - a memory stack variable record): (- llo_getField({A}, 4) -).
Section "Inline Definitions for Lazy Public Memory Stack Variable Record Accessors" - unindexed
To decide what number is the memory stack top address: (- (MStack + (4 * MStack_Top)) -).
To decide what number is the memory stack bottom address: (- MStack -).
Section "Lazy Public Memory Stack Variable Record Accessors"
To decide what number is the memory stack identifier of (A - a memory stack variable record) (this is determining the memory stack identifier of a memory stack variable record):
let the result be the possibly invalid memory stack identifier of A;
if the result is:
-- -1:
now the result is the first number value matching the synthetic textual key the owner name of A in the rulebook creation hash table or -1 if there are no matches;
write the memory stack identifier the result to A;
-- -10001:
now the result is 10000 plus the first number value matching the synthetic textual key the owner name of A in the activity creation hash table or -20001 if there are no matches;
write the memory stack identifier the result to A;
-- -20001:
now the result is 20000 plus the first number value matching the synthetic textual key the owner name of A in the action creation hash table or -40001 if there are no matches;
write the memory stack identifier the result to A;
decide on the result.
To decide what number is the current address of (A - a memory stack variable record) (this is determining the current address of a memory stack variable record):
let the stack address be the memory stack top address;
let the previous stack address be the stack address;
let the seen hash table be a new hash table with the memory stack frame hash table size buckets;
insert the key the stack address into the seen hash table;
if the stack address is a invalid integer address or the stack address is less than the memory stack bottom address:
delete the seen hash table;
decide on zero;
repeat until a break:
let the delta be the integer at address the stack address;
if the delta is zero:
delete the seen hash table;
decide on zero;
now the previous stack address is the stack address;
increase the stack address by four times the delta;
if the seen hash table contains the key the stack address:
delete the seen hash table;
decide on zero;
insert the key the stack address into the seen hash table;
let the check address be the stack address plus four;
if the check address is a invalid integer address or the stack address is less than the memory stack bottom address:
delete the seen hash table;
decide on zero;
if the integer at address check address is the memory stack identifier of A:
delete the seen hash table;
let the result be the stack address plus eight plus four times the memory stack offset of A;
if the result is at least the previous stack address:
decide on zero;
decide on the result.
Chapter "Permanent Hash Tables and Other Singletons" - unindexed
[Maps function addresses to routine records]
The routine record hash table is a permanent hash table that varies.
[A list of the above key-value pairs, sorted by stream position for the benefit of Glk libraries slower at file I/O.]
The routine record list is a permanent linked list that varies.
The routine record list tail is a permanent linked list tail that varies.
[Maps one-based I6 line numbers to routine records whose routines begin on those lines]
The routine beginning hash table is a permanent hash table that varies.
[Maps one-based I6 line numbers to source line records]
The source line record hash table is a permanent hash table that varies.
[Maps instruction addresses (only for instructions that begin at a sequence point) to routine records]
The sequence point routine record hash table is a permanent hash table that varies.
[Maps instruction addresses (only for instructions that begin at a sequence point) to one-based I6 line numbers (which are negated when we have made sure that any relocation has taken place)]
The sequence point line number hash table is a permanent hash table that varies.
[The base address for I6 globals]
The base address for I6 globals is a number that varies.
[The number of entries in the following hash table]
The I7 global count is a number that varies.
[Maps I7 global indices to global records]
The I7 global record hash table is a permanent hash table that varies.
[Maps canonical global names to global records]
The global record lookup hash table is a permanent hash table that varies.
[Counts the total number of entries in the next two hash tables]
The excess kind counter is a number that varies. The excess kind counter is zero.
[Maps kind-of-value names to a base kind code (the values are wrong until will finish processing the debugging log)]
The kind-of-value hash table is a permanent hash table that varies.
[Maps kind-of-object names to a base kind code (the values are wrong until will finish processing the debugging log)]
The kind-of-object hash table is a permanent hash table that varies.
[Maps singular source text names to plural source text names]
The debug plural hash table is a permanent hash table that varies.
[Maps rulebook names to their next available memory stack variable offsets]
The rulebook variable offset hash table is a permanent hash table that varies.
[Maps activity names to their next available memory stack variable offsets]
The activity variable offset hash table is a permanent hash table that varies.
[Maps action names to their next available memory stack variable offsets]
The action variable offset hash table is a permanent hash table that varies.
[Counts the total number of entries in the next hash table]
The rulebook counter is a number that varies. The rulebook counter is zero.
[Maps rulebook names to their creation indices]
The rulebook creation hash table is a permanent hash table that varies.
[Counts the total number of entries in the next hash table]
The activity counter is a number that varies. The activity counter is zero.
[Maps activity names to their creation indices]
The activity creation hash table is a permanent hash table that varies.
[Counts the total number of entries in the next hash table]
The action counter is a number that varies. The action counter is zero.
[Maps action names to their creation indices]
The action creation hash table is a permanent hash table that varies.
[Maps canonical memory stack variable names to memory stack variable records]
The memory stack variable record lookup hash table is a permanent hash table that varies.
[Counts the total number of entries that *could be* in the next hash table (anonymous objects aren't inserted, but they are counted)]
The object counter is a number that varies. The object counter is zero.
[Maps source text names for objects to object numbers (based on a traversal of the pristine tree)]
The object number lookup hash table is a permanent hash table that varies.
[Maps authorial object numbers to object addresses]
The object address lookup hash table is a permanent hash table that varies.
A first debug file setup rule (this is the allocate permanent hash tables for storing debug information rule):
now the routine record hash table is a new permanent hash table with the routine record hash table size buckets;
now the routine record list is an empty permanent linked list;
now the routine record list tail is an empty permanent linked list's tail;
now the routine beginning hash table is a new permanent hash table with the routine record hash table size buckets;
now the source line record hash table is a new permanent hash table with the source line record hash table size buckets;
now the sequence point routine record hash table is a new permanent hash table with the sequence point hash table size buckets;
now the sequence point line number hash table is a new permanent hash table with the sequence point hash table size buckets;
now the I7 global record hash table is a new permanent hash table with the global record hash table size buckets;
now the global record lookup hash table is a new permanent hash table with the global record hash table size buckets;
now the kind-of-value hash table is a new permanent hash table with the kind hash table size buckets;
now the kind-of-object hash table is a new permanent hash table with the kind hash table size buckets;
now the debug plural hash table is a new permanent hash table with the debug plural hash table size buckets;
now the rulebook variable offset hash table is a new permanent hash table with the memory stack variable hash table size buckets;
now the activity variable offset hash table is a new permanent hash table with the memory stack variable hash table size buckets;
now the action variable offset hash table is a new permanent hash table with the memory stack variable hash table size buckets;
now the rulebook creation hash table is a new permanent hash table with the memory stack variable hash table size buckets;
now the activity creation hash table is a new permanent hash table with the memory stack variable hash table size buckets;
now the action creation hash table is a new permanent hash table with the memory stack variable hash table size buckets;
now the memory stack variable record lookup hash table is a new permanent hash table with the memory stack variable hash table size buckets;
now the object number lookup hash table is a new permanent hash table with the object hash table size buckets;
now the object address lookup hash table is a new permanent hash table with the object hash table size buckets.
Section "Lazy Singleton Accessors"
To decide what routine record is the routine record for (F - a sayable value):
decide on the first routine record value matching the key the function address of F in the routine record hash table or an invalid routine record if there are no matches.
To decide what linked list is a new list of routine records for beginning line number (N - a number) (this is creating a routine record list for a beginning line number):
let the result be an empty linked list;
repeat with the routine record running through the routine record values matching the key N in the routine beginning hash table:
push the key the routine record onto the result;
decide on the result.
To decide what source line record is the source line record for line number (N - a number) (this is determining the source line record of a line number):
let the result be the first source line record value matching the key N in the source line record hash table or an invalid source line record if there are no matches;
if the result is not an invalid source line record or N is zero:
decide on the result;
load I6 line number N;
decide on the first source line record value matching the key N in the source line record hash table or an invalid source line record if there are no matches.
Definition: a number (called A) is a sequence point if the sequence point routine record hash table contains the key A.
To decide what routine record is the routine record owning the sequence point (S - a number) (this is determining the routine record of a sequence point):
decide on the first routine record value matching the key S in the sequence point routine record hash table or an invalid routine record if there are no matches.
To decide what number is the I6 line number for the sequence point (S - a number) (this is determining the I6 line number of a sequence point):
let the linked list vertex be the first match for the key S in the sequence point line number hash table;
if the linked list vertex is null:
decide on zero;
let the result be the number value of the linked list vertex;
if the result is less than zero:
decide on zero minus the result;
now the result is the relocation of the sequence point S from the line number the result;
write the value zero minus the result to the linked list vertex;
decide on the result.
To decide what number is the I6 line number for the sequence point (S - a number) supposedly in column number (C - a number) (this is determining the I6 line number of a sequence point with correction for labels):
let the linked list vertex be the first match for the key S in the sequence point line number hash table;
if the linked list vertex is null:
decide on zero;
let the result be the number value of the linked list vertex;
if the result is less than zero:
decide on zero minus the result;
now the result is the relocation of the sequence point S from the line number the result and the column number C;
write the value zero minus the result to the linked list vertex;
decide on the result.
To decide what number is the I7 line number for the sequence point (S - a number) in the routine record (R - a routine record) (this is determining the I7 line number of a sequence point in a known routine record):
let the beginning line number be the beginning line number of R;
let the end line number be the end line number of R;
let the result be the I6 line number for the sequence point S;
if the result is less than the beginning line number or the result is at least the end line number:
decide on zero;
let the source line record be the source line record for line number the result;
unless the I7 coda flag is set in the source line record:
while the result is at least the beginning line number:
now the source line record is the source line record for line number the result;
unless the I7 of the source line record is empty:
decide on the result;
decrement the result;
decide on the preamble line number of R.
[We don't ever use this internally. But other extension authors might want it.]
To decide what number is the I7 line number for the sequence point (S - a number) (this is determining the I7 line number of a sequence point):
let the routine record be the routine record owning the sequence point S;
if the routine record is an invalid routine record:
decide on zero;
decide on the I7 line number for the sequence point S in the routine record the routine record.
To decide what global record is the global record for I7 global index (I - a number) (this is determining the global record of an I7 global index):
decide on the first global record value matching the key I in the I7 global record hash table or an invalid global record if there are no matches.
To decide what linked list is a new list of global records matching the global name (T - some text) (this is creating a global record list for a global name):
let the result be an empty linked list;
repeat with the global record running through the global record values matching the textual key T in the global record lookup hash table:
push the key the global record onto the result;
decide on the result.
To decide what linked list is a new list of memory stack variable records matching the memory stack variable name (T - some text) (this is creating a memory stack variable record list for a memory stack variable name):
let the result be an empty linked list;
repeat with the memory stack variable record running through the memory stack variable record values matching the textual key T in the memory stack variable record lookup hash table:
push the key the memory stack variable record onto the result;
decide on the result.
To decide what linked list is a new list of object addresses matching the object name (T - some text) (this is creating an object address list for an object name):
let the result be an empty linked list;
repeat with the object number running through the number values matching the textual key T in the object number lookup hash table:
let the object address be the first number value matching the key the object number in the object address lookup hash table or zero if there are no matches;
push the key the object address onto the result;
decide on the result.
To decide what text is the debug plural of (T - some text) (this is determining a debug plural):
decide on the first text value matching the textual key T in the debug plural hash table or "" if there are no matches.
Book "Naming Helper Functions"
Chapter "Private Data Identifier Canonicalization Phrases" - unindexed
To say (A - a punctuated word array) as if it were a match made by a punctuated word parsing engine (this is saying a punctuated word array as if it were a match made by a punctuated word parsing engine):
let the first time flag be true;
repeat with the word running through A:
if the first time flag is true:
now the first time flag is false;
otherwise:
say " ";
say "[the word]".
To say the canonicalization of the data identifier (T - some text) (this is saying the canonicalization of a data identifier):
let the downcased identifier be a new synthetic text copied from T;
downcase the synthetic text the downcased identifier;
let the punctuated word array be a new punctuated word array for the synthetic text the downcased identifier;
delete the synthetic text the downcased identifier;
say the punctuated word array as if it were a match made by a punctuated word parsing engine;
delete the punctuated word array.
Chapter "Public Data Identifier Canonicalization Phrases" - unindexed
The identifier for canonicalizing identifiers is some text that varies.
To decide what text is a new canonicalization of the data identifier (T - some text) (this is creating a canonicalization of a data identifier):
now the identifier for canonicalizing identifiers is T;
decide on a new synthetic text copied from "[the canonicalization of the data identifier the identifier for canonicalizing identifiers]".
To decide what text is a new permanent canonicalization of the data identifier (T - some text) (this is creating a permanent canonicalization of a data identifier):
now the identifier for canonicalizing identifiers is T;
decide on a new permanent synthetic text copied from "[the canonicalization of the data identifier the identifier for canonicalizing identifiers]".
Book "The Infix Debug Stream" - unindexed
The Infix debug stream is a binary input file stream that varies.
Chapter "Infix Record Preprocessing" - unindexed
Section "Infix Record Preprocessor Array" - unindexed
Include (-
Constant DFP_INFIX_RECORD_COUNT = 15;
Array dfp_infixRecordPreprocessors --> DFP_INFIX_RECORD_COUNT;
-) after "Definitions.i6t".
To decide what number is the number of Infix record types: (- DFP_INFIX_RECORD_COUNT -).
To preprocess type (I - a number) Infix records by (P - a phrase nothing -> nothing): (- llo_setField(dfp_infixRecordPreprocessors, {I}, llo_getField({P}, 1)); -).
To preprocess a type (I - a number) Infix record: (- (llo_getField(dfp_infixRecordPreprocessors, {I}))(); -).
Section "Infix Record Types" - unindexed
To register the Infix record preprocessors (this is registering the Infix record preprocessors):
preprocess type 1 Infix records by preprocessing an Infix file record;
preprocess type 2 Infix records by preprocessing an Infix class record;
preprocess type 3 Infix records by preprocessing an Infix object record;
preprocess type 4 Infix records by preprocessing an Infix global record;
preprocess type 5 Infix records by preprocessing a common Infix [attribute] record;
preprocess type 6 Infix records by preprocessing a common Infix [property] record;
preprocess type 7 Infix records by preprocessing a common Infix [fake action] record;
preprocess type 8 Infix records by preprocessing a common Infix [action] record;
preprocess type 9 Infix records by preprocessing an Infix header record;
preprocess type 10 Infix records by preprocessing an Infix sequence point set record;
preprocess type 11 Infix records by preprocessing an Infix routine-beginning record;
preprocess type 12 Infix records by preprocessing a common Infix [array] record;
preprocess type 13 Infix records by preprocessing an Infix map record;
preprocess type 14 Infix records by preprocessing an Infix routine-ending record.
Section "Preprocessing File Debug Records" - unindexed
To preprocess an Infix file record (this is preprocessing an Infix file record):
let the file number be the next byte in the Infix debug stream;
if the file number is one:
skip the text in the Infix debug stream up through the next null terminator;
skip the text in the Infix debug stream up through the next null terminator;
otherwise:
skip the text in the Infix debug stream up through the next null terminator;
let the source file name be a new synthetic text extracted from the Infix debug stream until a null terminator;
fail at handling a second I6 source file named the source file name.
Section "Preprocessing Class Debug Records" - unindexed
To preprocess an Infix class record (this is preprocessing an Infix class record):
skip the text in the Infix debug stream up through the next null terminator;
skip eight bytes in the Infix debug stream.
Section "Preprocessing Object Debug Records" - unindexed
To preprocess an Infix object record (this is preprocessing an Infix object record):
skip two bytes in the Infix debug stream;
skip the text in the Infix debug stream up through the next null terminator;
skip eight bytes in the Infix debug stream.
Section "Preprocessing Global Debug Records" - unindexed
The minimum expected I6 global index for working around I6 global index overflow is a number that varies. The minimum expected I6 global index for working around I6 global index overflow is zero.
To decide what number is (N - a number) adjusted for I6 global index overflow (this is adjusting an I6 global index for overflow):
let the result be N;
while the result is less than the minimum expected I6 global index for working around I6 global index overflow:
increase the result by 256;
now the minimum expected I6 global index for working around I6 global index overflow is the result;
decide on the result.
To preprocess an Infix global record (this is preprocessing an Infix global record):
let the global index be the next byte in the Infix debug stream adjusted for I6 global index overflow;
let the global variable name be a new permanent synthetic text extracted from the Infix debug stream until a null terminator;
let the global record be a new I6 global record with index the global index and human-friendly name the global variable name;
let the downcased global variable name be a new permanent synthetic text copied from the global variable name;
downcase the synthetic text the downcased global variable name;
insert the textual key the downcased global variable name and the value the global record into the global record lookup hash table.
Section "Preprocessing Common Debug Records" - unindexed
To preprocess a common Infix record (this is preprocessing a common Infix record):
skip two bytes in the Infix debug stream;
skip the text in the Infix debug stream up through the next null terminator.
Section "Preprocessing Header Debug Records" - unindexed
[At the time of writing, the Inform 6 compiler doesn't actually emit these for Glulx, which can be unfortunate for us.]
To preprocess an Infix header record (this is preprocessing an Infix header record):
repeat with the index running from zero to 15:
let the integer address be the index times four;
let the expected integer be the integer at address integer address;
let the actual integer be the next integer in the Infix debug stream;
always check that the actual integer is the expected integer or else fail at matching the header of the debug information file.
Section "Adjusting for Line Number Overflow" - unindexed
[Line numbers occasionally decrease; we try to separate normal decreases from overflows by thresholding.]
To decide what number is the maximum line number backtrack: (- 2048 -).
The minimum expected line number for working around line number overflow is a number that varies. The minimum expected line number for working around line number overflow is zero.
To decide what number is (N - a number) adjusted for line number overflow (this is adjusting a line number for overflow):
let the result be N;
while the result is less than the minimum expected line number for working around line number overflow:
increase the result by 65536;
now the minimum expected line number for working around line number overflow is the result minus the maximum line number backtrack;
decide on the result.
To decide what number is (N - a number) adjusted for line number overflow with minimum (M - a number) (this is adjusting a line number for overflow when a minimum is known):
let the result be N;
while the result is less than M:
increase the result by 65536;
decide on the result.
Adjusting for line number overflow is a truth state that varies. Adjusting for line number overflow is true.
Section "Preprocessing Routine Debug Records" - unindexed
To decide what number is the base address for code: (- 60 -).
[Some routines have no valid line numbers; we can detect them by thresholding.]
To decide what number is the minimum line number: (- 2 -).
The last-seen routine record is a routine record that varies.
To preprocess an Infix routine-beginning record (this is preprocessing an Infix routine-beginning record):
let the stream position be the stream position of the Infix debug stream;
skip three bytes in the Infix debug stream;
let the beginning line number be the next short in the Infix debug stream;
skip one byte in the Infix debug stream;
let the function address be the base address for code plus the next triple in the Infix debug stream;
if adjusting for line number overflow is true:
if the function address is the address of I6_Print__PName or the beginning line number is less than the minimum line number and the function at address the function address is a veneer routine:
now the beginning line number is zero;
now adjusting for line number overflow is false;
otherwise:
now the beginning line number is the beginning line number adjusted for line number overflow;
otherwise:
now the beginning line number is zero;
skip the text in the Infix debug stream up through the next null terminator;
while the next byte in the Infix debug stream is not zero:
skip the text in the Infix debug stream up through the next null terminator;
now the last-seen routine record is a new routine record with function address function address and beginning line number beginning line number and beginning stream position stream position;
insert the key the function address and the value the last-seen routine record into the routine record hash table;
enqueue the key the function address and the value the last-seen routine record in the routine record list through the routine record list tail;
if the beginning line number is not zero:
insert the key the beginning line number and the value last-seen routine record into the routine beginning hash table.
To preprocess an Infix routine-ending record (this is preprocessing an Infix routine-ending record):
let the stream position be the stream position of the Infix debug stream;
skip three bytes in the Infix debug stream;
let the end line number be the next short in the Infix debug stream;
if adjusting for line number overflow is true:
now the end line number is the end line number adjusted for line number overflow;
otherwise:
now the end line number is zero;
if the end line number is less than the beginning line number of the last-seen routine record:
now the end line number is the beginning line number of the last-seen routine record;
skip four bytes in the Infix debug stream;
write the end line number end line number plus one to the last-seen routine record; [plus one to convert from a closed interval to a half-open interval]
write the end stream position stream position to the last-seen routine record.
Section "Preprocessing Sequence Point Set Debug Records" - unindexed
To preprocess an Infix sequence point set record (this is preprocessing an Infix sequence point set record):
let the stream position be the stream position of the Infix debug stream;
skip two bytes in the Infix debug stream;
let the sequence point count be the next short in the Infix debug stream;
write the sequence point stream position stream position to the last-seen routine record;
let the base address be the function address of the last-seen routine record;
repeat with the sequence point index running from one to the sequence point count:
skip one byte in the Infix debug stream;
let the line number be the next short in the Infix debug stream;
if adjusting for line number overflow is true:
now the line number is the line number adjusted for line number overflow;
otherwise:
now the line number is zero;
skip one byte in the Infix debug stream;
let the instruction address be the base address plus the next short in the Infix debug stream;