xref: /csrg-svn/old/dbx/tree.c (revision 11862)
19681Slinton /* Copyright (c) 1982 Regents of the University of California */
29681Slinton 
3*11862Slinton static char sccsid[] = "@(#)tree.c 1.3 04/08/83";
49681Slinton 
59681Slinton /*
69681Slinton  * Parse tree management.
79681Slinton  */
89681Slinton 
99681Slinton #include "defs.h"
109681Slinton #include "tree.h"
119681Slinton #include "operators.h"
129681Slinton #include "eval.h"
139681Slinton #include "events.h"
149681Slinton #include "symbols.h"
159681Slinton #include "scanner.h"
169681Slinton #include "source.h"
179681Slinton #include "object.h"
189681Slinton #include "mappings.h"
199681Slinton #include "process.h"
209681Slinton #include "machine.h"
219681Slinton 
229681Slinton #ifndef public
239681Slinton #include "lists.h"
249681Slinton 
259681Slinton typedef struct Node *Node;
269681Slinton typedef Node Command;
279681Slinton typedef List Cmdlist;
289681Slinton 
299681Slinton #include "operators.h"
309681Slinton #include "symbols.h"
319681Slinton #include "events.h"
329681Slinton 
339681Slinton #define MAXNARGS 5
349681Slinton 
359681Slinton struct Node {
369681Slinton     Operator op;
379681Slinton     Symbol nodetype;
389681Slinton     union treevalue {
399681Slinton 	Symbol sym;
409681Slinton 	Name name;
419681Slinton 	long lcon;
429681Slinton 	double fcon;
439681Slinton 	String scon;
449681Slinton 	Node arg[MAXNARGS];
459681Slinton 	struct {
469681Slinton 	    Node cond;
479681Slinton 	    Cmdlist actions;
489681Slinton 	} event;
499681Slinton 	struct {
509681Slinton 	    Boolean inst;
519681Slinton 	    Event event;
529681Slinton 	    Cmdlist actions;
539681Slinton 	} trace;
549681Slinton 	struct {
559681Slinton 	    Boolean source;
569681Slinton 	    Boolean skipcalls;
579681Slinton 	} step;
589681Slinton 	struct {
599681Slinton 	    String mode;
609681Slinton 	    Node beginaddr;
619681Slinton 	    Node endaddr;
629681Slinton 	    Integer count;
639681Slinton 	} examine;
649681Slinton     } value;
659681Slinton };
669681Slinton 
679681Slinton #define evalcmd(cmd) eval(cmd)
689681Slinton #define cmdlist_append(cmd, cl) list_append(list_item(cmd), nil, cl)
699681Slinton 
709681Slinton #endif
719681Slinton 
729681Slinton typedef char *Arglist;
739681Slinton 
749681Slinton #define nextarg(type)  ((type *) (ap += sizeof(type)))[-1]
759681Slinton 
769681Slinton /*
779681Slinton  * Build a tree.
789681Slinton  */
799681Slinton 
809681Slinton /* VARARGS1 */
819681Slinton public Node build(op, args)
829681Slinton Operator op;
839681Slinton {
849681Slinton     register Node p, q;
859681Slinton     register Arglist ap;
869681Slinton     Integer i;
879681Slinton 
889681Slinton     p = new(Node);
899681Slinton     p->op = op;
909681Slinton     p->nodetype = nil;
919681Slinton     ap = (Arglist) &args;
929681Slinton     switch (op) {
939681Slinton 	case O_NAME:
949681Slinton 	    p->value.name = nextarg(Name);
959681Slinton 	    break;
969681Slinton 
979681Slinton 	case O_SYM:
989681Slinton 	case O_PRINTCALL:
999681Slinton 	case O_PRINTRTN:
1009681Slinton 	case O_PROCRTN:
1019681Slinton 	    p->value.sym = nextarg(Symbol);
1029681Slinton 	    break;
1039681Slinton 
1049681Slinton 	case O_LCON:
105*11862Slinton 	case O_CONT:
1069681Slinton 	case O_DELETE:
1079681Slinton 	case O_CATCH:
1089681Slinton 	case O_IGNORE:
1099681Slinton 	case O_TRACEOFF:
1109681Slinton 	    p->value.lcon = nextarg(long);
1119681Slinton 	    break;
1129681Slinton 
1139681Slinton 	case O_FCON:
1149681Slinton 	    p->value.fcon = nextarg(double);
1159681Slinton 	    break;
1169681Slinton 
1179681Slinton 	case O_SCON:
1189681Slinton 	case O_CHFILE:
1199681Slinton 	case O_EDIT:
1209681Slinton 	case O_SOURCE:
1219681Slinton 	    p->value.scon = nextarg(String);
1229681Slinton 	    break;
1239681Slinton 
1249681Slinton 	case O_RVAL:
1259681Slinton 	    q = nextarg(Node);
1269681Slinton 	    if (q->op == O_CALL) {
1279681Slinton 		*p = *q;
1289681Slinton 		dispose(q);
1299681Slinton 	    } else {
1309681Slinton 		p->value.arg[0] = q;
1319681Slinton 	    }
1329681Slinton 	    break;
1339681Slinton 
1349681Slinton 	case O_INDIR:
1359681Slinton 	    q = nextarg(Node);
1369681Slinton 	    if (q != nil and q->op == O_RVAL) {
1379681Slinton 		p->value.arg[0] = q->value.arg[0];
1389681Slinton 		dispose(q);
1399681Slinton 	    } else {
1409681Slinton 		p->value.arg[0] = q;
1419681Slinton 	    }
1429681Slinton 	    break;
1439681Slinton 
1449681Slinton 	case O_ADDEVENT:
1459681Slinton 	case O_ONCE:
1469681Slinton 	case O_IF:
1479681Slinton 	    p->value.event.cond = nextarg(Node);
1489681Slinton 	    p->value.event.actions = nextarg(Cmdlist);
1499681Slinton 	    break;
1509681Slinton 
1519681Slinton 	case O_TRACEON:
1529681Slinton 	    p->value.trace.inst = nextarg(Boolean);
1539681Slinton 	    p->value.trace.event = nil;
1549681Slinton 	    p->value.trace.actions = nextarg(Cmdlist);
1559681Slinton 	    break;
1569681Slinton 
1579681Slinton 	case O_STEP:
1589681Slinton 	    p->value.step.source = nextarg(Boolean);
1599681Slinton 	    p->value.step.skipcalls = nextarg(Boolean);
1609681Slinton 	    break;
1619681Slinton 
1629681Slinton 	case O_EXAMINE:
1639681Slinton 	    p->value.examine.mode = nextarg(String);
1649681Slinton 	    p->value.examine.beginaddr = nextarg(Node);
1659681Slinton 	    p->value.examine.endaddr = nextarg(Node);
1669681Slinton 	    p->value.examine.count = nextarg(Integer);
1679681Slinton 	    break;
1689681Slinton 
1699681Slinton 	default:
1709681Slinton 	    for (i = 0; i < nargs(op); i++) {
1719681Slinton 		p->value.arg[i] = nextarg(Node);
1729681Slinton 	    }
1739681Slinton 	    break;
1749681Slinton     }
1759681Slinton     check(p);
1769681Slinton     assigntypes(p);
1779681Slinton     return p;
1789681Slinton }
1799681Slinton 
1809681Slinton /*
1819681Slinton  * Create a command list from a single command.
1829681Slinton  */
1839681Slinton 
1849681Slinton public Cmdlist buildcmdlist(cmd)
1859681Slinton Command cmd;
1869681Slinton {
1879681Slinton     Cmdlist cmdlist;
1889681Slinton 
1899681Slinton     cmdlist = list_alloc();
1909681Slinton     cmdlist_append(cmd, cmdlist);
1919681Slinton     return cmdlist;
1929681Slinton }
1939681Slinton 
1949681Slinton /*
1959681Slinton  * Return the tree for a unary ampersand operator.
1969681Slinton  */
1979681Slinton 
1989681Slinton public Node amper(p)
1999681Slinton Node p;
2009681Slinton {
2019681Slinton     Node r;
2029681Slinton 
2039681Slinton     checkref(p);
2049681Slinton     switch (p->op) {
2059681Slinton 	case O_RVAL:
2069681Slinton 	    r = p->value.arg[0];
2079681Slinton 	    break;
2089681Slinton 
2099681Slinton 	case O_CALL:
2109681Slinton 	    r = build(O_LCON, codeloc(p->value.arg[0]->value.sym));
2119681Slinton 	    tfree(p);
2129681Slinton 	    break;
2139681Slinton 
2149681Slinton 	case O_SYM:
2159681Slinton 	    if (isblock(p->value.sym)) {
2169681Slinton 		r = build(O_LCON, codeloc(p->value.sym));
2179681Slinton 	    } else {
2189681Slinton 		r = build(O_LCON, address(p->value.sym, nil));
2199681Slinton 	    }
2209681Slinton 	    tfree(p);
2219681Slinton 	    break;
2229681Slinton 
2239681Slinton 	case O_DOT:
2249681Slinton 	    r = p;
2259681Slinton 	    break;
2269681Slinton 
2279681Slinton 	case O_INDIR:
2289681Slinton 	    r = p->value.arg[0];
2299681Slinton 	    dispose(p);
2309681Slinton 	    break;
2319681Slinton 
2329681Slinton 	default:
2339681Slinton 	    beginerrmsg();
2349681Slinton 	    fprintf(stderr, "expected variable, found ");
2359681Slinton 	    prtree(stderr, p);
2369681Slinton 	    tfree(p);
2379681Slinton 	    enderrmsg();
2389681Slinton 	    /* NOTREACHED */
2399681Slinton     }
2409681Slinton     r->nodetype = t_int;
2419681Slinton     return r;
2429681Slinton }
2439681Slinton 
2449681Slinton /*
2459681Slinton  * Create a "concrete" version of a node.
2469681Slinton  * This is necessary when the type of the node contains
2479681Slinton  * an unresolved type reference.
2489681Slinton  */
2499681Slinton 
2509681Slinton public Node concrete(p)
2519681Slinton Node p;
2529681Slinton {
2539681Slinton     findtype(p->nodetype);
2549681Slinton     return build(O_INDIR, p);
2559681Slinton }
2569681Slinton 
2579681Slinton /*
2589681Slinton  * Print out a command.
2599681Slinton  */
2609681Slinton 
2619681Slinton public printcmd(f, cmd)
2629681Slinton File f;
2639681Slinton Command cmd;
2649681Slinton {
2659681Slinton     register Integer i;
2669681Slinton     register Command c;
2679681Slinton     register Node p;
2689681Slinton 
2699681Slinton     switch (cmd->op) {
2709681Slinton 	case O_PRINTIFCHANGED:
2719681Slinton 	case O_PRINTSRCPOS:
2729681Slinton 	case O_STOPIFCHANGED:
2739681Slinton 	case O_TRACEON:
2749681Slinton 	    break;
2759681Slinton 
2769681Slinton 	case O_STEP:
2779681Slinton 	    if (cmd->value.step.skipcalls) {
2789681Slinton 		fprintf(f, "next");
2799681Slinton 	    } else {
2809681Slinton 		fprintf(f, "step");
2819681Slinton 	    }
2829681Slinton 	    if (not cmd->value.step.source) {
2839681Slinton 		fprintf(f, "i");
2849681Slinton 	    }
2859681Slinton 	    break;
2869681Slinton 
2879681Slinton 	default:
2889681Slinton 	    fprintf(f, "%s", opinfo[ord(cmd->op)].opstring);
2899681Slinton 	    if (nargs(cmd->op) != 0) {
2909681Slinton 		fprintf(f, " ");
2919681Slinton 	    }
2929681Slinton 	    break;
2939681Slinton     }
2949681Slinton     switch (cmd->op) {
2959681Slinton 	case O_PRINTCALL:
2969681Slinton 	case O_PRINTRTN:
2979681Slinton 	case O_PROCRTN:
2989681Slinton 	    fprintf(f, "%s", symname(cmd->value.sym));
2999681Slinton 	    break;
3009681Slinton 
3019681Slinton 	case O_PRINTSRCPOS:
3029681Slinton 	    p = cmd->value.arg[0];
3039681Slinton 	    if (p != nil and p->op != O_QLINE) {
3049681Slinton 		printf("trace ");
3059681Slinton 		prtree(f, p);
3069681Slinton 	    }
3079681Slinton 	    break;
3089681Slinton 
3099681Slinton 	case O_CHFILE:
3109681Slinton 	case O_EDIT:
3119681Slinton 	case O_SOURCE:
3129681Slinton 	    fprintf(f, "%s", cmd->value.scon);
3139681Slinton 	    break;
3149681Slinton 
3159681Slinton 	case O_DELETE:
3169681Slinton 	case O_CATCH:
3179681Slinton 	case O_IGNORE:
3189681Slinton 	case O_TRACEOFF:
3199681Slinton 	    fprintf(f, "%d", cmd->value.lcon);
3209681Slinton 	    break;
3219681Slinton 
3229681Slinton 	case O_ADDEVENT:
3239681Slinton 	case O_ONCE:
3249681Slinton 	case O_IF:
3259681Slinton 	    fprintf(f, " ");
3269681Slinton 	    prtree(f, cmd->value.event.cond);
3279681Slinton 	    fprintf(f, " { ");
3289681Slinton 	    foreach (Command, c, cmd->value.event.actions)
3299681Slinton 		printcmd(f, c);
3309681Slinton 		if (not list_islast()) {
3319681Slinton 		    fprintf(f, ";");
3329681Slinton 		}
3339681Slinton 	    endfor
3349681Slinton 	    fprintf(f, " }", opinfo[ord(cmd->op)].opstring);
3359681Slinton 	    break;
3369681Slinton 
3379681Slinton 	case O_TRACEON:
3389681Slinton 	    print_tracestop(f, cmd);
3399681Slinton 	    break;
3409681Slinton 
3419681Slinton 	case O_EXAMINE:
3429681Slinton 	    prtree(f, cmd->value.examine.beginaddr);
3439681Slinton 	    if (cmd->value.examine.endaddr != nil) {
3449681Slinton 		fprintf(f, ",");
3459681Slinton 		prtree(f, cmd->value.examine.endaddr);
3469681Slinton 	    }
3479681Slinton 	    fprintf(f, "/");
3489681Slinton 	    if (cmd->value.examine.count > 1) {
3499681Slinton 		fprintf(f, "%d", cmd->value.examine.count);
3509681Slinton 	    }
3519681Slinton 	    fprintf("%s", cmd->value.examine.mode);
3529681Slinton 	    break;
3539681Slinton 
3549681Slinton 	default:
3559681Slinton 	    if (nargs(cmd->op) != 0) {
3569681Slinton 		i = 0;
3579681Slinton 		for (;;) {
3589681Slinton 		    prtree(f, cmd->value.arg[i]);
3599681Slinton 		    ++i;
3609681Slinton 		if (i >= nargs(cmd->op)) break;
3619681Slinton 		    fprintf(f, " ");
3629681Slinton 		}
3639681Slinton 	    }
3649681Slinton 	    break;
3659681Slinton     }
3669681Slinton }
3679681Slinton 
3689681Slinton /*
3699681Slinton  * Print out a trace/stop command name.
3709681Slinton  */
3719681Slinton 
3729681Slinton private print_tracestop(f, cmd)
3739681Slinton File f;
3749681Slinton Command cmd;
3759681Slinton {
3769681Slinton     register Command c, ifcmd, stopcmd;
3779681Slinton     Boolean done;
3789681Slinton 
3799681Slinton     done = false;
3809681Slinton     ifcmd = list_element(Command, list_head(cmd->value.trace.actions));
3819681Slinton     checkref(ifcmd);
3829681Slinton     if (ifcmd->op == O_IF) {
3839681Slinton 	stopcmd = list_element(Command, list_head(ifcmd->value.event.actions));
3849681Slinton 	checkref(stopcmd);
3859681Slinton 	if (stopcmd->op == O_STOPX) {
3869681Slinton 	    fprintf(f, "%s if ", cmd->value.trace.inst ? "stopi" : "stop");
3879681Slinton 	    prtree(f, ifcmd->value.event.cond);
3889681Slinton 	    done = true;
3899681Slinton 	}
3909681Slinton     }
3919681Slinton     if (not done) {
3929681Slinton 	fprintf(f, "%s ", cmd->value.trace.inst ? "tracei" : "trace");
3939681Slinton 	foreach (Command, c, cmd->value.trace.actions)
3949681Slinton 	    printcmd(f, c);
3959681Slinton 	    if (not list_islast()) {
3969681Slinton 		fprintf(f, ";");
3979681Slinton 	    }
3989681Slinton 	endfor
3999681Slinton     }
4009681Slinton }
4019681Slinton 
4029681Slinton /*
4039681Slinton  * Print a tree back out in Pascal form.
4049681Slinton  */
4059681Slinton 
4069681Slinton public prtree(f, p)
4079681Slinton File f;
4089681Slinton register Node p;
4099681Slinton {
4109681Slinton     register Node q;
4119681Slinton     Operator op;
4129681Slinton 
4139681Slinton     if (p != nil) {
4149681Slinton 	op = p->op;
4159681Slinton 	if (ord(op) > ord(O_LASTOP)) {
4169681Slinton 	    panic("bad op %d in prtree", p->op);
4179681Slinton 	}
4189681Slinton 	switch (op) {
4199681Slinton 	    case O_NAME:
4209681Slinton 		fprintf(f, "%s", ident(p->value.name));
4219681Slinton 		break;
4229681Slinton 
4239681Slinton 	    case O_SYM:
4249681Slinton 		printname(f, p->value.sym);
4259681Slinton 		break;
4269681Slinton 
4279681Slinton 	    case O_QLINE:
4289681Slinton 		if (nlhdr.nfiles > 1) {
4299681Slinton 		    prtree(f, p->value.arg[0]);
4309681Slinton 		    fprintf(f, ":");
4319681Slinton 		}
4329681Slinton 		prtree(f, p->value.arg[1]);
4339681Slinton 		break;
4349681Slinton 
4359681Slinton 	    case O_LCON:
4369681Slinton 		if (compatible(p->nodetype, t_char)) {
4379681Slinton 		    fprintf(f, "'%c'", p->value.lcon);
4389681Slinton 		} else {
4399681Slinton 		    fprintf(f, "%d", p->value.lcon);
4409681Slinton 		}
4419681Slinton 		break;
4429681Slinton 
4439681Slinton 	    case O_FCON:
4449681Slinton 		fprintf(f, "%g", p->value.fcon);
4459681Slinton 		break;
4469681Slinton 
4479681Slinton 	    case O_SCON:
4489681Slinton 		fprintf(f, "\"%s\"", p->value.scon);
4499681Slinton 		break;
4509681Slinton 
4519681Slinton 	    case O_INDEX:
4529681Slinton 		prtree(f, p->value.arg[0]);
4539681Slinton 		fprintf(f, "[");
4549681Slinton 		prtree(f, p->value.arg[1]);
4559681Slinton 		fprintf(f, "]");
4569681Slinton 		break;
4579681Slinton 
4589681Slinton 	    case O_COMMA:
4599681Slinton 		prtree(f, p->value.arg[0]);
4609681Slinton 		if (p->value.arg[1] != nil) {
4619681Slinton 		    fprintf(f, ", ");
4629681Slinton 		    prtree(f, p->value.arg[1]);
4639681Slinton 		}
4649681Slinton 		break;
4659681Slinton 
4669681Slinton 	    case O_RVAL:
4679681Slinton 		if (p->value.arg[0]->op == O_SYM) {
4689681Slinton 		    printname(f, p->value.arg[0]->value.sym);
4699681Slinton 		} else {
4709681Slinton 		    prtree(f, p->value.arg[0]);
4719681Slinton 		}
4729681Slinton 		break;
4739681Slinton 
4749681Slinton 	    case O_ITOF:
4759681Slinton 		prtree(f, p->value.arg[0]);
4769681Slinton 		break;
4779681Slinton 
4789681Slinton 	    case O_CALL:
4799681Slinton 		prtree(f, p->value.arg[0]);
4809681Slinton 		if (p->value.arg[1]!= nil) {
4819681Slinton 		    fprintf(f, "(");
4829681Slinton 		    prtree(f, p->value.arg[1]);
4839681Slinton 		    fprintf(f, ")");
4849681Slinton 		}
4859681Slinton 		break;
4869681Slinton 
4879681Slinton 	    case O_INDIR:
4889681Slinton 		q = p->value.arg[0];
4899681Slinton 		if (isvarparam(q->nodetype)) {
4909681Slinton 		    prtree(f, q);
4919681Slinton 		} else {
4929681Slinton 		    if (q->op == O_SYM or q->op == O_LCON or q->op == O_DOT) {
4939681Slinton 			prtree(f, q);
4949681Slinton 			fprintf(f, "^");
4959681Slinton 		    } else {
4969681Slinton 			fprintf(f, "*(");
4979681Slinton 			prtree(f, q);
4989681Slinton 			fprintf(f, ")");
4999681Slinton 		    }
5009681Slinton 		}
5019681Slinton 		break;
5029681Slinton 
5039681Slinton 	    case O_DOT:
5049681Slinton 		q = p->value.arg[0];
5059681Slinton 		if (q->op == O_INDIR) {
5069681Slinton 		    prtree(f, q->value.arg[0]);
5079681Slinton 		} else {
5089681Slinton 		    prtree(f, q);
5099681Slinton 		}
5109681Slinton 		fprintf(f, ".%s", symname(p->value.arg[1]->value.sym));
5119681Slinton 		break;
5129681Slinton 
5139681Slinton 	    default:
5149681Slinton 		switch (degree(op)) {
5159681Slinton 		    case BINARY:
5169681Slinton 			prtree(f, p->value.arg[0]);
5179681Slinton 			fprintf(f, "%s", opinfo[ord(op)].opstring);
5189681Slinton 			prtree(f, p->value.arg[1]);
5199681Slinton 			break;
5209681Slinton 
5219681Slinton 		    case UNARY:
5229681Slinton 			fprintf(f, "%s", opinfo[ord(op)].opstring);
5239681Slinton 			prtree(f, p->value.arg[0]);
5249681Slinton 			break;
5259681Slinton 
5269681Slinton 		    default:
5279681Slinton 			error("internal error: bad op %d in prtree", op);
5289681Slinton 		}
5299681Slinton 		break;
5309681Slinton 	}
5319681Slinton     }
5329681Slinton }
5339681Slinton 
5349681Slinton /*
5359681Slinton  * Free storage associated with a tree.
5369681Slinton  */
5379681Slinton 
5389681Slinton public tfree(p)
5399681Slinton Node p;
5409681Slinton {
5419681Slinton     Integer i;
5429681Slinton 
5439681Slinton     if (p == nil) {
5449681Slinton 	return;
5459681Slinton     }
5469681Slinton     switch (p->op) {
5479681Slinton 	case O_QLINE:
5489681Slinton 	    dispose(p->value.arg[0]->value.scon);
5499681Slinton 	    dispose(p->value.arg[0]);
5509681Slinton 	    tfree(p->value.arg[1]);
5519681Slinton 	    break;
5529681Slinton 
5539681Slinton 	case O_SCON:
5549681Slinton 	    unmkstring(p->nodetype);
5559681Slinton 	    dispose(p->nodetype);
5569681Slinton 	    dispose(p->value.scon);
5579681Slinton 	    break;
5589681Slinton 
5599681Slinton 	default:
5609681Slinton 	    for (i = 0; i < nargs(p->op); i++) {
5619681Slinton 		tfree(p->value.arg[i]);
5629681Slinton 	    }
5639681Slinton 	    break;
5649681Slinton     }
5659681Slinton     dispose(p);
5669681Slinton }
5679681Slinton 
5689681Slinton /*
5699681Slinton  * A recursive tree search routine to test if two trees * are equivalent.
5709681Slinton  */
5719681Slinton 
5729681Slinton public Boolean tr_equal(t1, t2)
5739681Slinton register Node t1;
5749681Slinton register Node t2;
5759681Slinton {
5769681Slinton     register Boolean b;
5779681Slinton 
5789681Slinton     if (t1 == nil and t2 == nil) {
5799681Slinton 	b = true;
5809681Slinton     } else if (t1 == nil or t2 == nil) {
5819681Slinton 	b = false;
5829681Slinton     } else if (t1->op != t2->op or degree(t1->op) != degree(t2->op)) {
5839681Slinton 	b = false;
5849681Slinton     } else {
5859681Slinton 	switch (degree(t1->op)) {
5869681Slinton 	    case LEAF:
5879681Slinton 		switch (t1->op) {
5889681Slinton 		    case O_NAME:
5899681Slinton 			b = (Boolean) (t1->value.name == t2->value.name);
5909681Slinton 			break;
5919681Slinton 
5929681Slinton 		    case O_SYM:
5939681Slinton 			b = (Boolean) (t1->value.sym == t2->value.sym);
5949681Slinton 			break;
5959681Slinton 
5969681Slinton 		    case O_LCON:
5979681Slinton 			b = (Boolean) (t1->value.lcon == t2->value.lcon);
5989681Slinton 			break;
5999681Slinton 
6009681Slinton 		    case O_FCON:
6019681Slinton 			b = (Boolean) (t1->value.fcon == t2->value.fcon);
6029681Slinton 			break;
6039681Slinton 
6049681Slinton 		    case O_SCON:
6059681Slinton 			b = (Boolean) (t1->value.scon == t2->value.scon);
6069681Slinton 			break;
6079681Slinton 
6089681Slinton 		    default:
6099681Slinton 			panic("tr_equal: leaf %d\n", t1->op);
6109681Slinton 		}
6119681Slinton 		/*NOTREACHED*/
6129681Slinton 
6139681Slinton 	    case BINARY:
6149681Slinton 		if (not tr_equal(t1->value.arg[0], t2->value.arg[0])) {
6159681Slinton 		    b = false;
6169681Slinton 		} else {
6179681Slinton 		    b = tr_equal(t1->value.arg[1], t2->value.arg[1]);
6189681Slinton 		}
6199681Slinton 		break;
6209681Slinton 
6219681Slinton 	    case UNARY:
6229681Slinton 		b = tr_equal(t1->value.arg[0], t2->value.arg[0]);
6239681Slinton 		break;
6249681Slinton 
6259681Slinton 	    default:
6269681Slinton 		panic("tr_equal: bad degree for op %d\n", t1->op);
6279681Slinton 	}
6289681Slinton     }
6299681Slinton     return b;
6309681Slinton }
631