-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathheader.h
2929 lines (2587 loc) · 110 KB
/
header.h
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
/* ------------------------------------------------------------------------- */
/* Header file for Inform: Z-machine ("Infocom" format) compiler */
/* */
/* Inform 6.43 */
/* */
/* This header file and the others making up the Inform source code are */
/* copyright (c) Graham Nelson 1993 - 2024 */
/* */
/* Manuals for this language are available from the IF-Archive at */
/* https://www.ifarchive.org/ */
/* */
/* For notes on how this program may legally be used, see the Designer's */
/* Manual introduction. (Any recreational use is fine, and so is some */
/* commercial use.) */
/* */
/* For detailed documentation on how this program internally works, and */
/* how to port it to a new environment, see the Technical Manual. */
/* */
/* *** To compile this program in one of the existing ports, you must */
/* at least change the machine definition (on the next page). */
/* In most cases no other work will be needed. *** */
/* */
/* Contents: */
/* */
/* Machine/host OS definitions (in alphabetical order) */
/* Default definitions */
/* Standard ANSI inclusions, macro definitions, structures */
/* Definitions of internal code numbers */
/* Extern declarations for linkage (in alphabetical order of file) */
/* */
/* ------------------------------------------------------------------------- */
/* For releases, set to the release date in the form "1st January 2000" */
#define RELEASE_DATE "in development"
#define RELEASE_NUMBER 1643
#define GLULX_RELEASE_NUMBER 38
#define VNUMBER RELEASE_NUMBER
/* N indicates an intermediate release for Inform 7 */
/*#define RELEASE_SUFFIX "N"*/
/* ------------------------------------------------------------------------- */
/* Our host machine or OS for today is... */
/* */
/* [ Inform should compile (possibly with warnings) and work safely */
/* if you just: */
/* */
/* #define AMIGA - for the Commodore Amiga under SAS/C */
/* #define ARCHIMEDES - for Acorn RISC OS machines under Norcroft C */
/* #define ATARIST - for the Atari ST */
/* #define BEOS - for the BeBox */
/* #define LINUX - for Linux under gcc (essentially as Unix) */
/* #define MACOS - for the Apple Mac with OS X (another Unix) */
/* #define MAC_CLASSIC - for the Apple Mac under Think C or Codewarrior */
/* #define MAC_MPW - for MPW under Codewarrior (and maybe Think C) */
/* #define OS2 - for OS/2 32-bit mode under IBM's C Set++ */
/* #define PC - for 386+ IBM PCs, eg. Microsoft Visual C/C++ */
/* #define PC_QUICKC - for small IBM PCs under QuickC */
/* #define PC_WIN32 - for Borland C++ or Microsoft Visual C++ */
/* #define UNIX - for Unix under gcc (or big IBM PC under djgpp) */
/* #define VMS - for VAX or ALPHA under DEC C, but not VAX C */
/* */
/* In most cases executables are already available at */
/* https://www.ifarchive.org/, and these are sometimes enhanced with */
/* e.g. windowed interfaces whose source is not archived with the */
/* main Inform source.] */
/* */
/* (If no machine is defined, then cautious #defines will be made. In */
/* most cases, porting to a new machine is a matter of carefully filling */
/* out a block of definitions like those below.) */
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* The first task is to include the ANSI header files, and typedef */
/* suitable 32-bit integer types. */
/* ------------------------------------------------------------------------- */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <limits.h>
#include <math.h>
#ifndef VAX
#if SCHAR_MAX >= 0x7FFFFFFFL && SCHAR_MIN <= -0x7FFFFFFFL
typedef signed char int32;
typedef unsigned char uint32;
#elif SHRT_MAX >= 0x7FFFFFFFL && SHRT_MIN <= -0x7FFFFFFFL
typedef signed short int int32;
typedef unsigned short int uint32;
#elif INT_MAX >= 0x7FFFFFFFL && INT_MIN <= -0x7FFFFFFFL
typedef signed int int32;
typedef unsigned int uint32;
#elif LONG_MAX >= 0x7FFFFFFFL && LONG_MIN <= -0x7FFFFFFFL
typedef signed long int int32;
typedef unsigned long int uint32;
#else
#error No type large enough to support 32-bit integers.
#endif
#else
/* VAX C does not provide these limit constants, contrary to ANSI */
typedef int int32;
typedef unsigned int uint32;
#endif
/* ------------------------------------------------------------------------- */
/* The next part of this file contains blocks of definitions, one for */
/* each port, of machine or OS-dependent constants needed by Inform. */
/* */
/* 1. MACHINE_STRING should be set to the name of the machine or OS. */
/* */
/* 2. Some miscellaneous #define options (set if the constant is */
/* defined, otherwise not set): */
/* */
/* PROMPT_INPUT - prompt input (don't use Unix-style command line) */
/* TIME_UNAVAILABLE - don't use ANSI time routines to work out today's */
/* date */
/* CHAR_IS_UNSIGNED - if on your compiler the type "char" is unsigned */
/* by default, you should define this */
/* HAS_REALPATH - the POSIX realpath() function is available to */
/* find the absolute path to a file */
/* */
/* 3. This was DEFAULT_MEMORY_SIZE, now withdrawn. */
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* 4. Filenaming definitions: */
/* */
/* It's assumed that the host OS has the concept of subdirectories and */
/* has "pathnames", that is, filenames giving a chain of subdirectories */
/* divided by the FN_SEP (filename separator) character: e.g. for Unix */
/* FN_SEP is defined below as '/' and a typical name is */
/* "users/graham/jigsaw.z5". */
/* White space is not allowed in filenames, and nor is the special */
/* character FN_ALT, which unless defined here will be a comma and will */
/* be used to separate alternative locations in a path variable. */
/* */
/* If NO_FILE_EXTENSIONS is undefined then the OS allows "file extensions" */
/* of 1 to 3 alphanumeric characters like ".txt" (for text files), ".z5" */
/* (for game files), etc., to indicate the file's type (and, crucially, */
/* regards the same filename but with different extensions -- e.g., */
/* "frog.amp" and "frog.lil" -- as being different names). */
/* (The file extensions defined below are widely accepted, so please use */
/* them unless there's a good reason why not.) */
/* */
/* You should then define STANDARD_DIRECTORIES (you can define it anyway) */
/* in which case Inform will expect by default that files are sorted out */
/* by being put into suitable directories (e.g., a "games" directory for */
/* story files). */
/* */
/* If it's convenient for your port you can alter the detailed definitions */
/* which these broad settings make. Be careful if NO_FILE_EXTENSIONS */
/* is set without STANDARD_DIRECTORIES, as then Inform may */
/* overwrite its source with object code. */
/* */
/* 5. Filenames (or code related to filenames) for temporary files. */
/* These included Temporary_Name, Temporary_Directory, and */
/* INCLUDE_TASK_ID. These options have been removed, and are listed here */
/* only for people who might ask "what happened to 5?" */
/* */
/* 6. Any other definitions specific to the OS or machine. */
/* (In particular DEFAULT_ERROR_FORMAT is 0 on most machines and 1 on PCs; */
/* it controls the style of error messages, which is important for some */
/* error-throwback debugging tools.) */
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
/* The blocks now follow in alphabetical order. */
/* ------------------------------------------------------------------------- */
/* AMIGA block */
/* ------------------------------------------------------------------------- */
#ifdef AMIGA
/* 1 */
#define MACHINE_STRING "Amiga"
/* 4 */
#define FN_SEP '/'
#endif
/* ------------------------------------------------------------------------- */
/* ARCHIMEDES block: Acorn/RISC OS settings */
/* ------------------------------------------------------------------------- */
#ifdef ARCHIMEDES
/* 1 */
#define MACHINE_STRING "RISC OS"
/* 2 */
#define CHAR_IS_UNSIGNED
/* 4 */
#define FN_SEP '.'
#define STANDARD_DIRECTORIES
#define NO_FILE_EXTENSIONS
#define Source_Directory "inform"
#define ICL_Directory "ICL"
/* 6 */
#define ARC_THROWBACK
#endif
/* ------------------------------------------------------------------------- */
/* Atari ST block */
/* ------------------------------------------------------------------------- */
#ifdef ATARIST
/* 1 */
#define MACHINE_STRING "Atari ST"
/* 4 */
#define FN_SEP '/'
#endif
/* ------------------------------------------------------------------------- */
/* BEOS block */
/* ------------------------------------------------------------------------- */
#ifdef BEOS
/* 1 */
#define MACHINE_STRING "BeOS"
/* 4 */
#define FN_SEP '/'
#define FILE_EXTENSIONS
#endif
/* ------------------------------------------------------------------------- */
/* LINUX block */
/* ------------------------------------------------------------------------- */
#ifdef LINUX
/* 1 */
#define MACHINE_STRING "Linux"
/* 2 */
#define HAS_REALPATH
/* 4 */
#define FN_SEP '/'
/* 6 */
#define PATHLEN 8192
#if defined(__STDC__) && (__STDC_VERSION__ >= 201112L)
#define USE_C11_TIME_API
#endif
#endif
/* ------------------------------------------------------------------------- */
/* Macintosh block */
/* ------------------------------------------------------------------------- */
#ifdef MAC_MPW
#define MAC_CLASSIC
#endif
#ifdef MAC_CLASSIC
/* 1 */
#ifdef MAC_MPW
#define MACHINE_STRING "Macintosh Programmer's Workshop"
#else
#define MACHINE_STRING "Macintosh"
#endif
/* 2 */
#ifdef MAC_FACE
#define EXTERNAL_SHELL
#endif
#ifndef MAC_FACE
#ifndef MAC_MPW
#define PROMPT_INPUT
#endif
#endif
/* 4 */
#define FN_SEP ':'
#ifdef MAC_MPW
#define Include_Extension ".h"
#endif
/* 6 */
#ifdef MAC_FACE
#include "TB Inform.h"
#endif
#ifdef MAC_MPW
#include <CursorCtl.h>
#define DEFAULT_ERROR_FORMAT 2
#endif
#endif
/* ------------------------------------------------------------------------- */
/* OS/2 block */
/* ------------------------------------------------------------------------- */
#ifdef OS2
/* 1 */
#define MACHINE_STRING "OS/2"
/* 2 */
#define CHAR_IS_UNSIGNED
/* 4 */
#define FN_SEP '/'
#endif
/* ------------------------------------------------------------------------- */
/* MACOS block */
/* ------------------------------------------------------------------------- */
#ifdef MACOS
/* 1 */
#define MACHINE_STRING "MacOS"
/* 2 */
#define HAS_REALPATH
/* 4 */
#define FN_SEP '/'
/* 6 */
#define PATHLEN 8192
#if defined(__STDC__) && (__STDC_VERSION__ >= 201112L)
#define USE_C11_TIME_API
#endif
#endif
/* ------------------------------------------------------------------------- */
/* PC and PC_QUICKC block */
/* ------------------------------------------------------------------------- */
#ifdef PC_QUICKC
#define PC
#endif
#ifdef PC
/* 1 */
#define MACHINE_STRING "PC"
/* 4 */
#define FN_SEP '\\'
/* 6 */
#define DEFAULT_ERROR_FORMAT 1
#endif
/* ------------------------------------------------------------------------- */
/* PC_WIN32 block */
/* ------------------------------------------------------------------------- */
#ifdef PC_WIN32
/* 1 */
#define MACHINE_STRING "Win32"
/* 2 */
#define HAS_REALPATH
/* 4 */
#define FN_SEP '\\'
/* 6 */
#define DEFAULT_ERROR_FORMAT 1
#define PATHLEN 512
#if _MSC_VER >= 1920 /* Visual C++ 2019 */
#define USE_C11_TIME_API
#endif
#endif
/* ------------------------------------------------------------------------- */
/* UNIX block */
/* ------------------------------------------------------------------------- */
#ifdef UNIX
/* 1 */
#ifndef MACHINE_STRING
#define MACHINE_STRING "Unix"
#endif
/* 2 */
#define HAS_REALPATH
/* 4 */
#define FN_SEP '/'
#endif
/* ------------------------------------------------------------------------- */
/* VMS (Dec VAX and Alpha) block */
/* ------------------------------------------------------------------------- */
#ifdef __VMS
#define VMS
#endif
#ifdef VMS
/* 1 */
#ifdef __ALPHA
#define MACHINE_STRING "Alpha/VMS"
#else
#define MACHINE_STRING "VAX/VMS"
#endif
/* 2 */
#define CHAR_IS_UNSIGNED
/* 4 */
#define FN_SEP '/'
#define Code_Extension ".zip"
#define V4Code_Extension ".zip"
#define V5Code_Extension ".zip"
#define V6Code_Extension ".zip"
#define V7Code_Extension ".zip"
#define V8Code_Extension ".zip"
#endif
/* ========================================================================= */
/* Default settings: */
/* ------------------------------------------------------------------------- */
#ifndef NO_FILE_EXTENSIONS
#define FILE_EXTENSIONS
#endif
#ifndef Transcript_File
#ifdef FILE_EXTENSIONS
#define Transcript_File "gametext.txt"
#else
#define Transcript_File "gametext"
#endif
#endif
#ifndef Debugging_File
#ifdef FILE_EXTENSIONS
#define Debugging_File "gameinfo.dbg"
#else
#define Debugging_File "gamedebug"
#endif
#endif
#ifndef Default_Language
#define Default_Language "English"
#endif
#ifdef FILE_EXTENSIONS
#ifndef Source_Extension
#define Source_Extension ".inf"
#endif
#ifndef Include_Extension
#define Include_Extension ".h"
#endif
#ifndef Code_Extension
#define Code_Extension ".z3"
#endif
#ifndef V4Code_Extension
#define V4Code_Extension ".z4"
#endif
#ifndef V5Code_Extension
#define V5Code_Extension ".z5"
#endif
#ifndef V6Code_Extension
#define V6Code_Extension ".z6"
#endif
#ifndef V7Code_Extension
#define V7Code_Extension ".z7"
#endif
#ifndef V8Code_Extension
#define V8Code_Extension ".z8"
#endif
#ifndef GlulxCode_Extension
#define GlulxCode_Extension ".ulx"
#endif
#ifndef ICL_Extension
#define ICL_Extension ".icl"
#endif
#else
#define Source_Extension ""
#define Include_Extension ""
#define Code_Extension ""
#define V4Code_Extension ""
#define V5Code_Extension ""
#define V6Code_Extension ""
#define V7Code_Extension ""
#define V8Code_Extension ""
#define GlulxCode_Extension ""
#define ICL_Extension ""
#endif
#ifdef STANDARD_DIRECTORIES
#ifndef Source_Directory
#define Source_Directory "source"
#endif
#ifndef Include_Directory
#define Include_Directory "library"
#endif
#ifndef Code_Directory
#define Code_Directory "games"
#endif
#ifndef ICL_Directory
#define ICL_Directory ""
#endif
#else
#ifndef Source_Directory
#define Source_Directory ""
#endif
#ifndef Include_Directory
#define Include_Directory ""
#endif
#ifndef Code_Directory
#define Code_Directory ""
#endif
#ifndef ICL_Directory
#define ICL_Directory ""
#endif
#endif
#ifndef FN_SEP
#define FN_SEP '/'
#endif
#ifndef FN_ALT
#define FN_ALT ','
#endif
#ifndef PATHLEN
#define PATHLEN 128
#endif
#ifndef DEFAULT_ERROR_FORMAT
#define DEFAULT_ERROR_FORMAT 0
#endif
#ifndef CHAR_IS_UNSIGNED
typedef unsigned char uchar;
#else
typedef char uchar;
#endif
#if defined(__GNUC__) || defined(__clang__)
#define NORETURN __attribute__((__noreturn__))
#endif /* defined(__GNUC__) || defined(__clang__) */
#if defined(_MSC_VER)
#define NORETURN_PRE __declspec(noreturn)
#endif
#ifndef NORETURN
#define NORETURN
#endif
#ifndef NORETURN_PRE
#define NORETURN_PRE
#endif
/* ------------------------------------------------------------------------- */
/* subtract_pointers() measures an address difference in bytes. This is */
/* a macro. */
/* We also declare some memory functions for PC_QUICKC. */
/* ------------------------------------------------------------------------- */
#ifdef PC_QUICKC
void _huge * halloc(long, size_t);
void hfree(void *);
#define subtract_pointers(p1,p2) (long)((char _huge *)p1-(char _huge *)p2)
#else
#define subtract_pointers(p1,p2) (((char *) p1)-((char *) p2))
#endif
/* ------------------------------------------------------------------------- */
/* Definitions for time measurement. TIMEVALUE is a type; TIMEVALUE_NOW() */
/* sets it; TIMEVALUE_DIFFERENCE() determines a difference in seconds, */
/* as a float. */
/* Modern platforms should support timespec_get() or clock_gettime(). To */
/* use timespec_get(), #define USE_C11_TIME_API. To use clock_gettime(), */
/* #define USE_POSIX_TIME_API. To use the old implementation using */
/* time(), #define USE_OLD_TIME_API. This can only measure in integer */
/* second counts, but it's better than waiting for gnomon. */
/* ------------------------------------------------------------------------- */
#if !defined(USE_C11_TIME_API) && !defined(USE_POSIX_TIME_API) && !defined(USE_OLD_TIME_API)
#define USE_OLD_TIME_API
#endif
#if defined(USE_OLD_TIME_API)
#define TIMEVALUE time_t
#define TIMEVALUE_NOW(t) (*t) = time(0)
#define TIMEVALUE_DIFFERENCE(begt, endt) (float)(*(endt) - *(begt))
#elif defined(USE_C11_TIME_API)
#define TIMEVALUE struct timespec
#define TIMEVALUE_NOW(t) timespec_get((t), TIME_UTC)
#define TIMEVALUE_DIFFERENCE(begt, endt) ((float)((endt)->tv_sec - (begt)->tv_sec) + (float)((endt)->tv_nsec - (begt)->tv_nsec) / 1000000000.0F)
#elif defined(USE_POSIX_TIME_API)
#define TIMEVALUE struct timespec
#define TIMEVALUE_NOW(t) clock_gettime(CLOCK_REALTIME, (t))
#define TIMEVALUE_DIFFERENCE(begt, endt) ((float)((endt)->tv_sec - (begt)->tv_sec) + (float)((endt)->tv_nsec - (begt)->tv_nsec) / 1000000000.0F)
#endif
/* ------------------------------------------------------------------------- */
/* SEEK_SET is a constant which should be defined in the ANSI header files */
/* but which is not present in some implementations: it's used as a */
/* parameter for "fseek", defined in "stdio". In pre-ANSI C, the value */
/* 0 was used as a parameter instead, hence the definition below. */
/* ------------------------------------------------------------------------- */
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
/* ------------------------------------------------------------------------- */
/* A large block of #define'd constant values follows. */
/* ------------------------------------------------------------------------- */
#define TRUE -1
#define FALSE 0
/* These checked the glulx_mode global during development, but are no
longer needed. */
#define ASSERT_ZCODE()
#define ASSERT_GLULX()
#define ReadInt32(ptr) \
( (((uint32)(((uchar *)(ptr))[0])) << 24) \
| (((uint32)(((uchar *)(ptr))[1])) << 16) \
| (((uint32)(((uchar *)(ptr))[2])) << 8) \
| (((uint32)(((uchar *)(ptr))[3])) ) )
#define ReadInt16(ptr) \
( (((uint32)(((uchar *)(ptr))[0])) << 8) \
| (((uint32)(((uchar *)(ptr))[1])) ) )
#define WriteInt32(ptr, val) \
((ptr)[0] = (uchar)(((int32)(val)) >> 24), \
(ptr)[1] = (uchar)(((int32)(val)) >> 16), \
(ptr)[2] = (uchar)(((int32)(val)) >> 8), \
(ptr)[3] = (uchar)(((int32)(val)) ) )
#define WriteInt16(ptr, val) \
((ptr)[0] = (uchar)(((int32)(val)) >> 8), \
(ptr)[1] = (uchar)(((int32)(val)) ) )
/* ------------------------------------------------------------------------- */
/* If your compiler doesn't recognise \t, and you use ASCII, you could */
/* define T_C as (char) 9; failing that, it _must_ be defined as ' ' */
/* (space) and is _not_ allowed to be 0 or any recognisable character. */
/* ------------------------------------------------------------------------- */
#define TAB_CHARACTER '\t'
/* ------------------------------------------------------------------------- */
/* Maxima. */
/* ------------------------------------------------------------------------- */
#define MAX_ERRORS 100
#define MAX_NUM_ATTR_BYTES 39
#define VENEER_CONSTRAINT_ON_CLASSES_Z 256
#define VENEER_CONSTRAINT_ON_IP_TABLE_SIZE_Z 128
#define VENEER_CONSTRAINT_ON_CLASSES_G 32768
#define VENEER_CONSTRAINT_ON_IP_TABLE_SIZE_G 32768
#define VENEER_CONSTRAINT_ON_CLASSES \
(glulx_mode ? VENEER_CONSTRAINT_ON_CLASSES_G \
: VENEER_CONSTRAINT_ON_CLASSES_Z)
#define VENEER_CONSTRAINT_ON_IP_TABLE_SIZE \
(glulx_mode ? VENEER_CONSTRAINT_ON_IP_TABLE_SIZE_G \
: VENEER_CONSTRAINT_ON_IP_TABLE_SIZE_Z)
#define GLULX_HEADER_SIZE 36
/* Number of bytes in the header. */
#define GLULX_STATIC_ROM_SIZE 24
/* Number of bytes in the Inform-specific block right after the header. */
#define GPAGESIZE 256
/* All Glulx memory boundaries must be multiples of GPAGESIZE. */
/* ------------------------------------------------------------------------- */
/* Structure definitions (there are a few others local to files) */
/* ------------------------------------------------------------------------- */
/* A memory list is a sequential array of items. The list grows as
necessary, but it is *not* sparse.
This can optionally maintain an external pointer (of any type) which
also refers to the allocated array. The external pointer will always
have the same value as data.
(Note: the external pointer must itself have a stable location, because
we keep a pointer *to* it. It cannot live in another memory list or
realloced array. Most of our memory lists refer to global or static
variables, so that's fine.)
*/
typedef struct memory_list_s
{
char *whatfor; /* must be a static string */
void *data; /* allocated array of count*itemsize bytes */
void **extpointer; /* pointer to keep in sync */
size_t itemsize; /* item size in bytes */
size_t count; /* number of items allocated */
} memory_list;
typedef struct brief_location_s
{ int32 file_index;
int32 line_number;
int32 orig_file_index;
int32 orig_line_number;
} brief_location;
typedef struct assembly_operand_t
{ int type; /* ?_OT value */
int32 value;
int symindex; /* index in symbols array, if derived from a symbol */
int marker; /* ?_MV value */
} assembly_operand;
#define INITAOTV(aop, typ, val) ((aop)->type=(typ), (aop)->value=(val), (aop)->marker=0, (aop)->symindex=-1)
#define INITAOT(aop, typ) INITAOTV(aop, typ, 0)
#define INITAO(aop) INITAOTV(aop, 0, 0)
typedef struct variableinfo_s {
int32 token; /* Symbol table index for variable name */
int usage; /* TRUE if referred to */
} variableinfo;
typedef struct verbt {
int lines;
int *l; /* alloced array of grammar line indexes
(positions in grammar_lines[]) */
int size; /* allocated size of l */
brief_location line; /* originally defined at */
int used; /* only set at locate_dead_grammar_lines() time */
} verbt;
typedef struct actioninfo_s {
int32 symbol; /* The symbol table index of the action name */
int32 byte_offset; /* The (byte) offset in the Z-machine code area of
the ...Sub routine */
int meta; /* Only used if $GRAMMAR_META_FLAG */
} actioninfo;
typedef struct actionsort_s {
int internal_to_ext;
int external_to_int;
} actionsort;
/* Information about an object class. */
typedef struct classinfo_s {
/* The number of the prototype-object for this class */
int object_number;
/* The offset of properties block for this class (always an offset inside the properties table) */
int32 begins_at;
/* Class name symbol number */
int32 symbol;
} classinfo;
/* Common property information. */
typedef struct commonpropinfo_s {
int32 default_value; /* Common property default value */
int is_long; /* "Long" means "never write a 1-byte value to
this property", and is an obsolete feature:
since Inform 5 all properties have been "long" */
int is_additive; /* "Additive" means that values accumulate rather
than erase each other during class inheritance */
} commonpropinfo;
/* Property entry record (Z). */
typedef struct prop {
uchar l, num;
assembly_operand ao[32];
} prop;
/* Properties and attributes of the object currently being constructed (Z). */
/* Only one of this object. */
typedef struct fpropt {
uchar atts[6];
int l;
prop pp[64];
int32 symbol; /* name symbol or 0 */
} fpropt;
/* Constructed object (Z). */
typedef struct objecttz {
uchar atts[6];
int parent, next, child;
int propsize;
int32 symbol; /* name symbol or 0 */
} objecttz;
/* Property entry record (G). */
typedef struct propg {
int num;
int continuation;
int flags;
int32 datastart;
int32 datalen;
} propg;
/* Properties and attributes of the object currently being constructed (G). */
/* Only one of this object. */
typedef struct fproptg {
uchar atts[MAX_NUM_ATTR_BYTES];
int numprops;
propg *props; /* allocated to numprops */
memory_list props_memlist;
int propdatasize;
assembly_operand *propdata; /* allocated to propdatasize */
memory_list propdata_memlist;
int32 finalpropaddr;
/* It's safe to use memory_lists in this object because there's just
one and it's static. */
int32 symbol; /* name symbol or 0 */
} fproptg;
/* Constructed object (G). */
typedef struct objecttg {
/* attributes are stored in a separate array */
int32 shortname;
int32 parent, next, child;
int32 propaddr;
int32 propsize;
int32 symbol; /* name symbol or 0 */
} objecttg;
typedef struct abbreviation_s {
int value;
int quality;
int freq;
int textpos; /* in abbreviations_text */
int textlen;
} abbreviation;
typedef struct maybe_file_position_S
{ int valid;
fpos_t position;
} maybe_file_position;
typedef struct debug_location_s
{ int32 file_index;
int32 beginning_byte_index;
int32 end_byte_index;
int32 beginning_line_number;
int32 end_line_number;
int32 beginning_character_number;
int32 end_character_number;
int32 orig_file_index;
int32 orig_beg_line_number;
int32 orig_beg_char_number;
/* We only track the beginning #origsource location, not the end. */
} debug_location;
typedef struct debug_locations_s
{ debug_location location;
struct debug_locations_s *next;
int reference_count;
} debug_locations;
typedef struct debug_location_beginning_s
{ debug_locations *head;
int32 beginning_byte_index;
int32 beginning_line_number;
int32 beginning_character_number;
int32 orig_file_index;
int32 orig_beg_line_number;
int32 orig_beg_char_number;
} debug_location_beginning;
#define MAX_KEYWORD_GROUP_SIZE (159)
typedef struct keyword_group_s
{ char *keywords[MAX_KEYWORD_GROUP_SIZE+1]; /* empty-string-terminated */
int change_token_type;
int enabled;
int case_sensitive;
} keyword_group;
typedef struct lexeme_data_s {
char *text; /* points at lextexts array */
int32 value;
int type; /* a *_TT value */
int newsymbol; /* (for SYMBOL_TT) this token created the symbol */
debug_location location;
int lextext; /* index of text string in lextexts */
int context; /* lexical context used to interpret this token */
} lexeme_data;
typedef struct token_data_s {
char *text;
int32 value;
int type; /* a *_TT value */
int symindex;
int symtype;
int symflags;
int marker;
} token_data;
typedef struct symbolinfo_s {
char *name; /* Points into a symbol_name_space_chunk */
int32 value;
int marker; /* ?_MV value */
brief_location line;
unsigned int flags; /* ?_SFLAGS bitmask */
uchar type; /* ?_T value */
int next_entry; /* Linked list for symbol hash table */
} symbolinfo;
typedef struct symboldebuginfo_s {
maybe_file_position backpatch_pos;
maybe_file_position replacement_backpatch_pos;
} symboldebuginfo;
typedef struct arrayinfo_s {
int32 symbol; /* index in symbols[] */
int size; /* length of array */
int type; /* BYTE_ARRAY, WORD_ARRAY, etc */
int loc; /* true for static, false for dynamic (regular) arrays */
} arrayinfo;
typedef struct labelinfo_s {
int32 offset; /* Offset (zmachine_pc) value */
int32 symbol; /* Symbol numbers if defined in source */
int next; /* For linked list */
int prev; /* For linked list */
} labelinfo;
typedef struct sequencepointinfo_s {
int label; /* Label number */
debug_location location; /* Source code reference (used for making
debugging file) */
} sequencepointinfo;
typedef struct FileId_s /* Source code file identifier: */
{ char *filename; /* The filename (after translation) */
FILE *handle; /* Handle of file (when open), or
NULL when closed */
int is_input; /* Is this a source file that we are
parsing? If not, this is an
origsource filename (and handle
is NULL). */
int initial_buffering; /* Are we still in the initial
begin_buffering_file() call? */
} FileId;
typedef struct ErrorPosition_s
{ int file_number;
char *source;
int line_number;
int main_flag;
int orig_file;
char *orig_source;
int32 orig_line;
int32 orig_char;
} ErrorPosition;
/* This serves for both Z-code and Glulx instructions. Glulx doesn't use
the text, store_variable_number, branch_label_number, or branch_flag
fields. */
typedef struct assembly_instruction_t
{ int internal_number;
int store_variable_number;
int32 branch_label_number;
int branch_flag;
char *text; /* if set, generally points to token_text */
int operand_count;
assembly_operand operand[8];
} assembly_instruction;
typedef struct expression_tree_node_s
{
/* Data used in tree construction */
int up, down, right;
int operator_number; /* Only meaningful for non-leaves */
assembly_operand value; /* Only meaningful for leaves */
/* Attributes synthesised during code generation */
int must_produce_value; /* e.g. FALSE in a void context */
int label_after; /* -1, or "put this label after code" */
int to_expression; /* TRUE if a condition used as numeric val */
int true_label; /* On condition "true", jump to this (or keep
going if -1) */
int false_label; /* Likewise if the condition is "false". */
} expression_tree_node;
typedef struct operator_s
{ int precedence; /* Level 0 to 13 (13 is highest) */
int token_type; /* Lexical token type */
int token_value; /* Lexical token value */
int usage; /* Infix (IN_U), prefix or postfix */
int associativity; /* Left (L_A), right (R_A)
or 0 for "it is an error to
implicitly associate this" */
int requires_lvalue; /* TRUE if the first operand must
be an "lvalue" (the name of some
storage object, such as a variable
or an array entry) */
int opcode_number_z; /* Translation number (see below) */
int opcode_number_g; /* Translation number (see below) */
int side_effect; /* TRUE if evaluating the operator
has potential side-effects in
terms of changing the Z-machine */
int negation; /* 0 for an unconditional operator,
otherwise the negation operator */
char *description; /* Text describing the operator
for error messages and tracing */
} operator;
/* The translation number of an operator is as follows:
Z-code:
an internal opcode number if the operator can be translated
directly to a single Z-machine opcode;
400+n if it can be translated to branch opcode n;
800+n if to the negated form of branch opcode n;
(using n = 200, 201 for two conditions requiring special
translation)
-1 otherwise
Glulx:
an internal opcode number if the operator can be translated
directly to a single Glulx opcode;
FIRST_CC to LAST_CC if it is a condition;
-1 otherwise */
/* ------------------------------------------------------------------------- */
/* Assembly operand types. */
/* ------------------------------------------------------------------------- */
/* For Z-machine... */
#define LONG_CONSTANT_OT 0 /* General constant */
#define SHORT_CONSTANT_OT 1 /* Constant in range 0 to 255 */
#define VARIABLE_OT 2 /* Variable (global, local or sp) */
#define OMITTED_OT 3 /* Value used in type field to indicate
that no operand is supplied */
#define EXPRESSION_OT 4 /* Meaning: to determine this value, run code
equivalent to the expression tree whose
root node-number is the value given */
/* For Glulx... */
/* #define OMITTED_OT 3 */ /* Same as above */
/* #define EXPRESSION_OT 4 */ /* Same as above */
#define CONSTANT_OT 5 /* Four-byte constant */
#define HALFCONSTANT_OT 6 /* Two-byte constant */
#define BYTECONSTANT_OT 7 /* One-byte constant */
#define ZEROCONSTANT_OT 8 /* Constant zero (no bytes of data) */
#define SYSFUN_OT 9 /* System function value */