diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2012-10-24 09:50:09 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2012-10-24 09:50:09 (GMT) |
commit | c450611fa62e31564086453d6921a47bd7fb9044 (patch) | |
tree | 619b0222ff0ba50faefe176fa0080011972e3d07 /generic | |
parent | 0dfd8fc69d7d64b99cf8585a29cfe35133865249 (diff) | |
download | tcl-c450611fa62e31564086453d6921a47bd7fb9044.zip tcl-c450611fa62e31564086453d6921a47bd7fb9044.tar.gz tcl-c450611fa62e31564086453d6921a47bd7fb9044.tar.bz2 |
Added compilation of [dict unset]; the bytecode needed already existed anyway.
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclCompCmds.c | 61 | ||||
-rw-r--r-- | generic/tclDictObj.c | 2 | ||||
-rw-r--r-- | generic/tclInt.h | 3 |
3 files changed, 65 insertions, 1 deletions
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 61f7988..fc60016 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -787,6 +787,67 @@ TclCompileDictGetCmd( } int +TclCompileDictUnsetCmd( + Tcl_Interp *interp, /* Used for looking up stuff. */ + 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. */ +{ + Tcl_Token *tokenPtr; + DefineLineInformation; /* TIP #280 */ + int i, dictVarIndex, nameChars; + const char *name; + + /* + * There must be at least one argument after the variable name for us to + * compile to bytecode. + */ + + if (parsePtr->numWords < 3) { + 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. + */ + + tokenPtr = TokenAfter(parsePtr->tokenPtr); + if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { + return TCL_ERROR; + } + name = tokenPtr[1].start; + nameChars = tokenPtr[1].size; + if (!TclIsLocalScalar(name, nameChars)) { + return TCL_ERROR; + } + dictVarIndex = TclFindCompiledLocal(name, nameChars, 1, envPtr); + if (dictVarIndex < 0) { + return TCL_ERROR; + } + + /* + * Remaining words (the key path) can be handled normally. + */ + + for (i=2 ; i<parsePtr->numWords ; i++) { + tokenPtr = TokenAfter(tokenPtr); + CompileWord(envPtr, tokenPtr, interp, i); + } + + /* + * Now emit the instruction to do the dict manipulation. + */ + + TclEmitInstInt4( INST_DICT_UNSET, parsePtr->numWords-2, envPtr); + TclEmitInt4( dictVarIndex, envPtr); + return TCL_OK; +} + +int TclCompileDictForCmd( Tcl_Interp *interp, /* Used for looking up stuff. */ Tcl_Parse *parsePtr, /* Points to a parse structure for the command diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index d1087b2..ea9411c 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -104,7 +104,7 @@ static const EnsembleImplMap implementationMap[] = { {"replace", DictReplaceCmd, NULL, NULL, NULL, 0 }, {"set", DictSetCmd, TclCompileDictSetCmd, NULL, NULL, 0 }, {"size", DictSizeCmd, NULL, NULL, NULL, 0 }, - {"unset", DictUnsetCmd, NULL, NULL, NULL, 0 }, + {"unset", DictUnsetCmd, TclCompileDictUnsetCmd, NULL, NULL, 0 }, {"update", DictUpdateCmd, TclCompileDictUpdateCmd, NULL, NULL, 0 }, {"values", DictValuesCmd, NULL, NULL, NULL, 0 }, {"with", DictWithCmd, TclCompileDictWithCmd, NULL, NULL, 0 }, diff --git a/generic/tclInt.h b/generic/tclInt.h index 860755a..ea712b8 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3519,6 +3519,9 @@ MODULE_SCOPE int TclCompileDictLappendCmd(Tcl_Interp *interp, MODULE_SCOPE int TclCompileDictSetCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); +MODULE_SCOPE int TclCompileDictUnsetCmd(Tcl_Interp *interp, + Tcl_Parse *parsePtr, Command *cmdPtr, + struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileDictUpdateCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); |