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

📄 tclexpr.c

📁 tcl源码详细资料
💻 C
📖 第 1 页 / 共 3 页
字号:
	    case MULT:		if (valuePtr->type == TYPE_INT) {		    valuePtr->intValue *= value2.intValue;		} else {		    valuePtr->doubleValue *= value2.doubleValue;		}		break;	    case DIVIDE:		if (valuePtr->type == TYPE_INT) {		    if (value2.intValue == 0) {			divideByZero:			interp->result = "divide by zero";			result = TCL_ERROR;			goto done;		    }		    valuePtr->intValue /= value2.intValue;		} else {		    if (value2.doubleValue == 0.0) {			goto divideByZero;		    }		    valuePtr->doubleValue /= value2.doubleValue;		}		break;	    case MOD:		if (value2.intValue == 0) {		    goto divideByZero;		}		valuePtr->intValue %= value2.intValue;		break;	    case PLUS:		if (valuePtr->type == TYPE_INT) {		    valuePtr->intValue += value2.intValue;		} else {		    valuePtr->doubleValue += value2.doubleValue;		}		break;	    case MINUS:		if (valuePtr->type == TYPE_INT) {		    valuePtr->intValue -= value2.intValue;		} else {		    valuePtr->doubleValue -= value2.doubleValue;		}		break;	    case LEFT_SHIFT:		valuePtr->intValue <<= value2.intValue;		break;	    case RIGHT_SHIFT:		/*		 * The following code is a bit tricky:  it ensures that		 * right shifts propagate the sign bit even on machines		 * where ">>" won't do it by default.		 */		if (valuePtr->intValue < 0) {		    valuePtr->intValue =			    ~((~valuePtr->intValue) >> value2.intValue);		} else {		    valuePtr->intValue >>= value2.intValue;		}		break;	    case LESS:		if (valuePtr->type == TYPE_INT) {		    valuePtr->intValue =			valuePtr->intValue < value2.intValue;		} else if (valuePtr->type == TYPE_DOUBLE) {		    valuePtr->intValue =			valuePtr->doubleValue < value2.doubleValue;		} else {		    valuePtr->intValue =			    strcmp(valuePtr->pv.buffer, value2.pv.buffer) < 0;		}		valuePtr->type = TYPE_INT;		break;	    case GREATER:		if (valuePtr->type == TYPE_INT) {		    valuePtr->intValue =			valuePtr->intValue > value2.intValue;		} else if (valuePtr->type == TYPE_DOUBLE) {		    valuePtr->intValue =			valuePtr->doubleValue > value2.doubleValue;		} else {		    valuePtr->intValue =			    strcmp(valuePtr->pv.buffer, value2.pv.buffer) > 0;		}		valuePtr->type = TYPE_INT;		break;	    case LEQ:		if (valuePtr->type == TYPE_INT) {		    valuePtr->intValue =			valuePtr->intValue <= value2.intValue;		} else if (valuePtr->type == TYPE_DOUBLE) {		    valuePtr->intValue =			valuePtr->doubleValue <= value2.doubleValue;		} else {		    valuePtr->intValue =			    strcmp(valuePtr->pv.buffer, value2.pv.buffer) <= 0;		}		valuePtr->type = TYPE_INT;		break;	    case GEQ:		if (valuePtr->type == TYPE_INT) {		    valuePtr->intValue =			valuePtr->intValue >= value2.intValue;		} else if (valuePtr->type == TYPE_DOUBLE) {		    valuePtr->intValue =			valuePtr->doubleValue >= value2.doubleValue;		} else {		    valuePtr->intValue =			    strcmp(valuePtr->pv.buffer, value2.pv.buffer) >= 0;		}		valuePtr->type = TYPE_INT;		break;	    case EQUAL:		if (valuePtr->type == TYPE_INT) {		    valuePtr->intValue =			valuePtr->intValue == value2.intValue;		} else if (valuePtr->type == TYPE_DOUBLE) {		    valuePtr->intValue =			valuePtr->doubleValue == value2.doubleValue;		} else {		    valuePtr->intValue =			    strcmp(valuePtr->pv.buffer, value2.pv.buffer) == 0;		}		valuePtr->type = TYPE_INT;		break;	    case NEQ:		if (valuePtr->type == TYPE_INT) {		    valuePtr->intValue =			valuePtr->intValue != value2.intValue;		} else if (valuePtr->type == TYPE_DOUBLE) {		    valuePtr->intValue =			valuePtr->doubleValue != value2.doubleValue;		} else {		    valuePtr->intValue =			    strcmp(valuePtr->pv.buffer, value2.pv.buffer) != 0;		}		valuePtr->type = TYPE_INT;		break;	    case BIT_AND:		valuePtr->intValue &= value2.intValue;		break;	    case BIT_XOR:		valuePtr->intValue ^= value2.intValue;		break;	    case BIT_OR:		valuePtr->intValue |= value2.intValue;		break;	    /*	     * For AND and OR, we know that the first value has already	     * been converted to an integer.  Thus we need only consider	     * the possibility of int vs. double for the second value.	     */	    case AND:		if (value2.type == TYPE_DOUBLE) {		    value2.intValue = value2.doubleValue != 0;		    value2.type = TYPE_INT;		}		valuePtr->intValue = valuePtr->intValue && value2.intValue;		break;	    case OR:		if (value2.type == TYPE_DOUBLE) {		    value2.intValue = value2.doubleValue != 0;		    value2.type = TYPE_INT;		}		valuePtr->intValue = valuePtr->intValue || value2.intValue;		break;	    case COLON:		interp->result = "can't have : operator without ? first";		result = TCL_ERROR;		goto done;	}    }    done:    if (value2.pv.buffer != value2.staticSpace) {	ckfree(value2.pv.buffer);    }    return result;    syntaxError:    Tcl_ResetResult(interp);    Tcl_AppendResult(interp, "syntax error in expression \"",	    infoPtr->originalExpr, "\"", (char *) NULL);    result = TCL_ERROR;    goto done;    illegalType:    Tcl_AppendResult(interp, "can't use ", (badType == TYPE_DOUBLE) ?	    "floating-point value" : "non-numeric string",	    " as operand of \"", operatorStrings[operator], "\"",	    (char *) NULL);    result = TCL_ERROR;    goto done;}/* *-------------------------------------------------------------- * * ExprMakeString -- * *	Convert a value from int or double representation to *	a string. * * Results: *	The information at *valuePtr gets converted to string *	format, if it wasn't that way already. * * Side effects: *	None. * *-------------------------------------------------------------- */static voidExprMakeString(valuePtr)    register Value *valuePtr;		/* Value to be converted. */{    int shortfall;    shortfall = 150 - (valuePtr->pv.end - valuePtr->pv.buffer);    if (shortfall > 0) {	(*valuePtr->pv.expandProc)(&valuePtr->pv, shortfall);    }    if (valuePtr->type == TYPE_INT) {	sprintf(valuePtr->pv.buffer, "%ld", valuePtr->intValue);    } else if (valuePtr->type == TYPE_DOUBLE) {	sprintf(valuePtr->pv.buffer, "%g", valuePtr->doubleValue);    }    valuePtr->type = TYPE_STRING;}/* *-------------------------------------------------------------- * * ExprTopLevel -- * *	This procedure provides top-level functionality shared by *	procedures like Tcl_ExprInt, Tcl_ExprDouble, etc. * * Results: *	The result is a standard Tcl return value.  If an error *	occurs then an error message is left in interp->result. *	The value of the expression is returned in *valuePtr, in *	whatever form it ends up in (could be string or integer *	or double).  Caller may need to convert result.  Caller *	is also responsible for freeing string memory in *valuePtr, *	if any was allocated. * * Side effects: *	None. * *-------------------------------------------------------------- */static intExprTopLevel(interp, string, valuePtr)    Tcl_Interp *interp;			/* Context in which to evaluate the					 * expression. */    char *string;			/* Expression to evaluate. */    Value *valuePtr;			/* Where to store result.  Should					 * not be initialized by caller. */{    ExprInfo info;    int result;    info.originalExpr = string;    info.expr = string;    valuePtr->pv.buffer = valuePtr->pv.next = valuePtr->staticSpace;    valuePtr->pv.end = valuePtr->pv.buffer + STATIC_STRING_SPACE - 1;    valuePtr->pv.expandProc = TclExpandParseValue;    valuePtr->pv.clientData = (ClientData) NULL;    result = ExprGetValue(interp, &info, -1, valuePtr);    if (result != TCL_OK) {	return result;    }    if (info.token != END) {	Tcl_AppendResult(interp, "syntax error in expression \"",		string, "\"", (char *) NULL);	return TCL_ERROR;    }    return TCL_OK;}/* *-------------------------------------------------------------- * * Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean -- * *	Procedures to evaluate an expression and return its value *	in a particular form. * * Results: *	Each of the procedures below returns a standard Tcl result. *	If an error occurs then an error message is left in *	interp->result.  Otherwise the value of the expression, *	in the appropriate form, is stored at *resultPtr.  If *	the expression had a result that was incompatible with the *	desired form then an error is returned. * * Side effects: *	None. * *-------------------------------------------------------------- */intTcl_ExprLong(interp, string, ptr)    Tcl_Interp *interp;			/* Context in which to evaluate the					 * expression. */    char *string;			/* Expression to evaluate. */    long *ptr;				/* Where to store result. */{    Value value;    int result;    result = ExprTopLevel(interp, string, &value);    if (result == TCL_OK) {	if (value.type == TYPE_INT) {	    *ptr = value.intValue;	} else if (value.type == TYPE_DOUBLE) {	    *ptr = value.doubleValue;	} else {	    interp->result = "expression didn't have numeric value";	    result = TCL_ERROR;	}    }    if (value.pv.buffer != value.staticSpace) {	ckfree(value.pv.buffer);    }    return result;}intTcl_ExprDouble(interp, string, ptr)    Tcl_Interp *interp;			/* Context in which to evaluate the					 * expression. */    char *string;			/* Expression to evaluate. */    double *ptr;			/* Where to store result. */{    Value value;    int result;    result = ExprTopLevel(interp, string, &value);    if (result == TCL_OK) {	if (value.type == TYPE_INT) {	    *ptr = value.intValue;	} else if (value.type == TYPE_DOUBLE) {	    *ptr = value.doubleValue;	} else {	    interp->result = "expression didn't have numeric value";	    result = TCL_ERROR;	}    }    if (value.pv.buffer != value.staticSpace) {	ckfree(value.pv.buffer);    }    return result;}intTcl_ExprBoolean(interp, string, ptr)    Tcl_Interp *interp;			/* Context in which to evaluate the					 * expression. */    char *string;			/* Expression to evaluate. */    int *ptr;				/* Where to store 0/1 result. */{    Value value;    int result;    result = ExprTopLevel(interp, string, &value);    if (result == TCL_OK) {	if (value.type == TYPE_INT) {	    *ptr = value.intValue != 0;	} else if (value.type == TYPE_DOUBLE) {	    *ptr = value.doubleValue != 0.0;	} else {	    interp->result = "expression didn't have numeric value";	    result = TCL_ERROR;	}    }    if (value.pv.buffer != value.staticSpace) {	ckfree(value.pv.buffer);    }    return result;}/* *-------------------------------------------------------------- * * Tcl_ExprString -- * *	Evaluate an expression and return its value in string form. * * Results: *	A standard Tcl result.  If the result is TCL_OK, then the *	interpreter's result is set to the string value of the *	expression.  If the result is TCL_OK, then interp->result *	contains an error message. * * Side effects: *	None. * *-------------------------------------------------------------- */intTcl_ExprString(interp, string)    Tcl_Interp *interp;			/* Context in which to evaluate the					 * expression. */    char *string;			/* Expression to evaluate. */{    Value value;    int result;    result = ExprTopLevel(interp, string, &value);    if (result == TCL_OK) {	if (value.type == TYPE_INT) {	    sprintf(interp->result, "%ld", value.intValue);	} else if (value.type == TYPE_DOUBLE) {	    sprintf(interp->result, "%g", value.doubleValue);	} else {	    if (value.pv.buffer != value.staticSpace) {		interp->result = value.pv.buffer;		interp->freeProc = (Tcl_FreeProc *) free;		value.pv.buffer = value.staticSpace;	    } else {		Tcl_SetResult(interp, value.pv.buffer, TCL_VOLATILE);	    }	}    }    if (value.pv.buffer != value.staticSpace) {	ckfree(value.pv.buffer);    }    return result;}#elsestatic const char file_name[] = "tclExpr.c";#endif /* EXCLUDE_TCL */

⌨️ 快捷键说明

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