|
|
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.