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

📄 eval.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
	case O_TRACEON:	    traceon(p->value.trace.inst, p->value.trace.event,		p->value.trace.actions);	    break;	case O_TRACEOFF:	    traceoff(p->value.lcon);	    break;	default:	    panic("eval: bad op %d", p->op);    } if(debug_flag[2]) { 	fprintf(stderr," evaluated %s \n",showoperator(p->op)); }           }/* * Evaluate a list of commands. */public evalcmdlist(cl)Cmdlist cl;{    Command c;    foreach (Command, c, cl)	evalcmd(c);    endfor}/* * Push "len" bytes onto the expression stack from address "addr" * in the process.  If there isn't room on the stack, print an error message. */public rpush(addr, len)Address addr;int len;{    if (not canpush(len)) {	error("expression too large to evaluate");    } else {	chksp();	dread(sp, addr, len);	sp += len;    }}/* * Check if the stack has n bytes available. */public Boolean canpush(n)Integer n;{    return (Boolean) (sp + n < &stack[STACKSIZE]);}/* * Push a small scalar of the given type onto the stack. */public pushsmall(t, v)Symbol t;long v;{    register Integer s;    s = size(t);    switch (s) {	case sizeof(char):	    push(char, v);	    break;	case sizeof(short):	    push(short, v);	    break;	case sizeof(long):	    push(long, v);	    break;	default:	    panic("bad size %d in popsmall", s);    }}/* * Pop an item of the given type which is assumed to be no larger * than a long and return it expanded into a long. */public long popsmall(t)Symbol t;{    long r;    switch (size(t)) {	case sizeof(char):	    r = (long) pop(char);	    break;	case sizeof(short):	    r = (long) pop(short);	    break;	case sizeof(long):	    r = pop(long);	    break;	default:	    panic("popsmall: size is %d", size(t));    }    return r;}/* * Evaluate a conditional expression. */public Boolean cond(p)Node p;{    register Boolean b;    if (p == nil) {	b = true;    } else {	eval(p);	b = (Boolean) pop(Boolrep);    }    return b;}/* * Return the address corresponding to a given tree. */public Address lval(p)Node p;{    if (p->op == O_RVAL) {	eval(p->value.arg[0]);    } else {	eval(p);    }    return (Address) (pop(long));}/* * Process a trace command, translating into the appropriate events * and associated actions. */public trace(p)Node p;{    Node exp, place, cond;    Node left;    exp = p->value.arg[0];    place = p->value.arg[1];    cond = p->value.arg[2];    if (exp == nil) {	traceall(p->op, place, cond);    } else if (exp->op == O_QLINE or exp->op == O_LCON) {	traceinst(p->op, exp, cond);    } else if (place != nil and place->op == O_QLINE) {	traceat(p->op, exp, place, cond);    } else {	left = exp;	if (left->op == O_RVAL or left->op == O_CALL) {	    left = left->value.arg[0];	}	if (left->op == O_SYM and isblock(left->value.sym)) {	    traceproc(p->op, left->value.sym, place, cond);	} else {	    tracedata(p->op, exp, place, cond);	}    }}/* * Set a breakpoint that will turn on tracing. */private traceall(op, place, cond)Operator op;Node place;Node cond;{    Symbol s;    Node event;    Command action;    if (place == nil) {	s = program;    } else {	s = place->value.sym;    }    event = build(O_EQ, build(O_SYM, procsym), build(O_SYM, s));    action = build(O_PRINTSRCPOS,	build(O_QLINE, nil, build(O_LCON, (op == O_TRACE) ? 1 : 0)));    if (cond != nil) {	action = build(O_IF, cond, buildcmdlist(action));    }    action = build(O_TRACEON, (op == O_TRACEI), buildcmdlist(action));    action->value.trace.event = addevent(event, buildcmdlist(action));    if (isstdin()) {	printevent(action->value.trace.event);    }}/* * Set up the appropriate breakpoint for tracing an instruction. */private traceinst(op, exp, cond)Operator op;Node exp;Node cond;{    Node event, wh;    Command action;    Event e;    if (exp->op == O_LCON) {	wh = build(O_QLINE, build(O_SCON, cursource), exp);    } else {	wh = exp;    }    if (op == O_TRACEI) {	event = build(O_EQ, build(O_SYM, pcsym), wh);    } else {	event = build(O_EQ, build(O_SYM, linesym), wh);    }    action = build(O_PRINTSRCPOS, wh);    if (cond) {	action = build(O_IF, cond, buildcmdlist(action));    }    e = addevent(event, buildcmdlist(action));    if (isstdin()) {	printevent(e);    }}/* * Set a breakpoint to print an expression at a given line or address. */private traceat(op, exp, place, cond)Operator op;Node exp;Node place;Node cond;{    Node event;    Command action;    Event e;    if (op == O_TRACEI) {	event = build(O_EQ, build(O_SYM, pcsym), place);    } else {	event = build(O_EQ, build(O_SYM, linesym), place);    }    action = build(O_PRINTSRCPOS, exp);    if (cond != nil) {	action = build(O_IF, cond, buildcmdlist(action));    }    e = addevent(event, buildcmdlist(action));    if (isstdin()) {	printevent(e);    }}/* * Construct event for tracing a procedure. * * What we want here is * * 	when $proc = p do *	    if <condition> then *	        printcall; *	        once $pc = $retaddr do *	            printrtn; *	        end; *	    end if; *	end; * * Note that "once" is like "when" except that the event * deletes itself as part of its associated action. */private traceproc(op, p, place, cond)Operator op;Symbol p;Node place;Node cond;{    Node event;    Command action;    Cmdlist actionlist;    Event e;    action = build(O_PRINTCALL, p);    actionlist = list_alloc();    cmdlist_append(action, actionlist);    event = build(O_EQ, build(O_SYM, pcsym), build(O_SYM, retaddrsym));    action = build(O_ONCE, event, buildcmdlist(build(O_PRINTRTN, p)));    cmdlist_append(action, actionlist);    if (cond != nil) {	actionlist = buildcmdlist(build(O_IF, cond, actionlist));    }    event = build(O_EQ, build(O_SYM, procsym), build(O_SYM, p));    e = addevent(event, actionlist);    if (isstdin()) {	printevent(e);    }}/* * Set up breakpoint for tracing data. */private tracedata(op, exp, place, cond)Operator op;Node exp;Node place;Node cond;{    Symbol p;    Node event;    Command action;    p = (place == nil) ? tcontainer(exp) : place->value.sym;    if (p == nil) {	p = program;    }    action = build(O_PRINTIFCHANGED, exp);    if (cond != nil) {	action = build(O_IF, cond, buildcmdlist(action));    }    action = build(O_TRACEON, (op == O_TRACEI), buildcmdlist(action));    event = build(O_EQ, build(O_SYM, procsym), build(O_SYM, p));    action->value.trace.event = addevent(event, buildcmdlist(action));    if (isstdin()) {	printevent(action->value.trace.event);    }}/* * Setting and unsetting of stops. */public stop(p)Node p;{    Node exp, place, cond, t;    Symbol s;    Command action;    Event e;    exp = p->value.arg[0];    place = p->value.arg[1];    cond = p->value.arg[2];    if (exp != nil) {	stopvar(p->op, exp, place, cond);    } else {	action = build(O_STOPX);	if (cond != nil) {	    action = build(O_IF, cond, buildcmdlist(action));	}	if (place == nil or place->op == O_SYM) {	    if (place == nil) {		s = program;	    } else {		s = place->value.sym;	    }	    t = build(O_EQ, build(O_SYM, procsym), build(O_SYM, s));	    if (cond != nil) {		action = build(O_TRACEON, (p->op == O_STOPI),		    buildcmdlist(action));		e = addevent(t, buildcmdlist(action));		action->value.trace.event = e;	    } else {		e = addevent(t, buildcmdlist(action));	    }	    if (isstdin()) {		printevent(e);	    }	} else {	    stopinst(p->op, place, cond, action);	}    }}private stopinst(op, place, cond, action)Operator op;Node place;Node cond;Command action;{    Node event;    Event e;    if (op == O_STOP) {	event = build(O_EQ, build(O_SYM, linesym), place);    } else {	event = build(O_EQ, build(O_SYM, pcsym), place);    }    e = addevent(event, buildcmdlist(action));    if (isstdin()) {	printevent(e);    }}/* * Implement stopping on assignment to a variable by adding it to * the variable list. */private stopvar(op, exp, place, cond)Operator op;Node exp;Node place;Node cond;{    Symbol p;    Node event;    Command action;    if (place == nil) {	if (exp->op == O_LCON) {	    p = program;	} else {	    p = tcontainer(exp);	    if (p == nil) {		p = program;	    }	}    } else {	p = place->value.sym;    }    action = build(O_STOPIFCHANGED, exp);    if (cond != nil) {	action = build(O_IF, cond, buildcmdlist(action));    }    action = build(O_TRACEON, (op == O_STOPI), buildcmdlist(action));    event = build(O_EQ, build(O_SYM, procsym), build(O_SYM, p));    action->value.trace.event = addevent(event, buildcmdlist(action));    if (isstdin()) {	printevent(action->value.trace.event);    }}/* * Assign the value of an expression to a variable (or term). */public assign(var, exp)Node var;Node exp;{    Address addr;    integer varsize, expsize;    char cvalue;    short svalue;    long lvalue;    float fvalue;    if (not compatible(var->nodetype, exp->nodetype)) {	error("incompatible types");    }    addr = lval(var);    varsize = size(var->nodetype);    expsize = size(exp->nodetype);    eval(exp);    if (varsize == sizeof(float) and expsize == sizeof(double)) {	fvalue = (float) pop(double);	dwrite(&fvalue, addr, sizeof(fvalue));    } else {	if (varsize < sizeof(long)) {	    lvalue = 0;	    popn(expsize, &lvalue);	    switch (varsize) {		case sizeof(char):		    cvalue = lvalue;		    dwrite(&cvalue, addr, sizeof(cvalue));		    break;		case sizeof(short):		    svalue = lvalue;		    dwrite(&svalue, addr, sizeof(svalue));		    break;		default:		    panic("bad size %d", varsize);	    }	} else {	    if (expsize <= varsize) {		sp -= expsize;		dwrite(sp, addr, expsize);	    } else {		sp -= expsize;		dwrite(sp, addr, varsize);	    }	}    }}/* * Send some nasty mail to the current support person. */public gripe(){    typedef Operation();    Operation *old;    int pid, status;    extern int versionNumber;    char subject[100];    char *maintainer = "linton@berkeley";    puts("Type control-D to end your message.  Be sure to include");    puts("your name and the name of the file you are debugging.");    putchar('\n');    old = signal(SIGINT, SIG_DFL);    sprintf(subject, "dbx (version %d) gripe", versionNumber);    pid = back("Mail", stdin, stdout, "-s", subject, maintainer, nil);    signal(SIGINT, SIG_IGN);    pwait(pid, &status);    signal(SIGINT, old);    if (status == 0) {	puts("Thank you.");    } else {	puts("\nMail not sent.");    }}/* * Give the user some help. */public help(){    puts("run                    - begin execution of the program");    puts("print <exp>            - print the value of the expression");    puts("where                  - print currently active procedures");    puts("stop at <line>         - suspend execution at the line");    puts("stop in <proc>         - suspend execution when <proc> is called");    puts("cont                   - continue execution");    puts("step                   - single step one line");    puts("next                   - step to next line (skip over calls)");    puts("trace <line#>          - trace execution of the line");    puts("trace <proc>           - trace calls to the procedure");    puts("trace <var>            - trace changes to the variable");    puts("trace <exp> at <line#> - print <exp> when <line> is reached");    puts("status                 - print trace/stop's in effect");    puts("delete <number>        - remove trace or stop of given number");    puts("call <proc>            - call a procedure in program");    puts("whatis <name>          - print the declaration of the name");    puts("list <line>, <line>    - list source lines");    puts("gripe                  - send mail to the person in charge of dbx");    puts("quit                   - exit dbx");}/* * Divert output to the given file name. * Cannot redirect to an existing file. */private int so_fd;private Boolean notstdout;public setout(filename)String filename;{    File f;    f = fopen(filename, "r");    if (f != nil) {	fclose(f);	error("%s: file already exists", filename);    } else {	so_fd = dup(1);	close(1);	if (creat(filename, 0666) == nil) {	    unsetout();	    error("can't create %s", filename);	}	notstdout = true;    }}/* * Revert output to standard output. */public unsetout(){    fflush(stdout);    close(1);    if (dup(so_fd) != 1) {	panic("standard out dup failed");    }    close(so_fd);    notstdout = false;}/* * Determine is standard output is currently being redirected * to a file (as far as we know). */public Boolean isredirected(){    return notstdout;}

⌨️ 快捷键说明

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