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

📄 tclcompexpr.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
		    "syntax error in expression \"", infoPtr->originalExpr,		    "\"", (char *) NULL);	    result = TCL_ERROR;	    goto done;	}	if (!infoPtr->hasOperators) {	    TclEmitOpcode(INST_TRY_CVT_TO_NUMERIC, envPtr);	}	result = GetToken(interp, infoPtr, envPtr); /* skip over the ':' */	if (result != TCL_OK) {	    goto done;	}	/*	 * Emit an unconditional jump around the "else" condExpr.	 */	TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,	        &jumpAroundElseFixup);	/*	 * Compile the "else" expression.	 */	infoPtr->hasOperators = 0;	elseCodeOffset = TclCurrCodeOffset();	result = CompileCondExpr(interp, infoPtr, flags, envPtr);	if (result != TCL_OK) {	    goto done;	}	maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);	if (!infoPtr->hasOperators) {	    TclEmitOpcode(INST_TRY_CVT_TO_NUMERIC, envPtr);	}	/*	 * Fix up the second jump: the unconditional jump around the "else"	 * expression. If the distance is too great (> 127 bytes), replace	 * it with a four byte instruction and move the instructions after	 * the jump down.	 */	currCodeOffset = TclCurrCodeOffset();	jumpDist = (currCodeOffset - jumpAroundElseFixup.codeOffset);	if (TclFixupForwardJump(envPtr, &jumpAroundElseFixup, jumpDist, 127)) {	    /*	     * Update the else expression's starting code offset since it	     * moved down 3 bytes too.	     */	    	    elseCodeOffset += 3;	}		/*	 * Now fix up the first branch: the jumpFalse after the test. If the	 * distance is too great, replace it with a four byte instruction	 * and update the code offsets for the commands in both the "then"	 * and "else" expressions.	 */	jumpDist = (elseCodeOffset - jumpAroundThenFixup.codeOffset);	TclFixupForwardJump(envPtr, &jumpAroundThenFixup, jumpDist, 127);	infoPtr->hasOperators = 1;	/*	 * A comparison is not the top-level operator in this expression.	 */	infoPtr->exprIsComparison = 0;    }    done:    envPtr->maxStackDepth = maxDepth;    return result;}/* *---------------------------------------------------------------------- * * CompileLorExpr -- * *	This procedure compiles a Tcl logical or expression: *	lorExpr ::= landExpr {'||' landExpr} * * Results: *	The return value is TCL_OK on a successful compilation and TCL_ERROR *	on failure. If TCL_ERROR is returned, then the interpreter's result *	contains an error message. * *	envPtr->maxStackDepth is updated with the maximum number of stack *	elements needed to execute the expression. * * Side effects: *	Adds instructions to envPtr to evaluate the expression at runtime. * *---------------------------------------------------------------------- */static intCompileLorExpr(interp, infoPtr, flags, envPtr)    Tcl_Interp *interp;		/* Used for error reporting. */    ExprInfo *infoPtr;		/* Describes the compilation state for the				 * expression being compiled. */    int flags;			/* Flags to control compilation (same as				 * passed to Tcl_Eval). */    CompileEnv *envPtr;		/* Holds resulting instructions. */{    int maxDepth;		/* Maximum number of stack elements needed				 * to execute the expression. */    JumpFixupArray jumpFixupArray;				/* Used to fix up the forward "short				 * circuit" jump after each or-ed				 * subexpression to just after the last				 * subexpression. */    JumpFixup jumpTrueFixup, jumpFixup;    				/* Used to emit the jumps in the code to				 * convert the first operand to a 0 or 1. */    int fixupIndex, jumpDist, currCodeOffset, objIndex, j, result;    Tcl_Obj *objPtr;        HERE("lorExpr", 2);    result = CompileLandExpr(interp, infoPtr, flags, envPtr);    if ((result != TCL_OK) || (infoPtr->token != OR)) {	return result;		/* envPtr->maxStackDepth is already set */    }    infoPtr->hasOperators = 1;    infoPtr->exprIsJustVarRef = 0;    maxDepth = envPtr->maxStackDepth;    TclInitJumpFixupArray(&jumpFixupArray);    while (infoPtr->token == OR) {	result = GetToken(interp, infoPtr, envPtr); /* skip over the '||' */	if (result != TCL_OK) {	    goto done;	}	if (jumpFixupArray.next == 0) {	    /*	     * Just the first "lor" operand is on the stack. The following	     * is slightly ugly: we need to convert that first "lor" operand	     * to a "0" or "1" to get the correct result if it is nonzero.	     * Eventually we'll use a new instruction for this.	     */	    TclEmitForwardJump(envPtr, TCL_TRUE_JUMP, &jumpTrueFixup);	    	    objIndex = TclObjIndexForString("0", 1, /*allocStrRep*/ 0,					    /*inHeap*/ 0, envPtr);	    objPtr = envPtr->objArrayPtr[objIndex];	    Tcl_InvalidateStringRep(objPtr);	    objPtr->internalRep.longValue = 0;	    objPtr->typePtr = &tclIntType;	    	    TclEmitPush(objIndex, envPtr);	    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);	    jumpDist = (TclCurrCodeOffset() - jumpTrueFixup.codeOffset);	    if (TclFixupForwardJump(envPtr, &jumpTrueFixup, jumpDist, 127)) {		panic("CompileLorExpr: bad jump distance %d\n", jumpDist);	    }	    objIndex = TclObjIndexForString("1", 1, /*allocStrRep*/ 0,				            /*inHeap*/ 0, envPtr);	    objPtr = envPtr->objArrayPtr[objIndex];	    Tcl_InvalidateStringRep(objPtr);	    objPtr->internalRep.longValue = 1;	    objPtr->typePtr = &tclIntType;	    	    TclEmitPush(objIndex, envPtr);	    jumpDist = (TclCurrCodeOffset() - jumpFixup.codeOffset);	    if (TclFixupForwardJump(envPtr, &jumpFixup, jumpDist, 127)) {		panic("CompileLorExpr: bad jump distance %d\n", jumpDist);	    }	}	/*	 * Duplicate the value on top of the stack to prevent the jump from	 * consuming it.	 */	TclEmitOpcode(INST_DUP, envPtr);	/*	 * Emit the "short circuit" jump around the rest of the lorExp if	 * the previous expression was true. We emit a one byte (relative)	 * jump here, and replace it later with a four byte jump if the jump	 * target is more than 127 bytes away.	 */	if (jumpFixupArray.next == jumpFixupArray.end) {	    TclExpandJumpFixupArray(&jumpFixupArray);	}	fixupIndex = jumpFixupArray.next;	jumpFixupArray.next++;	TclEmitForwardJump(envPtr, TCL_TRUE_JUMP,	        &(jumpFixupArray.fixup[fixupIndex]));		/*	 * Compile the subexpression.	 */	result = CompileLandExpr(interp, infoPtr, flags, envPtr);	if (result != TCL_OK) {	    goto done;	}	maxDepth = TclMax((envPtr->maxStackDepth + 1), maxDepth);	/*	 * Emit a "logical or" instruction. This does not try to "short-	 * circuit" the evaluation of both operands of a Tcl "||" operator,	 * but instead ensures that we either have a "1" or a "0" result.	 */	TclEmitOpcode(INST_LOR, envPtr);    }    /*     * Now that we know the target of the forward jumps, update the jumps     * with the correct distance. Also, if the distance is too great (> 127     * bytes), replace the jump with a four byte instruction and move the     * instructions after the jump down.     */        for (j = jumpFixupArray.next;  j > 0;  j--) {	fixupIndex = (j - 1);	/* process closest jump first */	currCodeOffset = TclCurrCodeOffset();	jumpDist = (currCodeOffset - jumpFixupArray.fixup[fixupIndex].codeOffset);	TclFixupForwardJump(envPtr, &(jumpFixupArray.fixup[fixupIndex]), jumpDist, 127);    }    /*     * We get here only if one or more ||'s appear as top-level operators.     */    done:    infoPtr->exprIsComparison = 0;    TclFreeJumpFixupArray(&jumpFixupArray);    envPtr->maxStackDepth = maxDepth;    return result;}/* *---------------------------------------------------------------------- * * CompileLandExpr -- * *	This procedure compiles a Tcl logical and expression: *	landExpr ::= bitOrExpr {'&&' bitOrExpr} * * Results: *	The return value is TCL_OK on a successful compilation and TCL_ERROR *	on failure. If TCL_ERROR is returned, then the interpreter's result *	contains an error message. * *	envPtr->maxStackDepth is updated with the maximum number of stack *	elements needed to execute the expression. * * Side effects: *	Adds instructions to envPtr to evaluate the expression at runtime. * *---------------------------------------------------------------------- */static intCompileLandExpr(interp, infoPtr, flags, envPtr)    Tcl_Interp *interp;		/* Used for error reporting. */    ExprInfo *infoPtr;		/* Describes the compilation state for the				 * expression being compiled. */    int flags;			/* Flags to control compilation (same as				 * passed to Tcl_Eval). */    CompileEnv *envPtr;		/* Holds resulting instructions. */{    int maxDepth;		/* Maximum number of stack elements needed				 * to execute the expression. */    JumpFixupArray jumpFixupArray;				/* Used to fix up the forward "short				 * circuit" jump after each and-ed				 * subexpression to just after the last				 * subexpression. */    JumpFixup jumpTrueFixup, jumpFixup;    				/* Used to emit the jumps in the code to				 * convert the first operand to a 0 or 1. */    int fixupIndex, jumpDist, currCodeOffset, objIndex, j, result;    Tcl_Obj *objPtr;    HERE("landExpr", 3);    result = CompileBitOrExpr(interp, infoPtr, flags, envPtr);    if ((result != TCL_OK) || (infoPtr->token != AND)) {	return result;		/* envPtr->maxStackDepth is already set */    }    infoPtr->hasOperators = 1;    infoPtr->exprIsJustVarRef = 0;    maxDepth = envPtr->maxStackDepth;    TclInitJumpFixupArray(&jumpFixupArray);    while (infoPtr->token == AND) {	result = GetToken(interp, infoPtr, envPtr); /* skip over the '&&' */	if (result != TCL_OK) {	    goto done;	}	if (jumpFixupArray.next == 0) {	    /*	     * Just the first "land" operand is on the stack. The following	     * is slightly ugly: we need to convert the first "land" operand	     * to a "0" or "1" to get the correct result if it is	     * nonzero. Eventually we'll use a new instruction.	     */	    TclEmitForwardJump(envPtr, TCL_TRUE_JUMP, &jumpTrueFixup);	     	    objIndex = TclObjIndexForString("0", 1, /*allocStrRep*/ 0,				            /*inHeap*/ 0, envPtr);	    objPtr = envPtr->objArrayPtr[objIndex];	    Tcl_InvalidateStringRep(objPtr);	    objPtr->internalRep.longValue = 0;	    objPtr->typePtr = &tclIntType;	    	    TclEmitPush(objIndex, envPtr);	    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);	    jumpDist = (TclCurrCodeOffset() - jumpTrueFixup.codeOffset);	    if (TclFixupForwardJump(envPtr, &jumpTrueFixup, jumpDist, 127)) {		panic("CompileLandExpr: bad jump distance %d\n", jumpDist);	    }	    objIndex = TclObjIndexForString("1", 1, /*allocStrRep*/ 0,				            /*inHeap*/ 0, envPtr);	    objPtr = envPtr->objArrayPtr[objIndex];	    Tcl_InvalidateStringRep(objPtr);	    objPtr->internalRep.longValue = 1;	    objPtr->typePtr = &tclIntType;	    	    TclEmitPush(objIndex, envPtr);	    jumpDist = (TclCurrCodeOffset() - jumpFixup.codeOffset);	    if (TclFixupForwardJump(envPtr, &jumpFixup, jumpDist, 127)) {		panic("CompileLandExpr: bad jump distance %d\n", jumpDist);	    }	}	/*	 * Duplicate the value on top of the stack to prevent the jump from	 * consuming it.	 */	TclEmitOpcode(INST_DUP, envPtr);	/*	 * Emit the "short circuit" jump around the rest of the landExp if	 * the previous expression was false. We emit a one byte (relative)	 * jump here, and replace it later with a four byte jump if the jump	 * target is more than 127 bytes away.	 */	if (jumpFixupArray.next == jumpFixupArray.end) {	    TclExpandJumpFixupArray(&jumpFixupArray);	}	fixupIndex = jumpFixupArray.next;	jumpFixupArray.next++;	TclEmitForwardJump(envPtr, TCL_FALSE_JUMP,		&(jumpFixupArray.fixup[fixupIndex]));		/*	 * Compile the subexpression.	 */	result = CompileBitOrExpr(interp, infoPtr, flags, envPtr);	if (result != TCL_OK) {	    goto done;	}	maxDepth = TclMax((envPtr->maxStackDepth + 1), maxDepth);	/*	 * Emit a "logical and" instruction. This does not try to "short-	 * circuit" the evaluation of both operands of a Tcl "&&" operator,	 * but instead ensures that we either have a "1" or a "0" result.	 */	TclEmitOpcode(INST_LAND, envPtr);    }    /*     * Now that we know the target of the forward jumps, update the jumps     * with the correct distance. Also, if the distance is too great (> 127     * bytes), replace the jump with a four byte instruction and move the     * instructions after the jump down.     */        for (j = jumpFixupArray.next;  j > 0;  j--) {	fixupIndex = (j - 1);	/* process closest jump first */	currCodeOffset = TclCurrCodeOffset();	jumpDist = (currCodeOffset - jumpFixupArray.fixup[fixupIndex].codeOffset);	TclFixupForwardJump(envPtr, &(jumpFixupArray.fixup[fixupIndex]),	        jumpDist, 127);    }    /*     * We get here only if one or more &&'s appear as top-level operators.     */    done:    infoPtr->exprIsComparison = 0;    TclFreeJumpFixupArray(&jumpFixupArray);    envPtr->maxStackDepth = maxDepth;    return result;}/* *---------------------------------------------------------------------- * * CompileBitOrExpr -- * *	This procedure compiles a Tcl bitwise or expression: *	bitOrExpr ::= bitXorExpr {'|' bitXorExpr} * * Results: *	The return value is TCL_OK on a successful compilation and TCL_ERROR *	on failure. If TCL_ERROR is returned, then the interpreter's result *	contains an error message. * *	envPtr->maxStackDepth is updated with the maximum number of stack *	elements needed to execute the expression. * * Side effects: *	Adds instructions to envPtr to evaluate the expression at runtime. * *---------------------------------------------------------------------- */static intCompileBitOrExpr(interp, infoPtr, flags, envPtr)    Tcl_Interp *interp;		/* Used for error reporting. */    ExprInfo *infoPtr;		/* Describes the compilation state for the				 * expression being compiled. */    int flags;			/* Flags to control compilation (same as				 * passed to Tcl_Eval). */    CompileEnv *envPtr;		/* Holds resulting instructions. */{    int maxDepth = 0;		/* Maximum number of stack elements needed				 * to execute the expression. */    int result;    HERE("bitOrExpr", 4);

⌨️ 快捷键说明

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