From 540f62b18de23e912d85b8b0fe9ea4f35dda0d2b Mon Sep 17 00:00:00 2001 From: twylite Date: Wed, 8 Aug 2012 15:28:09 +0000 Subject: Back-out 'foreacha' implementation but leave code cleanup of 'mapeach' and 'dict map'. --- generic/tclBasic.c | 1 - generic/tclCmdAH.c | 58 ++++++++++----------------------------------------- generic/tclCompCmds.c | 23 ++------------------ generic/tclCompile.h | 1 - generic/tclExecute.c | 17 +++------------ generic/tclInt.h | 10 --------- 6 files changed, 16 insertions(+), 94 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index fe8fa5a..a35da29 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -219,7 +219,6 @@ static const CmdInfo builtInCmds[] = { {"expr", Tcl_ExprObjCmd, TclCompileExprCmd, TclNRExprObjCmd, 1}, {"for", Tcl_ForObjCmd, TclCompileForCmd, TclNRForObjCmd, 1}, {"foreach", Tcl_ForeachObjCmd, TclCompileForeachCmd, TclNRForeachCmd, 1}, - {"foreacha", Tcl_ForeachaObjCmd, TclCompileForeachaCmd, TclNRForeachaCmd, 1}, {"format", Tcl_FormatObjCmd, NULL, NULL, 1}, {"global", Tcl_GlobalObjCmd, TclCompileGlobalCmd, NULL, 1}, {"if", Tcl_IfObjCmd, TclCompileIfCmd, TclNRIfObjCmd, 1}, diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c index 333946a..a10646c 100644 --- a/generic/tclCmdAH.c +++ b/generic/tclCmdAH.c @@ -45,7 +45,7 @@ static int EncodingDirsObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static inline int ForeachAssignments(Tcl_Interp *interp, - struct ForeachState *statePtr, int collect); + struct ForeachState *statePtr); static inline void ForeachCleanup(Tcl_Interp *interp, struct ForeachState *statePtr); static int GetStatBuf(Tcl_Interp *interp, Tcl_Obj *pathPtr, @@ -2619,26 +2619,6 @@ TclNRMapeachCmd( } int -Tcl_ForeachaObjCmd( - ClientData dummy, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - return Tcl_NRCallObjProc(interp, TclNRForeachaCmd, dummy, objc, objv); -} - -int -TclNRForeachaCmd( - ClientData dummy, - Tcl_Interp *interp, - int objc, - Tcl_Obj *const objv[]) -{ - return TclNREachloopCmd(dummy, interp, objc, objv, TCL_EACH_ACCUM); -} - -int TclNREachloopCmd( ClientData dummy, Tcl_Interp *interp, @@ -2720,13 +2700,9 @@ TclNREachloopCmd( TclListObjGetElements(NULL, statePtr->aCopyList[i], &statePtr->argcList[i], &statePtr->argvList[i]); - j = (i == 0) && (collect == TCL_EACH_ACCUM); /* Accumulator present? */ - /* If accumulator is only var in list, then we iterate j=1 times */ - if (statePtr->varcList[i] > j) { - /* We need listLen/numVars round up = ((listLen+numVars-1)/numVars) - * When accum is present we need (listLen-1)/(numVars-1) round up */ - j = (statePtr->argcList[i] - j + statePtr->varcList[i] - j - 1) - / (statePtr->varcList[i] - j); + j = statePtr->argcList[i] / statePtr->varcList[i]; + if ((statePtr->argcList[i] % statePtr->varcList[i]) != 0) { + j++; } if (j > statePtr->maxj) { statePtr->maxj = j; @@ -2739,7 +2715,7 @@ TclNREachloopCmd( */ if (statePtr->maxj > 0) { - result = ForeachAssignments(interp, statePtr, collect); + result = ForeachAssignments(interp, statePtr); if (result == TCL_ERROR) { goto done; } @@ -2803,7 +2779,7 @@ ForeachLoopStep( */ if (statePtr->maxj > ++statePtr->j) { - result = ForeachAssignments(interp, statePtr, collect); + result = ForeachAssignments(interp, statePtr); if (result == TCL_ERROR) { goto done; } @@ -2816,18 +2792,9 @@ ForeachLoopStep( /* * We're done. Tidy up our work space and finish off. */ -finish: - if (collect == TCL_EACH_ACCUM) { - Tcl_Obj* valueObj = Tcl_ObjGetVar2(interp, statePtr->varvList[0][0], - NULL, TCL_LEAVE_ERR_MSG); - if (valueObj == NULL) { - goto done; - } - Tcl_SetObjResult(interp, valueObj); - } else { - Tcl_SetObjResult(interp, statePtr->resultList); - statePtr->resultList = NULL; /* Don't clean it up */ - } + finish: + Tcl_SetObjResult(interp, statePtr->resultList); + statePtr->resultList = NULL; /* Don't clean it up */ done: ForeachCleanup(interp, statePtr); return result; @@ -2840,16 +2807,13 @@ finish: static inline int ForeachAssignments( Tcl_Interp *interp, - struct ForeachState *statePtr, - int collect) /* Select collecting or accumulating mode (TCL_EACH_*) */ + struct ForeachState *statePtr) { int i, v, k; Tcl_Obj *valuePtr, *varValuePtr; for (i=0 ; inumLists ; i++) { - /* Don't modify the accumulator except on the first iteration */ - v = ((i == 0) && (collect == TCL_EACH_ACCUM) && (statePtr->index[i] > 0)); - for (; vvarcList[i] ; v++) { + for (v=0 ; vvarcList[i] ; v++) { k = statePtr->index[i]++; if (k < statePtr->argcList[i]) { diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 07a5eea..395a0f8 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -1911,9 +1911,9 @@ TclCompileForCmd( /* *---------------------------------------------------------------------- * - * TclCompileForeachCmd, TclCompileForeachaCmd -- + * TclCompileForeachCmd -- * - * Procedure called to compile the "foreach" and "foreacha" commands. + * Procedure called to compile the "foreach" command. * * Results: * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer @@ -1937,18 +1937,6 @@ TclCompileForeachCmd( { return TclCompileEachloopCmd(interp, parsePtr, cmdPtr, envPtr, 0); } - -int -TclCompileForeachaCmd( - Tcl_Interp *interp, /* Used for error reporting. */ - Tcl_Parse *parsePtr, /* Points to a parse structure for the command - * created by Tcl_ParseCommand. */ - Command *cmdPtr, /* Points to defintion of command being - * compiled. */ - CompileEnv *envPtr) /* Holds resulting instructions. */ -{ - return TclCompileEachloopCmd(interp, parsePtr, cmdPtr, envPtr, 2); -} /* *---------------------------------------------------------------------- @@ -2136,7 +2124,6 @@ TclCompileEachloopCmd( infoPtr->numLists = numLists; infoPtr->firstValueTemp = firstValueTemp; infoPtr->loopCtTemp = loopCtTemp; - infoPtr->collect = collect; for (loopIndex = 0; loopIndex < numLists; loopIndex++) { ForeachVarList *varListPtr; @@ -2150,9 +2137,6 @@ TclCompileEachloopCmd( varListPtr->varIndexes[j] = TclFindCompiledLocal(varName, nameChars, /*create*/ 1, envPtr); - if ((collect == TCL_EACH_ACCUM) && ((loopIndex + j) == 0)) { - collectTemp = varListPtr->varIndexes[j]; - } } infoPtr->varLists[loopIndex] = varListPtr; } @@ -2344,7 +2328,6 @@ DupForeachInfo( dupPtr->numLists = numLists; dupPtr->firstValueTemp = srcPtr->firstValueTemp; dupPtr->loopCtTemp = srcPtr->loopCtTemp; - dupPtr->collect = srcPtr->collect; for (i = 0; i < numLists; i++) { srcListPtr = srcPtr->varLists[i]; @@ -2435,8 +2418,6 @@ PrintForeachInfo( } Tcl_AppendPrintfToObj(appendObj, "], loop=%%v%u", (unsigned) infoPtr->loopCtTemp); - Tcl_AppendPrintfToObj(appendObj, "], collect=%%v%u", - (unsigned) infoPtr->collect); for (i=0 ; inumLists ; i++) { if (i) { Tcl_AppendToObj(appendObj, ",", -1); diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 7a41bb1..ba78c36 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -807,7 +807,6 @@ typedef struct ForeachInfo { * the loop's iteration count. Used to * determine next value list element to assign * each loop var. */ - int collect; /* Selected collecting or accumulating mode. */ ForeachVarList *varLists[1];/* An array of pointers to ForeachVarList * structures describing each var list. The * actual size of this field will be large diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 952eb32..e402634 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5492,15 +5492,7 @@ TEBCresume( opnd, i, O2S(listPtr)), Tcl_GetObjResult(interp)); goto gotError; } - - /* If the accumulator is the only variable then this list gets - * just one iteration. Otherwise we must keep going until the - * list is exhausted by non-accumulator loop vars */ - j = ((i == 0) && (iterNum > 0) - && (infoPtr->collect == TCL_EACH_ACCUM)); - /* j is 1 if the accumulator is present but does not consume - * an element, or 0 otherwise (consuming or not-present). */ - if ((numVars > j) && (listLen > (iterNum * (numVars - j) + j))) { + if (listLen > iterNum * numVars) { continueLoop = 1; } listTmpIndex++; @@ -5525,11 +5517,8 @@ TEBCresume( listPtr = TclListObjCopy(NULL, listVarPtr->value.objPtr); TclListObjGetElements(interp, listPtr, &listLen, &elements); - /* Don't modify the accumulator except on the first iteration */ - j = ((i == 0) && (iterNum > 0) - && (infoPtr->collect == TCL_EACH_ACCUM)); - valIndex = (iterNum * (numVars - j) + j); - for (; j < numVars; j++) { + valIndex = (iterNum * numVars); + for (j = 0; j < numVars; j++) { if (valIndex >= listLen) { TclNewObj(valuePtr); } else { diff --git a/generic/tclInt.h b/generic/tclInt.h index 6600dd9..4fc265f 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2773,7 +2773,6 @@ MODULE_SCOPE Tcl_ObjCmdProc TclNRCatchObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRExprObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRForObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRForeachCmd; -MODULE_SCOPE Tcl_ObjCmdProc TclNRForeachaCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRIfObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRMapeachCmd; MODULE_SCOPE Tcl_ObjCmdProc TclNRSourceObjCmd; @@ -2865,9 +2864,6 @@ struct Tcl_LoadHandle_ { #define TCL_EACH_COLLECT 1 /* Collect iteration result like [mapeach] */ -#define TCL_EACH_ACCUM 2 - /* First loop var is accumulator like [foreacha] */ - /* *---------------------------------------------------------------- @@ -3314,9 +3310,6 @@ MODULE_SCOPE int Tcl_ForObjCmd(ClientData clientData, MODULE_SCOPE int Tcl_ForeachObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -MODULE_SCOPE int Tcl_ForeachaObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); MODULE_SCOPE int Tcl_FormatObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -3549,9 +3542,6 @@ MODULE_SCOPE int TclCompileForCmd(Tcl_Interp *interp, MODULE_SCOPE int TclCompileForeachCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); -MODULE_SCOPE int TclCompileForeachaCmd(Tcl_Interp *interp, - Tcl_Parse *parsePtr, Command *cmdPtr, - struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileGlobalCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); -- cgit v0.12