1733Speter /* Copyright (c) 1979 Regents of the University of California */ 2733Speter 3*6358Speter /* static char sccsid[] = "@(#)0.h 1.14 03/29/82"; */ 4733Speter 5733Speter #define DEBUG 63071Smckusic #define CONSETS 7733Speter #define CHAR 8733Speter #define STATIC 9733Speter #define hp21mx 0 10733Speter 11733Speter #include <stdio.h> 12733Speter #include <sys/types.h> 13733Speter 143071Smckusic typedef enum {FALSE, TRUE} bool; 15733Speter 16733Speter /* 17733Speter * Option flags 18733Speter * 19733Speter * The following options are recognized in the text of the program 20733Speter * and also on the command line: 21733Speter * 22733Speter * b block buffer the file output 23733Speter * 24733Speter * i make a listing of the procedures and functions in 25733Speter * the following include files 26733Speter * 27733Speter * l make a listing of the program 28733Speter * 29733Speter * n place each include file on a new page with a header 30733Speter * 31733Speter * p disable post mortem and statement limit counting 32733Speter * 33733Speter * t disable run-time tests 34733Speter * 35733Speter * u card image mode; only first 72 chars of input count 36733Speter * 37733Speter * w suppress special diagnostic warnings 38733Speter * 39733Speter * z generate counters for an execution profile 40733Speter */ 41733Speter #ifdef DEBUG 42733Speter bool fulltrace, errtrace, testtrace, yyunique; 43733Speter #endif DEBUG 44733Speter 45733Speter /* 46733Speter * Each option has a stack of 17 option values, with opts giving 47733Speter * the current, top value, and optstk the value beneath it. 48733Speter * One refers to option `l' as, e.g., opt('l') in the text for clarity. 49733Speter */ 50733Speter char opts[ 'z' - 'A' + 1]; 51733Speter short optstk[ 'z' - 'A' + 1]; 52733Speter 53733Speter #define opt(c) opts[c-'A'] 54733Speter 55733Speter /* 56733Speter * Monflg is set when we are generating 57733Speter * a pxp profile. this is set by the -z command line option. 58733Speter */ 59733Speter bool monflg; 60733Speter 61733Speter /* 62733Speter * profflag is set when we are generating a prof profile. 63733Speter * this is set by the -p command line option. 64733Speter */ 65733Speter bool profflag; 66733Speter 67733Speter 68733Speter /* 69733Speter * NOTES ON THE DYNAMIC NATURE OF THE DATA STRUCTURES 70733Speter * 71733Speter * Pi uses expandable tables for 72733Speter * its namelist (symbol table), string table 73733Speter * hash table, and parse tree space. The following 74733Speter * definitions specify the size of the increments 75733Speter * for these items in fundamental units so that 76733Speter * each uses approximately 1024 bytes. 77733Speter */ 78733Speter 79733Speter #define STRINC 1024 /* string space increment */ 80733Speter #define TRINC 512 /* tree space increment */ 81733Speter #define HASHINC 509 /* hash table size in words, each increment */ 82733Speter #define NLINC 56 /* namelist increment size in nl structs */ 83733Speter 84733Speter /* 85733Speter * The initial sizes of the structures. 86733Speter * These should be large enough to compile 87733Speter * an "average" sized program so as to minimize 88733Speter * storage requests. 89733Speter * On a small system or and 11/34 or 11/40 90733Speter * these numbers can be trimmed to make the 91733Speter * compiler smaller. 92733Speter */ 93733Speter #define ITREE 2000 94733Speter #define INL 200 95733Speter #define IHASH 509 96733Speter 97733Speter /* 98733Speter * The following limits on hash and tree tables currently 99733Speter * allow approximately 1200 symbols and 20k words of tree 100733Speter * space. The fundamental limit of 64k total data space 101733Speter * should be exceeded well before these are full. 102733Speter */ 103733Speter /* 104733Speter * TABLE_MULTIPLIER is for uniformly increasing the sizes of the tables 105733Speter */ 1063071Smckusic #ifdef VAX 107733Speter #define TABLE_MULTIPLIER 8 1083071Smckusic #else 1093071Smckusic #define TABLE_MULTIPLIER 1 1103071Smckusic #endif VAX 111733Speter #define MAXHASH (4 * TABLE_MULTIPLIER) 112733Speter #define MAXNL (12 * TABLE_MULTIPLIER) 113733Speter #define MAXTREE (30 * TABLE_MULTIPLIER) 114733Speter /* 115733Speter * MAXDEPTH is the depth of the parse stack. 116733Speter * STACK_MULTIPLIER is for increasing its size. 117733Speter */ 1183071Smckusic #ifdef VAX 119733Speter #define STACK_MULTIPLIER 8 1203071Smckusic #else 1213071Smckusic #define STACK_MULTIPLIER 1 1223071Smckusic #endif VAX 123733Speter #define MAXDEPTH ( 150 * STACK_MULTIPLIER ) 124733Speter 125733Speter /* 126733Speter * ERROR RELATED DEFINITIONS 127733Speter */ 128733Speter 129733Speter /* 130733Speter * Exit statuses to pexit 131733Speter * 132733Speter * AOK 133733Speter * ERRS Compilation errors inhibit obj productin 134733Speter * NOSTART Errors before we ever got started 135733Speter * DIED We ran out of memory or some such 136733Speter */ 137733Speter #define AOK 0 138733Speter #define ERRS 1 139733Speter #define NOSTART 2 140733Speter #define DIED 3 141733Speter 142733Speter bool Recovery; 143733Speter 144733Speter #define eholdnl() Eholdnl = 1 145733Speter #define nocascade() Enocascade = 1 146733Speter 147733Speter bool Eholdnl, Enocascade; 148733Speter 149733Speter 150733Speter /* 151733Speter * The flag eflg is set whenever we have a hard error. 152733Speter * The character in errpfx will precede the next error message. 153733Speter * When cgenflg is set code generation is suppressed. 154733Speter * This happens whenver we have an error (i.e. if eflg is set) 155733Speter * and when we are walking the tree to determine types only. 156733Speter */ 157733Speter bool eflg; 158733Speter char errpfx; 159733Speter 160733Speter #define setpfx(x) errpfx = x 161733Speter 162733Speter #define standard() setpfx('s') 163733Speter #define warning() setpfx('w') 164733Speter #define recovered() setpfx('e') 165*6358Speter #define continuation() setpfx(' ') 166733Speter 1673071Smckusic int cgenflg; 168733Speter 169733Speter 170733Speter /* 171733Speter * The flag syneflg is used to suppress the diagnostics of the form 172733Speter * E 10 a, defined in someprocedure, is neither used nor set 173733Speter * when there were syntax errors in "someprocedure". 174733Speter * In this case, it is likely that these warinings would be spurious. 175733Speter */ 176733Speter bool syneflg; 177733Speter 178733Speter /* 179733Speter * The compiler keeps its error messages in a file. 180733Speter * The variable efil is the unit number on which 181733Speter * this file is open for reading of error message text. 182733Speter * Similarly, the file ofil is the unit of the file 183733Speter * "obj" where we write the interpreter code. 184733Speter */ 185733Speter short efil; 186733Speter short ofil; 187733Speter short obuf[518]; 188733Speter 1893071Smckusic bool Enoline; 1903071Smckusic #define elineoff() Enoline = TRUE 1913071Smckusic #define elineon() Enoline = FALSE 192733Speter 193733Speter 194733Speter /* 195733Speter * SYMBOL TABLE STRUCTURE DEFINITIONS 196733Speter * 197733Speter * The symbol table is henceforth referred to as the "namelist". 198733Speter * It consists of a number of structures of the form "nl" below. 199733Speter * These are contained in a number of segments of the symbol 200733Speter * table which are dynamically allocated as needed. 201733Speter * The major namelist manipulation routines are contained in the 202733Speter * file "nl.c". 203733Speter * 204733Speter * The major components of a namelist entry are the "symbol", giving 205733Speter * a pointer into the string table for the string associated with this 206733Speter * entry and the "class" which tells which of the (currently 19) 207733Speter * possible types of structure this is. 208733Speter * 209733Speter * Many of the classes use the "type" field for a pointer to the type 210733Speter * which the entry has. 211733Speter * 212733Speter * Other pieces of information in more than one class include the block 213733Speter * in which the symbol is defined, flags indicating whether the symbol 214733Speter * has been used and whether it has been assigned to, etc. 215733Speter * 216733Speter * A more complete discussion of the features of the namelist is impossible 217733Speter * here as it would be too voluminous. Refer to the "PI 1.0 Implementation 218733Speter * Notes" for more details. 219733Speter */ 220733Speter 221733Speter /* 222733Speter * The basic namelist structure. 223733Speter * There are also two other variants, defining the real 224733Speter * field as longs or integers given below. 225733Speter * 226733Speter * The array disptab defines the hash header for the symbol table. 227733Speter * Symbols are hashed based on the low 6 bits of their pointer into 228733Speter * the string table; see the routines in the file "lookup.c" and also "fdec.c" 229733Speter * especially "funcend". 230733Speter */ 2313220Smckusic extern struct nl *Fp; 2323220Smckusic extern int pnumcnt; 2333220Smckusic 234733Speter #ifdef PTREE 235733Speter # include "pTree.h" 236733Speter #endif PTREE 237733Speter struct nl { 238733Speter char *symbol; 239733Speter char class, nl_flags; 240733Speter #ifdef PC 2413823Speter char extra_flags; /* for where things are */ 242733Speter #endif PC 243733Speter struct nl *type; 244733Speter struct nl *chain, *nl_next; 2453296Smckusic int value[5]; 246733Speter # ifdef PTREE 247733Speter pPointer inTree; 248733Speter # endif PTREE 249733Speter } *nlp, *disptab[077+1]; 250733Speter 251733Speter extern struct nl nl[INL]; 252733Speter 253733Speter struct { 254733Speter char *symbol; 255733Speter char class, nl_flags; 256733Speter #ifdef PC 2573823Speter char extra_flags; 258733Speter #endif 259733Speter struct nl *type; 260733Speter struct nl *chain, *nl_next; 261733Speter double real; 262733Speter }; 263733Speter 264733Speter struct { 265733Speter char *symbol; 266733Speter char class, nl_block; 267733Speter #ifdef PC 2683823Speter char extra_flags; 269733Speter #endif 270733Speter struct nl *type; 271733Speter struct nl *chain, *nl_next; 272733Speter long range[2]; 273733Speter }; 274733Speter 275733Speter struct { 276733Speter char *symbol; 277733Speter char class, nl_flags; 278733Speter #ifdef PC 2793823Speter char extra_flags; 280733Speter #endif 281733Speter struct nl *type; 282733Speter struct nl *chain, *nl_next; 2833296Smckusic int *ptr[4]; 2843296Smckusic #ifdef PI 2853296Smckusic int entloc; 2863296Smckusic #endif PI 287733Speter }; 2883370Speter 289733Speter /* 290733Speter * NL FLAGS BITS 291733Speter * 292733Speter * Definitions of the usage of the bits in 293733Speter * the nl_flags byte. Note that the low 5 bits of the 294733Speter * byte are the "nl_block" and that some classes make use 295733Speter * of this byte as a "width". 296733Speter * 297733Speter * The only non-obvious bit definition here is "NFILES" 298733Speter * which records whether a structure contains any files. 299733Speter * Such structures are not allowed to be dynamically allocated. 300733Speter */ 3013370Speter 3023370Speter #define BLOCKNO( flag ) ( flag & 037 ) 3033370Speter #define NLFLAGS( flag ) ( flag &~ 037 ) 3043370Speter 305733Speter #define NUSED 0100 306733Speter #define NMOD 0040 307733Speter #define NFORWD 0200 308733Speter #define NFILES 0200 309733Speter #ifdef PC 310733Speter #define NEXTERN 0001 /* flag used to mark external funcs and procs */ 3113823Speter #define NLOCAL 0002 /* variable is a local */ 3123823Speter #define NPARAM 0004 /* variable is a parameter */ 3133823Speter #define NGLOBAL 0010 /* variable is a global */ 3143823Speter #define NREGVAR 0020 /* or'ed in if variable is in a register */ 3153823Speter #endif PC 3163370Speter 3173540Speter /* 3183540Speter * used to mark value[ NL_FORV ] for loop variables 3193540Speter */ 3203540Speter #define FORVAR 1 321733Speter 322733Speter /* 323733Speter * Definition of the commonly used "value" fields. 324733Speter * The most important one is NL_OFFS which gives 325733Speter * the offset of a variable in its stack mark. 326733Speter */ 327733Speter #define NL_OFFS 0 328733Speter 329733Speter #define NL_CNTR 1 3303296Smckusic #define NL_NLSTRT 2 3313296Smckusic #define NL_LINENO 3 332733Speter #define NL_FVAR 3 3333296Smckusic #define NL_FCHAIN 4 334733Speter 335733Speter #define NL_GOLEV 2 336733Speter #define NL_GOLINE 3 337733Speter #define NL_FORV 1 338733Speter 339733Speter #define NL_FLDSZ 1 340733Speter #define NL_VARNT 2 341733Speter #define NL_VTOREC 2 342733Speter #define NL_TAG 3 343733Speter 3443071Smckusic #define NL_ELABEL 4 345733Speter 346733Speter /* 347733Speter * For BADUSE nl structures, NL_KINDS is a bit vector 348733Speter * indicating the kinds of illegal usages complained about 349733Speter * so far. For kind of bad use "kind", "1 << kind" is set. 350733Speter * The low bit is reserved as ISUNDEF to indicate whether 351733Speter * this identifier is totally undefined. 352733Speter */ 353733Speter #define NL_KINDS 0 354733Speter 355733Speter #define ISUNDEF 1 3563275Smckusic 3573823Speter /* 3583823Speter * variables come in three flavors: globals, parameters, locals; 3593823Speter * they can also hide in registers, but that's a different flag 3603823Speter */ 3613275Smckusic #define PARAMVAR 1 3623275Smckusic #define LOCALVAR 2 3633823Speter #define GLOBALVAR 3 364733Speter 365733Speter /* 366733Speter * NAMELIST CLASSES 367733Speter * 368733Speter * The following are the namelist classes. 369733Speter * Different classes make use of the value fields 370733Speter * of the namelist in different ways. 371733Speter * 372733Speter * The namelist should be redesigned by providing 373733Speter * a number of structure definitions with one corresponding 374733Speter * to each namelist class, ala a variant record in Pascal. 375733Speter */ 376733Speter #define BADUSE 0 377733Speter #define CONST 1 378733Speter #define TYPE 2 379733Speter #define VAR 3 380733Speter #define ARRAY 4 381733Speter #define PTRFILE 5 382733Speter #define RECORD 6 383733Speter #define FIELD 7 384733Speter #define PROC 8 385733Speter #define FUNC 9 386733Speter #define FVAR 10 387733Speter #define REF 11 388733Speter #define PTR 12 389733Speter #define FILET 13 390733Speter #define SET 14 391733Speter #define RANGE 15 392733Speter #define LABEL 16 393733Speter #define WITHPTR 17 394733Speter #define SCAL 18 395733Speter #define STR 19 396733Speter #define PROG 20 397733Speter #define IMPROPER 21 398733Speter #define VARNT 22 3991194Speter #define FPROC 23 4001194Speter #define FFUNC 24 401733Speter 402733Speter /* 403733Speter * Clnames points to an array of names for the 404733Speter * namelist classes. 405733Speter */ 406733Speter char **clnames; 407733Speter 408733Speter /* 409733Speter * PRE-DEFINED NAMELIST OFFSETS 410733Speter * 411733Speter * The following are the namelist offsets for the 412733Speter * primitive types. The ones which are negative 413733Speter * don't actually exist, but are generated and tested 414733Speter * internally. These definitions are sensitive to the 415733Speter * initializations in nl.c. 416733Speter */ 417733Speter #define TFIRST -7 418733Speter #define TFILE -7 419733Speter #define TREC -6 420733Speter #define TARY -5 421733Speter #define TSCAL -4 422733Speter #define TPTR -3 423733Speter #define TSET -2 424733Speter #define TSTR -1 425733Speter #define NIL 0 426733Speter #define TBOOL 1 427733Speter #define TCHAR 2 428733Speter #define TINT 3 429733Speter #define TDOUBLE 4 430733Speter #define TNIL 5 431733Speter #define T1INT 6 432733Speter #define T2INT 7 433733Speter #define T4INT 8 434733Speter #define T1CHAR 9 435733Speter #define T1BOOL 10 436733Speter #define T8REAL 11 437733Speter #define TLAST 11 438733Speter 439733Speter /* 440733Speter * SEMANTIC DEFINITIONS 441733Speter */ 442733Speter 443733Speter /* 444733Speter * NOCON and SAWCON are flags in the tree telling whether 445733Speter * a constant set is part of an expression. 4463314Speter * these are no longer used, 4473314Speter * since we now do constant sets at compile time. 448733Speter */ 449733Speter #define NOCON 0 450733Speter #define SAWCON 1 451733Speter 452733Speter /* 453733Speter * The variable cbn gives the current block number, 454733Speter * the variable bn is set as a side effect of a call to 455733Speter * lookup, and is the block number of the variable which 456733Speter * was found. 457733Speter */ 458733Speter short bn, cbn; 459733Speter 460733Speter /* 461733Speter * The variable line is the current semantic 462733Speter * line and is set in stat.c from the numbers 463733Speter * embedded in statement type tree nodes. 464733Speter */ 465733Speter short line; 466733Speter 467733Speter /* 468733Speter * The size of the display 469733Speter * which defines the maximum nesting 470733Speter * of procedures and functions allowed. 471733Speter * Because of the flags in the current namelist 472733Speter * this must be no greater than 32. 473733Speter */ 474733Speter #define DSPLYSZ 20 475733Speter 4763425Speter /* 4773425Speter * the display is made up of saved AP's and FP's. 4783425Speter * FP's are used to find locals, and AP's are used to find parameters. 4793425Speter * FP and AP are untyped pointers, but are used throughout as (char *). 4803425Speter * the display is used by adding AP_OFFSET or FP_OFFSET to the 4813425Speter * address of the approriate display entry. 4823425Speter */ 4833425Speter struct dispsave { 4843425Speter char *savedAP; 4853425Speter char *savedFP; 4863425Speter } display[ DSPLYSZ ]; 4873425Speter 4883425Speter #define AP_OFFSET ( 0 ) 4893425Speter #define FP_OFFSET ( sizeof(char *) ) 4903425Speter 4913425Speter /* 4923425Speter * formal routine structure: 4933425Speter */ 4943425Speter struct formalrtn { 4953425Speter long (*fentryaddr)(); /* formal entry point */ 4963425Speter long fbn; /* block number of function */ 4973425Speter struct dispsave fdisp[ DSPLYSZ ]; /* saved at first passing */ 4983425Speter } frtn; 4993425Speter 5003425Speter #define FENTRYOFFSET 0 5013425Speter #define FBNOFFSET ( FENTRYOFFSET + sizeof frtn.fentryaddr ) 5023425Speter #define FDISPOFFSET ( FBNOFFSET + sizeof frtn.fbn ) 5033425Speter 504733Speter /* 505733Speter * The following structure is used 506733Speter * to keep track of the amount of variable 507733Speter * storage required by each block. 508733Speter * "Max" is the high water mark, "off" 509733Speter * the current need. Temporaries for "for" 510733Speter * loops and "with" statements are allocated 511733Speter * in the local variable area and these 512733Speter * numbers are thereby changed if necessary. 513733Speter */ 514733Speter struct om { 515733Speter long om_max; 5163220Smckusic long reg_max; 5173220Smckusic struct tmps { 5183220Smckusic long om_off; 5193220Smckusic long reg_off; 5203220Smckusic } curtmps; 521733Speter } sizes[DSPLYSZ]; 5223220Smckusic #define NOREG 0 5233220Smckusic #define REGOK 1 524733Speter 525733Speter /* 526733Speter * the following structure records whether a level declares 527733Speter * any variables which are (or contain) files. 528733Speter * this so that the runtime routines for file cleanup can be invoked. 529733Speter */ 530733Speter bool dfiles[ DSPLYSZ ]; 531733Speter 532733Speter /* 533733Speter * Structure recording information about a constant 534733Speter * declaration. It is actually the return value from 535733Speter * the routine "gconst", but since C doesn't support 536733Speter * record valued functions, this is more convenient. 537733Speter */ 538733Speter struct { 539733Speter struct nl *ctype; 540733Speter short cival; 541733Speter double crval; 542733Speter int *cpval; 543733Speter } con; 544733Speter 545733Speter /* 546733Speter * The set structure records the lower bound 547733Speter * and upper bound with the lower bound normalized 548733Speter * to zero when working with a set. It is set by 549733Speter * the routine setran in var.c. 550733Speter */ 551733Speter struct { 552733Speter short lwrb, uprbp; 553733Speter } set; 554733Speter 555733Speter /* 556733Speter * structures of this kind are filled in by precset and used by postcset 557733Speter * to indicate things about constant sets. 558733Speter */ 559733Speter struct csetstr { 560733Speter struct nl *csettype; 561733Speter long paircnt; 562733Speter long singcnt; 563733Speter bool comptime; 564733Speter }; 565733Speter /* 566733Speter * The following flags are passed on calls to lvalue 567733Speter * to indicate how the reference is to affect the usage 568733Speter * information for the variable being referenced. 569733Speter * MOD is used to set the NMOD flag in the namelist 570733Speter * entry for the variable, ASGN permits diagnostics 571733Speter * to be formed when a for variable is assigned to in 572733Speter * the range of the loop. 573733Speter */ 574733Speter #define NOFLAGS 0 575733Speter #define MOD 01 576733Speter #define ASGN 02 577733Speter #define NOUSE 04 578733Speter 579733Speter /* 580733Speter * the following flags are passed to lvalue and rvalue 581733Speter * to tell them whether an lvalue or rvalue is required. 582733Speter * the semantics checking is done according to the function called, 583733Speter * but for pc, lvalue may put out an rvalue by indirecting afterwards, 584733Speter * and rvalue may stop short of putting out the indirection. 585733Speter */ 586733Speter #define LREQ 01 587733Speter #define RREQ 02 588733Speter 589733Speter double MAXINT; 590733Speter double MININT; 591733Speter 592733Speter /* 593733Speter * Variables for generation of profile information. 594733Speter * Monflg is set when we want to generate a profile. 595733Speter * Gocnt record the total number of goto's and 596733Speter * cnts records the current counter for generating 597733Speter * COUNT operators. 598733Speter */ 599733Speter short gocnt; 600733Speter short cnts; 601733Speter 602733Speter /* 603733Speter * Most routines call "incompat" rather than asking "!compat" 604733Speter * for historical reasons. 605733Speter */ 606733Speter #define incompat !compat 607733Speter 608733Speter /* 609733Speter * Parts records which declaration parts have been seen. 610833Speter * The grammar allows the "label" "const" "type" "var" and routine 611733Speter * parts to be repeated and to be in any order, so that 612733Speter * they can be detected semantically to give better 613733Speter * error diagnostics. 614733Speter */ 615833Speter int parts[ DSPLYSZ ]; 616733Speter 617833Speter #define LPRT 1 618833Speter #define CPRT 2 619833Speter #define TPRT 4 620833Speter #define VPRT 8 621833Speter #define RPRT 16 622733Speter 623733Speter /* 624733Speter * Flags for the "you used / instead of div" diagnostic 625733Speter */ 626733Speter bool divchk; 627733Speter bool divflg; 628733Speter 6293071Smckusic bool errcnt[DSPLYSZ]; 630733Speter 631733Speter /* 632733Speter * Forechain links those types which are 633733Speter * ^ sometype 634733Speter * so that they can be evaluated later, permitting 635733Speter * circular, recursive list structures to be defined. 636733Speter */ 637733Speter struct nl *forechain; 638733Speter 639733Speter /* 640733Speter * Withlist links all the records which are currently 641733Speter * opened scopes because of with statements. 642733Speter */ 643733Speter struct nl *withlist; 644733Speter 645733Speter struct nl *intset; 646733Speter struct nl *input, *output; 647733Speter struct nl *program; 648733Speter 649733Speter /* progseen flag used by PC to determine if 650733Speter * a routine segment is being compiled (and 651733Speter * therefore no program statement seen) 652733Speter */ 653733Speter bool progseen; 654733Speter 655733Speter 656733Speter /* 657733Speter * STRUCTURED STATEMENT GOTO CHECKING 658733Speter * 659733Speter * The variable level keeps track of the current 660733Speter * "structured statement level" when processing the statement 661733Speter * body of blocks. This is used in the detection of goto's into 662733Speter * structured statements in a block. 663733Speter * 664733Speter * Each label's namelist entry contains two pieces of information 665733Speter * related to this check. The first `NL_GOLEV' either contains 666733Speter * the level at which the label was declared, `NOTYET' if the label 667733Speter * has not yet been declared, or `DEAD' if the label is dead, i.e. 668733Speter * if we have exited the level in which the label was defined. 669733Speter * 670733Speter * When we discover a "goto" statement, if the label has not 671733Speter * been defined yet, then we record the current level and the current line 672733Speter * for a later error check. If the label has been already become "DEAD" 673733Speter * then a reference to it is an error. Now the compiler maintains, 674733Speter * for each block, a linked list of the labels headed by "gotos[bn]". 675733Speter * When we exit a structured level, we perform the routine 676733Speter * ungoto in stat.c. It notices labels whose definition levels have been 677733Speter * exited and makes them be dead. For labels which have not yet been 678733Speter * defined, ungoto will maintain NL_GOLEV as the minimum structured level 679733Speter * since the first usage of the label. It is not hard to see that the label 680733Speter * must eventually be declared at this level or an outer level to this 681733Speter * one or a goto into a structured statement will exist. 682733Speter */ 683733Speter short level; 684733Speter struct nl *gotos[DSPLYSZ]; 685733Speter 686733Speter #define NOTYET 10000 687733Speter #define DEAD 10000 688733Speter 689733Speter /* 690733Speter * Noreach is true when the next statement will 691733Speter * be unreachable unless something happens along 692733Speter * (like exiting a looping construct) to save 693733Speter * the day. 694733Speter */ 695733Speter bool noreach; 696733Speter 697733Speter /* 698733Speter * UNDEFINED VARIABLE REFERENCE STRUCTURES 699733Speter */ 700733Speter struct udinfo { 701733Speter int ud_line; 702733Speter struct udinfo *ud_next; 703733Speter char nullch; 704733Speter }; 705733Speter 706733Speter /* 707733Speter * CODE GENERATION DEFINITIONS 708733Speter */ 709733Speter 710733Speter /* 711733Speter * NSTAND is or'ed onto the abstract machine opcode 712733Speter * for non-standard built-in procedures and functions. 713733Speter */ 714733Speter #define NSTAND 0400 715733Speter 716733Speter #define codeon() cgenflg++ 717733Speter #define codeoff() --cgenflg 7183314Speter #define CGENNING ( cgenflg >= 0 ) 719733Speter 720733Speter /* 721733Speter * Codeline is the last lino output in the code generator. 722733Speter * It used to be used to suppress LINO operators but no 723733Speter * more since we now count statements. 724733Speter * Lc is the intepreter code location counter. 725733Speter * 726733Speter short codeline; 727733Speter */ 728733Speter char *lc; 729733Speter 730733Speter 731733Speter /* 732733Speter * Routines which need types 733733Speter * other than "integer" to be 734733Speter * assumed by the compiler. 735733Speter */ 736733Speter double atof(); 737733Speter long lwidth(); 7383071Smckusic long leven(); 739733Speter long aryconst(); 740733Speter long a8tol(); 7413071Smckusic long roundup(); 7423823Speter struct nl *tmpalloc(); 743733Speter struct nl *lookup(); 744733Speter double atof(); 745733Speter int *tree(); 746733Speter int *hash(); 747733Speter char *alloc(); 748733Speter int *calloc(); 749733Speter char *savestr(); 7503283Smckusic char *parnam(); 7513283Smckusic bool fcompat(); 752733Speter struct nl *lookup1(); 753733Speter struct nl *hdefnl(); 754733Speter struct nl *defnl(); 755733Speter struct nl *enter(); 756733Speter struct nl *nlcopy(); 757733Speter struct nl *tyrecl(); 758733Speter struct nl *tyary(); 759733Speter struct nl *fields(); 760733Speter struct nl *variants(); 761733Speter struct nl *deffld(); 762733Speter struct nl *defvnt(); 763733Speter struct nl *tyrec1(); 764733Speter struct nl *reclook(); 765733Speter struct nl *asgnop1(); 766733Speter struct nl *gtype(); 767733Speter struct nl *call(); 768733Speter struct nl *lvalue(); 769733Speter struct nl *rvalue(); 770733Speter struct nl *cset(); 771733Speter 772733Speter /* 773733Speter * type cast NIL to keep lint happy (which is not so bad) 774733Speter */ 775733Speter #define NLNIL ( (struct nl *) NIL ) 776733Speter 777733Speter /* 778733Speter * Funny structures to use 779733Speter * pointers in wild and wooly ways 780733Speter */ 781733Speter struct { 782733Speter char pchar; 783733Speter }; 784733Speter struct { 785733Speter short pint; 786733Speter short pint2; 787733Speter }; 788733Speter struct { 789733Speter long plong; 790733Speter }; 791733Speter struct { 792733Speter double pdouble; 793733Speter }; 794733Speter 795733Speter #define OCT 1 796733Speter #define HEX 2 797733Speter 798733Speter /* 799733Speter * MAIN PROGRAM VARIABLES, MISCELLANY 800733Speter */ 801733Speter 802733Speter /* 803733Speter * Variables forming a data base referencing 804733Speter * the command line arguments with the "i" option, e.g. 805733Speter * in "pi -i scanner.i compiler.p". 806733Speter */ 807733Speter char **pflist; 808733Speter short pflstc; 809733Speter short pfcnt; 810733Speter 811733Speter char *filename; /* current source file name */ 812733Speter long tvec; 813733Speter extern char *snark; /* SNARK */ 814733Speter extern char *classes[ ]; /* maps namelist classes to string names */ 815733Speter 816733Speter #define derror error 817733Speter 818733Speter #ifdef PC 819733Speter 820733Speter /* 821733Speter * the current function number, for [ lines 822733Speter */ 823733Speter int ftnno; 824733Speter 825733Speter /* 826733Speter * the pc output stream 827733Speter */ 828733Speter FILE *pcstream; 829733Speter 830733Speter #endif PC 831