diff options
author | dgp <dgp@users.sourceforge.net> | 2018-03-08 21:58:30 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2018-03-08 21:58:30 (GMT) |
commit | 947fb98db5ca258e0f170c51a9392816a6f48a8f (patch) | |
tree | cde6178f76174ecc247366f0167594184fe6f193 | |
parent | ed53b715acb5d9a060c898f5ad4cfa79d6c9db1d (diff) | |
download | tcl-947fb98db5ca258e0f170c51a9392816a6f48a8f.zip tcl-947fb98db5ca258e0f170c51a9392816a6f48a8f.tar.gz tcl-947fb98db5ca258e0f170c51a9392816a6f48a8f.tar.bz2 |
Stop failing error ordering tests in compiled [lreplace].
-rw-r--r-- | generic/tclCompCmdsGR.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index de02ee7..e2ddb11 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -1563,7 +1563,7 @@ TclCompileLreplaceCmd( Tcl_Token *tokenPtr, *listTokenPtr; DefineLineInformation; /* TIP #280 */ int idx1, idx2, i, offset, offset2; - int emptyPrefix, suffixStart = 0; + int emptyPrefix=1, suffixStart = 0; if (parsePtr->numWords < 4) { return TCL_ERROR; @@ -1625,13 +1625,35 @@ TclCompileLreplaceCmd( CompileWord(envPtr, listTokenPtr, interp, 1); /* + * Push all the replacement values next so any errors raised in + * creating them get raised first. + */ + if (parsePtr->numWords > 4) { + /* Push the replacement arguments */ + tokenPtr = TokenAfter(tokenPtr); + for (i=4 ; i<parsePtr->numWords ; i++) { + CompileWord(envPtr, tokenPtr, interp, i); + tokenPtr = TokenAfter(tokenPtr); + } + + /* Make a list of them... */ + TclEmitInstInt4( INST_LIST, i - 4, envPtr); + + emptyPrefix = 0; + } + + /* * [lreplace] raises an error when idx1 points after the list, but * only when the list is not empty. This is maximum stupidity. * * TODO: TIP this nonsense away! */ if (idx1 >= TCL_INDEX_START) { - TclEmitOpcode( INST_DUP, envPtr); + if (emptyPrefix) { + TclEmitOpcode( INST_DUP, envPtr); + } else { + TclEmitInstInt4( INST_OVER, 1, envPtr); + } TclEmitOpcode( INST_LIST_LENGTH, envPtr); TclEmitOpcode( INST_DUP, envPtr); offset = CurrentOffset(envPtr); @@ -1667,26 +1689,17 @@ TclCompileLreplaceCmd( return TCL_OK; } - emptyPrefix = (idx1 == TCL_INDEX_START); - if (!emptyPrefix) { + if (idx1 != TCL_INDEX_START) { /* Prefix may not be empty; generate bytecode to push it */ - TclEmitOpcode( INST_DUP, envPtr); + if (emptyPrefix) { + TclEmitOpcode( INST_DUP, envPtr); + } else { + TclEmitInstInt4( INST_OVER, 1, envPtr); + } TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); TclEmitInt4( idx1 - 1, envPtr); - } - - if (parsePtr->numWords > 4) { - /* Push the replacement arguments */ - tokenPtr = TokenAfter(tokenPtr); - for (i=4 ; i<parsePtr->numWords ; i++) { - CompileWord(envPtr, tokenPtr, interp, i); - tokenPtr = TokenAfter(tokenPtr); - } - - /* Make a list of them... */ - TclEmitInstInt4( INST_LIST, i - 4, envPtr); if (!emptyPrefix) { - /* ...and join to the prefix, if any. */ + TclEmitInstInt4( INST_REVERSE, 2, envPtr); TclEmitOpcode( INST_LIST_CONCAT, envPtr); } emptyPrefix = 0; |