summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--generic/tclCompCmds.c90
2 files changed, 91 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 0207c97..425bd24 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -20,9 +20,13 @@
* tests/parse.test: Tests for expanded literals quoting detection.
+ * generic/tclCompCmds.c: New TclFindElement() is also a better
+ fit for the [switch] compiler.
+
* generic/tclInt.h: Replace TclCountSpaceRuns() with
* generic/tclListObj.c: TclMaxListLength() which is the function we
* generic/tclUtil.c: actually want.
+ * generic/tclCompCmds.c:
2011-04-28 Don Porter <dgp@users.sourceforge.net>
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
index ddd2242..81fd615 100644
--- a/generic/tclCompCmds.c
+++ b/generic/tclCompCmds.c
@@ -3907,7 +3907,9 @@ TclCompileSwitchCmd(
int savedStackDepth = envPtr->currStackDepth;
int noCase; /* Has the -nocase flag been given? */
int foundMode = 0; /* Have we seen a mode flag yet? */
+#if 0
int isListedArms = 0;
+#endif
int i, valueIndex;
DefineLineInformation; /* TIP #280 */
int* clNext = envPtr->clNext;
@@ -4047,6 +4049,7 @@ TclCompileSwitchCmd(
*/
if (numWords == 1) {
+#if 0
Tcl_DString bodyList;
const char **argv = NULL, *tokenStartPtr, *p;
int bline; /* TIP #280: line of the pattern/action list,
@@ -4085,7 +4088,9 @@ TclCompileSwitchCmd(
return TCL_ERROR;
}
+#if 0
isListedArms = 1;
+#endif
bodyTokenArray = (Tcl_Token *) ckalloc(sizeof(Tcl_Token) * numWords);
bodyToken = (Tcl_Token **) ckalloc(sizeof(Tcl_Token *) * numWords);
bodyLines = (int *) ckalloc(sizeof(int) * numWords);
@@ -4178,6 +4183,74 @@ TclCompileSwitchCmd(
ckfree((char *) bodyNext);
return TCL_ERROR;
}
+#else
+ CONST char *bytes;
+ int maxLen, numBytes;
+ int bline; /* TIP #280: line of the pattern/action list,
+ * and start of list for when tracking the
+ * location. This list comes immediately after
+ * the value we switch on. */
+
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+ return TCL_ERROR;
+ }
+ bytes = tokenPtr[1].start;
+ numBytes = tokenPtr[1].size;
+
+ /* Allocate enough space to work in. */
+ maxLen = TclMaxListLength(bytes, numBytes, NULL);
+ if (maxLen < 2) {
+ return TCL_ERROR;
+ }
+ bodyTokenArray = (Tcl_Token *) ckalloc(sizeof(Tcl_Token) * maxLen);
+ bodyToken = (Tcl_Token **) ckalloc(sizeof(Tcl_Token *) * maxLen);
+ bodyLines = (int *) ckalloc(sizeof(int) * maxLen);
+ bodyNext = (int **) ckalloc(sizeof(int*) * maxLen);
+
+ bline = mapPtr->loc[eclIndex].line[valueIndex+1];
+ numWords = 0;
+
+ while (numBytes > 0) {
+ CONST char *prevBytes = bytes;
+ int literal;
+
+ if (TCL_OK != TclFindElement(NULL, bytes, numBytes,
+ &(bodyTokenArray[numWords].start), &bytes,
+ &(bodyTokenArray[numWords].size), &literal) || !literal) {
+ abort:
+ ckfree((char *) bodyToken);
+ ckfree((char *) bodyTokenArray);
+ ckfree((char *) bodyLines);
+ ckfree((char *) bodyNext);
+ return TCL_ERROR;
+ }
+
+ bodyTokenArray[numWords].type = TCL_TOKEN_TEXT;
+ bodyTokenArray[numWords].numComponents = 0;
+ bodyToken[numWords] = bodyTokenArray + numWords;
+
+ /*
+ * TIP #280: Now determine the line the list element starts on
+ * (there is no need to do it earlier, due to the possibility of
+ * aborting, see above).
+ */
+
+ TclAdvanceLines(&bline, prevBytes, bodyTokenArray[numWords].start);
+ TclAdvanceContinuations (&bline, &clNext,
+ bodyTokenArray[numWords].start - envPtr->source);
+ bodyLines[numWords] = bline;
+ bodyNext[numWords] = clNext;
+ TclAdvanceLines(&bline, bodyTokenArray[numWords].start, bytes);
+ TclAdvanceContinuations (&bline, &clNext, bytes - envPtr->source);
+
+ numBytes -= (bytes - prevBytes);
+ numWords++;
+ }
+ if (numWords % 2) {
+ goto abort;
+ }
+
+#endif
} else if (numWords % 2 || numWords == 0) {
/*
@@ -4205,8 +4278,11 @@ TclCompileSwitchCmd(
* traces, etc.
*/
- if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD ||
- tokenPtr->numComponents != 1) {
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD
+#if 0
+ || tokenPtr->numComponents != 1
+#endif
+ ) {
ckfree((char *) bodyToken);
ckfree((char *) bodyLines);
ckfree((char *) bodyNext);
@@ -4255,7 +4331,15 @@ TclCompileSwitchCmd(
* but it handles the most common case well enough.
*/
- if (isListedArms && mode == Switch_Exact && !noCase) {
+ if (
+#if 0
+ isListedArms &&
+#endif
+ mode == Switch_Exact
+#if 0
+ && !noCase
+#endif
+ ) {
JumptableInfo *jtPtr;
int infoIndex, isNew, *finalFixups, numRealBodies = 0, jumpLocation;
int mustGenerate, jumpToDefault;