summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorapnadkarni <apnmbx-wits@yahoo.com>2022-10-30 04:27:03 (GMT)
committerapnadkarni <apnmbx-wits@yahoo.com>2022-10-30 04:27:03 (GMT)
commit5da6b8e3c356a3786e96336ea19a8c4fabcb17fa (patch)
tree3e526db88ab7054a18579db74b3132d33d87f30b /generic
parent61814ba324f4652c444ecb2776f2cf8eb799dac7 (diff)
downloadtcl-5da6b8e3c356a3786e96336ea19a8c4fabcb17fa.zip
tcl-5da6b8e3c356a3786e96336ea19a8c4fabcb17fa.tar.gz
tcl-5da6b8e3c356a3786e96336ea19a8c4fabcb17fa.tar.bz2
New bytecode for linsert
Diffstat (limited to 'generic')
-rw-r--r--generic/tclCompCmdsGR.c41
-rw-r--r--generic/tclCompile.c8
-rw-r--r--generic/tclCompile.h2
-rw-r--r--generic/tclExecute.c15
4 files changed, 20 insertions, 46 deletions
diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c
index 4aa454b..ddb9746 100644
--- a/generic/tclCompCmdsGR.c
+++ b/generic/tclCompCmdsGR.c
@@ -1391,48 +1391,16 @@ TclCompileLinsertCmd(
*/
CompileWord(envPtr, listTokenPtr, interp, 1);
- if (parsePtr->numWords == 3) {
- TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
- TclEmitInt4( (int)TCL_INDEX_END, envPtr);
- return TCL_OK;
- }
for (i=3 ; i<parsePtr->numWords ; i++) {
tokenPtr = TokenAfter(tokenPtr);
CompileWord(envPtr, tokenPtr, interp, i);
}
- TclEmitInstInt4( INST_LIST, i - 3, envPtr);
- if (idx == (int)TCL_INDEX_START) {
- TclEmitInstInt4( INST_REVERSE, 2, envPtr);
- TclEmitOpcode( INST_LIST_CONCAT, envPtr);
- } else if (idx == (int)TCL_INDEX_END) {
- TclEmitOpcode( INST_LIST_CONCAT, envPtr);
- } else {
- /*
- * Here we handle two ranges for idx. First when idx > 0, we
- * want the first half of the split to end at index idx-1 and
- * the second half to start at index idx.
- * Second when idx < TCL_INDEX_END, indicating "end-N" indexing,
- * we want the first half of the split to end at index end-N and
- * the second half to start at index end-N+1. We accomplish this
- * with a pre-adjustment of the end-N value.
- * The root of this is that the commands [lrange] and [linsert]
- * differ in their interpretation of the "end" index.
- */
-
- if (idx < (int)TCL_INDEX_END) {
- idx++;
- }
- TclEmitInstInt4( INST_OVER, 1, envPtr);
- TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
- TclEmitInt4( idx - 1, envPtr);
- TclEmitInstInt4( INST_REVERSE, 3, envPtr);
- TclEmitInstInt4( INST_LIST_RANGE_IMM, idx, envPtr);
- TclEmitInt4( (int)TCL_INDEX_END, envPtr);
- TclEmitOpcode( INST_LIST_CONCAT, envPtr);
- TclEmitOpcode( INST_LIST_CONCAT, envPtr);
- }
+ TclEmitInstInt4(INST_LREPLACE4, parsePtr->numWords - 2, envPtr);
+ TclEmitInt4(0, envPtr);
+ TclEmitInt4(idx, envPtr);
+ TclEmitInt4(idx-1, envPtr);
return TCL_OK;
}
@@ -3086,6 +3054,7 @@ TclCompileXxCmd(
}
TclEmitInstInt4(INST_LREPLACE4, parsePtr->numWords - 2, envPtr);
+ TclEmitInt4(0, envPtr);
TclEmitInt4(idx, envPtr);
TclEmitInt4(idx-1, envPtr);
diff --git a/generic/tclCompile.c b/generic/tclCompile.c
index 2535167..c01ddb8 100644
--- a/generic/tclCompile.c
+++ b/generic/tclCompile.c
@@ -675,8 +675,12 @@ InstructionDesc const tclInstructionTable[] = {
/* String Less or equal: push (stknext <= stktop) */
{"strge", 1, -1, 0, {OPERAND_NONE}},
/* String Greater or equal: push (stknext >= stktop) */
- {"lreplace4", 13, INT_MIN, 3, {OPERAND_UINT4, OPERAND_INT4, OPERAND_INT4}},
- /* Stack: ... listobj num_elems first last new1 ... newN => ... newlistobj */
+ {"lreplace4", 17, INT_MIN, 4, {OPERAND_UINT4, OPERAND_UINT4, OPERAND_INT4, OPERAND_INT4}},
+ /* Operands: number of arguments, end_indicator, firstIdx, lastIdx
+ * end_indicator: 0 if "end" is treated as index of last element,
+ * 1 if "end" is position after last element
+ * firstIdx,lastIdx: range of elements to delete
+ * Stack: ... listobj new1 ... newN => ... newlistobj */
{NULL, 0, 0, 0, {OPERAND_NONE}}
};
diff --git a/generic/tclCompile.h b/generic/tclCompile.h
index c82dc6e..9633050 100644
--- a/generic/tclCompile.h
+++ b/generic/tclCompile.h
@@ -862,7 +862,7 @@ typedef struct ByteCode {
* instruction.
*/
-#define MAX_INSTRUCTION_OPERANDS 3
+#define MAX_INSTRUCTION_OPERANDS 4
typedef enum InstOperandType {
OPERAND_NONE,
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 629df59..2713093 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -5246,17 +5246,18 @@ TEBCresume(
case INST_LREPLACE4:
{
- int firstIdx, lastIdx, numToDelete, numNewElems;
+ int firstIdx, lastIdx, numToDelete, numNewElems, end_indicator;
opnd = TclGetInt4AtPtr(pc + 1);
- firstIdx = TclGetInt4AtPtr(pc + 5); /* First delete position */
- lastIdx = TclGetInt4AtPtr(pc + 9); /* Last delete position */
+ end_indicator = TclGetInt4AtPtr(pc + 5);
+ firstIdx = TclGetInt4AtPtr(pc + 9);
+ lastIdx = TclGetInt4AtPtr(pc + 13);
numNewElems = opnd - 1;
valuePtr = OBJ_AT_DEPTH(numNewElems);
if (Tcl_ListObjLength(interp, valuePtr, &length) != TCL_OK) {
TRACE_ERROR(interp);
goto gotError;
}
- firstIdx = TclIndexDecode(firstIdx, length-1);
+ firstIdx = TclIndexDecode(firstIdx, length-end_indicator);
if (firstIdx == TCL_INDEX_NONE) {
firstIdx = 0;
} else if (firstIdx > length) {
@@ -5264,7 +5265,7 @@ TEBCresume(
}
numToDelete = 0;
if (lastIdx != TCL_INDEX_NONE) {
- lastIdx = TclIndexDecode(lastIdx, length - 1);
+ lastIdx = TclIndexDecode(lastIdx, length - end_indicator);
if (lastIdx >= firstIdx) {
numToDelete = lastIdx - firstIdx + 1;
}
@@ -5283,7 +5284,7 @@ TEBCresume(
goto gotError;
}
TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
- NEXT_INST_V(13, opnd, 1);
+ NEXT_INST_V(17, opnd, 1);
} else {
if (Tcl_ListObjReplace(interp,
valuePtr,
@@ -5296,7 +5297,7 @@ TEBCresume(
goto gotError;
}
TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr)));
- NEXT_INST_V(13, opnd-1, 0);
+ NEXT_INST_V(17, opnd-1, 0);
}
}