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

📄 expr.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/* * *	debugger * */#include "defs.h"#include "fns.h"static long	round(long, long);extern	ADDR	ditto;uvlong	expv;static WORDascval(void){	Rune r;	if (readchar() == 0)		return (0);	r = lastc;	while(quotchar())	/*discard chars to ending quote */		;	return((WORD) r);}/* * read a floating point number * the result must fit in a WORD */static WORDfpin(char *buf){	union {		WORD w;		float f;	} x;	x.f = atof(buf);	return (x.w);}WORDdefval(WORD w){	if (expr(0))		return (expv);	else		return (w);}expr(int a){	/* term | term dyadic expr |  */	int	rc;	WORD	lhs;	rdc();	reread();	rc=term(a);	while (rc) {		lhs = expv;		switch ((int)readchar()) {		case '+':			term(a|1);			expv += lhs;			break;		case '-':			term(a|1);			expv = lhs - expv;			break;		case '#':			term(a|1);			expv = round(lhs,expv);			break;		case '*':			term(a|1);			expv *= lhs;			break;		case '%':			term(a|1);			if(expv != 0)				expv = lhs/expv;			else{				if(lhs)					expv = 1;				else					expv = 0;			}			break;		case '&':			term(a|1);			expv &= lhs;			break;		case '|':			term(a|1);			expv |= lhs;			break;		case ')':			if ((a&2)==0)				error("unexpected `)'");		default:			reread();			return(rc);		}	}	return(rc);}term(int a){	/* item | monadic item | (expr) | */	ADDR e;	switch ((int)readchar()) {	case '*':		term(a|1);		if (geta(cormap, expv, &e) < 0)			error("%r");		expv = e;		return(1);	case '@':		term(a|1);		if (geta(symmap, expv, &e) < 0)			error("%r");		expv = e;		return(1);	case '-':		term(a|1);		expv = -expv;		return(1);	case '~':		term(a|1);		expv = ~expv;		return(1);	case '(':		expr(2);		if (readchar()!=')')			error("syntax error: `)' expected");		return(1);	default:		reread();		return(item(a));	}}item(int a){	/* name [ . local ] | number | . | ^  | <register | 'x | | */	char	*base;	char	savc;	uvlong e;	Symbol s;	char gsym[MAXSYM], lsym[MAXSYM];	readchar();	if (isfileref()) {		readfname(gsym);		rdc();			/* skip white space */		if (lastc == ':') {	/* it better be */			rdc();		/* skip white space */			if (!getnum(readchar))				error("bad number");			if (expv == 0)				expv = 1;	/* file begins at line 1 */			expv = file2pc(gsym, expv);			if (expv == -1)				error("%r");			return 1;		}		error("bad file location");	} else if (symchar(0)) {			readsym(gsym);		if (lastc=='.') {			readchar();	/* ugh */			if (lastc == '.') {				lsym[0] = '.';				readchar();				readsym(lsym+1);			} else if (symchar(0)) {				readsym(lsym);			} else				lsym[0] = 0;			if (localaddr(cormap, gsym, lsym, &e, rget) < 0)				error("%r");			expv = e;		}		else {			if (lookup(0, gsym, &s) == 0)				error("symbol not found");			expv = s.value;		}		reread();	} else if (getnum(readchar)) {		;	} else if (lastc=='.') {			readchar();		if (!symchar(0) && lastc != '.') {			expv = dot;		} else {			if (findsym(rget(cormap, mach->pc), CTEXT, &s) == 0)				error("no current function");			if (lastc == '.') {				lsym[0] = '.';				readchar();				readsym(lsym+1);			} else				readsym(lsym);			if (localaddr(cormap, s.name, lsym, &e, rget) < 0)				error("%r");			expv = e;		}			reread();	} else if (lastc=='"') {		expv=ditto;	} else if (lastc=='+') {		expv=inkdot(dotinc);	} else if (lastc=='^') {		expv=inkdot(-dotinc);	} else if (lastc=='<') {		savc=rdc();		base = regname(savc);		expv = rget(cormap, base);	}	else if (lastc=='\'')		expv = ascval();	else if (a)		error("address expected");	else {			reread();		return(0);	}	return(1);}#define	MAXBASE	16/* service routines for expression reading */getnum(int (*rdf)(void)){	char *cp;	int base, d;	BOOL fpnum;	char num[MAXLIN];	base = 0;	fpnum = FALSE;	if (lastc == '#') {		base = 16;		(*rdf)();	}	if (convdig(lastc) >= MAXBASE)		return (0);	if (lastc == '0')		switch ((*rdf)()) {		case 'x':		case 'X':			base = 16;			(*rdf)();			break;		case 't':		case 'T':			base = 10;			(*rdf)();			break;		case 'o':		case 'O':			base = 8;			(*rdf)();			break;		default:			if (base == 0)				base = 8;			break;		}	if (base == 0)		base = 10;	expv = 0;	for (cp = num, *cp = lastc; ;(*rdf)()) {		if ((d = convdig(lastc)) < base) {			expv *= base;			expv += d;			*cp++ = lastc;		}		else if (lastc == '.') {			fpnum = TRUE;			*cp++ = lastc;		} else {			reread();			break;		}	}	if (fpnum)		expv = fpin(num);	return (1);}voidreadsym(char *isymbol){	char	*p;	Rune r;	p = isymbol;	do {		if (p < &isymbol[MAXSYM-UTFmax-1]){			r = lastc;			p += runetochar(p, &r);		}		readchar();	} while (symchar(1));	*p = 0;}voidreadfname(char *filename){	char	*p;	Rune	c;	/* snarf chars until un-escaped char in terminal char set */	p = filename;	do {		if ((c = lastc) != '\\' && p < &filename[MAXSYM-UTFmax-1])			p += runetochar(p, &c);		readchar();	} while (c == '\\' || strchr(CMD_VERBS, lastc) == 0);	*p = 0;	reread();}convdig(int c){	if (isdigit(c))		return(c-'0');	else if (!isxdigit(c))		return(MAXBASE);	else if (isupper(c))		return(c-'A'+10);	else		return(c-'a'+10);}symchar(int dig){	if (lastc=='\\') {		readchar();		return(TRUE);	}	return(isalpha(lastc) || lastc>0x80 || lastc=='_' || dig && isdigit(lastc));}static longround(long a, long b){	long w;	w = (a/b)*b;	if (a!=w)		w += b;	return(w);}

⌨️ 快捷键说明

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