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