xref: /csrg-svn/old/dbx/check.c (revision 9861)
19660Slinton /* Copyright (c) 1982 Regents of the University of California */
29660Slinton 
3*9861Slinton static char sccsid[] = "@(#)check.c 1.3 12/20/82";
49660Slinton 
59660Slinton /*
69660Slinton  * Check a tree for semantic correctness.
79660Slinton  */
89660Slinton 
99660Slinton #include "defs.h"
109660Slinton #include "tree.h"
119660Slinton #include "operators.h"
129660Slinton #include "events.h"
139660Slinton #include "symbols.h"
149660Slinton #include "scanner.h"
159660Slinton #include "source.h"
169660Slinton #include "object.h"
179660Slinton #include "mappings.h"
189660Slinton #include "process.h"
199660Slinton 
209660Slinton #ifndef public
219660Slinton #endif
229660Slinton 
239660Slinton /*
249660Slinton  * Check that the nodes in a tree have the correct arguments
259660Slinton  * in order to be evaluated.  Basically the error checking here
269660Slinton  * frees the evaluation routines from worrying about anything
279660Slinton  * except dynamic errors, e.g. subscript out of range.
289660Slinton  */
299660Slinton 
309660Slinton public check(p)
319660Slinton register Node p;
329660Slinton {
339660Slinton     Address addr;
349660Slinton     Symbol f;
359660Slinton 
369660Slinton     checkref(p);
379660Slinton     switch (p->op) {
389660Slinton 	case O_LIST:
399660Slinton 	    if (p->value.arg[0]->op == O_SYM) {
409660Slinton 		f = p->value.arg[0]->value.sym;
419660Slinton 		if (not isblock(f) or ismodule(f)) {
429660Slinton 		    error("\"%s\" is not a procedure or function", symname(f));
439660Slinton 		}
449660Slinton 		addr = firstline(f);
459660Slinton 		if (addr == NOADDR) {
469660Slinton 		    error("\"%s\" is empty", symname(f));
479660Slinton 		}
489660Slinton 	    }
499660Slinton 	    break;
509660Slinton 
519660Slinton 	case O_TRACE:
529660Slinton 	case O_TRACEI:
539660Slinton 	    chktrace(p);
549660Slinton 	    break;
559660Slinton 
569660Slinton 	case O_STOP:
579660Slinton 	case O_STOPI:
589660Slinton 	    chkstop(p);
599660Slinton 	    break;
609660Slinton 
619660Slinton 	default:
629660Slinton 	    break;
639660Slinton     }
649660Slinton }
659660Slinton 
669660Slinton /*
679660Slinton  * Check arguments to a trace command.
689660Slinton  */
699660Slinton 
709660Slinton private chktrace(p)
719660Slinton Node p;
729660Slinton {
739660Slinton     Node exp, place, cond;
749660Slinton 
759660Slinton     exp = p->value.arg[0];
769660Slinton     place = p->value.arg[1];
779660Slinton     cond = p->value.arg[2];
789660Slinton     if (exp == nil) {
799660Slinton 	chkblock(place);
809660Slinton     } else if (exp->op == O_LCON or exp->op == O_QLINE) {
819660Slinton 	if (place != nil) {
829660Slinton 	    error("unexpected \"at\" or \"in\"");
839660Slinton 	}
849660Slinton 	if (p->op == O_TRACE) {
859660Slinton 	    chkline(exp);
869660Slinton 	} else {
879660Slinton 	    chkaddr(exp);
889660Slinton 	}
899660Slinton     } else if (place != nil and (place->op == O_QLINE or place->op == O_LCON)) {
909660Slinton 	if (p->op == O_TRACE) {
919660Slinton 	    chkline(place);
929660Slinton 	} else {
939660Slinton 	    chkaddr(place);
949660Slinton 	}
959660Slinton     } else {
96*9861Slinton 	if (exp->op != O_RVAL and exp->op != O_SYM and exp->op != O_CALL) {
979660Slinton 	    error("can't trace expressions");
989660Slinton 	}
999660Slinton 	chkblock(place);
1009660Slinton     }
1019660Slinton }
1029660Slinton 
1039660Slinton /*
1049660Slinton  * Check arguments to a stop command.
1059660Slinton  */
1069660Slinton 
1079660Slinton private chkstop(p)
1089660Slinton Node p;
1099660Slinton {
1109660Slinton     Node exp, place, cond;
1119660Slinton 
1129660Slinton     exp = p->value.arg[0];
1139660Slinton     place = p->value.arg[1];
1149660Slinton     cond = p->value.arg[2];
1159660Slinton     if (exp != nil) {
1169660Slinton 	if (exp->op != O_RVAL and exp->op != O_SYM) {
1179660Slinton 	    beginerrmsg();
1189660Slinton 	    fprintf(stderr, "expected variable, found ");
1199660Slinton 	    prtree(stderr, exp);
1209660Slinton 	    enderrmsg();
1219660Slinton 	}
1229660Slinton 	chkblock(place);
1239660Slinton     } else if (cond != nil) {
1249660Slinton 	chkblock(place);
1259660Slinton     } else if (place->op == O_SYM) {
1269660Slinton 	chkblock(place);
1279660Slinton     } else {
1289660Slinton 	if (p->op == O_STOP) {
1299660Slinton 	    chkline(place);
1309660Slinton 	} else {
1319660Slinton 	    chkaddr(place);
1329660Slinton 	}
1339660Slinton     }
1349660Slinton }
1359660Slinton 
1369660Slinton /*
1379660Slinton  * Check to see that the given node specifies some subprogram.
1389660Slinton  * Nil is ok since that means the entire program.
1399660Slinton  */
1409660Slinton 
1419660Slinton private chkblock(b)
1429660Slinton Node b;
1439660Slinton {
1449660Slinton     if (b != nil) {
1459660Slinton 	if (b->op != O_SYM) {
1469660Slinton 	    beginerrmsg();
1479660Slinton 	    fprintf(stderr, "expected subprogram, found ");
1489660Slinton 	    prtree(stderr, b);
1499660Slinton 	    enderrmsg();
1509660Slinton 	} else if (not isblock(b->value.sym) or ismodule(b->value.sym)) {
1519660Slinton 	    error("\"%s\" is not a subprogram", symname(b->value.sym));
1529660Slinton 	}
1539660Slinton     }
1549660Slinton }
1559660Slinton 
1569660Slinton /*
1579660Slinton  * Check to make sure a node corresponds to a source line.
1589660Slinton  */
1599660Slinton 
1609660Slinton private chkline(p)
1619660Slinton Node p;
1629660Slinton {
1639660Slinton     if (p == nil) {
1649660Slinton 	error("missing line");
1659660Slinton     } else if (p->op != O_QLINE and p->op != O_LCON) {
1669660Slinton 	error("expected source line number, found \"%t\"", p);
1679660Slinton     }
1689660Slinton }
1699660Slinton 
1709660Slinton /*
1719660Slinton  * Check to make sure a node corresponds to an address.
1729660Slinton  */
1739660Slinton 
1749660Slinton private chkaddr(p)
1759660Slinton Node p;
1769660Slinton {
1779660Slinton     if (p == nil) {
1789660Slinton 	error("missing address");
1799660Slinton     } else if (p->op != O_LCON and p->op != O_QLINE) {
1809660Slinton 	beginerrmsg();
1819660Slinton 	fprintf(stderr, "expected address, found \"");
1829660Slinton 	prtree(stderr, p);
1839660Slinton 	fprintf(stderr, "\"");
1849660Slinton 	enderrmsg();
1859660Slinton     }
1869660Slinton }
187