xref: /original-bsd/old/dbx/check.c (revision c43e4352)
1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)check.c 1.4 07/08/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) {
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 }
185