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