1760Speter /* Copyright (c) 1979 Regents of the University of California */ 2760Speter 3*1197Speter static char sccsid[] = "@(#)nl.c 1.2 10/03/80"; 4760Speter 5760Speter #include "whoami.h" 6760Speter #include "0.h" 7760Speter #include "opcode.h" 8760Speter #include "objfmt.h" 9760Speter 10760Speter /* 11760Speter * NAMELIST SEGMENT DEFINITIONS 12760Speter */ 13760Speter struct nls { 14760Speter struct nl *nls_low; 15760Speter struct nl *nls_high; 16760Speter } ntab[MAXNL], *nlact; 17760Speter 18760Speter struct nl nl[INL]; 19760Speter struct nl *nlp = nl; 20760Speter struct nls *nlact = ntab; 21760Speter 22760Speter /* 23760Speter * all these strings must be places where people can find them 24760Speter * since lookup only looks at the string pointer, not the chars. 25760Speter * see, for example, pTreeInit. 26760Speter */ 27760Speter 28760Speter /* 29760Speter * built in constants 30760Speter */ 31760Speter char *in_consts[] = { 32760Speter "true" , 33760Speter "false" , 34760Speter "TRUE", 35760Speter "FALSE", 36760Speter "minint" , 37760Speter "maxint" , 38760Speter "minchar" , 39760Speter "maxchar" , 40760Speter "bell" , 41760Speter "tab" , 42760Speter 0 43760Speter }; 44760Speter 45760Speter /* 46760Speter * built in simple types 47760Speter */ 48760Speter char *in_types[] = 49760Speter { 50760Speter "boolean", 51760Speter "char", 52760Speter "integer", 53760Speter "real", 54760Speter "_nil", /* dummy name */ 55760Speter 0 56760Speter }; 57760Speter 58760Speter int in_rclasses[] = 59760Speter { 60760Speter TINT , 61760Speter TINT , 62760Speter TINT , 63760Speter TCHAR , 64760Speter TBOOL , 65760Speter TDOUBLE , 66760Speter 0 67760Speter }; 68760Speter 69760Speter long in_ranges[] = 70760Speter { 71760Speter -128L , 128L , 72760Speter -32768L , 32767L , 73760Speter -2147483648L , 2147483647L , 74760Speter 0L , 127L , 75760Speter 0L , 1L , 76760Speter 0L , 0L /* fake for reals */ 77760Speter }; 78760Speter 79760Speter /* 80760Speter * built in constructed types 81760Speter */ 82760Speter char *in_ctypes[] = { 83760Speter "Boolean" , 84760Speter "intset" , 85760Speter "alfa" , 86760Speter "text" , 87760Speter 0 88760Speter }; 89760Speter 90760Speter /* 91760Speter * built in variables 92760Speter */ 93760Speter char *in_vars[] = { 94760Speter "input" , 95760Speter "output" , 96760Speter 0 97760Speter }; 98760Speter 99760Speter /* 100760Speter * built in functions 101760Speter */ 102760Speter char *in_funcs[] = 103760Speter { 104760Speter "abs" , 105760Speter "arctan" , 106760Speter "card" , 107760Speter "chr" , 108760Speter "clock" , 109760Speter "cos" , 110760Speter "eof" , 111760Speter "eoln" , 112760Speter "eos" , 113760Speter "exp" , 114760Speter "expo" , 115760Speter "ln" , 116760Speter "odd" , 117760Speter "ord" , 118760Speter "pred" , 119760Speter "round" , 120760Speter "sin" , 121760Speter "sqr" , 122760Speter "sqrt" , 123760Speter "succ" , 124760Speter "trunc" , 125760Speter "undefined" , 126760Speter /* 127760Speter * Extensions 128760Speter */ 129760Speter "argc" , 130760Speter "random" , 131760Speter "seed" , 132760Speter "wallclock" , 133760Speter "sysclock" , 134760Speter 0 135760Speter }; 136760Speter 137760Speter /* 138760Speter * Built-in procedures 139760Speter */ 140760Speter char *in_procs[] = 141760Speter { 142760Speter "date" , 143760Speter "dispose" , 144760Speter "flush" , 145760Speter "get" , 146760Speter "getseg" , 147760Speter "halt" , 148760Speter "linelimit" , 149760Speter "message" , 150760Speter "new" , 151760Speter "pack" , 152760Speter "page" , 153760Speter "put" , 154760Speter "putseg" , 155760Speter "read" , 156760Speter "readln" , 157760Speter "remove" , 158760Speter "reset" , 159760Speter "rewrite" , 160760Speter "time" , 161760Speter "unpack" , 162760Speter "write" , 163760Speter "writeln" , 164760Speter /* 165760Speter * Extensions 166760Speter */ 167760Speter "argv" , 168760Speter "null" , 169760Speter "stlimit" , 170760Speter 0 171760Speter }; 172760Speter 173760Speter #ifndef PI0 174760Speter /* 175760Speter * and their opcodes 176760Speter */ 177760Speter int in_fops[] = 178760Speter { 179760Speter O_ABS2, 180760Speter O_ATAN, 181760Speter O_CARD|NSTAND, 182760Speter O_CHR2, 183760Speter O_CLCK|NSTAND, 184760Speter O_COS, 185760Speter O_EOF, 186760Speter O_EOLN, 187760Speter 0, 188760Speter O_EXP, 189760Speter O_EXPO|NSTAND, 190760Speter O_LN, 191760Speter O_ODD2, 192760Speter O_ORD2, 193760Speter O_PRED2, 194760Speter O_ROUND, 195760Speter O_SIN, 196760Speter O_SQR2, 197760Speter O_SQRT, 198760Speter O_SUCC2, 199760Speter O_TRUNC, 200760Speter O_UNDEF|NSTAND, 201760Speter /* 202760Speter * Extensions 203760Speter */ 204760Speter O_ARGC|NSTAND, 205760Speter O_RANDOM|NSTAND, 206760Speter O_SEED|NSTAND, 207760Speter O_WCLCK|NSTAND, 208760Speter O_SCLCK|NSTAND 209760Speter }; 210760Speter 211760Speter /* 212760Speter * Built-in procedures 213760Speter */ 214760Speter int in_pops[] = 215760Speter { 216760Speter O_DATE|NSTAND, 217760Speter O_DISPOSE, 218760Speter O_FLUSH|NSTAND, 219760Speter O_GET, 220760Speter 0, 221760Speter O_HALT|NSTAND, 222760Speter O_LLIMIT|NSTAND, 223760Speter O_MESSAGE|NSTAND, 224760Speter O_NEW, 225760Speter O_PACK, 226760Speter O_PAGE, 227760Speter O_PUT, 228760Speter 0, 229760Speter O_READ4, 230760Speter O_READLN, 231760Speter O_REMOVE|NSTAND, 232760Speter O_RESET, 233760Speter O_REWRITE, 234760Speter O_TIME|NSTAND, 235760Speter O_UNPACK, 236760Speter O_WRITEF, 237760Speter O_WRITLN, 238760Speter /* 239760Speter * Extensions 240760Speter */ 241760Speter O_ARGV|NSTAND, 242760Speter O_ABORT|NSTAND, 243760Speter O_STLIM|NSTAND 244760Speter }; 245760Speter #endif 246760Speter 247760Speter /* 248760Speter * Initnl initializes the first namelist segment and then 249760Speter * initializes the name list for block 0. 250760Speter */ 251760Speter initnl() 252760Speter { 253760Speter register char **cp; 254760Speter register struct nl *np; 255760Speter struct nl *fp; 256760Speter int *ip; 257760Speter long *lp; 258760Speter 259760Speter #ifdef DEBUG 260760Speter if ( hp21mx ) 261760Speter { 262760Speter MININT = -32768.; 263760Speter MAXINT = 32767.; 264760Speter #ifndef PI0 265760Speter genmx(); 266760Speter #endif 267760Speter } 268760Speter #endif 269760Speter ntab[0].nls_low = nl; 270760Speter ntab[0].nls_high = &nl[INL]; 271760Speter defnl ( 0 , 0 , 0 , 0 ); 272760Speter 273760Speter /* 274760Speter * Types 275760Speter */ 276760Speter for ( cp = in_types ; *cp != 0 ; cp ++ ) 277760Speter hdefnl ( *cp , TYPE , nlp , 0 ); 278760Speter 279760Speter /* 280760Speter * Ranges 281760Speter */ 282760Speter lp = in_ranges; 283760Speter for ( ip = in_rclasses ; *ip != 0 ; ip ++ ) 284760Speter { 285760Speter np = defnl ( 0 , RANGE , nl+(*ip) , 0 ); 286760Speter nl[*ip].type = np; 287760Speter np -> range[0] = *lp ++ ; 288760Speter np -> range[1] = *lp ++ ; 289760Speter 290760Speter }; 291760Speter 292760Speter /* 293760Speter * built in constructed types 294760Speter */ 295760Speter 296760Speter cp = in_ctypes; 297760Speter /* 298760Speter * Boolean = boolean; 299760Speter */ 300760Speter hdefnl ( *cp++ , TYPE , nl+T1BOOL , 0 ); 301760Speter 302760Speter /* 303760Speter * intset = set of 0 .. 127; 304760Speter */ 305760Speter intset = *cp++; 306760Speter hdefnl( intset , TYPE , nlp+1 , 0 ); 307760Speter defnl ( 0 , SET , nlp+1 , 0 ); 308760Speter np = defnl ( 0 , RANGE , nl+TINT , 0 ); 309760Speter np -> range[0] = 0L; 310760Speter np -> range[1] = 127L; 311760Speter 312760Speter /* 313760Speter * alfa = array [ 1 .. 10 ] of char; 314760Speter */ 315760Speter np = defnl ( 0 , RANGE , nl+TINT , 0 ); 316760Speter np -> range[0] = 1L; 317760Speter np -> range[1] = 10L; 318760Speter defnl ( 0 , ARRAY , nl+T1CHAR , 1 ) -> chain = np; 319760Speter hdefnl ( *cp++ , TYPE , nlp-1 , 0 ); 320760Speter 321760Speter /* 322760Speter * text = file of char; 323760Speter */ 324760Speter hdefnl ( *cp++ , TYPE , nlp+1 , 0 ); 325760Speter np = defnl ( 0 , FILET , nl+T1CHAR , 0 ); 326760Speter np -> nl_flags |= NFILES; 327760Speter 328760Speter /* 329760Speter * input,output : text; 330760Speter */ 331760Speter cp = in_vars; 332760Speter # ifndef PI0 333760Speter input = hdefnl ( *cp++ , VAR , np , INPUT_OFF ); 334760Speter output = hdefnl ( *cp++ , VAR , np , OUTPUT_OFF ); 335760Speter # else 336760Speter input = hdefnl ( *cp++ , VAR , np , 0 ); 337760Speter output = hdefnl ( *cp++ , VAR , np , 0 ); 338760Speter # endif 339760Speter 340760Speter /* 341760Speter * built in constants 342760Speter */ 343760Speter cp = in_consts; 344760Speter np = hdefnl ( *cp++ , CONST , nl + TBOOL , 1 ); 345760Speter fp = hdefnl ( *cp++ , CONST , nl + TBOOL , 0 ); 346760Speter (nl + TBOOL)->chain = fp; 347760Speter fp->chain = np; 348760Speter np = hdefnl ( *cp++ , CONST , nl + TBOOL , 1 ); 349760Speter fp = hdefnl ( *cp++ , CONST , nl + TBOOL , 0 ); 350760Speter fp->chain = np; 351760Speter if (opt('s')) 352760Speter (nl + TBOOL)->chain = fp; 353760Speter hdefnl ( *cp++ , CONST , nl + T4INT , 0 ) -> range[0] = MININT; 354760Speter hdefnl ( *cp++ , CONST , nl + T4INT , 0 ) -> range[0] = MAXINT; 355760Speter hdefnl ( *cp++ , CONST , nl + T1CHAR , 0 ); 356760Speter hdefnl ( *cp++ , CONST , nl + T1CHAR , 127 ); 357760Speter hdefnl ( *cp++ , CONST , nl + T1CHAR , '\007' ); 358760Speter hdefnl ( *cp++ , CONST , nl + T1CHAR , '\t' ); 359760Speter 360760Speter /* 361760Speter * Built-in functions and procedures 362760Speter */ 363760Speter #ifndef PI0 364760Speter ip = in_fops; 365760Speter for ( cp = in_funcs ; *cp != 0 ; cp ++ ) 366760Speter hdefnl ( *cp , FUNC , 0 , * ip ++ ); 367760Speter ip = in_pops; 368760Speter for ( cp = in_procs ; *cp != 0 ; cp ++ ) 369760Speter hdefnl ( *cp , PROC , 0 , * ip ++ ); 370760Speter #else 371760Speter for ( cp = in_funcs ; *cp != 0 ; cp ++ ) 372760Speter hdefnl ( *cp , FUNC , 0 , 0 ); 373760Speter for ( cp = in_procs ; *cp != 0 , cp ++ ) 374760Speter hdefnl ( *cp , PROC , 0 , 0 ); 375760Speter #endif 376760Speter # ifdef PTREE 377760Speter pTreeInit(); 378760Speter # endif 379760Speter } 380760Speter 381760Speter struct nl * 382760Speter hdefnl(sym, cls, typ, val) 383760Speter { 384760Speter register struct nl *p; 385760Speter 386760Speter #ifndef PI1 387760Speter if (sym) 388760Speter hash(sym, 0); 389760Speter #endif 390760Speter p = defnl(sym, cls, typ, val); 391760Speter if (sym) 392760Speter enter(p); 393760Speter return (p); 394760Speter } 395760Speter 396760Speter /* 397760Speter * Free up the name list segments 398760Speter * at the end of a statement/proc/func 399760Speter * All segments are freed down to the one in which 400760Speter * p points. 401760Speter */ 402760Speter nlfree(p) 403760Speter struct nl *p; 404760Speter { 405760Speter 406760Speter nlp = p; 407760Speter while (nlact->nls_low > nlp || nlact->nls_high < nlp) { 408760Speter free(nlact->nls_low); 409760Speter nlact->nls_low = NIL; 410760Speter nlact->nls_high = NIL; 411760Speter --nlact; 412760Speter if (nlact < &ntab[0]) 413760Speter panic("nlfree"); 414760Speter } 415760Speter } 416760Speter 417760Speter 418760Speter char *VARIABLE = "variable"; 419760Speter 420760Speter char *classes[ ] = { 421760Speter "undefined", 422760Speter "constant", 423760Speter "type", 424760Speter "variable", /* VARIABLE */ 425760Speter "array", 426760Speter "pointer or file", 427760Speter "record", 428760Speter "field", 429760Speter "procedure", 430760Speter "function", 431760Speter "variable", /* VARIABLE */ 432760Speter "variable", /* VARIABLE */ 433760Speter "pointer", 434760Speter "file", 435760Speter "set", 436760Speter "subrange", 437760Speter "label", 438760Speter "withptr", 439760Speter "scalar", 440760Speter "string", 441760Speter "program", 442*1197Speter "improper", 443*1197Speter "variant", 444*1197Speter "formal procedure", 445*1197Speter "formal function" 446760Speter }; 447760Speter 448760Speter char *snark = "SNARK"; 449760Speter 450760Speter #ifdef PI 451760Speter #ifdef DEBUG 452760Speter char *ctext[] = 453760Speter { 454760Speter "BADUSE", 455760Speter "CONST", 456760Speter "TYPE", 457760Speter "VAR", 458760Speter "ARRAY", 459760Speter "PTRFILE", 460760Speter "RECORD", 461760Speter "FIELD", 462760Speter "PROC", 463760Speter "FUNC", 464760Speter "FVAR", 465760Speter "REF", 466760Speter "PTR", 467760Speter "FILET", 468760Speter "SET", 469760Speter "RANGE", 470760Speter "LABEL", 471760Speter "WITHPTR", 472760Speter "SCAL", 473760Speter "STR", 474760Speter "PROG", 475760Speter "IMPROPER", 476*1197Speter "VARNT", 477*1197Speter "FPROC", 478*1197Speter "FFUNC" 479760Speter }; 480760Speter 481760Speter char *stars = "\t***"; 482760Speter 483760Speter /* 484760Speter * Dump the namelist from the 485760Speter * current nlp down to 'to'. 486760Speter * All the namelist is dumped if 487760Speter * to is NIL. 488760Speter */ 489760Speter dumpnl(to, rout) 490760Speter struct nl *to; 491760Speter { 492760Speter register struct nl *p; 493760Speter register int j; 494760Speter struct nls *nlsp; 495760Speter int i, v, head; 496760Speter 497760Speter if (opt('y') == 0) 498760Speter return; 499760Speter if (to != NIL) 500760Speter printf("\n\"%s\" Block=%d\n", rout, cbn); 501760Speter nlsp = nlact; 502760Speter head = NIL; 503760Speter for (p = nlp; p != to;) { 504760Speter if (p == nlsp->nls_low) { 505760Speter if (nlsp == &ntab[0]) 506760Speter break; 507760Speter nlsp--; 508760Speter p = nlsp->nls_high; 509760Speter } 510760Speter p--; 511760Speter if (head == NIL) { 512760Speter printf("\tName\tClass Bn+Flags\tType\tVal\tChn\n"); 513760Speter head++; 514760Speter } 515760Speter printf("%3d:", nloff(p)); 516760Speter if (p->symbol) 517760Speter printf("\t%.7s", p->symbol); 518760Speter else 519760Speter printf(stars); 520760Speter if (p->class) 521760Speter printf("\t%s", ctext[p->class]); 522760Speter else 523760Speter printf(stars); 524760Speter if (p->nl_flags) { 525760Speter pchr('\t'); 526760Speter if (p->nl_flags & 037) 527760Speter printf("%d ", p->nl_flags & 037); 528760Speter #ifndef PI0 529760Speter if (p->nl_flags & NMOD) 530760Speter pchr('M'); 531760Speter if (p->nl_flags & NUSED) 532760Speter pchr('U'); 533760Speter #endif 534760Speter if (p->nl_flags & NFILES) 535760Speter pchr('F'); 536760Speter } else 537760Speter printf(stars); 538760Speter if (p->type) 539760Speter printf("\t[%d]", nloff(p->type)); 540760Speter else 541760Speter printf(stars); 542760Speter v = p->value[0]; 543760Speter switch (p->class) { 544760Speter case TYPE: 545760Speter break; 546760Speter case VARNT: 547760Speter goto con; 548760Speter case CONST: 549760Speter switch (nloff(p->type)) { 550760Speter default: 551760Speter printf("\t%d", v); 552760Speter break; 553760Speter case TDOUBLE: 554760Speter printf("\t%f", p->real); 555760Speter break; 556760Speter case TINT: 557760Speter case T4INT: 558760Speter con: 559760Speter printf("\t%ld", p->range[0]); 560760Speter break; 561760Speter case TSTR: 562760Speter printf("\t'%s'", p->ptr[0]); 563760Speter break; 564760Speter } 565760Speter break; 566760Speter case VAR: 567760Speter case REF: 568760Speter case WITHPTR: 569*1197Speter case FFUNC: 570*1197Speter case FPROC: 571760Speter printf("\t%d,%d", cbn, v); 572760Speter break; 573760Speter case SCAL: 574760Speter case RANGE: 575760Speter printf("\t%ld..%ld", p->range[0], p->range[1]); 576760Speter break; 577760Speter case RECORD: 578760Speter printf("\t%d(%d)", v, p->value[NL_FLDSZ]); 579760Speter break; 580760Speter case FIELD: 581760Speter printf("\t%d", v); 582760Speter break; 583760Speter case STR: 584760Speter printf("\t|%d|", p->value[0]); 585760Speter break; 586760Speter case FVAR: 587760Speter case FUNC: 588760Speter case PROC: 589760Speter case PROG: 590760Speter if (cbn == 0) { 591760Speter printf("\t<%o>", p->value[0] & 0377); 592760Speter #ifndef PI0 593760Speter if (p->value[0] & NSTAND) 594760Speter printf("\tNSTAND"); 595760Speter #endif 596760Speter break; 597760Speter } 598760Speter v = p->value[1]; 599760Speter default: 600760Speter casedef: 601760Speter if (v) 602760Speter printf("\t<%d>", v); 603760Speter else 604760Speter printf(stars); 605760Speter } 606760Speter if (p->chain) 607760Speter printf("\t[%d]", nloff(p->chain)); 608760Speter switch (p->class) { 609760Speter case RECORD: 610760Speter if (p->ptr[NL_VARNT]) 611760Speter printf("\tVARNT=[%d]", nloff(p->ptr[NL_VARNT])); 612760Speter if (p->ptr[NL_TAG]) 613760Speter printf(" TAG=[%d]", nloff(p->ptr[NL_TAG])); 614760Speter break; 615760Speter case VARNT: 616760Speter printf("\tVTOREC=[%d]", nloff(p->ptr[NL_VTOREC])); 617760Speter break; 618760Speter } 619760Speter # ifdef PTREE 620760Speter pchr( '\t' ); 621760Speter pPrintPointer( stdout , "%s" , p -> inTree ); 622760Speter # endif 623760Speter pchr('\n'); 624760Speter } 625760Speter if (head == 0) 626760Speter printf("\tNo entries\n"); 627760Speter } 628760Speter #endif 629760Speter 630760Speter 631760Speter /* 632760Speter * Define a new name list entry 633760Speter * with initial symbol, class, type 634760Speter * and value[0] as given. A new name 635760Speter * list segment is allocated to hold 636760Speter * the next name list slot if necessary. 637760Speter */ 638760Speter struct nl * 639760Speter defnl(sym, cls, typ, val) 640760Speter char *sym; 641760Speter int cls; 642760Speter struct nl *typ; 643760Speter int val; 644760Speter { 645760Speter register struct nl *p; 646760Speter register int *q, i; 647760Speter char *cp; 648760Speter 649760Speter p = nlp; 650760Speter 651760Speter /* 652760Speter * Zero out this entry 653760Speter */ 654760Speter q = p; 655760Speter i = (sizeof *p)/(sizeof (int)); 656760Speter do 657760Speter *q++ = 0; 658760Speter while (--i); 659760Speter 660760Speter /* 661760Speter * Insert the values 662760Speter */ 663760Speter p->symbol = sym; 664760Speter p->class = cls; 665760Speter p->type = typ; 666760Speter p->nl_block = cbn; 667760Speter p->value[0] = val; 668760Speter 669760Speter /* 670760Speter * Insure that the next namelist 671760Speter * entry actually exists. This is 672760Speter * really not needed here, it would 673760Speter * suffice to do it at entry if we 674760Speter * need the slot. It is done this 675760Speter * way because, historically, nlp 676760Speter * always pointed at the next namelist 677760Speter * slot. 678760Speter */ 679760Speter nlp++; 680760Speter if (nlp >= nlact->nls_high) { 681760Speter i = NLINC; 682760Speter cp = malloc(NLINC * sizeof *nlp); 683760Speter if (cp == -1) { 684760Speter i = NLINC / 2; 685760Speter cp = malloc((NLINC / 2) * sizeof *nlp); 686760Speter } 687760Speter if (cp == -1) { 688760Speter error("Ran out of memory (defnl)"); 689760Speter pexit(DIED); 690760Speter } 691760Speter nlact++; 692760Speter if (nlact >= &ntab[MAXNL]) { 693760Speter error("Ran out of name list tables"); 694760Speter pexit(DIED); 695760Speter } 696760Speter nlp = cp; 697760Speter nlact->nls_low = nlp; 698760Speter nlact->nls_high = nlact->nls_low + i; 699760Speter } 700760Speter return (p); 701760Speter } 702760Speter 703760Speter /* 704760Speter * Make a duplicate of the argument 705760Speter * namelist entry for, e.g., type 706760Speter * declarations of the form 'type a = b' 707760Speter * and array indicies. 708760Speter */ 709760Speter struct nl * 710760Speter nlcopy(p) 711760Speter struct nl *p; 712760Speter { 713760Speter register int *p1, *p2, i; 714760Speter 715760Speter p1 = p; 716760Speter p = p2 = defnl(0, 0, 0, 0); 717760Speter i = (sizeof *p)/(sizeof (int)); 718760Speter do 719760Speter *p2++ = *p1++; 720760Speter while (--i); 721760Speter p->chain = NIL; 722760Speter return (p); 723760Speter } 724760Speter 725760Speter /* 726760Speter * Compute a namelist offset 727760Speter */ 728760Speter nloff(p) 729760Speter struct nl *p; 730760Speter { 731760Speter 732760Speter return (p - nl); 733760Speter } 734760Speter 735760Speter /* 736760Speter * Enter a symbol into the block 737760Speter * symbol table. Symbols are hashed 738760Speter * 64 ways based on low 6 bits of the 739760Speter * character pointer into the string 740760Speter * table. 741760Speter */ 742760Speter struct nl * 743760Speter enter(np) 744760Speter struct nl *np; 745760Speter { 746760Speter register struct nl *rp, *hp; 747760Speter register struct nl *p; 748760Speter int i; 749760Speter 750760Speter rp = np; 751760Speter if (rp == NIL) 752760Speter return (NIL); 753760Speter #ifndef PI1 754760Speter if (cbn > 0) 755760Speter if (rp->symbol == input->symbol || rp->symbol == output->symbol) 756760Speter error("Pre-defined files input and output must not be redefined"); 757760Speter #endif 758760Speter i = rp->symbol; 759760Speter i &= 077; 760760Speter hp = disptab[i]; 761760Speter if (rp->class != BADUSE && rp->class != FIELD) 762760Speter for (p = hp; p != NIL && (p->nl_block & 037) == cbn; p = p->nl_next) 763760Speter if (p->symbol == rp->symbol && p->class != BADUSE && p->class != FIELD) { 764760Speter #ifndef PI1 765760Speter error("%s is already defined in this block", rp->symbol); 766760Speter #endif 767760Speter break; 768760Speter 769760Speter } 770760Speter rp->nl_next = hp; 771760Speter disptab[i] = rp; 772760Speter return (rp); 773760Speter } 774760Speter #endif 775