1747Speter /* Copyright (c) 1979 Regents of the University of California */ 2747Speter 3*3825Speter static char sccsid[] = "@(#)clas.c 1.4 06/01/81"; 4747Speter 5747Speter #include "whoami.h" 6747Speter #include "0.h" 7747Speter #include "tree.h" 8747Speter 9747Speter /* 10747Speter * This is the array of class 11747Speter * names for the classes returned 12747Speter * by classify. The order of the 13747Speter * classes is the same as the base 14747Speter * of the namelist, with special 15747Speter * negative index entries for structures, 16747Speter * scalars, pointers, sets and strings 17747Speter * to be collapsed into. 18747Speter */ 19747Speter char *clnxxxx[] = 20747Speter { 21747Speter "file", /* -7 TFILE */ 22747Speter "record", /* -6 TREC */ 23747Speter "array", /* -5 TARY */ 24747Speter "scalar", /* -4 TSCAL */ 25747Speter "pointer", /* -3 TPTR */ 26747Speter "set", /* -2 TSET */ 27747Speter "string", /* -1 TSTR */ 28747Speter "SNARK", /* 0 NIL */ 29747Speter "Boolean", /* 1 TBOOL */ 30747Speter "char", /* 2 TCHAR */ 31747Speter "integer", /* 3 TINT */ 32747Speter "real", /* 4 TREAL */ 33747Speter "\"nil\"", /* 5 TNIL */ 34747Speter }; 35747Speter 36747Speter char **clnames = &clnxxxx[-(TFIRST)]; 37747Speter 38747Speter /* 39747Speter * Classify takes a pointer 40747Speter * to a type and returns one 41747Speter * of several interesting group 42747Speter * classifications for easy use. 43747Speter */ 44747Speter classify(p1) 45747Speter struct nl *p1; 46747Speter { 47747Speter register struct nl *p; 48747Speter 49747Speter p = p1; 50747Speter swit: 51747Speter if (p == NIL) { 52747Speter nocascade(); 53747Speter return (NIL); 54747Speter } 55747Speter if (p == &nl[TSTR]) 56747Speter return (TSTR); 57747Speter if ( p == &nl[ TSET ] ) { 58747Speter return TSET; 59747Speter } 60747Speter switch (p->class) { 61747Speter case PTR: 62747Speter return (TPTR); 63747Speter case ARRAY: 64747Speter if (p->type == nl+T1CHAR) 65747Speter return (TSTR); 66747Speter return (TARY); 67747Speter case STR: 68747Speter return (TSTR); 69747Speter case SET: 70747Speter return (TSET); 71747Speter case RANGE: 72747Speter p = p->type; 73747Speter goto swit; 74747Speter case TYPE: 75747Speter if (p <= nl+TLAST) 76747Speter return (p - nl); 77747Speter panic("clas2"); 78747Speter case FILET: 79747Speter return (TFILE); 80747Speter case RECORD: 81747Speter return (TREC); 82747Speter case SCAL: 83747Speter return (TSCAL); 84747Speter default: 85747Speter panic("clas"); 86747Speter } 87747Speter } 88747Speter 89747Speter #ifndef PI0 90747Speter /* 91747Speter * Is p a text file? 92747Speter */ 93747Speter text(p) 94747Speter struct nl *p; 95747Speter { 96747Speter 97747Speter return (p != NIL && p->class == FILET && p->type == nl+T1CHAR); 98747Speter } 99747Speter #endif 100747Speter 101747Speter /* 102747Speter * Scalar returns a pointer to 103747Speter * the the base scalar type of 104747Speter * its argument if its argument 105747Speter * is a SCALar else NIL. 106747Speter */ 107747Speter scalar(p1) 108747Speter struct nl *p1; 109747Speter { 110747Speter register struct nl *p; 111747Speter 112747Speter p = p1; 113747Speter if (p == NIL) 114747Speter return (NIL); 115747Speter if (p->class == RANGE) 116747Speter p = p->type; 117747Speter if (p == NIL) 118747Speter return (NIL); 119747Speter return (p->class == SCAL ? p : NIL); 120747Speter } 121747Speter 122747Speter /* 123747Speter * Isa tells whether p 124747Speter * is one of a group of 125747Speter * namelist classes. The 126747Speter * classes wanted are specified 127747Speter * by the characters in s. 128747Speter * (Note that s would more efficiently, 129747Speter * if less clearly, be given by a mask.) 130747Speter */ 131747Speter isa(p, s) 132747Speter register struct nl *p; 133747Speter char *s; 134747Speter { 135747Speter register i; 136747Speter register char *cp; 137747Speter 138747Speter if (p == NIL) 139747Speter return (NIL); 140747Speter /* 141747Speter * map ranges down to 142747Speter * the base type 143747Speter */ 144747Speter if (p->class == RANGE) 145747Speter p = p->type; 146747Speter /* 147747Speter * the following character/class 148747Speter * associations are made: 149747Speter * 150747Speter * s scalar 151747Speter * b Boolean 152747Speter * c character 153747Speter * i integer 154747Speter * d double (real) 155747Speter * t set 156747Speter */ 157747Speter switch (p->class) { 158747Speter case SET: 159747Speter i = TDOUBLE+1; 160747Speter break; 161747Speter case SCAL: 162747Speter i = 0; 163747Speter break; 164747Speter default: 165747Speter i = p - nl; 166747Speter } 167747Speter if (i >= 0 && i <= TDOUBLE+1) { 168747Speter i = "sbcidt"[i]; 169747Speter cp = s; 170747Speter while (*cp) 171747Speter if (*cp++ == i) 172747Speter return (1); 173747Speter } 174747Speter return (NIL); 175747Speter } 176747Speter 177747Speter /* 178747Speter * Isnta is !isa 179747Speter */ 180747Speter isnta(p, s) 181747Speter { 182747Speter 183747Speter return (!isa(p, s)); 184747Speter } 185747Speter 186747Speter /* 187747Speter * "shorthand" 188747Speter */ 189747Speter nameof(p) 190747Speter { 191747Speter 192747Speter return (clnames[classify(p)]); 193747Speter } 194747Speter 195747Speter #ifndef PI0 196747Speter nowexp(r) 197747Speter int *r; 198747Speter { 199747Speter if (r[0] == T_WEXP) { 200747Speter if (r[2] == NIL) 201747Speter error("Oct/hex allowed only on writeln/write calls"); 202747Speter else 203747Speter error("Width expressions allowed only in writeln/write calls"); 204747Speter return (1); 205747Speter } 206747Speter return (NIL); 207747Speter } 208747Speter #endif 2093276Smckusic 2103276Smckusic /* 211*3825Speter * is a variable a local, a formal parameter, or a global? 2123276Smckusic * all this from just the offset: 213*3825Speter * globals are at levels 0 or 1 2143276Smckusic * positives are parameters 2153276Smckusic * negative evens are locals 2163276Smckusic */ 217*3825Speter whereis( level , offset , extra_flags ) 218*3825Speter int level; 219*3825Speter int offset; 220*3825Speter char extra_flags; 2213276Smckusic { 2223276Smckusic 223*3825Speter # ifdef OBJ 224*3825Speter return ( offset >= 0 ? PARAMVAR : LOCALVAR ); 225*3825Speter # endif OBJ 226*3825Speter # ifdef PC 227*3825Speter switch ( extra_flags & ( NGLOBAL | NPARAM | NLOCAL ) ) { 228*3825Speter case NGLOBAL: 229*3825Speter return GLOBALVAR; 230*3825Speter case NPARAM: 231*3825Speter return PARAMVAR; 232*3825Speter case NLOCAL: 233*3825Speter return LOCALVAR; 234*3825Speter default: 235*3825Speter panic( "whereis" ); 236*3825Speter } 237*3825Speter # endif PC 2383276Smckusic } 239