|
|
1.1 ! root 1: /* Copyright (c) 1982 Regents of the University of California */ ! 2: ! 3: static char sccsid[] = "@(#)check.c 1.5 8/10/83"; ! 4: ! 5: /* ! 6: * Check a tree for semantic correctness. ! 7: */ ! 8: ! 9: #include "defs.h" ! 10: #include "tree.h" ! 11: #include "operators.h" ! 12: #include "events.h" ! 13: #include "symbols.h" ! 14: #include "scanner.h" ! 15: #include "source.h" ! 16: #include "object.h" ! 17: #include "mappings.h" ! 18: #include "process.h" ! 19: ! 20: #ifndef public ! 21: #endif ! 22: ! 23: /* ! 24: * Check that the nodes in a tree have the correct arguments ! 25: * in order to be evaluated. Basically the error checking here ! 26: * frees the evaluation routines from worrying about anything ! 27: * except dynamic errors, e.g. subscript out of range. ! 28: */ ! 29: ! 30: public check(p) ! 31: register Node p; ! 32: { ! 33: Address addr; ! 34: Symbol f; ! 35: ! 36: checkref(p); ! 37: switch (p->op) { ! 38: case O_LIST: ! 39: if (p->value.arg[0]->op == O_SYM) { ! 40: f = p->value.arg[0]->value.sym; ! 41: if (not isblock(f) or ismodule(f)) { ! 42: error("\"%s\" is not a procedure or function", symname(f)); ! 43: } ! 44: addr = firstline(f); ! 45: if (addr == NOADDR) { ! 46: error("\"%s\" is empty", symname(f)); ! 47: } ! 48: } ! 49: break; ! 50: ! 51: case O_TRACE: ! 52: case O_TRACEI: ! 53: chktrace(p); ! 54: break; ! 55: ! 56: case O_STOP: ! 57: case O_STOPI: ! 58: chkstop(p); ! 59: break; ! 60: ! 61: default: ! 62: break; ! 63: } ! 64: } ! 65: ! 66: /* ! 67: * Check arguments to a trace command. ! 68: */ ! 69: ! 70: private chktrace(p) ! 71: Node p; ! 72: { ! 73: Node exp, place, cond; ! 74: ! 75: exp = p->value.arg[0]; ! 76: place = p->value.arg[1]; ! 77: cond = p->value.arg[2]; ! 78: if (exp == nil) { ! 79: chkblock(place); ! 80: } else if (exp->op == O_LCON or exp->op == O_QLINE) { ! 81: if (place != nil) { ! 82: error("unexpected \"at\" or \"in\""); ! 83: } ! 84: if (p->op == O_TRACE) { ! 85: chkline(exp); ! 86: } else { ! 87: chkaddr(exp); ! 88: } ! 89: } else if (place != nil and (place->op == O_QLINE or place->op == O_LCON)) { ! 90: if (p->op == O_TRACE) { ! 91: chkline(place); ! 92: } else { ! 93: chkaddr(place); ! 94: } ! 95: } else { ! 96: if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_CALL) { ! 97: error("can't trace expressions"); ! 98: } ! 99: chkblock(place); ! 100: } ! 101: } ! 102: ! 103: /* ! 104: * Check arguments to a stop command. ! 105: */ ! 106: ! 107: private chkstop(p) ! 108: Node p; ! 109: { ! 110: Node exp, place, cond; ! 111: ! 112: exp = p->value.arg[0]; ! 113: place = p->value.arg[1]; ! 114: cond = p->value.arg[2]; ! 115: if (exp != nil) { ! 116: if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_LCON) { ! 117: beginerrmsg(); ! 118: fprintf(stderr, "expected variable, found "); ! 119: prtree(stderr, exp); ! 120: enderrmsg(); ! 121: } ! 122: chkblock(place); ! 123: } else if (place->op == O_SYM) { ! 124: chkblock(place); ! 125: } else { ! 126: if (p->op == O_STOP) { ! 127: chkline(place); ! 128: } else { ! 129: chkaddr(place); ! 130: } ! 131: } ! 132: } ! 133: ! 134: /* ! 135: * Check to see that the given node specifies some subprogram. ! 136: * Nil is ok since that means the entire program. ! 137: */ ! 138: ! 139: private chkblock(b) ! 140: Node b; ! 141: { ! 142: if (b != nil) { ! 143: if (b->op != O_SYM) { ! 144: beginerrmsg(); ! 145: fprintf(stderr, "expected subprogram, found "); ! 146: prtree(stderr, b); ! 147: enderrmsg(); ! 148: } else if (not isblock(b->value.sym) or ismodule(b->value.sym)) { ! 149: error("\"%s\" is not a subprogram", symname(b->value.sym)); ! 150: } ! 151: } ! 152: } ! 153: ! 154: /* ! 155: * Check to make sure a node corresponds to a source line. ! 156: */ ! 157: ! 158: private chkline(p) ! 159: Node p; ! 160: { ! 161: if (p == nil) { ! 162: error("missing line"); ! 163: } else if (p->op != O_QLINE and p->op != O_LCON) { ! 164: error("expected source line number, found \"%t\"", p); ! 165: } ! 166: } ! 167: ! 168: /* ! 169: * Check to make sure a node corresponds to an address. ! 170: */ ! 171: ! 172: private chkaddr(p) ! 173: Node p; ! 174: { ! 175: if (p == nil) { ! 176: error("missing address"); ! 177: } else if (p->op != O_LCON and p->op != O_QLINE) { ! 178: beginerrmsg(); ! 179: fprintf(stderr, "expected address, found \""); ! 180: prtree(stderr, p); ! 181: fprintf(stderr, "\""); ! 182: enderrmsg(); ! 183: } ! 184: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.