1: /*
   2:  * Copyright (c) 1983 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: static char sccsid[] = "@(#)check.c	5.2 (Berkeley) 1/10/86";
   9: #endif not lint
  10: 
  11: static char rcsid[] = "$Header: check.c,v 1.5 84/12/26 10:38:35 linton Exp $";
  12: 
  13: /*
  14:  * Check a tree for semantic correctness.
  15:  */
  16: 
  17: #include "defs.h"
  18: #include "tree.h"
  19: #include "operators.h"
  20: #include "events.h"
  21: #include "symbols.h"
  22: #include "scanner.h"
  23: #include "source.h"
  24: #include "object.h"
  25: #include "mappings.h"
  26: #include "process.h"
  27: #include <signal.h>
  28: 
  29: #ifndef public
  30: #endif
  31: 
  32: /*
  33:  * Check that the nodes in a tree have the correct arguments
  34:  * in order to be evaluated.  Basically the error checking here
  35:  * frees the evaluation routines from worrying about anything
  36:  * except dynamic errors, e.g. subscript out of range.
  37:  */
  38: 
  39: public check(p)
  40: register Node p;
  41: {
  42:     Node p1, p2;
  43:     Address addr;
  44:     Symbol f;
  45: 
  46:     checkref(p);
  47:     switch (p->op) {
  48:     case O_ASSIGN:
  49:         p1 = p->value.arg[0];
  50:         p2 = p->value.arg[1];
  51:         if (varIsSet("$unsafeassign")) {
  52:         if (size(p1->nodetype) != size(p2->nodetype)) {
  53:             error("incompatible sizes");
  54:         }
  55:         } else if (not compatible(p1->nodetype, p2->nodetype)) {
  56:         error("incompatible types");
  57:         }
  58:         break;
  59: 
  60:     case O_CATCH:
  61:     case O_IGNORE:
  62:         if (p->value.lcon < 0 or p->value.lcon > NSIG) {
  63:         error("invalid signal number");
  64:         }
  65:         break;
  66: 
  67:     case O_CONT:
  68:         if (p->value.lcon != DEFSIG and (
  69:         p->value.lcon < 0 or p->value.lcon > NSIG)
  70:         ) {
  71:         error("invalid signal number");
  72:         }
  73:         break;
  74: 
  75:     case O_DUMP:
  76:         if (p->value.arg[0] != nil) {
  77:         if (p->value.arg[0]->op == O_SYM) {
  78:             f = p->value.arg[0]->value.sym;
  79:             if (not isblock(f)) {
  80:             error("\"%s\" is not a block", symname(f));
  81:             }
  82:         } else {
  83:             beginerrmsg();
  84:             fprintf(stderr, "expected a symbol, found \"");
  85:             prtree(stderr, p->value.arg[0]);
  86:             fprintf(stderr, "\"");
  87:             enderrmsg();
  88:         }
  89:         }
  90:         break;
  91: 
  92:     case O_LIST:
  93:         if (p->value.arg[0]->op == O_SYM) {
  94:         f = p->value.arg[0]->value.sym;
  95:         if (not isblock(f) or ismodule(f)) {
  96:             error("\"%s\" is not a procedure or function", symname(f));
  97:         }
  98:         addr = firstline(f);
  99:         if (addr == NOADDR) {
 100:             error("\"%s\" is empty", symname(f));
 101:         }
 102:         }
 103:         break;
 104: 
 105:     case O_TRACE:
 106:     case O_TRACEI:
 107:         chktrace(p);
 108:         break;
 109: 
 110:     case O_STOP:
 111:     case O_STOPI:
 112:         chkstop(p);
 113:         break;
 114: 
 115:     case O_CALLPROC:
 116:     case O_CALL:
 117:         if (not isroutine(p->value.arg[0]->nodetype)) {
 118:         beginerrmsg();
 119:         fprintf(stderr, "\"");
 120:         prtree(stderr, p->value.arg[0]);
 121:         fprintf(stderr, "\" not call-able");
 122:         enderrmsg();
 123:         }
 124:         break;
 125: 
 126:     case O_WHEREIS:
 127:         if (p->value.arg[0]->op == O_SYM and
 128:           p->value.arg[0]->value.sym == nil) {
 129:         error("symbol not defined");
 130:         }
 131:         break;
 132: 
 133:     default:
 134:         break;
 135:     }
 136: }
 137: 
 138: /*
 139:  * Check arguments to a trace command.
 140:  */
 141: 
 142: private chktrace(p)
 143: Node p;
 144: {
 145:     Node exp, place, cond;
 146: 
 147:     exp = p->value.arg[0];
 148:     place = p->value.arg[1];
 149:     cond = p->value.arg[2];
 150:     if (exp == nil) {
 151:     chkblock(place);
 152:     } else if (exp->op == O_LCON or exp->op == O_QLINE) {
 153:     if (place != nil) {
 154:         error("unexpected \"at\" or \"in\"");
 155:     }
 156:     if (p->op == O_TRACE) {
 157:         chkline(exp);
 158:     } else {
 159:         chkaddr(exp);
 160:     }
 161:     } else if (place != nil and (place->op == O_QLINE or place->op == O_LCON)) {
 162:     if (p->op == O_TRACE) {
 163:         chkline(place);
 164:     } else {
 165:         chkaddr(place);
 166:     }
 167:     } else {
 168:     if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_CALL) {
 169:         error("can't trace expressions");
 170:     }
 171:     chkblock(place);
 172:     }
 173: }
 174: 
 175: /*
 176:  * Check arguments to a stop command.
 177:  */
 178: 
 179: private chkstop(p)
 180: Node p;
 181: {
 182:     Node exp, place, cond;
 183: 
 184:     exp = p->value.arg[0];
 185:     place = p->value.arg[1];
 186:     cond = p->value.arg[2];
 187:     if (exp != nil) {
 188:     if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_LCON) {
 189:         beginerrmsg();
 190:         fprintf(stderr, "expected variable, found ");
 191:         prtree(stderr, exp);
 192:         enderrmsg();
 193:     }
 194:     chkblock(place);
 195:     } else if (place != nil) {
 196:     if (place->op == O_SYM) {
 197:         chkblock(place);
 198:     } else {
 199:         if (p->op == O_STOP) {
 200:         chkline(place);
 201:         } else {
 202:         chkaddr(place);
 203:         }
 204:     }
 205:     }
 206: }
 207: 
 208: /*
 209:  * Check to see that the given node specifies some subprogram.
 210:  * Nil is ok since that means the entire program.
 211:  */
 212: 
 213: private chkblock(b)
 214: Node b;
 215: {
 216:     Symbol p, outer;
 217: 
 218:     if (b != nil) {
 219:     if (b->op != O_SYM) {
 220:         beginerrmsg();
 221:         fprintf(stderr, "expected subprogram, found ");
 222:         prtree(stderr, b);
 223:         enderrmsg();
 224:     } else if (ismodule(b->value.sym)) {
 225:         outer = b->value.sym;
 226:         while (outer != nil) {
 227:         find(p, outer->name) where p->block == outer endfind(p);
 228:         if (p == nil) {
 229:             outer = nil;
 230:             error("\"%s\" is not a subprogram", symname(b->value.sym));
 231:         } else if (ismodule(p)) {
 232:             outer = p;
 233:         } else {
 234:             outer = nil;
 235:             b->value.sym = p;
 236:         }
 237:         }
 238:     } else if (
 239:         b->value.sym->class == VAR and
 240:         b->value.sym->name == b->value.sym->block->name and
 241:         b->value.sym->block->class == FUNC
 242:     ) {
 243:         b->value.sym = b->value.sym->block;
 244:     } else if (not isblock(b->value.sym)) {
 245:         error("\"%s\" is not a subprogram", symname(b->value.sym));
 246:     }
 247:     }
 248: }
 249: 
 250: /*
 251:  * Check to make sure a node corresponds to a source line.
 252:  */
 253: 
 254: private chkline(p)
 255: Node p;
 256: {
 257:     if (p == nil) {
 258:     error("missing line");
 259:     } else if (p->op != O_QLINE and p->op != O_LCON) {
 260:     error("expected source line number, found \"%t\"", p);
 261:     }
 262: }
 263: 
 264: /*
 265:  * Check to make sure a node corresponds to an address.
 266:  */
 267: 
 268: private chkaddr(p)
 269: Node p;
 270: {
 271:     if (p == nil) {
 272:     error("missing address");
 273:     } else if (p->op != O_LCON and p->op != O_QLINE) {
 274:     beginerrmsg();
 275:     fprintf(stderr, "expected address, found \"");
 276:     prtree(stderr, p);
 277:     fprintf(stderr, "\"");
 278:     enderrmsg();
 279:     }
 280: }

Defined functions

check defined in line 39; used 1 times
chkaddr defined in line 268; used 3 times
chkblock defined in line 213; used 4 times
chkline defined in line 254; used 3 times
chkstop defined in line 179; used 1 times
chktrace defined in line 142; used 1 times

Defined variables

rcsid defined in line 11; never used
sccsid defined in line 8; never used
Last modified: 1986-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1256
Valid CSS Valid XHTML 1.0 Strict