henesyinit from p9fce6d0435 years agoHistory
385 lines · 5.5 KB · C
RawDownload
/* * *	debugger * */ #include "defs.h"#include "fns.h" static long	round(long, long); extern	char	lastc, peekc; extern	ADDR	ditto;WORD	expv; static WORDascval(void){	Rune r;	int i;	char buf[UTFmax+1]; 	for (i = 0; i < UTFmax; i++) {	/* extract a rune */		if (fullrune(buf, i))			break;		if (readchar() == 0)			return (0);		buf[i] = lastc;	}	buf[i] = 0;	chartorune(&r, buf);	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) | */ 	switch ((int)readchar()) { 	case '*':		term(a|1);		if (get4(cormap, (ADDR)expv, &expv) < 0)			error("%r");		return(1); 	case '@':		term(a|1);		if (get4(symmap, (ADDR)expv, &expv) < 0)			error("%r");		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); 	case '%':		term(a|1);		if (get4(cormap, (ADDR)expv+mach->kbase, &expv) < 0)			error("%r");		return(1); 	default:		reread();		return(item(a));	}} item(int a){	/* name [ . local ] | number | . | ^  | <register | 'x | | */	char	*base;	char	savc;	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, &expv, rget) < 0)				error("%r");		}		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, &expv, rget) < 0)				error("%r");		}			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; 	p = isymbol;	do {		if (p < &isymbol[MAXSYM-1])			*p++ = lastc;		readchar();	} while (symchar(1));	*p = 0;} voidreadfname(char *filename){	char	*p;	char	c; 	/* snarf chars until un-escaped char in terminal char set */	p = filename;	do {		if ((c = lastc) != '\\' && p < &filename[MAXSYM-1])			*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=='_' || dig && isdigit(lastc));} static longround(long a, long b){	long w; 	w = (a/b)*b;	if (a!=w)		w += b;	return(w);}