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

📄 umath.c

📁 举世闻名的joe记事本源程序
💻 C
字号:
/* *	Math *	Copyright *		(C) 1992 Joseph H. Allen * *	This file is part of JOE (Joe's Own Editor) */#include "types.h"unsigned char *merr;int mode_hex;int mode_eng;int mode_ins;double vzero = 0.0;static RETSIGTYPE fperr(int unused){	if (!merr) {		merr = joe_gettext(_("Float point exception"));	}	REINSTALL_SIGHANDLER(SIGFPE, fperr);}struct var {	unsigned char *name;	double (*func)(double n);	int set;	double val;	struct var *next;} *vars = NULL;static struct var *get(unsigned char *str){	struct var *v;	for (v = vars; v; v = v->next) {		if (!zcmp(v->name, str)) {			return v;		}	}	v = (struct var *) joe_malloc(sizeof(struct var));	v->set = 0;	v->func = 0;	v->val = 0;	v->next = vars;	vars = v;	v->name = zdup(str);	return v;}unsigned char *ptr;struct var *dumb;static double eval(unsigned char *s);int recur=0;/* en means enable evaluation */static double expr(int prec, int en,struct var **rtv){	double x = 0.0, y, z;	struct var *v = NULL;	while (*ptr == ' ' || *ptr == '\t') {		++ptr;	}	if ((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= 'A' && *ptr <= 'Z')	    || *ptr == '_') {		unsigned char *s = ptr, c;		while ((*ptr >= 'a' && *ptr <= 'z')		       || (*ptr >= 'A' && *ptr <= 'Z')		       || *ptr == '_' || (*ptr >= '0' && *ptr <= '9')) {			++ptr;		}		c = *ptr;		*ptr = 0;		if (!zcmp(s,USTR "joe")) {			*ptr = c;			v = 0;			x = 0.0;			while (*ptr==' ' || *ptr=='\t')				++ptr;			if (*ptr=='(') {				unsigned char *q = ++ptr;				MACRO *m;				int sta;				while (*q && *q!=')')					++q;				if (*q!=')') {					if (!merr)						merr = joe_gettext(_("Missing )"));				} else					*q++ = 0;				if (en) {					m = mparse(NULL,ptr,&sta);					ptr = q;					if (m) {						x = !exmacro(m,1);						rmmacro(m);					} else {						if (!merr)							merr = joe_gettext(_("Syntax error in macro"));					}				} else {					ptr = q;				}			} else {				if (!merr)					merr = joe_gettext(_("Missing ("));			}			c = *ptr;		} else if (!en) {			v = 0;			x = 0.0;		} else if (!zcmp(s,USTR "hex")) {			mode_hex = 1;			mode_eng = 0;			v = get(USTR "ans");			x = v->val;		} else if (!zcmp(s,USTR "dec")) {			mode_hex = 0;			mode_eng = 0;			v = get(USTR "ans");			x = v->val;		} else if (!zcmp(s,USTR "eng")) {			mode_hex = 0;			mode_eng = 1;			v = get(USTR "ans");			x = v->val;		} else if (!zcmp(s,USTR "ins")) {			mode_ins = 1;			v = get(USTR "ans");			x = v->val;		} else if (!zcmp(s,USTR "sum")) {			double xsq;			int cnt = blksum(&x, &xsq);			if (!merr && cnt<=0)				merr = joe_gettext(_("No numbers in block"));			v = 0;		} else if (!zcmp(s,USTR "cnt")) {			double xsq;			int cnt = blksum(&x, &xsq);			if (!merr && cnt<=0)				merr = joe_gettext(_("No numbers in block"));			v = 0;			x = cnt;		} else if (!zcmp(s,USTR "avg")) {			double xsq;			int cnt = blksum(&x, &xsq);			if (!merr && cnt<=0)				merr = joe_gettext(_("No numbers in block"));			v = 0;			if (cnt)				x /= (double)cnt;		} else if (!zcmp(s,USTR "dev")) {			double xsq;			double avg;			int cnt = blksum(&x, &xsq);			if (!merr && cnt<=0)				merr = joe_gettext(_("No numbers in block"));			v = 0;			if (cnt) {				avg = x / (double)cnt;				x = sqrt(xsq + (double)cnt*avg*avg - 2.0*avg*x);			}		} else if (!zcmp(s,USTR "eval")) {			unsigned char *save = ptr;			unsigned char *e = blkget();			if (e) {				v = 0;				x = eval(e);				joe_free(e);				ptr = save;			} else if (!merr) {				merr = joe_gettext(_("No block"));			}		} else {			v = get(s);			x = v->val;		}		*ptr = c;	} else if ((*ptr >= '0' && *ptr <= '9') || *ptr == '.') {		char *eptr;		x = strtod((char *)ptr,&eptr);		ptr = (unsigned char *)eptr;	} else if (*ptr == '(') {		++ptr;		x = expr(0, en, &v);		if (*ptr == ')')			++ptr;		else {			if (!merr)				merr = joe_gettext(_("Missing )"));		}	} else if (*ptr == '-') {		++ptr;		x = -expr(10, en, &dumb);	} else if (*ptr == '!') {		++ptr;		x = !expr(10, en, &dumb);	}      loop:	while (*ptr == ' ' || *ptr == '\t')		++ptr;	if (*ptr == '(' && 11 > prec) {		++ptr;		y = expr(0, en, &dumb);		if (*ptr == ')')			++ptr;		else {			if (!merr)				merr = joe_gettext(_("Missing )"));		}		if (v && v->func)			x = v->func(y);		else {			if (!merr)				merr = joe_gettext(_("Called object is not a function"));		}		goto loop;	} else if (*ptr == '!' && ptr[1]!='=' && 10 >= prec) {		++ptr;		if (x == (int)x && x>=1.0 && x<70.0) {			y = 1.0;			while (x>1.0) {				y *= x;				x -= 1.0;			}			x = y;		} else {			if (!merr)				merr = joe_gettext(_("Factorial can only take positive integers"));		}		v = 0;		goto loop;	} else if (*ptr == '*' && ptr[1] == '*' && 8 > prec) {		ptr+=2;		x = pow(x, expr(8, en, &dumb));		v = 0;		goto loop;	} else if (*ptr == '^' && 8 > prec) {		++ptr;		x = pow(x, expr(8, en, &dumb));		v = 0;		goto loop;	} else if (*ptr == '*' && 7 > prec) {		++ptr;		x *= expr(7, en, &dumb);		v = 0;		goto loop;	} else if (*ptr == '/' && 7 > prec) {		++ptr;		x /= expr(7, en, &dumb);		v = 0;		goto loop;	} else if(*ptr=='%' && 7>prec) {		++ptr;		y = expr(7, en, &dumb);		if ((int)y == 0) x = 1.0/vzero;		else x = ((int) x) % (int)y;		v = 0;		goto loop;	} else if (*ptr == '+' && 6 > prec) {		++ptr;		x += expr(6, en, &dumb);		v = 0;		goto loop;	} else if (*ptr == '-' && 6 > prec) {		++ptr;		x -= expr(6, en, &dumb);		v = 0;		goto loop;	} else if (*ptr == '<' && 5 > prec) {		++ptr;		if (*ptr == '=') ++ptr, x = (x <= expr(5, en, &dumb));		else x = (x < expr(5,en,&dumb));		v = 0;		goto loop;	} else if (*ptr == '>' && 5 > prec) {		++ptr;		if (*ptr == '=') ++ptr, x=(x >= expr(5,en,&dumb));		else x = (x > expr(5,en,&dumb));		v = 0;		goto loop;	} else if (*ptr == '=' && ptr[1] == '=' && 5 > prec) {		++ptr, ++ptr;		x = (x == expr(5,en,&dumb));		v = 0;		goto loop;	} else if (*ptr == '!' && ptr[1] == '=' && 5 > prec) {		++ptr, ++ptr;		x = (x != expr(5,en,&dumb));		v = 0;		goto loop;	} else if (*ptr == '&' && ptr[1] == '&' && 3 > prec) {		++ptr, ++ptr;		y = expr(3,x!=0.0 && en,&dumb);		x = (int)x && (int)y;		v = 0;		goto loop;	} else if (*ptr=='|' && ptr[1]=='|' &&  3 > prec) {		++ptr, ++ptr;		y = expr(3,x==0.0 && en,&dumb);		x = (int)x || (int)y;		v= 0;		goto loop;	} else if (*ptr=='?' && 2 >= prec) {		++ptr;		y = expr(2,x!=0.0 && en,&dumb);		if (*ptr==':') {			++ptr;			z = expr(2,x==0.0 && en,&dumb);			if (x != 0.0)				x = y;			else				x = z;			v = 0;  		} else if (!merr) {			merr = USTR ": missing after ?";		}		goto loop;	} else if (*ptr == '=' && 1 >= prec) {		++ptr;		x = expr(1, en,&dumb);		if (v) {			v->val = x;			v->set = 1;		} else {			if (!merr)				merr = joe_gettext(_("Left side of = is not an l-value"));		}		v = 0;		goto loop;	}	*rtv = v;	return x;}static double eval(unsigned char *s){	double result = 0.0;	struct var *v;	if(++recur==1000) {		merr = joe_gettext(_("Recursion depth exceeded"));		--recur;		return 0.0;	}	ptr = s;	while (!merr && *ptr) {		result = expr(0, 1, &dumb);		v = get(USTR "ans");		v->val = result;		v->set = 1;		if (!merr) {			while (*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n') {				++ptr;			}			if (*ptr == ':') {				++ptr;				while (*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n') {					++ptr;				}			} else if (*ptr) {				merr = joe_gettext(_("Extra junk after end of expr"));			}		}	}	--recur;	return result;}double m_sin(double n) { return sin(n); }double m_cos(double n) { return cos(n); }double m_tan(double n) { return tan(n); }double m_exp(double n) { return exp(n); }double m_sqrt(double n) { return sqrt(n); }double m_cbrt(double n) { return cbrt(n); }double m_log(double n) { return log(n); }double m_log10(double n) { return log10(n); }double m_asin(double n) { return asin(n); }double m_acos(double n) { return acos(n); }double m_atan(double n) { return atan(n); }double m_sinh(double n) { return sinh(n); }double m_cosh(double n) { return cosh(n); }double m_tanh(double n) { return tanh(n); }double m_asinh(double n) { return asinh(n); }double m_acosh(double n) { return acosh(n); }double m_atanh(double n) { return atanh(n); }double m_int(double n) { return (int)(n); }double m_floor(double n) { return floor(n); }double m_ceil(double n) { return ceil(n); }double m_fabs(double n) { return fabs(n); }double m_erf(double n) { return erf(n); }double m_erfc(double n) { return erfc(n); }double m_j0(double n) { return j0(n); }double m_j1(double n) { return j1(n); }double m_y0(double n) { return y0(n); }double m_y1(double n) { return y1(n); }double calc(BW *bw, unsigned char *s){	/* BW *tbw = bw->parent->main->object; */	BW *tbw = bw;	struct var *v;	int c = brch(bw->cursor);	if (!vars) {		v = get(USTR "sin"); v->func = m_sin;		v = get(USTR "cos"); v->func = m_cos;		v = get(USTR "tan"); v->func = m_tan;		v = get(USTR "exp"); v->func = m_exp;		v = get(USTR "sqrt"); v->func = m_sqrt;		v = get(USTR "cbrt"); v->func = m_cbrt;		v = get(USTR "ln"); v->func = m_log;		v = get(USTR "log"); v->func = m_log10;		v = get(USTR "asin"); v->func = m_asin;		v = get(USTR "acos"); v->func = m_acos;		v = get(USTR "atan"); v->func = m_atan;		v = get(USTR "pi"); v->val = M_PI; v->set = 1;		v = get(USTR "e"); v->val = M_E; v->set = 1;		v = get(USTR "sinh"); v->func = m_sinh;		v = get(USTR "cosh"); v->func = m_cosh;		v = get(USTR "tanh"); v->func = m_tanh;		v = get(USTR "asinh"); v->func = m_asinh;		v = get(USTR "acosh"); v->func = m_acosh;		v = get(USTR "atanh"); v->func = m_atanh;		v = get(USTR "int"); v->func = m_int;		v = get(USTR "floor"); v->func = m_floor;		v = get(USTR "ceil"); v->func = m_ceil;		v = get(USTR "abs"); v->func = m_fabs;		v = get(USTR "erf"); v->func = m_erf;		v = get(USTR "erfc"); v->func = m_erfc;		v = get(USTR "j0"); v->func = m_j0;		v = get(USTR "j1"); v->func = m_j1;		v = get(USTR "y0"); v->func = m_y0;		v = get(USTR "y1"); v->func = m_y1;	}	v = get(USTR "top");	v->val = tbw->top->line + 1;	v->set = 1;	v = get(USTR "lines");	v->val = tbw->b->eof->line + 1;	v->set = 1;	v = get(USTR "line");	v->val = tbw->cursor->line + 1;	v->set = 1;	v = get(USTR "col");	v->val = tbw->cursor->col + 1;	v->set = 1;	v = get(USTR "byte");	v->val = tbw->cursor->byte + 1;	v->set = 1;	v = get(USTR "size");	v->val = tbw->b->eof->byte;	v->set = 1;	v = get(USTR "height");	v->val = tbw->h;	v->set = 1;	v = get(USTR "width");	v->val = tbw->w;	v->set = 1;	v = get(USTR "char");	v->val = (c == NO_MORE_DATA ? -1.0 : c);	v->set = 1;	v = get(USTR "markv");	v->val = markv(1) ? 1.0 : 0.0;	v->set = 1;	v = get(USTR "rdonly");	v->val = tbw->b->rdonly;	v->set = 1;	v = get(USTR "arg");	v->val = current_arg;	v->set = 1;	v = get(USTR "argset");	v->val = current_arg_set;	v->set = 1;	v = get(USTR "no_windows");	v->val = countmain(bw->parent->t);	v->set = 1;	merr = 0;	return eval(s);}/* Main user interface */static int domath(BW *bw, unsigned char *s, void *object, int *notify){	double result = calc(bw, s);	if (notify) {		*notify = 1;	}	if (merr) {		msgnw(bw->parent, merr);		return -1;	}	vsrm(s);	if (mode_hex)		joe_snprintf_1(msgbuf, JOE_MSGBUFSIZE, "0x%lX", (long)result);	else if (mode_eng)		joe_snprintf_1(msgbuf, JOE_MSGBUFSIZE, "%.16G", result);	else		joe_snprintf_1(msgbuf, JOE_MSGBUFSIZE, "%.16G", result);	if (bw->parent->watom->what != TYPETW || mode_ins) {		binsm(bw->cursor, sz(msgbuf));		pfwrd(bw->cursor, zlen(msgbuf));		bw->cursor->xcol = piscol(bw->cursor);	} else {		msgnw(bw->parent, msgbuf);	}	mode_ins = 0;	return 0;}B *mathhist = NULL;int umath(BW *bw){	joe_set_signal(SIGFPE, fperr);	if (wmkpw(bw->parent, USTR "=", &mathhist, domath, USTR "Math", NULL, NULL, NULL, NULL, locale_map, 0)) {		return 0;	} else {		return -1;	}}

⌨️ 快捷键说明

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