Distinguish logical and logical*2 types, and print both types correctly;
[unix-history] / usr / src / old / dbx / check.c
CommitLineData
2a24676e
DF
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 */
b329a001 6
2a24676e
DF
7#ifndef lint
8static char sccsid[] = "@(#)check.c 5.1 (Berkeley) %G%";
9#endif not lint
0022c355
ML
10
11static char rcsid[] = "$Header: check.c,v 1.5 84/12/26 10:38:35 linton Exp $";
b329a001
ML
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"
0022c355 27#include <signal.h>
b329a001
ML
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
39public check(p)
40register Node p;
41{
0022c355 42 Node p1, p2;
b329a001
ML
43 Address addr;
44 Symbol f;
45
46 checkref(p);
47 switch (p->op) {
0022c355
ML
48 case O_ASSIGN:
49 p1 = p->value.arg[0];
50 p2 = p->value.arg[1];
51 if (not compatible(p1->nodetype, p2->nodetype)) {
52 error("incompatible types");
53 }
54 break;
55
56 case O_CATCH:
57 case O_IGNORE:
58 if (p->value.lcon < 0 or p->value.lcon > NSIG) {
59 error("invalid signal number");
60 }
61 break;
62
63 case O_CONT:
64 if (p->value.lcon != DEFSIG and (
65 p->value.lcon < 0 or p->value.lcon > NSIG)
66 ) {
67 error("invalid signal number");
68 }
69 break;
70
71 case O_DUMP:
72 if (p->value.arg[0] != nil) {
73 if (p->value.arg[0]->op == O_SYM) {
74 f = p->value.arg[0]->value.sym;
75 if (not isblock(f)) {
76 error("\"%s\" is not a block", symname(f));
77 }
78 } else {
79 beginerrmsg();
80 fprintf(stderr, "expected a symbol, found \"");
81 prtree(stderr, p->value.arg[0]);
82 fprintf(stderr, "\"");
83 enderrmsg();
84 }
85 }
86 break;
87
b329a001
ML
88 case O_LIST:
89 if (p->value.arg[0]->op == O_SYM) {
90 f = p->value.arg[0]->value.sym;
91 if (not isblock(f) or ismodule(f)) {
92 error("\"%s\" is not a procedure or function", symname(f));
93 }
94 addr = firstline(f);
95 if (addr == NOADDR) {
96 error("\"%s\" is empty", symname(f));
97 }
98 }
99 break;
100
101 case O_TRACE:
102 case O_TRACEI:
103 chktrace(p);
104 break;
105
106 case O_STOP:
107 case O_STOPI:
108 chkstop(p);
109 break;
110
0022c355 111 case O_CALLPROC:
2fd0f574
SL
112 case O_CALL:
113 if (not isroutine(p->value.arg[0]->nodetype)) {
114 beginerrmsg();
115 fprintf(stderr, "\"");
116 prtree(stderr, p->value.arg[0]);
117 fprintf(stderr, "\" not call-able");
118 enderrmsg();
119 }
120 break;
121
0022c355
ML
122 case O_WHEREIS:
123 if (p->value.arg[0]->op == O_SYM and
124 p->value.arg[0]->value.sym == nil) {
125 error("symbol not defined");
126 }
127 break;
128
b329a001
ML
129 default:
130 break;
131 }
132}
133
134/*
135 * Check arguments to a trace command.
136 */
137
138private chktrace(p)
139Node p;
140{
141 Node exp, place, cond;
142
143 exp = p->value.arg[0];
144 place = p->value.arg[1];
145 cond = p->value.arg[2];
146 if (exp == nil) {
147 chkblock(place);
148 } else if (exp->op == O_LCON or exp->op == O_QLINE) {
149 if (place != nil) {
150 error("unexpected \"at\" or \"in\"");
151 }
152 if (p->op == O_TRACE) {
153 chkline(exp);
154 } else {
155 chkaddr(exp);
156 }
157 } else if (place != nil and (place->op == O_QLINE or place->op == O_LCON)) {
158 if (p->op == O_TRACE) {
159 chkline(place);
160 } else {
161 chkaddr(place);
162 }
163 } else {
7bf092d9 164 if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_CALL) {
b329a001
ML
165 error("can't trace expressions");
166 }
167 chkblock(place);
168 }
169}
170
171/*
172 * Check arguments to a stop command.
173 */
174
175private chkstop(p)
176Node p;
177{
178 Node exp, place, cond;
179
180 exp = p->value.arg[0];
181 place = p->value.arg[1];
182 cond = p->value.arg[2];
183 if (exp != nil) {
7cc22d81 184 if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_LCON) {
b329a001
ML
185 beginerrmsg();
186 fprintf(stderr, "expected variable, found ");
187 prtree(stderr, exp);
188 enderrmsg();
189 }
190 chkblock(place);
2fd0f574
SL
191 } else if (place != nil) {
192 if (place->op == O_SYM) {
193 chkblock(place);
b329a001 194 } else {
2fd0f574
SL
195 if (p->op == O_STOP) {
196 chkline(place);
197 } else {
198 chkaddr(place);
199 }
b329a001
ML
200 }
201 }
202}
203
204/*
205 * Check to see that the given node specifies some subprogram.
206 * Nil is ok since that means the entire program.
207 */
208
209private chkblock(b)
210Node b;
211{
2fd0f574
SL
212 Symbol p, outer;
213
b329a001
ML
214 if (b != nil) {
215 if (b->op != O_SYM) {
216 beginerrmsg();
217 fprintf(stderr, "expected subprogram, found ");
218 prtree(stderr, b);
219 enderrmsg();
2fd0f574
SL
220 } else if (ismodule(b->value.sym)) {
221 outer = b->value.sym;
222 while (outer != nil) {
223 find(p, outer->name) where p->block == outer endfind(p);
224 if (p == nil) {
225 outer = nil;
226 error("\"%s\" is not a subprogram", symname(b->value.sym));
227 } else if (ismodule(p)) {
228 outer = p;
229 } else {
230 outer = nil;
231 b->value.sym = p;
232 }
233 }
0022c355
ML
234 } else if (
235 b->value.sym->class == VAR and
236 b->value.sym->name == b->value.sym->block->name and
237 b->value.sym->block->class == FUNC
238 ) {
239 b->value.sym = b->value.sym->block;
2fd0f574 240 } else if (not isblock(b->value.sym)) {
b329a001
ML
241 error("\"%s\" is not a subprogram", symname(b->value.sym));
242 }
243 }
244}
245
246/*
247 * Check to make sure a node corresponds to a source line.
248 */
249
250private chkline(p)
251Node p;
252{
253 if (p == nil) {
254 error("missing line");
255 } else if (p->op != O_QLINE and p->op != O_LCON) {
256 error("expected source line number, found \"%t\"", p);
257 }
258}
259
260/*
261 * Check to make sure a node corresponds to an address.
262 */
263
264private chkaddr(p)
265Node p;
266{
267 if (p == nil) {
268 error("missing address");
269 } else if (p->op != O_LCON and p->op != O_QLINE) {
270 beginerrmsg();
271 fprintf(stderr, "expected address, found \"");
272 prtree(stderr, p);
273 fprintf(stderr, "\"");
274 enderrmsg();
275 }
276}