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

📄 interp.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
/*	SC	A Spreadsheet Calculator *		Expression interpreter and assorted support routines. * *		original by James Gosling, September 1982 *		modified by Mark Weiser and Bruce Israel,  *			University of Maryland * *              More mods Robert Bond, 12/86 *		More mods by Alan Silverstein, 3-4/88, see list of changes. *		$Revision: 6.8 $ */#define DEBUGDTS 1		/* REMOVE ME *//* #define EXPRTREE	/* expr. dependency tree stuff, not ready yet */#ifdef aiws#undef _C_func			/* Fixes for undefined symbols on AIX */#endif#ifdef IEEE_MATH#include <ieeefp.h>#endif /* IEEE_MATH */#include <math.h>#include <signal.h>#include <setjmp.h>#include <stdio.h>extern int errno;		/* set by math functions */#ifdef BSD42#include <strings.h>#include <sys/time.h>#ifndef strchr#define strchr index#endif#else#include <time.h>#ifndef SYSIII#include <string.h>#endif#endif#include <curses.h>#include "sc.h"#if defined(BSD42) || defined(BSD43)char *re_comp();#endif#if defined(SYSV2) || defined(SYSV3)char *regcmp();char *regex();#endif#ifdef SIGVOID    void quit();#else    int quit();#endif/* Use this structure to save the the last 'g' command */struct go_save {	int g_type;	double g_n;	char *g_s;	int  g_row;	int  g_col;} gs;/* g_type can be: */#define G_NONE 0			/* Starting value - must be 0*/#define G_NUM 1#define G_STR 2#define G_CELL 3#define ISVALID(r,c)	((r)>=0 && (r)<maxrows && (c)>=0 && (c)<maxcols)extern FILE *popen();jmp_buf fpe_save;int	exprerr;	/* Set by eval() and seval() if expression errors */double  prescale = 1.0;	/* Prescale for constants in let() */int	extfunc  = 0;	/* Enable/disable external functions */int     loading = 0;	/* Set when readfile() is active */double fn1_eval();double fn2_eval();struct	ent *firstev = (struct ent *)0;	/* first expr in the eval list */#define PI (double)3.14159265358979323846#define dtr(x) ((x)*(PI/(double)180.0))#define rtd(x) ((x)*(180.0/(double)PI))double finfunc(fun,v1,v2,v3)int fun;double v1,v2,v3;{ 	double answer,p;  	p = fn2_eval(pow, 1 + v2, v3);  	switch(fun) 	{ 	case PV: 		answer = v1 * (1 - 1/p) / v2; 		break; 	case FV: 		answer = v1 * (p - 1) / v2; 		break; 	case PMT: 		answer = v1 * v2 / (1 - 1/p); 		break;	default:		error("Unknown function in finfunc");		return((double)0);	}	return(answer);}char *dostindex( val, minr, minc, maxr, maxc)double val;int minr, minc, maxr, maxc;{    register r,c;    register struct ent *p;    char *pr;    int x;    x = (int) val;    r = minr; c = minc;    p = (struct ent *)0;    if ( minr == maxr ) { /* look along the row */	c = minc + x - 1;	if (c <= maxc && c >=minc)	    p = *ATBL(tbl, r, c);    } else if ( minc == maxc ) { /* look down the column */	r = minr + x - 1;	if (r <= maxr && r >=minr)	    p = *ATBL(tbl, r, c);    } else {	error ("range specified to @stindex");	return((char *)0);    }    if (p && p->label) {	pr = xmalloc((unsigned)(strlen(p->label)+1));	(void)strcpy(pr, p->label);	return (pr);     } else	return((char *)0);}doubledoindex( val, minr, minc, maxr, maxc)double val;int minr, minc, maxr, maxc;{    double v;    register r,c;    register struct ent *p;    int x;    x = (int) val;    v = (double)0;    r = minr; c = minc;    if ( minr == maxr ) { /* look along the row */	c = minc + x - 1;	if (c <= maxc && c >=minc 		&& (p = *ATBL(tbl, r, c)) && p->flags&is_valid )					return p->v;	}    else if ( minc == maxc ){ /* look down the column */	r = minr + x - 1;	if (r <= maxr && r >=minr 		&& (p = *ATBL(tbl, r, c)) && p->flags&is_valid )					return p->v;	}    else error(" range specified to @index");    return v;}doubledolookup( val, minr, minc, maxr, maxc, offr, offc)struct enode * val;int minr, minc, maxr, maxc, offr, offc;{    double v, ret = (double)0;    register r,c;    register struct ent *p = (struct ent *)0;    int incr,incc,fndr,fndc;    char *s;    incr = (offc != 0); incc = (offr != 0);    if (etype(val) == NUM) {	v = eval(val);	for (r = minr, c = minc; r <= maxr && c <= maxc; r+=incr, c+=incc) {	    if ( (p = *ATBL(tbl, r, c)) && p->flags&is_valid ) {		if (p->v <= v) {		    fndr = incc ? (minr + offr) : r;		    fndc = incr ? (minc + offc) : c;		    if (ISVALID(fndr,fndc))			p = *ATBL(tbl, fndr, fndc);		    else error(" range specified to @[hv]lookup");		    if ( p && p->flags&is_valid)			ret = p->v;		} else break;	    }	}    } else {	s = seval(val);	for (r = minr, c = minc; r <= maxr && c <= maxc; r+=incr, c+=incc) {	    if ( (p = *ATBL(tbl, r, c)) && p->label ) {		if (strcmp(p->label,s) == 0) {		    fndr = incc ? (minr + offr) : r;		    fndc = incr ? (minc + offc) : c;		    if (ISVALID(fndr,fndc))			p = *ATBL(tbl, fndr, fndc);		    else error(" range specified to @[hv]lookup");		    break;		}	    }	}	if ( p && p->flags&is_valid)	    ret = p->v;	xfree(s);    }    return ret;}doubledocount(minr, minc, maxr, maxc)int minr, minc, maxr, maxc;{    int v;    register r,c;    register struct ent *p;    v = 0;    for (r = minr; r<=maxr; r++)	for (c = minc; c<=maxc; c++)	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid)		v++;    return v;}doubledosum(minr, minc, maxr, maxc)int minr, minc, maxr, maxc;{    double v;    register r,c;    register struct ent *p;    v = (double)0;    for (r = minr; r<=maxr; r++)	for (c = minc; c<=maxc; c++)	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid)		v += p->v;    return v;}doubledoprod(minr, minc, maxr, maxc)int minr, minc, maxr, maxc;{    double v;    register r,c;    register struct ent *p;    v = 1;    for (r = minr; r<=maxr; r++)	for (c = minc; c<=maxc; c++)	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid)		v *= p->v;    return v;}doubledoavg(minr, minc, maxr, maxc)int minr, minc, maxr, maxc;{    double v;    register r,c,count;    register struct ent *p;    v = (double)0;    count = 0;    for (r = minr; r<=maxr; r++)	for (c = minc; c<=maxc; c++)	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {		v += p->v;		count++;	    }    if (count == 0) 	return ((double) 0);    return (v / (double)count);}doubledostddev(minr, minc, maxr, maxc)int minr, minc, maxr, maxc;{    double lp, rp, v, nd;    register r,c,n;    register struct ent *p;    n = 0;    lp = 0;    rp = 0;    for (r = minr; r<=maxr; r++)	for (c = minc; c<=maxc; c++)	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {		v = p->v;		lp += v*v;		rp += v;		n++;	    }    if ((n == 0) || (n == 1)) 	return ((double) 0);    nd = (double)n;    return (sqrt((nd*lp-rp*rp)/(nd*(nd-1))));}doubledomax(minr, minc, maxr, maxc)int minr, minc, maxr, maxc;{    double v = (double)0;    register r,c,count;    register struct ent *p;    count = 0;    for (r = minr; r<=maxr; r++)	for (c = minc; c<=maxc; c++)	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {		if (!count) {		    v = p->v;		    count++;		} else if (p->v > v)		    v = p->v;	    }    if (count == 0) 	return ((double) 0);    return (v);}doubledomin(minr, minc, maxr, maxc)int minr, minc, maxr, maxc;{    double v = (double)0;    register r,c,count;    register struct ent *p;    count = 0;    for (r = minr; r<=maxr; r++)	for (c = minc; c<=maxc; c++)	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {		if (!count) {		    v = p->v;		    count++;		} else if (p->v < v)		    v = p->v;	    }    if (count == 0) 	return ((double) 0);    return (v);}#define sec_min 60#define sec_hr  3600L#define sec_day 86400L#define sec_yr  31471200L     /* 364.25 days/yr */#define sec_mo  2622600L       /* sec_yr/12: sort of an average */int mdays[12]={ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };doubledodts(mo, day, yr)int mo, day, yr;{    long trial;    register struct tm *tp;     register int i;    register long jdate;    mdays[1] = 28 + (yr%4 == 0);    if (mo < 1 || mo > 12 || day < 1 || day > mdays[--mo] ||		yr > 1999 || yr < 1970) {	error("@dts: invalid argument");	return(0.0);    }    jdate = day-1;    for (i=0; i<mo; i++)	    jdate += mdays[i];    for (i = 1970; i < yr; i++)	    jdate += 365 + (i%4 == 0);    trial = jdate * sec_day;     yr -= 1900;    tp = localtime(&trial);    if (tp->tm_year != yr) {	    /*	    * We may fail this test once a year because of time zone	     * and daylight savings time errors.  This bounces the	     * trial time past the boundary.  The error introduced is	     * corrected below.	     */	    trial += sec_day*(yr - tp->tm_year);	    tp = localtime(&trial);    }    if (tp->tm_mon != mo) {	    /* We may fail this test once a month.  */	    trial += sec_day*(mo - tp->tm_mon);	    tp = localtime(&trial);    }    if (tp->tm_mday + tp->tm_hour + tp->tm_min + tp->tm_sec != day) {	trial -= (tp->tm_mday - day)*sec_day +  tp->tm_hour*sec_hr		 + tp->tm_min*sec_min + tp->tm_sec;    }#ifdef DEBUGDTS    tp = localtime(&trial);    if (tp->tm_mday + tp->tm_hour + tp->tm_min + tp->tm_sec + 	tp->tm_year + tp->tm_mon != yr+mo+day)		error("Dts broke down");#endif    return ((double)trial);}doubledotts(hr, min, sec)int hr, min, sec;{    if (hr < 0 || hr > 23 || min < 0 || min > 59 || sec < 0 || sec > 59) {	error ("@tts: Invalid argument");	return ((double)0);    }    return ((double)(sec+min*60+hr*3600));}doubledotime(which, when)int which;double when;{	long time();	static long t_cache;	static struct tm tm_cache;	struct tm *tp;	long tloc;	if (which == NOW) 	    return (double)time((long *)0);	tloc = (long)when;	if (tloc != t_cache) {	    tp = localtime(&tloc);	    tm_cache = *tp;	    tm_cache.tm_mon += 1;	    tm_cache.tm_year += 1900;	    t_cache = tloc;	}	switch (which) {	    case HOUR: return((double)(tm_cache.tm_hour));	    case MINUTE: return((double)(tm_cache.tm_min));	    case SECOND: return((double)(tm_cache.tm_sec));	    case MONTH: return((double)(tm_cache.tm_mon));	    case DAY: return((double)(tm_cache.tm_mday));	    case YEAR: return((double)(tm_cache.tm_year));	}	/* Safety net */	return ((double)0);}doubledoston(s)char *s;{    char *strtof();    double v;    if (!s)	return((double)0);    (void)strtof(s, &v);    xfree(s);    return(v);}doubledoeqs(s1, s2)char *s1, *s2;{    double v;    if (!s1 && !s2)	return((double)1.0);    if (!s1 || !s2)	v = 0.0;    else if (strcmp(s1, s2) == 0)	v = 1.0;    else	v = 0.0;    if (s1)    	xfree(s1);    if (s2)    	xfree(s2);    return(v);}/* * Given a string representing a column name and a value which is a column * number, return a pointer to the selected cell's entry, if any, else 0.  Use * only the integer part of the column number.  Always free the string. */struct ent *getent (colstr, rowdoub)    char *colstr;    double rowdoub;{

⌨️ 快捷键说明

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