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

📄 eval.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	    rslen = old_rslen;#ifdef DEBUGGING	    tmps = "READ";#endif	    break;	}#ifdef DEBUGGING	if (debug & 8)	    deb("%d.%s = '%s'\n",anum,tmps,str_peek(st[sp]));#endif	if (anum < 8)	    arglast[anum] = sp;    }    st += arglast[0];#ifdef SMALLSWITCHES    if (optype < O_CHOWN)#endif    switch (optype) {    case O_RCAT:	STABSET(str);	break;    case O_ITEM:	if (gimme == G_ARRAY)	    goto array_return;	/* FALL THROUGH */    case O_SCALAR:	STR_SSET(str,st[1]);	STABSET(str);	break;    case O_ITEM2:	if (gimme == G_ARRAY)	    goto array_return;	--anum;	STR_SSET(str,st[arglast[anum]-arglast[0]]);	STABSET(str);	break;    case O_ITEM3:	if (gimme == G_ARRAY)	goto array_return;	--anum;	STR_SSET(str,st[arglast[anum]-arglast[0]]);	STABSET(str);	break;    case O_CONCAT:	STR_SSET(str,st[1]);	str_scat(str,st[2]);	STABSET(str);	break;    case O_REPEAT:	if (gimme == G_ARRAY && arg[1].arg_flags & AF_ARYOK) {	    sp = do_repeatary(arglast);	    goto array_return;	}	STR_SSET(str,st[1]);	anum = (int)str_gnum(st[2]);	if (anum >= 1) {	    tmpstr = Str_new(50, 0);	    tmps = str_get(str);	    str_nset(tmpstr,tmps,str->str_cur);	    tmps = str_get(tmpstr);	/* force to be string */	    STR_GROW(str, (anum * str->str_cur) + 1);	    repeatcpy(str->str_ptr, tmps, tmpstr->str_cur, anum);	    str->str_cur *= anum;	    str->str_ptr[str->str_cur] = '\0';	    str->str_nok = 0;	    str_free(tmpstr);	}	else {	    if (dowarn && st[2]->str_pok && !looks_like_number(st[2]))		warn("Right operand of x is not numeric");	    str_sset(str,&str_no);	}	STABSET(str);	break;    case O_MATCH:	sp = do_match(str,arg,	  gimme,arglast);	if (gimme == G_ARRAY)	    goto array_return;	STABSET(str);	break;    case O_NMATCH:	sp = do_match(str,arg,	  G_SCALAR,arglast);	str_sset(str, str_true(str) ? &str_no : &str_yes);	STABSET(str);	break;    case O_SUBST:	sp = do_subst(str,arg,arglast[0]);	goto array_return;    case O_NSUBST:	sp = do_subst(str,arg,arglast[0]);	str = arg->arg_ptr.arg_str;	str_set(str, str_true(str) ? No : Yes);	goto array_return;    case O_ASSIGN:	if (arg[1].arg_flags & AF_ARYOK) {	    if (arg->arg_len == 1) {		arg->arg_type = O_LOCAL;		goto local;	    }	    else {		arg->arg_type = O_AASSIGN;		goto aassign;	    }	}	else {	    arg->arg_type = O_SASSIGN;	    goto sassign;	}    case O_LOCAL:      local:	arglast[2] = arglast[1];	/* push a null array */	/* FALL THROUGH */    case O_AASSIGN:      aassign:	sp = do_assign(arg,	  gimme,arglast);	goto array_return;    case O_SASSIGN:      sassign:#ifdef TAINT	if (tainted && !st[2]->str_tainted)	    tainted = 0;#endif	STR_SSET(str, st[2]);	STABSET(str);	break;    case O_CHOP:	st -= arglast[0];	str = arg->arg_ptr.arg_str;	for (sp = arglast[0] + 1; sp <= arglast[1]; sp++)	    do_chop(str,st[sp]);	st += arglast[0];	break;    case O_DEFINED:	if (arg[1].arg_type & A_DONT) {	    sp = do_defined(str,arg,		  gimme,arglast);	    goto array_return;	}	else if (str->str_pok || str->str_nok)	    goto say_yes;	goto say_no;    case O_UNDEF:	if (arg[1].arg_type & A_DONT) {	    sp = do_undef(str,arg,	      gimme,arglast);	    goto array_return;	}	else if (str != stab_val(defstab)) {	    if (str->str_len) {		if (str->str_state == SS_INCR)		    Str_Grow(str,0);		Safefree(str->str_ptr);		str->str_ptr = Nullch;		str->str_len = 0;	    }	    str->str_pok = str->str_nok = 0;	    STABSET(str);	}	goto say_undef;    case O_STUDY:	sp = do_study(str,arg,	  gimme,arglast);	goto array_return;    case O_POW:	value = str_gnum(st[1]);	value = pow(value,str_gnum(st[2]));	goto donumset;    case O_MULTIPLY:	value = str_gnum(st[1]);	value *= str_gnum(st[2]);	goto donumset;    case O_DIVIDE:	if ((value = str_gnum(st[2])) == 0.0)	    fatal("Illegal division by zero");#ifdef SLOPPYDIVIDE	/* insure that 20./5. == 4. */	{	    double x;	    int    k;	    x =  str_gnum(st[1]);	    if ((double)(int)x     == x &&		(double)(int)value == value &&		(k = (int)x/(int)value)*(int)value == (int)x) {		value = k;	    } else {		value = x/value;	    }	}#else	value = str_gnum(st[1]) / value;#endif	goto donumset;    case O_MODULO:	tmpulong = (unsigned long) str_gnum(st[2]);    	if (tmpulong == 0L)    	    fatal("Illegal modulus zero");#ifndef lint	value = str_gnum(st[1]);	if (value >= 0.0)	    value = (double)(((unsigned long)value) % tmpulong);	else {	    tmplong = (long)value;	    value = (double)(tmpulong - ((-tmplong - 1) % tmpulong)) - 1;	}#endif	goto donumset;    case O_ADD:	value = str_gnum(st[1]);	value += str_gnum(st[2]);	goto donumset;    case O_SUBTRACT:	value = str_gnum(st[1]);	value -= str_gnum(st[2]);	goto donumset;    case O_LEFT_SHIFT:	value = str_gnum(st[1]);	anum = (int)str_gnum(st[2]);#ifndef lint	value = (double)(U_L(value) << anum);#endif	goto donumset;    case O_RIGHT_SHIFT:	value = str_gnum(st[1]);	anum = (int)str_gnum(st[2]);#ifndef lint	value = (double)(U_L(value) >> anum);#endif	goto donumset;    case O_LT:	value = str_gnum(st[1]);	value = (value < str_gnum(st[2])) ? 1.0 : 0.0;	goto donumset;    case O_GT:	value = str_gnum(st[1]);	value = (value > str_gnum(st[2])) ? 1.0 : 0.0;	goto donumset;    case O_LE:	value = str_gnum(st[1]);	value = (value <= str_gnum(st[2])) ? 1.0 : 0.0;	goto donumset;    case O_GE:	value = str_gnum(st[1]);	value = (value >= str_gnum(st[2])) ? 1.0 : 0.0;	goto donumset;    case O_EQ:	if (dowarn) {	    if ((!st[1]->str_nok && !looks_like_number(st[1])) ||		(!st[2]->str_nok && !looks_like_number(st[2])) )		warn("Possible use of == on string value");	}	value = str_gnum(st[1]);	value = (value == str_gnum(st[2])) ? 1.0 : 0.0;	goto donumset;    case O_NE:	value = str_gnum(st[1]);	value = (value != str_gnum(st[2])) ? 1.0 : 0.0;	goto donumset;    case O_NCMP:	value = str_gnum(st[1]);	value -= str_gnum(st[2]);	if (value > 0.0)	    value = 1.0;	else if (value < 0.0)	    value = -1.0;	goto donumset;    case O_BIT_AND:	if (!sawvec || st[1]->str_nok || st[2]->str_nok) {	    value = str_gnum(st[1]);#ifndef lint	    value = (double)(U_L(value) & U_L(str_gnum(st[2])));#endif	    goto donumset;	}	else	    do_vop(optype,str,st[1],st[2]);	break;    case O_XOR:	if (!sawvec || st[1]->str_nok || st[2]->str_nok) {	    value = str_gnum(st[1]);#ifndef lint	    value = (double)(U_L(value) ^ U_L(str_gnum(st[2])));#endif	    goto donumset;	}	else	    do_vop(optype,str,st[1],st[2]);	break;    case O_BIT_OR:	if (!sawvec || st[1]->str_nok || st[2]->str_nok) {	    value = str_gnum(st[1]);#ifndef lint	    value = (double)(U_L(value) | U_L(str_gnum(st[2])));#endif	    goto donumset;	}	else	    do_vop(optype,str,st[1],st[2]);	break;/* use register in evaluating str_true() */    case O_AND:	if (str_true(st[1])) {	    anum = 2;	    optype = O_ITEM2;	    argflags = arg[anum].arg_flags;	    if (gimme == G_ARRAY)		argflags |= AF_ARYOK;	    argtype = arg[anum].arg_type & A_MASK;	    argptr = arg[anum].arg_ptr;	    maxarg = anum = 1;	    sp = arglast[0];	    st -= sp;	    goto re_eval;	}	else {	    if (assigning) {		str_sset(str, st[1]);		STABSET(str);	    }	    else		str = st[1];	    break;	}    case O_OR:	if (str_true(st[1])) {	    if (assigning) {		str_sset(str, st[1]);		STABSET(str);	    }	    else		str = st[1];	    break;	}	else {	    anum = 2;	    optype = O_ITEM2;	    argflags = arg[anum].arg_flags;	    if (gimme == G_ARRAY)		argflags |= AF_ARYOK;	    argtype = arg[anum].arg_type & A_MASK;	    argptr = arg[anum].arg_ptr;	    maxarg = anum = 1;	    sp = arglast[0];	    st -= sp;	    goto re_eval;	}    case O_COND_EXPR:	anum = (str_true(st[1]) ? 2 : 3);	optype = (anum == 2 ? O_ITEM2 : O_ITEM3);	argflags = arg[anum].arg_flags;	if (gimme == G_ARRAY)	    argflags |= AF_ARYOK;	argtype = arg[anum].arg_type & A_MASK;	argptr = arg[anum].arg_ptr;	maxarg = anum = 1;	sp = arglast[0];	st -= sp;	goto re_eval;    case O_COMMA:	if (gimme == G_ARRAY)	    goto array_return;	str = st[2];	break;    case O_NEGATE:	value = -str_gnum(st[1]);	goto donumset;    case O_NOT:#ifdef NOTNOT	{ char xxx = str_true(st[1]); value = (double) !xxx; }#else	value = (double) !str_true(st[1]);#endif	goto donumset;    case O_COMPLEMENT:	if (!sawvec || st[1]->str_nok) {#ifndef lint	    value = (double) ~U_L(str_gnum(st[1]));#endif	    goto donumset;	}	else {	    STR_SSET(str,st[1]);	    tmps = str_get(str);	    for (anum = str->str_cur; anum; anum--, tmps++)		*tmps = ~*tmps;	}	break;    case O_SELECT:	stab_efullname(str,defoutstab);	if (maxarg > 0) {	    if ((arg[1].arg_type & A_MASK) == A_WORD)		defoutstab = arg[1].arg_ptr.arg_stab;	    else		defoutstab = stabent(str_get(st[1]),TRUE);	    if (!stab_io(defoutstab))		stab_io(defoutstab) = stio_new();	    curoutstab = defoutstab;	}	STABSET(str);	break;    case O_WRITE:	if (maxarg == 0)	    stab = defoutstab;	else if ((arg[1].arg_type & A_MASK) == A_WORD) {	    if (!(stab = arg[1].arg_ptr.arg_stab))		stab = defoutstab;	}	else	    stab = stabent(str_get(st[1]),TRUE);	if (!stab_io(stab)) {	    str_set(str, No);	    STABSET(str);	    break;	}	curoutstab = stab;	fp = stab_io(stab)->ofp;	debarg = arg;	if (stab_io(stab)->fmt_stab)	    form = stab_form(stab_io(stab)->fmt_stab);	else	    form = stab_form(stab);	if (!form || !fp) {	    if (dowarn) {		if (form)		    warn("No format for filehandle");		else {		    if (stab_io(stab)->ifp)			warn("Filehandle only opened for input");		    else			warn("Write on closed filehandle");		}	    }	    str_set(str, No);	    STABSET(str);	    break;	}	format(&outrec,form,sp);	do_write(&outrec,stab,sp);	if (stab_io(stab)->flags & IOF_FLUSH)	    (void)fflush(fp);	str_set(str, Yes);	STABSET(str);	break;    case O_DBMOPEN:#ifdef SOME_DBM	anum = arg[1].arg_type & A_MASK;	if (anum == A_WORD || anum == A_STAB)	    stab = arg[1].arg_ptr.arg_stab;	else	    stab = stabent(str_get(st[1]),TRUE);	if (st[3]->str_nok || st[3]->str_pok)	    anum = (int)str_gnum(st[3]);	else	    anum = -1;	value = (double)hdbmopen(stab_hash(stab),str_get(st[2]),anum);	goto donumset;#else	fatal("No dbm or ndbm on this machine");#endif    case O_DBMCLOSE:#ifdef SOME_DBM	anum = arg[1].arg_type & A_MASK;	if (anum == A_WORD || anum == A_STAB)	    stab = arg[1].arg_ptr.arg_stab;	else	    stab = stabent(str_get(st[1]),TRUE);	hdbmclose(stab_hash(stab));	goto say_yes;#else	fatal("No dbm or ndbm on this machine");#endif    case O_OPEN:	if ((arg[1].arg_type & A_MASK) == A_WORD)	    stab = arg[1].arg_ptr.arg_stab;	else	    stab = stabent(str_get(st[1]),TRUE);	tmps = str_get(st[2]);	if (do_open(stab,tmps,st[2]->str_cur)) {	    value = (double)forkprocess;	    stab_io(stab)->lines = 0;	    goto donumset;	}	else if (forkprocess == 0)		/* we are a new child */	    goto say_zero;	else	    goto say_undef;	/* break; */    case O_TRANS:	value = (double) do_trans(str,arg);	str = arg->arg_ptr.arg_str;	goto donumset;    case O_NTRANS:	str_set(arg->arg_ptr.arg_str, do_trans(str,arg) == 0 ? Yes : No);	str = arg->arg_ptr.arg_str;	break;    case O_CLOSE:	if (maxarg == 0)	    stab = defoutstab;	else if ((arg[1].arg_type & A_MASK) == A_WORD)	    stab = arg[1].arg_ptr.arg_stab;	else	    stab = stabent(str_get(st[1]),TRUE);	str_set(str, do_close(stab,TRUE) ? Yes : No );	STABSET(str);	break;    case O_EACH:	sp = do_each(str,stab_hash(arg[1].arg_ptr.arg_stab),	  gimme,arglast);	goto array_return;    case O_VALUES:    case O_KEYS:	sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype,	  gimme,arglast);	goto array_return;    case O_LARRAY:	str->str_nok = str->str_pok = 0;	str->str_u.str_stab = arg[1].arg_ptr.arg_stab;	str->str_state = SS_ARY;	break;    case O_ARRAY:	ary = stab_array(arg[1].arg_ptr.arg_stab);	maxarg = ary->ary_fill + 1;	if (gimme == G_ARRAY) { /* array wanted */	    sp = arglast[0];	    st -= sp;	    if (maxarg > 0 && sp + maxarg > stack->ary_max) {		astore(stack,sp + maxarg, Nullstr);		st = stack->ary_array;	    }	    st += sp;	    Copy(ary->ary_array, &st[1], maxarg, STR*);	    sp += maxarg;	    goto array_return;	}	else {	    value = (double)maxarg;	    goto donumset;	}    case O_AELEM:	anum = ((int)str_gnum(st[2])) - arybase;	str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,FALSE);	break;    case O_DELETE:	tmpstab = arg[1].arg_ptr.arg_stab;	tmps = str_get(st[2]);	str = hdelete(stab_hash(tmpstab),tmps,st[2]->str_cur);	if (tmpstab == envstab)	    my_setenv(tmps,Nullch);

⌨️ 快捷键说明

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