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

📄 eval.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
/*#@(#)eval.c	4.1	Ultrix	7/17/90*//* Copyright (c) 1982 Regents of the University of California */static char sccsid[] = "@(#)eval.c 1.10 8/17/83";static char rcsid[] = "$Header: eval.c,v 1.3 84/03/27 10:20:23 linton Exp $";/* * Tree evaluation. */#include "defs.h"#include "tree.h"#include "operators.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 "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 *//* * 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, f;    Node n1, n2;    Boolean b;    File file;    checkref(p);    if (debug_flag[2]) {	fprintf(stderr," evaluating %s \n",showoperator(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));		    }		    push(long, address(s, nil));		} else if (isblock(s)) {		    push(Symbol, s);		} else {		    error("can't evaluate a %s", classname(s));		}	    }	    break;	case O_LCON:	    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:	    n = pop(long);	    i = evalindex(p->value.arg[0]->nodetype,		popsmall(p->value.arg[1]->nodetype));	    push(long, n + i*size(p->nodetype));	    break;	case O_DOT:	    s = p->value.arg[1]->value.sym;	    n = lval(p->value.arg[0]);	    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");	    }	    if (p->op == O_INDIR) {		len = sizeof(long);	    } else {		len = size(p->nodetype);	    }	    rpush(addr, len);	    break;	/*	 * Effectively, we want to pop n bytes off for the evaluated subtree	 * and push len bytes on for the new type of the same tree.	 */	case O_TYPERENAME:	    n = size(p->value.arg[0]->nodetype);	    len = size(p->nodetype);	    sp = sp - n + len;	    break;	case O_COMMA:	    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_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:	    if (p->value.arg[0]->op == O_SYM) {		f = p->value.arg[0]->value.sym;		addr = firstline(f);		if (addr == NOADDR) {		    error("no source lines for \"%s\"", symname(f));		}		setsource(srcfilename(addr));		r0 = srcline(addr) - 5;		r1 = r0 + 10;		if (r0 < 1) {		    r0 = 1;		}	    } else {		eval(p->value.arg[0]);		r0 = pop(long);		eval(p->value.arg[1]);		r1 = pop(long);	    }	    printlines((Lineno) r0, (Lineno) r1);	    break;	case O_FUNC:	    if (p->value.arg[0] == nil) {		printname(stdout, curfunc);		putchar('\n');	    } else {		s = p->value.arg[0]->value.sym;		if (isroutine(s)) {		    setcurfunc(s);		} else {		    find(f, s->name) where isroutine(f) endfind(f);		    if (f == nil) {			error("%s is not a procedure or function", symname(s));		    }		    setcurfunc(f);		}		addr = codeloc(curfunc);		if (addr != NOADDR) {		    setsource(srcfilename(addr));		    cursrcline = srcline(addr) - 5;		    if (cursrcline < 1) {			cursrcline = 1;		    }		}	    }	    break;	case O_EXAMINE:	    eval(p->value.examine.beginaddr);	    r0 = pop(long);	    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_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_PSYM:	    if (p->value.arg[0]->op == O_SYM) {		psym(p->value.arg[0]->value.sym);	    } else {		psym(p->value.arg[0]->nodetype);	    }	    break;	case O_QLINE:	    eval(p->value.arg[1]);	    break;	case O_STEP:	    b = inst_tracing;	    inst_tracing = (Boolean) (not p->value.step.source);	    if (p->value.step.skipcalls) {		next();	    } else {		stepc();	    }	    inst_tracing = b;	    useInstLoc = (Boolean) (not p->value.step.source);	    printnews();	    break;	case O_WHATIS:	    if (p->value.arg[0]->op == O_SYM) {		printdecl(p->value.arg[0]->value.sym);	    } else {		printdecl(p->value.arg[0]->nodetype);	    }	    break;	case O_WHERE:	    wherecmd();	    break;	case O_WHEREIS:	    if (p->value.arg[0]->op == O_SYM) {		printwhereis(stdout,p->value.arg[0]->value.sym);	    } else {		printwhereis(stdout,p->value.arg[0]->nodetype);	    }	    break;	case O_WHICH:	    if (p->value.arg[0]->op == O_SYM) {		printwhich(stdout,p->value.arg[0]->value.sym);	    } else {		printwhich(stdout,p->value.arg[0]->nodetype);	    }	    putchar('\n');	    break;	case O_ALIAS:	    n1 = p->value.arg[0];	    n2 = p->value.arg[1];	    if (n1 == nil) {		print_alias(nil);	    } else if (n2 == nil) {		print_alias(n1->value.name);	    } else {		enter_alias(n1->value.name, n2->value.name);	    }	    break;	case O_CALL:	    callproc(p->value.arg[0], p->value.arg[1]);	    break;	case O_CATCH:	    psigtrace(process, p->value.lcon, true);	    break;	case O_EDIT:	    edit(p->value.scon);	    break;        case O_DEBUG:            debug(p);	    break;	case O_DOWN:	    checkref(p->value.arg[0]);	    assert(p->value.arg[0]->op == O_LCON);	    down(p->value.arg[0]->value.lcon);	    break;	case O_DUMP:	    dump();	    break;	case O_GRIPE:	    gripe();	    break;	case O_HELP:	    help();	    break;	case O_IGNORE:	    psigtrace(process, p->value.lcon, false);	    break;	case O_RETURN:	    if (p->value.arg[0] == nil) {		rtnfunc(nil);	    } else {		assert(p->value.arg[0]->op == O_SYM);		rtnfunc(p->value.arg[0]->value.sym);	    }	    break;	case O_RUN:	    run();	    break;	case O_SOURCE:	    setinput(p->value.scon);	    break;	case O_STATUS:	    status();	    break;	case O_TRACE:	case O_TRACEI:	    trace(p);	    break;	case O_STOP:	case O_STOPI:	    stop(p);	    break;	case O_UP:	    checkref(p->value.arg[0]);	    assert(p->value.arg[0]->op == O_LCON);	    up(p->value.arg[0]->value.lcon);	    break;	case O_ADDEVENT:	    addevent(p->value.event.cond, p->value.event.actions);	    break;	case O_DELETE:	    n1 = p->value.arg[0];	    while (n1->op == O_COMMA) {		n2 = n1->value.arg[0];		assert(n2->op == O_LCON);		if (not delevent((unsigned int) n2->value.lcon)) {		    error("unknown event %ld", n2->value.lcon);		}		n1 = n1->value.arg[1];	    }	    assert(n1->op == O_LCON);	    if (not delevent((unsigned int) n1->value.lcon)) {		error("unknown event %ld", n1->value.lcon);	    }	    break;	case O_ENDX:	    endprogram();	    break;	case O_IF:	    if (cond(p->value.event.cond)) {		evalcmdlist(p->value.event.actions);	    }	    break;	case O_ONCE:	    event_once(p->value.event.cond, p->value.event.actions);	    break;	case O_PRINTCALL:	    printcall(p->value.sym, whatblock(return_addr()));	    break;	case O_PRINTIFCHANGED:	    printifchanged(p->value.arg[0]);	    break;	case O_PRINTRTN:	    printrtn(p->value.sym);	    break;	case O_PRINTSRCPOS:	    getsrcpos();	    if (p->value.arg[0] == nil) {		printsrcpos();		putchar('\n');		printlines(curline, curline);	    } else if (p->value.arg[0]->op == O_QLINE) {		if (p->value.arg[0]->value.arg[1]->value.lcon == 0) {		    printf("tracei: ");		    printinst(pc, pc);		} else {		    printf("trace:  ");		    printlines(curline, curline);		}	    } else {		printsrcpos();		printf(": ");		eval(p->value.arg[0]);		prtree(stdout, p->value.arg[0]);		printf(" = ");		printval(p->value.arg[0]->nodetype);		putchar('\n');	    }	    break;	case O_PROCRTN:	    procreturn(p->value.sym);	    break;	case O_STOPIFCHANGED:	    stopifchanged(p->value.arg[0]);	    break;	case O_STOPX:	    isstopped = true;	    break;

⌨️ 快捷键说明

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