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

📄 expr2.c

📁 EPIC IRC客户端。来源于IRCII客户端但做了很多性能和功能的优化。
💻 C
📖 第 1 页 / 共 5 页
字号:
	*t1 = pop_token(c);}__inline static	void	pop_2_floats (expr_info *c, double *a, double *b){	*b = pop_float(c);	*a = pop_float(c);}__inline static	void	pop_2_integers (expr_info *c, INTTYPE *a, INTTYPE *b){	*b = pop_integer(c);	*a = pop_integer(c);}__inline static void	pop_2_strings (expr_info *c, const char **s, const char **t){	*t = pop_expanded(c);	*s = pop_expanded(c);}__inline static void	pop_2_booleans (expr_info *c, BooL *a, BooL *b){	*b = pop_boolean(c);	*a = pop_boolean(c);}__inline static	void	pop_3_tokens (expr_info *c, BooL *a, TOKEN *v, TOKEN *w){	TOKEN	t1, t2, t3;	t3 = pop_token(c);	t2 = pop_token(c);	t1 = pop_token(c);	*a = get_token_boolean(c, t1);	*v = t2;	*w = t3;}/******************************* OPERATOR REDUCER **************************//* * This is the reducer.  It takes the relevant arguments off the argument * stack and then performs the neccesary operation on them. */static void	reduce (expr_info *cx, int what){	double	a, b;	BooL	c, d;	INTTYPE	i, j;	const char *s, *t;	TOKEN	v, w;	if (x_debug & DEBUG_NEW_MATH_DEBUG)		yell("Reducing last operation...");	if (cx->sp < 0) 	{		error("An operator is missing a required operand");		return;	}	if (cx->errflag)		return;		/* Dont parse on an error *//* Check to see if we are evaluating the expression at this point. */#define CHECK_NOEVAL							\	if (cx->noeval)							\	{								\		if (x_debug & DEBUG_NEW_MATH_DEBUG)			\			yell("O: Operation short-circuited");		\		push_token(cx, 0);					\		break;							\	}/* Perform an ordinary garden variety floating point binary operation. */#define BINARY_FLOAT(floatop)						\	{ 								\		pop_2_floats(cx, &a, &b); 				\		CHECK_NOEVAL						\		push_float(cx, (floatop));				\		if (x_debug & DEBUG_NEW_MATH_DEBUG) 			\			yell("O: %s (%f %f) -> %f", 			\				#floatop, a, b, floatop); 		\		break; 							\	}/* Perform an ordinary garden variety integer binary operation */#define BINARY_INTEGER(intop)						\	{ 								\		pop_2_integers(cx, &i, &j); 				\		CHECK_NOEVAL						\		push_integer(cx, (intop)); 				\		if (x_debug & DEBUG_NEW_MATH_DEBUG) 			\			yell("O: %s (" FORMAT " " FORMAT ") -> " FORMAT, \				#intop, i, j, intop); 			\		break; 							\	}/* Perform an ordinary garden variety boolean binary operation */#define BINARY_BOOLEAN(boolop) 						\	{ 								\		pop_2_booleans(cx, &c, &d); 				\		CHECK_NOEVAL						\		push_boolean(cx, (boolop)); 				\		if (x_debug & DEBUG_NEW_MATH_DEBUG) 			\			yell("O: %s (%d %d) -> %d", 			\				#boolop, c, d, boolop); 		\		break; 							\	}/* Perform a floating point binary operation where the rhs must not be 0. */#define BINARY_FLOAT_NOZERO(floatop)					\	{ 								\		pop_2_floats(cx, &a, &b); 				\		CHECK_NOEVAL						\		if (b == 0.0) 						\		{ 							\			if (x_debug & DEBUG_NEW_MATH_DEBUG) 		\				yell("O: %s (%f %f) -> []", 		\					#floatop, a, b); 		\			error("Division by zero"); 			\			push_token(cx, 0);				\		} 							\		else 							\		{ 							\			if (x_debug & DEBUG_NEW_MATH_DEBUG) 		\			    yell("O: %s (%f %f) -> %f", 		\					#floatop, a, b, floatop); 	\			push_float(cx, (floatop)); 			\		} 							\		break; 							\	}/* Perform a floating point binary operation where the rhs must not be 0. */#define BINARY_INTEGER_NOZERO(intop)					\	{ 								\		pop_2_integers(cx, &i, &j); 				\		CHECK_NOEVAL						\		if (j == 0) 						\		{ 							\			if (x_debug & DEBUG_NEW_MATH_DEBUG) 		\				yell("O: %s (" FORMAT " " FORMAT ") -> []", \					#intop, i, j); 			\			error("Division by zero"); 			\			push_token(cx, 0);				\		} 							\		else 							\		{ 							\			if (x_debug & DEBUG_NEW_MATH_DEBUG) 		\			    yell("O: %s (" FORMAT " " FORMAT ") -> " FORMAT, \					#intop, i, j, intop); 		\			push_integer(cx, (intop)); 			\		} 							\		break; 							\	}/***************** ASSIGNMENT MACROS *******************//* Prep the lvalue and the rvalue for a future assignment. */#define	GET_LVAL_RVAL							\		pop_2_tokens(cx, &v, &w);				\		if (!(s = get_token_lval(cx, v)))			\		{							\			push_token(cx, 0);				\			break;						\		}/* Perform an ordinary integer operation, assigning the result to the lvalue */#define IMPLIED_INTEGER(intop) 						\	{ 								\		GET_LVAL_RVAL						\		CHECK_NOEVAL						\		i = get_token_integer(cx, v);				\		j = get_token_integer(cx, w);				\									\		if (x_debug & DEBUG_NEW_MATH_DEBUG) 			\			yell("O: %s = %s (" FORMAT " " FORMAT ") -> " FORMAT, \				s, #intop, i, j, intop); 		\									\		w = tokenize_integer(cx, (intop));			\		t = get_token_expanded(cx, w);				\		add_var_alias(s, t, 0);					\		push_token(cx, w);					\		break; 							\	}/* Perform an ordinary float operation, assigning the result to the lvalue */#define IMPLIED_FLOAT(floatop) 						\	{ 								\		GET_LVAL_RVAL						\		CHECK_NOEVAL						\		a = get_token_float(cx, v);				\		b = get_token_float(cx, w);				\									\		if (x_debug & DEBUG_NEW_MATH_DEBUG) 			\			yell("O: %s = %s (%f %f) -> %f",  		\				s, #floatop, a, b, floatop);		\									\		w = tokenize_float(cx, (floatop));			\		t = get_token_expanded(cx, w);				\		add_var_alias(s, t, 0);					\		push_token(cx, w);					\		break; 							\	}/* Perform an ordinary boolean operation, assigning the result to the lvalue */#define IMPLIED_BOOLEAN(boolop) 					\	{ 								\		GET_LVAL_RVAL						\		CHECK_NOEVAL						\		c = get_token_boolean(cx, v);				\		d = get_token_boolean(cx, w);				\									\		if (x_debug & DEBUG_NEW_MATH_DEBUG) 			\			yell("O: %s = %s (%d %d) -> %d",  		\				s, #boolop, c, d, boolop); 		\									\		w = tokenize_bool(cx, (boolop));			\		t = get_token_expanded(cx, w);				\		add_var_alias(s, t, 0);					\		push_token(cx, w);					\		break; 							\	}/*  * Perform a float operation, rvalue must not be zero, assigning the result * to the lvalue.  */#define IMPLIED_FLOAT_NOZERO(floatop) 					\	{ 								\		GET_LVAL_RVAL						\		CHECK_NOEVAL						\		a = get_token_float(cx, v);				\		b = get_token_float(cx, w);				\									\		if (b == 0.0) 						\		{ 							\			if (x_debug & DEBUG_NEW_MATH_DEBUG) 		\				yell("O: %s = %s (%f %f) -> 0",  	\					s, #floatop, a, b); 		\			error("Division by zero"); 			\			add_var_alias(s, empty_string, 0);		\			push_token(cx, 0);				\			break;						\		} 							\									\		if (x_debug & DEBUG_NEW_MATH_DEBUG) 			\			yell("O: %s =  %s (%f %f) -> %f",  		\				s, #floatop, a, b, floatop); 		\									\		w = tokenize_float(cx, (floatop));			\		t = get_token_expanded(cx, w);				\		add_var_alias(s, t, 0);					\		push_token(cx, w);					\		break; 							\	}/*  * Perform a float operation, rvalue must not be zero, assigning the result * to the lvalue.  */#define IMPLIED_INTEGER_NOZERO(intop) 					\	{ 								\		GET_LVAL_RVAL						\		CHECK_NOEVAL						\		i = get_token_float(cx, v);				\		j = get_token_float(cx, w);				\									\		if (j == 0) 						\		{ 							\			if (x_debug & DEBUG_NEW_MATH_DEBUG) 		\				yell("O: %s = %s (" FORMAT " " FORMAT ") -> 0",\					s, #intop, i, j); 		\			error("Division by zero"); 			\			add_var_alias(s, empty_string, 0);		\			push_token(cx, 0);				\			break;						\		} 							\									\		if (x_debug & DEBUG_NEW_MATH_DEBUG) 			\			yell("O: %s =  %s (" FORMAT " "  FORMAT ") -> " FORMAT,\				s, #intop, i, j, intop); 		\									\		w = tokenize_float(cx, (intop));			\		t = get_token_expanded(cx, w);				\		add_var_alias(s, t, 0);					\		push_token(cx, w);					\		break; 							\	}/*  * Perform an auto(in|de)crement operation on the last operand, assigning * to it the value of 'x', but pushing the value of 'y' onto the stack. */#define AUTO_UNARY(intop_assign, intop_result) 				\	{ 								\		v = pop_token(cx); 					\		if (!(s = get_token_lval(cx, v)))			\		{							\			push_token(cx, 0);				\			break;						\		}							\		CHECK_NOEVAL						\									\		j = get_token_integer(cx, v);				\		if (x_debug & DEBUG_NEW_MATH_DEBUG) 			\			yell("O: %s (%s " FORMAT ") -> " FORMAT, 	\				#intop_result, s, j, (intop_result));	\									\		w = tokenize_integer(cx, (intop_assign));		\		t = get_token_expanded(cx, w);				\		add_var_alias(s, t, 0);					\									\		push_integer(cx, (intop_result));			\		break; 							\	}/* ****************** START HERE *********************/#define dpushn(x1,x2,y1) 						\	{ 								\		if (x_debug & DEBUG_NEW_MATH_DEBUG) 			\		{ 							\			yell("O: COMPARE"); 				\			yell("O: %s -> %d", #x2, (x2)); 		\		} 							\		push_boolean( x1 , y1 ); 				\	} #define COMPARE(x, y) 							\	{ 								\		pop_2_strings(cx, &s, &t);				\		CHECK_NOEVAL						\		if (is_real_number(s) && is_real_number(t))		\		{							\			a = atof(s), b = atof(t);			\			if (x_debug & DEBUG_NEW_MATH_DEBUG) 		\				yell("O: %s N(%f %f) -> %d", #x, a, b, (x)); \			if ((x))		dpushn(cx, x, 1) 	\			else			dpushn(cx, x, 0) 	\		} 							\		else 							\		{ 							\			if (x_debug & DEBUG_NEW_MATH_DEBUG) 		\				yell("O: %s S(%s %s) -> %d", #x, s, t, (y)); \			if ((y))		dpushn(cx, y, 1) 	\			else			dpushn(cx, y, 0) 	\		} 							\		break; 							\	}	/************** THE OPERATORS THEMSELVES ********************/	switch (what) 	{		/* Simple unary prefix operators */		case NOT:			c = pop_boolean(cx);			CHECK_NOEVAL			if (x_debug & DEBUG_NEW_MATH_DEBUG)				yell("O: !%d -> %d", c, !c);			push_boolean(cx, !c);			break;		case COMP:			i = pop_integer(cx);			CHECK_NOEVAL			if (x_debug & DEBUG_NEW_MATH_DEBUG)				yell(": ~" FORMAT " -> " FORMAT, i, ~i);			push_integer(cx, ~i);			break;		case UPLUS:			a = pop_float(cx);			CHECK_NOEVAL			if (x_debug & DEBUG_NEW_MATH_DEBUG)				yell("O: +%f -> %f", a, a);			push_float(cx, a);			break;		case UMINUS:			a = pop_float(cx);			CHECK_NOEVAL			if (x_debug & DEBUG_NEW_MATH_DEBUG)				yell("O: -%f -> %f", a, -a);			push_float(cx, -a);			break;		case STRLEN:			s = pop_expanded(cx);			CHECK_NOEVAL			i = strlen(s);			if (x_debug & DEBUG_NEW_MATH_DEBUG)				yell("O: @(%s) -> " FORMAT, s, i);			push_integer(cx, i);			break;		case WORDC:			s = pop_expanded(cx);			CHECK_NOEVAL			i = count_words(s, DWORD_YES, "\"");			if (x_debug & DEBUG_NEW_MATH_DEBUG)				yell("O: #(%s) -> " FORMAT, s, i);			push_integer(cx, i);			break;		case DEREF:		{			if (top(cx) == MAGIC_TOKEN)				break;		/* Dont do anything */			/*			 * We need to consume the operand, even if			 * we don't intend to use it; plus we need			 * to ensure this defeats auto-append.  Ick.			 */			s = pop_expanded(cx);			*cx->args_flag = 1;			CHECK_NOEVAL			push_lval(cx, s);			break;		}		/* (pre|post)(in|de)crement operators. */		case PREPLUS:   AUTO_UNARY(j + 1, j + 1)		case PREMINUS:  AUTO_UNARY(j - 1, j - 1)		case POSTPLUS:	AUTO_UNARY(j + 1, j)		case POSTMINUS: AUTO_UNARY(j - 1, j)		/* Simple binary operators */		case AND:	BINARY_INTEGER(i & j)		case XOR:	BINARY_INTEGER(i ^ j)		case OR:	BINARY_INTEGER(i | j)		case PLUS:	BINARY_FLOAT(a + b)		case MINUS:	BINARY_FLOAT(a - b)		case MUL:	BINARY_FLOAT(a * b)		case POWER:	BINARY_FLOAT(pow(a, b))		case SHLEFT:	BINARY_INTEGER(i << j)		case SHRIGHT:	BINARY_INTEGER(i >> j)		case DIV:	BINARY_FLOAT_NOZERO(a / b)		case MOD:	BINARY_INTEGER_NOZERO(i % j)		case DAND:	BINARY_BOOLEAN(c && d)		case DOR:	BINARY_BOOLEAN(c || d)		case DXOR:	BINARY_BOOLEAN((c && !d) || (!c && d))		case STRCAT:			{			char *	myval;			pop_2_strings(cx, &s, &t);			CHECK_NOEVAL			if (x_debug & DEBUG_NEW_MATH_DEBUG)				yell("O: (%s) ## (%s) -> %s%s", s, t, s, t);			myval = malloc_strdup2(s, t);			push_string(cx, myval);			new_free(&myval);			break;		}		/* Assignment operators */		case PLUSEQ:	IMPLIED_FLOAT(a + b)		case MINUSEQ:	IMPLIED_FLOAT(a - b)		case MULEQ:	IMPLIED_FLOAT(a * b)		case POWEREQ:	IMPLIED_FLOAT(pow(a, b))		case DIVEQ:	IMPLIED_FLOAT_NOZERO(a / b)		case MODEQ:	IMPLIED_INTEGER_NOZERO(i % j)		case ANDEQ:	IMPLIED_INTEGER(i & j)		case XOREQ:	IMPLIED_INTEGER(i ^ j)		case OREQ:	IMPLIED_INTEGER(i | j)		case SHLEFTEQ:	IMPLIED_INTEGER(i << j)		case SHRIGHTEQ: IMPLIED_INTEGER(i >> j)		case DANDEQ:	IMPLIED_BOOLEAN(c && d)		case DOREQ:	IMPLIED_BOOLEAN(c || d)		case DXOREQ:	IMPLIED_BOOLEAN((c && !d) || (!c && d))		case STRCATEQ:		{			char *	myval;			GET_LVAL_RVAL			CHECK_NOEVAL			myval = malloc_strdup(get_token_expanded(cx, v));			t = get_token_expanded(cx, w);			if (x_debug & DEBUG_NEW_MATH_DEBUG) 				yell("O: %s = (%s ## %s) -> %s%s", 					s, myval, t, myval, t);

⌨️ 快捷键说明

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