1747Speter /* Copyright (c) 1979 Regents of the University of California */ 2747Speter 314728Sthien #ifndef lint 4*15975Smckusick static char sccsid[] = "@(#)clas.c 1.8 02/08/84"; 514728Sthien #endif 6747Speter 7747Speter #include "whoami.h" 8747Speter #include "0.h" 9747Speter #include "tree.h" 1014728Sthien #include "tree_ty.h" 11747Speter 12747Speter /* 13747Speter * This is the array of class 14747Speter * names for the classes returned 15747Speter * by classify. The order of the 16747Speter * classes is the same as the base 17747Speter * of the namelist, with special 18747Speter * negative index entries for structures, 19747Speter * scalars, pointers, sets and strings 20747Speter * to be collapsed into. 21747Speter */ 22747Speter char *clnxxxx[] = 23747Speter { 24747Speter "file", /* -7 TFILE */ 25747Speter "record", /* -6 TREC */ 26747Speter "array", /* -5 TARY */ 27747Speter "scalar", /* -4 TSCAL */ 28747Speter "pointer", /* -3 TPTR */ 29747Speter "set", /* -2 TSET */ 30747Speter "string", /* -1 TSTR */ 31747Speter "SNARK", /* 0 NIL */ 32747Speter "Boolean", /* 1 TBOOL */ 33747Speter "char", /* 2 TCHAR */ 34747Speter "integer", /* 3 TINT */ 35747Speter "real", /* 4 TREAL */ 36747Speter "\"nil\"", /* 5 TNIL */ 37747Speter }; 38747Speter 39747Speter char **clnames = &clnxxxx[-(TFIRST)]; 40747Speter 41747Speter /* 42747Speter * Classify takes a pointer 43747Speter * to a type and returns one 44747Speter * of several interesting group 45747Speter * classifications for easy use. 46747Speter */ 47747Speter classify(p1) 48747Speter struct nl *p1; 49747Speter { 50747Speter register struct nl *p; 51747Speter 52747Speter p = p1; 53747Speter swit: 5414728Sthien if (p == NLNIL) { 55747Speter nocascade(); 56747Speter return (NIL); 57747Speter } 58747Speter if (p == &nl[TSTR]) 59747Speter return (TSTR); 60747Speter if ( p == &nl[ TSET ] ) { 61747Speter return TSET; 62747Speter } 63747Speter switch (p->class) { 64747Speter case PTR: 65747Speter return (TPTR); 66747Speter case ARRAY: 67747Speter if (p->type == nl+T1CHAR) 68747Speter return (TSTR); 69747Speter return (TARY); 70747Speter case STR: 71747Speter return (TSTR); 72747Speter case SET: 73747Speter return (TSET); 74*15975Smckusick case CRANGE: 75747Speter case RANGE: 76747Speter p = p->type; 77747Speter goto swit; 78747Speter case TYPE: 79747Speter if (p <= nl+TLAST) 80747Speter return (p - nl); 81747Speter panic("clas2"); 82747Speter case FILET: 83747Speter return (TFILE); 84747Speter case RECORD: 85747Speter return (TREC); 86747Speter case SCAL: 87747Speter return (TSCAL); 88747Speter default: 8914728Sthien { 9014728Sthien panic("clas"); 9114728Sthien return(NIL); 9214728Sthien } 93747Speter } 94747Speter } 95747Speter 96747Speter #ifndef PI0 97747Speter /* 98747Speter * Is p a text file? 99747Speter */ 100747Speter text(p) 101747Speter struct nl *p; 102747Speter { 103747Speter 104747Speter return (p != NIL && p->class == FILET && p->type == nl+T1CHAR); 105747Speter } 106747Speter #endif 107747Speter 108747Speter /* 109747Speter * Scalar returns a pointer to 110747Speter * the the base scalar type of 111747Speter * its argument if its argument 112747Speter * is a SCALar else NIL. 113747Speter */ 11414728Sthien struct nl * 115747Speter scalar(p1) 116747Speter struct nl *p1; 117747Speter { 118747Speter register struct nl *p; 119747Speter 120747Speter p = p1; 12114728Sthien if (p == NLNIL) 12214728Sthien return (NLNIL); 123*15975Smckusick if (p->class == RANGE || p->class == CRANGE) 124747Speter p = p->type; 12514728Sthien if (p == NLNIL) 12614728Sthien return (NLNIL); 12714728Sthien return (p->class == SCAL ? p : NLNIL); 128747Speter } 129747Speter 130747Speter /* 131747Speter * Isa tells whether p 132747Speter * is one of a group of 133747Speter * namelist classes. The 134747Speter * classes wanted are specified 135747Speter * by the characters in s. 136747Speter * (Note that s would more efficiently, 137747Speter * if less clearly, be given by a mask.) 138747Speter */ 139747Speter isa(p, s) 140747Speter register struct nl *p; 141747Speter char *s; 142747Speter { 143747Speter register i; 144747Speter register char *cp; 145747Speter 146747Speter if (p == NIL) 147747Speter return (NIL); 148747Speter /* 149747Speter * map ranges down to 150747Speter * the base type 151747Speter */ 152*15975Smckusick if (p->class == RANGE) { 153747Speter p = p->type; 154*15975Smckusick } 155747Speter /* 156747Speter * the following character/class 157747Speter * associations are made: 158747Speter * 159747Speter * s scalar 160747Speter * b Boolean 161747Speter * c character 162747Speter * i integer 163747Speter * d double (real) 164747Speter * t set 165747Speter */ 166747Speter switch (p->class) { 167747Speter case SET: 168747Speter i = TDOUBLE+1; 169747Speter break; 170747Speter case SCAL: 171747Speter i = 0; 172747Speter break; 173*15975Smckusick case CRANGE: 174*15975Smckusick /* 175*15975Smckusick * find the base type of a conformant array range 176*15975Smckusick */ 177*15975Smckusick switch (classify(p->type)) { 178*15975Smckusick case TBOOL: i = 1; break; 179*15975Smckusick case TCHAR: i = 2; break; 180*15975Smckusick case TINT: i = 3; break; 181*15975Smckusick case TSCAL: i = 0; break; 182*15975Smckusick default: 183*15975Smckusick panic( "isa" ); 184*15975Smckusick } 185*15975Smckusick break; 186747Speter default: 187747Speter i = p - nl; 188747Speter } 189747Speter if (i >= 0 && i <= TDOUBLE+1) { 190747Speter i = "sbcidt"[i]; 191747Speter cp = s; 192747Speter while (*cp) 193747Speter if (*cp++ == i) 194747Speter return (1); 195747Speter } 196747Speter return (NIL); 197747Speter } 198747Speter 199747Speter /* 200747Speter * Isnta is !isa 201747Speter */ 202747Speter isnta(p, s) 20314728Sthien struct nl *p; 20414728Sthien char *s; 205747Speter { 206747Speter 207747Speter return (!isa(p, s)); 208747Speter } 209747Speter 210747Speter /* 211747Speter * "shorthand" 212747Speter */ 21314728Sthien char * 214747Speter nameof(p) 21514728Sthien struct nl *p; 216747Speter { 217747Speter 218747Speter return (clnames[classify(p)]); 219747Speter } 220747Speter 221747Speter #ifndef PI0 22214728Sthien /* find out for sure what kind of node this is being passed 22314728Sthien possibly several different kinds of node are passed to it */ 22414728Sthien int nowexp(r) 22514728Sthien struct tnode *r; 226747Speter { 22714728Sthien if (r->tag == T_WEXP) { 22814728Sthien if (r->var_node.cptr == NIL) 229747Speter error("Oct/hex allowed only on writeln/write calls"); 230747Speter else 231747Speter error("Width expressions allowed only in writeln/write calls"); 232747Speter return (1); 233747Speter } 234747Speter return (NIL); 235747Speter } 236747Speter #endif 2373276Smckusic 2383276Smckusic /* 2393825Speter * is a variable a local, a formal parameter, or a global? 2403276Smckusic * all this from just the offset: 2413825Speter * globals are at levels 0 or 1 2423276Smckusic * positives are parameters 2433276Smckusic * negative evens are locals 2443276Smckusic */ 24514728Sthien /*ARGSUSED*/ 24614728Sthien whereis( offset , other_flags ) 2473825Speter int offset; 2487920Smckusick char other_flags; 2493276Smckusic { 2503276Smckusic 2513825Speter # ifdef OBJ 2523825Speter return ( offset >= 0 ? PARAMVAR : LOCALVAR ); 2533825Speter # endif OBJ 2543825Speter # ifdef PC 2559127Smckusick switch ( other_flags & ( NGLOBAL | NPARAM | NLOCAL | NNLOCAL) ) { 25614728Sthien default: 25714728Sthien panic( "whereis" ); 2583825Speter case NGLOBAL: 2593825Speter return GLOBALVAR; 2603825Speter case NPARAM: 2613825Speter return PARAMVAR; 2629127Smckusick case NNLOCAL: 2639127Smckusick return NAMEDLOCALVAR; 2643825Speter case NLOCAL: 2653825Speter return LOCALVAR; 2663825Speter } 2673825Speter # endif PC 2683276Smckusic } 269