⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eval.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
/************************************************************************ *									* *			Copyright (c) 1986 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				* *									* *  011	- Added support for vectors.							* *		  (L Miller, 18JAN90)									* *									* *	010 - Fixed 009: check for FIELD before isbitfield.		* *	      (jlr, April 13, 1989)					* *									* *	009 - Added code to handle bitfields to assign().		* *	      (Jon Reeves, January 21, 1989)				* *									* *	008 - Merged in 4.3 changes.					* *	      (vjh, April 29, 1986)					* *									* *	007 - Fixed another bug in trace.				* *	      (vjh, August 7, 1985)					* *									* *	006 - Fixed bugs/problems related to tracing (search for 006).	* *	      (vjh, July 23, 1985)					* *									* *	005 - Added test under O_CATCH and O_IGNORE in eval(), to	* *	      insure that the signal number is within the		* *	      appropriate range.					* *	      (vjh, June 14, 1985)					* *									* *	004 - Removed test after calling firstaddr() in eval(), under	* *	      the O_LIST case.  Testing for source is done by check()   * *	      immediately after the O_LIST node is built.		* *	      (vjh, May 30, 1985)					* *									* *	003 - Removed gripe().						* *	      (vjh, May 10, 1985)					* *									* *	002 - Added support for "delete *".				* *	      (vjh, April 25, 1985)					* *									* *	001 - Require a flag INHOUSE to be defined to allow commands 	* *	      "psym", "gripe", and "debug" to work.  These are all 	* *	      tools used in debugging dbx.				* *	      (Victoria Holt, April 15, 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. *//* Based on: "@(#)eval.c	5.3 (Berkeley) 6/21/85" */#ifndef lintstatic char sccsid[] = "@(#)eval.c	4.2	ULTRIX	11/9/90";#endif not lint/*static char rcsid[] = "$Header: eval.c,v 1.5 84/12/26 10:39:08 linton Exp $";*//* * Tree evaluation. */#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 "main.h"#include "mappings.h"#include "process.h"#include "runtime.h"#include "machine.h"#include <signal.h>#ifndef public#include "machine.h"#define STACKSIZE 20000typedef Char Stack;#define push(type, value) { \    ((type *) (sp += sizeof(type)))[-1] = (value); \}#define pop(type) ( \    (*((type *) (sp -= sizeof(type)))) \)#define popn(n, dest) { \    sp -= n; \    bcopy(sp, dest, n); \}#define alignstack() { \    sp = (Stack *) (( ((int) sp) + sizeof(int) - 1)&~(sizeof(int) - 1)); \}#endifpublic Stack stack[STACKSIZE];public Stack *sp = &stack[0];public Boolean useInstLoc = false;#define chksp() \{ \    if (sp < &stack[0]) { \	panic("stack underflow"); \    } \}#define poparg(n, r, fr) { \    eval(p->value.arg[n]); \    if (isreal(p->op)) { \	if (size(p->value.arg[n]->nodetype) == sizeof(float)) { \	    fr = pop(float); \	} else { \	    fr = pop(double); \	} \    } else if (isint(p->op)) { \	r = popsmall(p->value.arg[n]->nodetype); \    } \}#define Boolrep char	/* underlying representation type for booleans *//* * Command-level evaluation. */public Node topnode;public topeval (p)Node p;{    if (traceeval) {	fprintf(stderr, "topeval(");	prtree(stderr, p);	fprintf(stderr, ")\n");	fflush(stderr);    }    topnode = p;    eval(p);}/* * Evaluate a parse tree leaving the value on the top of the stack. */public eval(p)register Node p;{    long r0, r1;    double fr0, fr1;    Address addr;    long i, n;    int len;    Symbol s;    Node n1, n2;    Boolean b, callflag;    File file;    String str;    Vreg v;    checkref(p);    if (traceeval) {	fprintf(stderr, "begin eval %s\n", opname(p->op));    }    switch (degree(p->op)) {	case BINARY:	    poparg(1, r1, fr1);	    poparg(0, r0, fr0);	    break;	case UNARY:	    poparg(0, r0, fr0);	    break;	default:	    /* do nothing */;    }    switch (p->op) {	case O_SYM:	    s = p->value.sym;	    if (s == retaddrsym) {			push(long, return_addr());	    } else if (isvariable(s)) {		    if (s != program and not isactive(container(s))) {				error("\"%s\" is not active", symname(s));		    }			if (isvarparam(s) and not isopenarray(s)) {		    	rpush(address(s, nil), sizeof(Address));	        } else {		    	push(Address, address(s, nil));			}		} else if (isblock(s)) {		    push(Symbol, s);	    } else if (isconst(s)) {			eval(constval(s));		} else {		    error("can't evaluate a %s", classname(s));		}	    break;	case O_VREG:	    s = p->value.sym;	    if (not (p->nodetype == t_addr)) {	        /* Start vector support */		if (not canpush(sizeof (struct Vreg))) {		    error("expression too large to evaluate");		} else {		    chksp();		    v = vreg(s->symvalue.raddr.reg);		    switch(s->symvalue.raddr.reg)		    {			case VMR:		    	    push(Vquad, *(Vquad *)v);			    break;			case VCR:			case VAER:			case VLR:		    	    push(long, (long)v);			    break;		    default:			    push(struct Vreg, *v);			    break;		    }		}		/* End of vector support */	    } else {	        push(Address, address(s, nil));	    }	    break;	case O_LCON:	case O_CCON:	    r0 = p->value.lcon;	    pushsmall(p->nodetype, r0);	    break;	case O_FCON:	    push(double, p->value.fcon);	    break;	case O_SCON:	    len = size(p->nodetype);	    mov(p->value.scon, sp, len);	    sp += len;	    break;	case O_INDEX:	    s = p->value.arg[0]->nodetype;	    p->value.arg[0]->nodetype = t_addr;	    eval(p->value.arg[0]);	    p->value.arg[0]->nodetype = s;	    n = pop(Address);	    eval(p->value.arg[1]);	    evalindex(s, n, popsmall(p->value.arg[1]->nodetype));	    break;	case O_DOT:	    s = p->value.arg[1]->value.sym;	    eval(p->value.arg[0]);	    n = pop(long);	    push(long, n + (s->symvalue.field.offset div 8));	    break;	/*	 * Get the value of the expression addressed by the top of the stack.	 * Push the result back on the stack.	 */	case O_INDIR:	case O_RVAL:	    addr = pop(long);	    if (addr == 0) {			error("reference through nil pointer");	    }        len = size(p->nodetype);	    /* Start vector support */	    if (p->nodetype == t_vquad) {	        push(Vquad, *(Vquad *) addr);	    /* End of vector support */	    } else	        rpush(addr, len);	    break;	/*	 * Move the stack pointer so that the top of the stack has	 * something corresponding to the size of the current node type.	 * If this new type is bigger than the subtree (len > 0),	 * then the stack is padded with nulls.  If it's smaller,	 * the stack is just dropped by the appropriate amount.	 */	case O_TYPERENAME:		if(p->nodetype->type == t_vint ||				p->nodetype->type->type == t_vint) { 			if(p->value.arg[0]->nodetype->type->type != t_vquad) {				if(streq(ident(p->value.arg[0]->nodetype->name), "$vmr")) {					sp -= 8;				}				else {					sp -= size(p->value.arg[0]->nodetype);				}				error("rename to vint illegal in this context");			}		}		if(p->nodetype->type == t_vhex ||				p->nodetype->type->type == t_vhex) { 			if(p->value.arg[0]->nodetype->type->type != t_vquad) {				if(streq(ident(p->value.arg[0]->nodetype->name), "$vmr")) {					sp -= 8;				}				else {					sp -= size(p->value.arg[0]->nodetype);				}				error("rename to vhex illegal in this context");			}		}		if(p->nodetype->type == t_vfloat ||				p->nodetype->type->type == t_vfloat) { 			if(p->value.arg[0]->nodetype->type->type != t_vquad) {				if(streq(ident(p->value.arg[0]->nodetype->name), "$vmr")) {					sp -= 8;				}				else {					sp -= size(p->value.arg[0]->nodetype);				}				error("rename to vfloat illegal in this context");			}		}	    len = size(p->nodetype) - size(p->value.arg[0]->nodetype);	    if (len > 0) {			for (n = 0; n < len; n++) {		    	*sp++ = '\0';			}	    } else if (len < 0) {			sp -= len;	    }	    break;	case O_COMMA:	    eval(p->value.arg[0]);	    if (p->value.arg[1] != nil) {		eval(p->value.arg[1]);	    }	    break;	case O_ITOF:	    push(double, (double) r0);	    break;	case O_ADD:	    push(long, r0+r1);	    break;	case O_ADDF:	    push(double, fr0+fr1);	    break;	case O_SUB:	    push(long, r0-r1);	    break;	case O_SUBF:	    push(double, fr0-fr1);	    break;	case O_NEG:	    push(long, -r0);	    break;	case O_NEGF:	    push(double, -fr0);	    break;	case O_MUL:	    push(long, r0*r1);	    break;	case O_MULF:	    push(double, fr0*fr1);	    break;	case O_DIVF:	    if (fr1 == 0) {		error("error: division by 0");	    }	    push(double, fr0 / fr1);	    break;	case O_DIV:	    if (r1 == 0) {		error("error: div by 0");	    }	    push(long, r0 div r1);	    break;	case O_MOD:	    if (r1 == 0) {		error("error: mod by 0");	    }	    push(long, r0 mod r1);	    break;	case O_LT:	    push(Boolrep, r0 < r1);	    break;	case O_LTF:	    push(Boolrep, fr0 < fr1);	    break;	case O_LE:	    push(Boolrep, r0 <= r1);	    break;	case O_LEF:	    push(Boolrep, fr0 <= fr1);	    break;	case O_GT:	    push(Boolrep, r0 > r1);	    break;	case O_GTF:	    push(Boolrep, fr0 > fr1);	    break;	case O_GE:	    push(Boolrep, r0 >= r1);	    break;	case O_GEF:	    push(Boolrep, fr0 <= fr1);	case O_EQ:	    push(Boolrep, r0 == r1);	    break;	case O_EQF:	    push(Boolrep, fr0 == fr1);	    break;	case O_NE:	    push(Boolrep, r0 != r1);	    break;	case O_NEF:	    push(Boolrep, fr0 != fr1);	    break;	case O_AND:	    push(Boolrep, r0 and r1);	    break;	case O_OR:	    push(Boolrep, r0 or r1);	    break;	case O_ASSIGN:	    assign(p->value.arg[0], p->value.arg[1]);	    break;	case O_CHFILE:	    if (p->value.scon == nil) {		printf("%s\n", cursource);	    } else {		file = opensource(p->value.scon);		if (file == nil) {		    error("can't read \"%s\"", p->value.scon);		} else {		    fclose(file);		    setsource(p->value.scon);		}	    }	    break;	case O_CONT:	    cont(p->value.lcon);	    printnews();	    break;	case O_LIST:	    list(p);	    break;	case O_FUNC:	    func(p->value.arg[0]);	    break;	case O_EXAMINE:	    eval(p->value.examine.beginaddr);	    r0 = pop(long);		if(p->value.examine.beginaddr->op == O_QLINE) {		 	r0 =  objaddr(r0, cursource);				if(r0 == NOADDR || r0 == ADDRNOEXEC){					beginerrmsg();					if (r0 == NOADDR)		    			fprintf(stderr, "beyond end of file at line ");					else						fprintf(stderr, "no executable code found at line ");					prtree(stderr, p->value.examine.beginaddr);					enderrmsg();				break;			}		}	    if (p->value.examine.endaddr == nil) {		n = p->value.examine.count;		if (n == 0) {		    printvalue(r0, p->value.examine.mode);		} else if (streq(p->value.examine.mode, "i")) {		    printninst(n, (Address) r0);		} else {		    printndata(n, (Address) r0, p->value.examine.mode);		}	    } else {		eval(p->value.examine.endaddr);		r1 = pop(long);		if (streq(p->value.examine.mode, "i")) {		    printinst((Address)r0, (Address)r1);		} else {		    printdata((Address)r0, (Address)r1, p->value.examine.mode);		}	    }	    break;	case O_TMASK:	case O_FMASK:	{		Symbol t;			    for (n1 = p->value.arg[0]; n1 != nil; n1 = n1->value.arg[1]) {			t = n1->value.arg[0]->nodetype;			if(((streq(ident(t->name), "$vquad")) ||						(streq(ident(t->name), "$vmr")) ||						(streq(ident(t->name), "$vcr")) ||						(streq(ident(t->name), "$vaer")) ||						(streq(ident(t->name), "$vlr")))) {				error("incorrect symbol for mask operation");			}			if((p->value.arg[1]) && (p->value.arg[1]->op != O_SCON)) {				error("illegal mask");				break;			}			if(n1->value.arg[0]->op != O_VREG) {				error("rename illegal for mask operation");				break;			}			eval(n1->value.arg[0]);			printval_with_mask(n1->value.arg[0]->nodetype, p->op,													p->value.arg[1]);	    }	    putchar('\n');	    break;	}	case O_PRINT:	    for (n1 = p->value.arg[0]; n1 != nil; n1 = n1->value.arg[1]) {		eval(n1->value.arg[0]);		printval(n1->value.arg[0]->nodetype);		putchar(' ');	    }	    putchar('\n');	    break;	case O_PRINTF:#define MAXARGLIST 200	    { 			char *argv[MAXARGLIST];	      	int i;	      	long nsize;			for (i=0, n1=p->value.arg[0]; n1!=nil; n1=n1->value.arg[1]) {				if((i == 0) && (n1->value.arg[0]->op != O_SCON)) {					error("missing format");				}		    	if(n1->nodetype->class == ARRAY) {					argv[i++] = sp;					eval(n1->value.arg[0]);		    	} else if ((nsize = size(n1->value.arg[0]->nodetype))> 4) {					if (nsize/4 > MAXARGLIST)			    		error ("printf argument size (%d) exceeds max(%d)\n",														  nsize, 4*MAXARGLIST);					eval(n1->value.arg[0]);					nsize = (nsize + 3) & ~3;	/* round */					popn (nsize, &argv[i]);					i += nsize / 4;		    	} else {					eval(n1->value.arg[0]);					argv[i++] =(char *)popsmall(n1->value.arg[0]->nodetype);		    	}			}			argv[i] = NULL;			print_formatted(p, argv);			for (i=0, n1=p->value.arg[0]; n1!=nil; i++,n1=n1->value.arg[1]){		    	if(n1->nodetype->class == ARRAY) {					sp -= size(n1->nodetype);		    	}			}	    }	    break;	case O_PSYM:#	    ifdef INHOUSE	    	if (p->value.arg[0]->op == O_SYM) {		    psym(p->value.arg[0]->value.sym);	    	} else {		    psym(p->value.arg[0]->nodetype);	    	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -