📄 tree.c
字号:
/*@(#)tree.c 4.2 Ultrix 11/9/90*//************************************************************************ * * * Copyright (c) 1985 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * * * Modification History * * * * 003 - Added support for vectors. * * (L Miller, 18JAN90) * * * * 002 - Merged in 4.3 changes. * * (vjh, April 29, 1986) * * * * 001 - Added support for O_PRINTENTRY node. * * (Victoria Holt, July 22, 1985) * * * ************************************************************************//* * Copyright (c) 1983 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */#ifndef lintstatic char sccsid[] = "@(#)tree.c 5.1 (Berkeley) 5/31/85";#endif not lintstatic char rcsid[] = "$Header: tree.c,v 1.5 84/12/26 10:42:55 linton Exp $";/* * Parse tree management. */#include "defs.h"#include "tree.h"#include "operators.h"#include "debug.h"#include "eval.h"#include "events.h"#include "symbols.h"#include "scanner.h"#include "source.h"#include "object.h"#include "mappings.h"#include "process.h"#include "machine.h"#ifndef public#include "lists.h"typedef struct Node *Node;typedef Node Command;typedef List Cmdlist;#include "operators.h"#include "symbols.h"#include "events.h"#define MAXNARGS 5struct Node { Operator op; Symbol nodetype; union treevalue { Symbol sym; Name name; long lcon; double fcon; String scon; Node arg[MAXNARGS]; struct { Node cond; Cmdlist actions; } event; struct { Boolean inst; Event event; Cmdlist actions; } trace; struct { Boolean source; Boolean skipcalls; } step; struct { String mode; Node beginaddr; Node endaddr; Integer count; } examine; struct { Node clist; Language lang; } printform; } value;};#define evalcmd(cmd) eval(cmd)#define cmdlist_append(cmd, cl) list_append(list_item(cmd), nil, cl)#endiftypedef char *Arglist;#define nextarg(type) ((type *) (ap += sizeof(type)))[-1]/* * Build a tree. *//* VARARGS1 */public Node build(op, args)Operator op;{ register Node p, q; register Arglist ap; Integer i; p = new(Node); p->op = op; p->nodetype = nil; ap = (Arglist) &args; switch (op) { case O_NAME: p->value.name = nextarg(Name); break; case O_SYM: case O_PRINTCALL: case O_PRINTRTN: case O_PROCRTN: p->value.sym = nextarg(Symbol); break; case O_PRINTF: p->value.printform.clist = nextarg(Node); p->value.printform.lang = nextarg(Language); break; case O_DEBUG: case O_LCON: case O_CCON: case O_CONT: case O_CATCH: case O_IGNORE: case O_TRACEOFF: p->value.lcon = nextarg(long); break; case O_FCON: p->value.fcon = nextarg(double); break; case O_SCON: case O_CHFILE: case O_EDIT: case O_SOURCE: case O_RECORD: p->value.scon = nextarg(String); break; case O_RVAL: case O_INDIR: p->value.arg[0] = nextarg(Node); break; case O_CALL: q = nextarg(Node); if (q->op == O_SYM and (q->value.sym->class == TYPE or q->value.sym->class == TAG) ) { p->op = O_TYPERENAME; p->value.arg[0] = nextarg(Node); p->value.arg[1] = q; q = p->value.arg[0]; if (q->value.arg[1] != nil) { error("too many arguments to type rename"); } p->value.arg[0] = q->value.arg[0]; } else { p->value.arg[0] = q; p->value.arg[1] = nextarg(Node); } break; case O_ADDEVENT: case O_ONCE: case O_IF: p->value.event.cond = nextarg(Node); p->value.event.actions = nextarg(Cmdlist); break; case O_PRINTENTRY: case O_TRACEON: p->value.trace.inst = nextarg(Boolean); p->value.trace.event = nil; p->value.trace.actions = nextarg(Cmdlist); break; case O_STEP: case O_STEPV: p->value.step.source = nextarg(Boolean); p->value.step.skipcalls = nextarg(Boolean); break; case O_EXAMINE: p->value.examine.mode = nextarg(String); p->value.examine.beginaddr = nextarg(Node); p->value.examine.endaddr = nextarg(Node); p->value.examine.count = nextarg(Integer); break; case O_TMASK: case O_FMASK: p->value.arg[0] = nextarg(Node); p->value.arg[1] = nextarg(Node); break; default: for (i = 0; i < nargs(op); i++) { p->value.arg[i] = nextarg(Node); } break; } check(p); assigntypes(p); if (tracetree) { printf("built %s node 0x%x with arg[0] 0x%x arg[1] 0x%x\n", opname(p->op), p, p->value.arg[0], p->value.arg[1]); fflush(stdout); } return p;}/* * Strip away indirection from a node, thus returning a node for * interpreting the expression as an lvalue. */public Node unrval (exp)Node exp;{ Node p; if(exp->op == O_VREG and ((streq(ident(exp->nodetype->name), "$vmr")) || (streq(ident(exp->nodetype->name), "$vcr")) || (streq(ident(exp->nodetype->name), "$vaer")) || (streq(ident(exp->nodetype->name), "$vlr")))) { error("illegal vector register syntax"); } if(exp->op == O_SYM and isreg(exp->nodetype)) { error("illegal register syntax"); } if (exp->op == O_RVAL) { p = exp->value.arg[0]; dispose(exp); } else if (exp->op == O_INDIR) { p = exp->value.arg[0]; if (p->op == O_RVAL) { p->op = O_INDIR; p->nodetype = exp->nodetype; } dispose(exp); } else { p = exp; } return p;}/* * Create a node for renaming a node to a pointer type. */public Node renameptr (p, t)Node p;Node t;{ t->nodetype = newSymbol(nil, 0, PTR, t->nodetype, nil); p = build(O_TYPERENAME, p, t);}/* * Return the tree for a unary ampersand operator. */public Node amper(p)Node p;{ Node r; checkref(p); switch (p->op) { case O_RVAL: case O_INDIR: if(p->nodetype == t_vquad) { beginerrmsg(); fprintf(stderr, "can not take address of \""); prtree(stderr, p); fprintf(stderr, "\""); enderrmsg(); } else { r = p->value.arg[0]; r->nodetype = t_addr; } dispose(p); break; case O_TYPERENAME: r = p; r->nodetype = newSymbol(nil, 0, PTR, r->nodetype, nil); break; case O_SYM: if(isvreg(p->nodetype)) { beginerrmsg(); fprintf(stderr, "can not take address of \""); prtree(stderr, p); fprintf(stderr, "\""); enderrmsg(); /* NOTREACHED */ } else { if (isroutine(p->value.sym)) { r = build(O_LCON, codeloc(p->value.sym)); } else if (isblock(p->value.sym)) { beginerrmsg(); fprintf(stderr, "can not take address of module or program, please qualify"); enderrmsg(); } else { r = build(O_LCON, address(p->value.sym, nil)); } r->nodetype = t_addr; } dispose(p); break; case O_VREG: beginerrmsg(); fprintf(stderr, "can not take address of \""); prtree(stderr, p); fprintf(stderr, "\""); enderrmsg(); /* NOTREACHED */ break; case O_DOT: r = p; r->nodetype = t_addr; break; default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -