xref: /original-bsd/old/dbx/check.c (revision f0fd5f8a)
1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)check.c 1.2 12/15/82";
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) {
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) {
117 	    beginerrmsg();
118 	    fprintf(stderr, "expected variable, found ");
119 	    prtree(stderr, exp);
120 	    enderrmsg();
121 	}
122 	chkblock(place);
123     } else if (cond != nil) {
124 	chkblock(place);
125     } else if (place->op == O_SYM) {
126 	chkblock(place);
127     } else {
128 	if (p->op == O_STOP) {
129 	    chkline(place);
130 	} else {
131 	    chkaddr(place);
132 	}
133     }
134 }
135 
136 /*
137  * Check to see that the given node specifies some subprogram.
138  * Nil is ok since that means the entire program.
139  */
140 
141 private chkblock(b)
142 Node b;
143 {
144     if (b != nil) {
145 	if (b->op != O_SYM) {
146 	    beginerrmsg();
147 	    fprintf(stderr, "expected subprogram, found ");
148 	    prtree(stderr, b);
149 	    enderrmsg();
150 	} else if (not isblock(b->value.sym) or ismodule(b->value.sym)) {
151 	    error("\"%s\" is not a subprogram", symname(b->value.sym));
152 	}
153     }
154 }
155 
156 /*
157  * Check to make sure a node corresponds to a source line.
158  */
159 
160 private chkline(p)
161 Node p;
162 {
163     if (p == nil) {
164 	error("missing line");
165     } else if (p->op != O_QLINE and p->op != O_LCON) {
166 	error("expected source line number, found \"%t\"", p);
167     }
168 }
169 
170 /*
171  * Check to make sure a node corresponds to an address.
172  */
173 
174 private chkaddr(p)
175 Node p;
176 {
177     if (p == nil) {
178 	error("missing address");
179     } else if (p->op != O_LCON and p->op != O_QLINE) {
180 	beginerrmsg();
181 	fprintf(stderr, "expected address, found \"");
182 	prtree(stderr, p);
183 	fprintf(stderr, "\"");
184 	enderrmsg();
185     }
186 }
187