1*22078Sdist /* 2*22078Sdist * Copyright (c) 1980 Regents of the University of California. 3*22078Sdist * All rights reserved. The Berkeley software License Agreement 4*22078Sdist * specifies the terms and conditions for redistribution. 5*22078Sdist */ 6*22078Sdist 7*22078Sdist #ifndef lint 8*22078Sdist static char sccsid[] = "@(#)clas.c 5.1 (Berkeley) 06/05/85"; 9*22078Sdist #endif not lint 10*22078Sdist 11747Speter /* Copyright (c) 1979 Regents of the University of California */ 12747Speter 1314728Sthien #ifndef lint 14*22078Sdist static char sccsid[] = "@(#)clas.c 5.1 06/05/85"; 1514728Sthien #endif 16747Speter 17747Speter #include "whoami.h" 18747Speter #include "0.h" 19747Speter #include "tree.h" 2014728Sthien #include "tree_ty.h" 21747Speter 22747Speter /* 23747Speter * This is the array of class 24747Speter * names for the classes returned 25747Speter * by classify. The order of the 26747Speter * classes is the same as the base 27747Speter * of the namelist, with special 28747Speter * negative index entries for structures, 29747Speter * scalars, pointers, sets and strings 30747Speter * to be collapsed into. 31747Speter */ 32747Speter char *clnxxxx[] = 33747Speter { 34747Speter "file", /* -7 TFILE */ 35747Speter "record", /* -6 TREC */ 36747Speter "array", /* -5 TARY */ 37747Speter "scalar", /* -4 TSCAL */ 38747Speter "pointer", /* -3 TPTR */ 39747Speter "set", /* -2 TSET */ 40747Speter "string", /* -1 TSTR */ 41747Speter "SNARK", /* 0 NIL */ 42747Speter "Boolean", /* 1 TBOOL */ 43747Speter "char", /* 2 TCHAR */ 44747Speter "integer", /* 3 TINT */ 45747Speter "real", /* 4 TREAL */ 46747Speter "\"nil\"", /* 5 TNIL */ 47747Speter }; 48747Speter 49747Speter char **clnames = &clnxxxx[-(TFIRST)]; 50747Speter 51747Speter /* 52747Speter * Classify takes a pointer 53747Speter * to a type and returns one 54747Speter * of several interesting group 55747Speter * classifications for easy use. 56747Speter */ 57747Speter classify(p1) 58747Speter struct nl *p1; 59747Speter { 60747Speter register struct nl *p; 61747Speter 62747Speter p = p1; 63747Speter swit: 6414728Sthien if (p == NLNIL) { 65747Speter nocascade(); 66747Speter return (NIL); 67747Speter } 68747Speter if (p == &nl[TSTR]) 69747Speter return (TSTR); 70747Speter if ( p == &nl[ TSET ] ) { 71747Speter return TSET; 72747Speter } 73747Speter switch (p->class) { 74747Speter case PTR: 75747Speter return (TPTR); 76747Speter case ARRAY: 77747Speter if (p->type == nl+T1CHAR) 78747Speter return (TSTR); 79747Speter return (TARY); 80747Speter case STR: 81747Speter return (TSTR); 82747Speter case SET: 83747Speter return (TSET); 8415975Smckusick case CRANGE: 85747Speter case RANGE: 86747Speter p = p->type; 87747Speter goto swit; 88747Speter case TYPE: 89747Speter if (p <= nl+TLAST) 90747Speter return (p - nl); 91747Speter panic("clas2"); 92747Speter case FILET: 93747Speter return (TFILE); 94747Speter case RECORD: 95747Speter return (TREC); 96747Speter case SCAL: 97747Speter return (TSCAL); 98747Speter default: 9914728Sthien { 10014728Sthien panic("clas"); 10114728Sthien return(NIL); 10214728Sthien } 103747Speter } 104747Speter } 105747Speter 106747Speter #ifndef PI0 107747Speter /* 108747Speter * Is p a text file? 109747Speter */ 110747Speter text(p) 111747Speter struct nl *p; 112747Speter { 113747Speter 114747Speter return (p != NIL && p->class == FILET && p->type == nl+T1CHAR); 115747Speter } 116747Speter #endif 117747Speter 118747Speter /* 119747Speter * Scalar returns a pointer to 120747Speter * the the base scalar type of 121747Speter * its argument if its argument 122747Speter * is a SCALar else NIL. 123747Speter */ 12414728Sthien struct nl * 125747Speter scalar(p1) 126747Speter struct nl *p1; 127747Speter { 128747Speter register struct nl *p; 129747Speter 130747Speter p = p1; 13114728Sthien if (p == NLNIL) 13214728Sthien return (NLNIL); 13315975Smckusick if (p->class == RANGE || p->class == CRANGE) 134747Speter p = p->type; 13514728Sthien if (p == NLNIL) 13614728Sthien return (NLNIL); 13714728Sthien return (p->class == SCAL ? p : NLNIL); 138747Speter } 139747Speter 140747Speter /* 141747Speter * Isa tells whether p 142747Speter * is one of a group of 143747Speter * namelist classes. The 144747Speter * classes wanted are specified 145747Speter * by the characters in s. 146747Speter * (Note that s would more efficiently, 147747Speter * if less clearly, be given by a mask.) 148747Speter */ 149747Speter isa(p, s) 150747Speter register struct nl *p; 151747Speter char *s; 152747Speter { 153747Speter register i; 154747Speter register char *cp; 155747Speter 156747Speter if (p == NIL) 157747Speter return (NIL); 158747Speter /* 159747Speter * map ranges down to 160747Speter * the base type 161747Speter */ 16215975Smckusick if (p->class == RANGE) { 163747Speter p = p->type; 16415975Smckusick } 165747Speter /* 166747Speter * the following character/class 167747Speter * associations are made: 168747Speter * 169747Speter * s scalar 170747Speter * b Boolean 171747Speter * c character 172747Speter * i integer 173747Speter * d double (real) 174747Speter * t set 175747Speter */ 176747Speter switch (p->class) { 177747Speter case SET: 178747Speter i = TDOUBLE+1; 179747Speter break; 180747Speter case SCAL: 181747Speter i = 0; 182747Speter break; 18315975Smckusick case CRANGE: 18415975Smckusick /* 18515975Smckusick * find the base type of a conformant array range 18615975Smckusick */ 18715975Smckusick switch (classify(p->type)) { 18815975Smckusick case TBOOL: i = 1; break; 18915975Smckusick case TCHAR: i = 2; break; 19015975Smckusick case TINT: i = 3; break; 19115975Smckusick case TSCAL: i = 0; break; 19215975Smckusick default: 19315975Smckusick panic( "isa" ); 19415975Smckusick } 19515975Smckusick break; 196747Speter default: 197747Speter i = p - nl; 198747Speter } 199747Speter if (i >= 0 && i <= TDOUBLE+1) { 200747Speter i = "sbcidt"[i]; 201747Speter cp = s; 202747Speter while (*cp) 203747Speter if (*cp++ == i) 204747Speter return (1); 205747Speter } 206747Speter return (NIL); 207747Speter } 208747Speter 209747Speter /* 210747Speter * Isnta is !isa 211747Speter */ 212747Speter isnta(p, s) 21314728Sthien struct nl *p; 21414728Sthien char *s; 215747Speter { 216747Speter 217747Speter return (!isa(p, s)); 218747Speter } 219747Speter 220747Speter /* 221747Speter * "shorthand" 222747Speter */ 22314728Sthien char * 224747Speter nameof(p) 22514728Sthien struct nl *p; 226747Speter { 227747Speter 228747Speter return (clnames[classify(p)]); 229747Speter } 230747Speter 231747Speter #ifndef PI0 23214728Sthien /* find out for sure what kind of node this is being passed 23314728Sthien possibly several different kinds of node are passed to it */ 23414728Sthien int nowexp(r) 23514728Sthien struct tnode *r; 236747Speter { 23714728Sthien if (r->tag == T_WEXP) { 23814728Sthien if (r->var_node.cptr == NIL) 239747Speter error("Oct/hex allowed only on writeln/write calls"); 240747Speter else 241747Speter error("Width expressions allowed only in writeln/write calls"); 242747Speter return (1); 243747Speter } 244747Speter return (NIL); 245747Speter } 246747Speter #endif 2473276Smckusic 2483276Smckusic /* 2493825Speter * is a variable a local, a formal parameter, or a global? 2503276Smckusic * all this from just the offset: 2513825Speter * globals are at levels 0 or 1 2523276Smckusic * positives are parameters 2533276Smckusic * negative evens are locals 2543276Smckusic */ 25514728Sthien /*ARGSUSED*/ 25614728Sthien whereis( offset , other_flags ) 2573825Speter int offset; 2587920Smckusick char other_flags; 2593276Smckusic { 2603276Smckusic 2613825Speter # ifdef OBJ 2623825Speter return ( offset >= 0 ? PARAMVAR : LOCALVAR ); 2633825Speter # endif OBJ 2643825Speter # ifdef PC 2659127Smckusick switch ( other_flags & ( NGLOBAL | NPARAM | NLOCAL | NNLOCAL) ) { 26614728Sthien default: 26714728Sthien panic( "whereis" ); 2683825Speter case NGLOBAL: 2693825Speter return GLOBALVAR; 2703825Speter case NPARAM: 2713825Speter return PARAMVAR; 2729127Smckusick case NNLOCAL: 2739127Smckusick return NAMEDLOCALVAR; 2743825Speter case NLOCAL: 2753825Speter return LOCALVAR; 2763825Speter } 2773825Speter # endif PC 2783276Smckusic } 279