summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-12-11 15:19:38 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-12-11 15:19:38 (GMT)
commitb96a5cc09f4f051a6b7a85a9a240470e6f5d5553 (patch)
treeb65175d71ad13ddff7433d7e1ff90ab39eadf4dd
parent6e36638f7c05fb239d0b0d56fee36f8b2c62bcd1 (diff)
downloadtcl-b96a5cc09f4f051a6b7a85a9a240470e6f5d5553.zip
tcl-b96a5cc09f4f051a6b7a85a9a240470e6f5d5553.tar.gz
tcl-b96a5cc09f4f051a6b7a85a9a240470e6f5d5553.tar.bz2
Similar revisions to [dict incr] compiler.
-rw-r--r--generic/tclCompCmds.c60
1 files changed, 22 insertions, 38 deletions
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
index e0dee13..33598e7 100644
--- a/generic/tclCompCmds.c
+++ b/generic/tclCompCmds.c
@@ -707,20 +707,31 @@ TclCompileDictIncrCmd(
* compiled. */
CompileEnv *envPtr) /* Holds resulting instructions. */
{
- Proc *procPtr = envPtr->procPtr;
- DefineLineInformation; /* TIP #280 */
Tcl_Token *varTokenPtr, *keyTokenPtr;
- int dictVarIndex, nameChars, incrAmount;
- const char *name;
+ int dictVarIndex, incrAmount, isScalar, isSimple;
+ DefineLineInformation; /* TIP #280 */
/*
* There must be at least two arguments after the command.
*/
- if (parsePtr->numWords < 3 || parsePtr->numWords > 4 || procPtr == NULL) {
+ if (parsePtr->numWords < 3 || parsePtr->numWords > 4) {
return TCL_ERROR;
}
+
+ /*
+ * The dictionary variable must be a local scalar that is knowable at
+ * compile time; anything else exceeds the complexity of the opcode. So
+ * discover what the index is.
+ */
+
varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+ PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR,
+ &dictVarIndex, &isSimple, &isScalar, 1);
+ if (!isScalar || dictVarIndex < 0) {
+ return TCL_ERROR;
+ }
+
keyTokenPtr = TokenAfter(varTokenPtr);
/*
@@ -728,23 +739,12 @@ TclCompileDictIncrCmd(
*/
if (parsePtr->numWords == 4) {
- const char *word;
- int numBytes, code;
- Tcl_Token *incrTokenPtr;
- Tcl_Obj *intObj;
-
- incrTokenPtr = TokenAfter(keyTokenPtr);
- if (incrTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_ERROR;
- }
- word = incrTokenPtr[1].start;
- numBytes = incrTokenPtr[1].size;
-
- intObj = Tcl_NewStringObj(word, numBytes);
- Tcl_IncrRefCount(intObj);
- code = TclGetIntFromObj(NULL, intObj, &incrAmount);
- TclDecrRefCount(intObj);
- if (code != TCL_OK) {
+ Tcl_Token *incrTokenPtr = TokenAfter(keyTokenPtr);
+ Tcl_Obj *intObj = Tcl_NewObj();
+ int fail = (!TclWordKnownAtCompileTime(incrTokenPtr, intObj)
+ || TCL_ERROR == TclGetIntFromObj(NULL, intObj, &incrAmount));
+ Tcl_DecrRefCount(intObj);
+ if (fail) {
return TCL_ERROR;
}
} else {
@@ -752,22 +752,6 @@ TclCompileDictIncrCmd(
}
/*
- * The dictionary variable must be a local scalar that is knowable at
- * compile time; anything else exceeds the complexity of the opcode. So
- * discover what the index is.
- */
-
- if (varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
- return TCL_ERROR;
- }
- name = varTokenPtr[1].start;
- nameChars = varTokenPtr[1].size;
- if (!TclIsLocalScalar(name, nameChars)) {
- return TCL_ERROR;
- }
- dictVarIndex = TclFindCompiledLocal(name, nameChars, 1, procPtr);
-
- /*
* Emit the key and the code to actually do the increment.
*/