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

📄 interp.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
    right = FALSE;    left = FALSE;    switch(v->expr->op)    {		/* no real expression */	case 'v':		if (v->expr->o.v->evnext)			evdel(v->expr->o.v);	case 'k':	case LMAX:	case LMIN:	case NOW:	case O_SCONST:	case O_VAR:	default:		return;		/* left && right */	case '#':	case '%':	case '&':	case '*':	case '+':	case '-':	case '/':	case '<':	case '=':	case '>':	case '?':	case '^':	case '|':	case ATAN2:	case DTS:	case EQS:	case EXT:	case FMT:	case FV:	case HYPOT:	case IF:	case NVAL:	case PMT:	case POW:	case PV:	case REDUCE | '*':	case REDUCE | '+':	case REDUCE | 'a':	case REDUCE | 'c':	case REDUCE | 's':	case REDUCE | MAX:	case REDUCE | MIN:	case ROUND:	case STINDEX:	case SUBSTR:	case SVAL:	case TTS:		left = right = TRUE;		break;		/* right only */	case 'f':	case 'm':	case '~':	case ABS:	case ACOS:	case ASIN:	case ATAN:	case CEIL:	case COS:	case DATE:	case DAY:	case DTR:	case EXP:	case FABS:	case FLOOR:	case HLOOKUP:	case HOUR:	case IF:	case INDEX:	case LOG10:	case LOG:	case LOOKUP:	case MINUTE:	case MONTH:	case RND:	case RTD:	case SECOND:	case SIN:	case SQRT:	case STON:	case TAN:	case VLOOKUP:	case YEAR:		right = TRUE;		break;    }	/* for now insert at the beginning of the list */    v->evnext = firstev;    v->evprev = (struct ent *)0;    if (firstev)	firstev->evprev = v;    firstev = v;#endif    firstev = v;}#endif /* EXPRTREE*/voidhide_row(arg)int arg;{    if (arg < 0) {	error("Invalid Range");	return;    }    if (arg >= maxrows-1)    {	if (!growtbl(GROWROW, arg+1, 0))	{	error("You can't hide the last row");		return;	}    }    FullUpdate++;    row_hidden[arg] = 1;}voidhide_col(arg)int arg;{    if (arg < 0) {	error("Invalid Range");	return;    }    if (arg >= maxcols-1)    {	if ((arg >= ABSMAXCOLS-1) || !growtbl(GROWCOL, 0, arg+1))	{	error("You can't hide the last col");		return;	}    }    FullUpdate++;    col_hidden[arg] = 1;}voidclearent (v)struct ent *v;{    if (!v)	return;    label(v,"",-1);    v->v = (double)0;    if (v->expr)	efree(v, v->expr);    v->expr = (struct enode *)0;    v->flags |= (is_changed);    v->flags &= ~(is_valid);    changed++;    modflg++;}/* * Say if an expression is a constant (return 1) or not. */intconstant (e)    register struct enode *e;{    return ((e == (struct enode *)0)	 || ((e -> op) == O_CONST)	 || ((e -> op) == O_SCONST)	 || (((e -> op) != O_VAR)	  && (((e -> op) & REDUCE) != REDUCE)	  && constant (e -> e.o.left)	  && constant (e -> e.o.right)	  && (e -> op != EXT)	 /* functions look like constants but aren't */	  && (e -> op != NVAL)	  && (e -> op != SVAL)	  && (e -> op != NOW)));}voidefree (v, e)struct ent *v;struct enode *e;{    if (e) {	if (e->op != O_VAR && e->op !=O_CONST && e->op != O_SCONST		&& (e->op & REDUCE) != REDUCE) {	    efree(v, e->e.o.left);	    efree(v, e->e.o.right);	}	if (e->op == O_SCONST && e->e.s)	    xfree(e->e.s);	xfree ((char *)e);#ifdef EXPRTREE	/* delete this cell from the eval list */	if (v)	{	if (v->evprev)			v->evprev->evnext = v->evnext;		if (v->evnext)			v->evnext->evprev = v->evprev;	}#endif /* EXPRTREE */    }}voidlabel (v, s, flushdir)register struct ent *v;register char *s;int	flushdir;{    if (v) {	if (flushdir==0 && v->flags&is_valid) {	    register struct ent *tv;	    if (v->col>0 && ((tv=lookat(v->row,v->col-1))->flags&is_valid)==0)		v = tv, flushdir = 1;	    else if (((tv=lookat (v->row,v->col+1))->flags&is_valid)==0)		v = tv, flushdir = -1;	    else flushdir = -1;	}	if (v->label) xfree((char *)(v->label));	if (s && s[0]) {	    v->label = xmalloc ((unsigned)(strlen(s)+1));	    (void) strcpy (v->label, s);	} else	    v->label = (char *)0;	if (flushdir<0) v->flags |= is_leftflush;	else v->flags &= ~is_leftflush;	FullUpdate++;	modflg++;    }}voiddecodev (v)struct ent_ptr v; {	register struct range *r;	if (!v.vp) (void)sprintf (line+linelim,"VAR?");	else if ((r = find_range((char *)0, 0, v.vp, v.vp)) && !r->r_is_range)	    (void)sprintf(line+linelim, "%s", r->r_name);	else	    (void)sprintf (line+linelim, "%s%s%s%d",			v.vf & FIX_COL ? "$" : "",			coltoa(v.vp->col),			v.vf & FIX_ROW ? "$" : "",			v.vp->row);	linelim += strlen (line+linelim);}char *coltoa(col)int col;{    static char rname[3];    register char *p = rname;    if (col > 25) {	*p++ = col/26 + 'A' - 1;	col %= 26;    }    *p++ = col+'A';    *p = '\0';    return(rname);}/* *	To make list elements come out in the same order *	they were entered, we must do a depth-first eval *	of the ELIST tree */static voiddecompile_list(p)struct enode *p;{	if (!p) return;	decompile_list(p->e.o.left);	/* depth first */        decompile(p->e.o.right, 0);	line[linelim++] = ',';}voiddecompile(e, priority)register struct enode *e;int	priority;{    register char *s;    if (e) {	int mypriority;	switch (e->op) {	default: mypriority = 99; break;	case '?': mypriority = 1; break;	case ':': mypriority = 2; break;	case '|': mypriority = 3; break;	case '&': mypriority = 4; break;	case '<': case '=': case '>': mypriority = 6; break;	case '+': case '-': case '#': mypriority = 8; break;	case '*': case '/': case '%': mypriority = 10; break;	case '^': mypriority = 12; break;	}	if (mypriority<priority) line[linelim++] = '(';	switch (e->op) {	case 'f':	for (s="fixed "; line[linelim++] = *s++;);			linelim--;			decompile (e->e.o.right, 30);			break;	case 'm':	line[linelim++] = '-';			decompile (e->e.o.right, 30);			break;	case '~':	line[linelim++] = '~';			decompile (e->e.o.right, 30);			break;	case 'v':	decodev (e->e.v);			break;	case 'k':	(void)sprintf (line+linelim,"%.15g",e->e.k);			linelim += strlen (line+linelim);			break;	case '$':	(void)sprintf (line+linelim, "\"%s\"", e->e.s);			linelim += strlen(line+linelim);			break;	case REDUCE | '+': range_arg( "@sum(", e); break;	case REDUCE | '*': range_arg( "@prod(", e); break;	case REDUCE | 'a': range_arg( "@avg(", e); break;	case REDUCE | 'c': range_arg( "@count(", e); break;	case REDUCE | 's': range_arg( "@stddev(", e); break;	case REDUCE | MAX: range_arg( "@max(", e); break;	case REDUCE | MIN: range_arg( "@min(", e); break;	case ABS:		one_arg( "@abs(", e); break;	case ACOS:	one_arg( "@acos(", e); break;	case ASIN:	one_arg( "@asin(", e); break;	case ATAN:	one_arg( "@atan(", e); break;	case ATAN2:	two_arg( "@atan2(", e); break;	case CEIL:	one_arg( "@ceil(", e); break;	case COS:	one_arg( "@cos(", e); break;	case EXP:	one_arg( "@exp(", e); break;	case FABS:	one_arg( "@fabs(", e); break;	case FLOOR:	one_arg( "@floor(", e); break;	case HYPOT:	two_arg( "@hypot(", e); break;	case LOG:	one_arg( "@ln(", e); break;	case LOG10:	one_arg( "@log(", e); break;	case POW:	two_arg( "@pow(", e); break;	case SIN:	one_arg( "@sin(", e); break;	case SQRT:	one_arg( "@sqrt(", e); break;	case TAN:	one_arg( "@tan(", e); break;	case DTR:	one_arg( "@dtr(", e); break;	case RTD:	one_arg( "@rtd(", e); break;	case RND:	one_arg( "@rnd(", e); break;	case ROUND:	two_arg( "@round(", e); break;	case HOUR:	one_arg( "@hour(", e); break;	case MINUTE:	one_arg( "@minute(", e); break;	case SECOND:	one_arg( "@second(", e); break;	case MONTH:	one_arg( "@month(", e); break;	case DAY:	one_arg( "@day(", e); break;	case YEAR:	one_arg( "@year(", e); break;	case DATE:	one_arg( "@date(", e); break;	case DTS:	three_arg( "@dts(", e); break;	case TTS:	three_arg( "@tts(", e); break;	case STON:	one_arg( "@ston(", e); break;	case FMT:	two_arg( "@fmt(", e); break;	case EQS:	two_arg( "@eqs(", e); break;	case NOW:	for ( s = "@now"; line[linelim++] = *s++;);			linelim--;			break;	case LMAX:	list_arg("@max(", e); break;	case LMIN: 	list_arg("@min(", e); break;	case FV:	three_arg("@fv(", e); break;	case PV:	three_arg("@pv(", e); break;	case PMT:	three_arg("@pmt(", e); break;	case NVAL:	two_arg("@nval(", e); break;	case SVAL:	two_arg("@sval(", e); break;	case EXT:	two_arg("@ext(", e); break;	case SUBSTR:	three_arg("@substr(", e); break;	case STINDEX:	index_arg("@stindex(", e); break;	case INDEX:	index_arg("@index(", e); break;	case LOOKUP:	index_arg("@lookup(", e); break;	case HLOOKUP:	two_arg_index("@hlookup(", e); break;	case VLOOKUP:	two_arg_index("@vlookup(", e); break;	case IF:	three_arg("@if(", e); break;	default:	decompile (e->e.o.left, mypriority);			line[linelim++] = e->op;			decompile (e->e.o.right, mypriority+1);			break;	}	if (mypriority<priority) line[linelim++] = ')';    } else line[linelim++] = '?';}voidindex_arg(s, e)char *s;struct enode *e;{    for (; line[linelim++] = *s++;);    linelim--;    decompile( e-> e.o.left, 0 );    range_arg(", ", e->e.o.right);}voidtwo_arg_index(s, e)char *s;struct enode *e;{    for (; line[linelim++] = *s++;);    linelim--;    decompile( e->e.o.left->e.o.left, 0 );    range_arg(",", e->e.o.right);    linelim--;    line[linelim++] = ',';    decompile( e->e.o.left->e.o.right, 0 );    line[linelim++] = ')';}voidlist_arg(s, e)char *s;struct enode *e;{    for (; line[linelim++] = *s++;);    linelim--;    decompile (e->e.o.right, 0);    line[linelim++] = ',';    decompile_list(e->e.o.left);    line[linelim - 1] = ')';}voidone_arg(s, e)char *s;struct enode *e;{    for (; line[linelim++] = *s++;);    linelim--;    decompile (e->e.o.right, 0);    line[linelim++] = ')';}voidtwo_arg(s,e)char *s;struct enode *e;{    for (; line[linelim++] = *s++;);    linelim--;    decompile (e->e.o.left, 0);    line[linelim++] = ',';    decompile (e->e.o.right, 0);    line[linelim++] = ')';}voidthree_arg(s,e)char *s;struct enode *e;{    for (; line[linelim++] = *s++;);    linelim--;    decompile (e->e.o.left, 0);    line[linelim++] = ',';    decompile (e->e.o.right->e.o.left, 0);    line[linelim++] = ',';    decompile (e->e.o.right->e.o.right, 0);    line[linelim++] = ')';}voidrange_arg(s,e)char *s;struct enode *e;{    struct range *r;    for (; line[linelim++] = *s++;);    linelim--;    if ((r = find_range((char *)0, 0, e->e.r.left.vp,			     e->e.r.right.vp)) && r->r_is_range) {	(void)sprintf(line+linelim, "%s", r->r_name);	linelim += strlen(line+linelim);    } else {	decodev (e->e.r.left);	line[linelim++] = ':';	decodev (e->e.r.right);    }    line[linelim++] = ')';}voideditv (row, col)int row, col;{    register struct ent *p;    p = lookat (row, col);    (void)sprintf (line, "let %s = ", v_name(row, col));    linelim = strlen(line);    if (p->flags & is_strexpr || p->expr == 0) {	(void)sprintf (line+linelim, "%.15g", p->v);	linelim += strlen (line+linelim);    } else {        editexp(row,col);    }}voideditexp(row,col)int row, col;{    register struct ent *p;    p = lookat (row, col);    decompile (p->expr, 0);    line[linelim] = '\0';}voidedits (row, col)int row, col;{    register struct ent *p;    p = lookat (row, col);    (void)sprintf (line, "%sstring %s = ",			((p->flags&is_leftflush) ? "left" : "right"),			v_name(row, col));    linelim = strlen(line);    if (p->flags & is_strexpr && p->expr) {	editexp(row, col);    } else if (p->label) {        (void)sprintf (line+linelim, "\"%s\"", p->label);        linelim += strlen (line+linelim);    } else {        (void)sprintf (line+linelim, "\"");        linelim += 1;    }}

⌨️ 快捷键说明

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