diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2012-10-25 09:56:35 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2012-10-25 09:56:35 (GMT) |
commit | 8c9ab6bacf51046f3bb722ac655d9a3ddfd237d2 (patch) | |
tree | 06fab6fbf8d94dc0eb2f17c305d8dafffd79fd1c /generic/tclCompCmds.c | |
parent | dd02fe2c44cb40476303d7dacb4bc769c50ba185 (diff) | |
download | tcl-8c9ab6bacf51046f3bb722ac655d9a3ddfd237d2.zip tcl-8c9ab6bacf51046f3bb722ac655d9a3ddfd237d2.tar.gz tcl-8c9ab6bacf51046f3bb722ac655d9a3ddfd237d2.tar.bz2 |
Added compilation of [namespace code] (except for gnarly edge cases).
Diffstat (limited to 'generic/tclCompCmds.c')
-rw-r--r-- | generic/tclCompCmds.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index bba5384..66bc5f0 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -4040,6 +4040,56 @@ TclCompileNamespaceCurrentCmd( } int +TclCompileNamespaceCodeCmd( + Tcl_Interp *interp, /* Used for error reporting. */ + 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 */ + + if (parsePtr->numWords != 2) { + return TCL_ERROR; + } + tokenPtr = TokenAfter(parsePtr->tokenPtr); + + /* + * The specification of [namespace code] is rather shocking, in that it is + * supposed to check if the argument is itself the result of [namespace + * code] and not apply itself in that case. Which is excessively cautious, + * but what the test suite checks for. + */ + + if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD || (tokenPtr[1].size > 20 + && strncmp(tokenPtr[1].start, "::namespace inscope ", 20) == 0)) { + /* + * Technically, we could just pass a literal '::namespace inscope ' + * term through, but that's something which really shouldn't be + * occurring as something that the user writes so we'll just punt it. + */ + + return TCL_ERROR; + } + + /* + * Now we can compile using the same strategy as [namespace code]'s normal + * implementation does internally. Note that we can't bind the namespace + * name directly here, because TclOO plays complex games with namespaces; + * the value needs to be determined at runtime for safety. + */ + + PushLiteral(envPtr, "::namespace", 11); + PushLiteral(envPtr, "inscope", 7); + TclEmitOpcode( INST_NS_CURRENT, envPtr); + CompileWord(envPtr, tokenPtr, interp, 1); + TclEmitInstInt4( INST_LIST, 4, envPtr); + return TCL_OK; +} + +int TclCompileNamespaceUpvarCmd( Tcl_Interp *interp, /* Used for error reporting. */ Tcl_Parse *parsePtr, /* Points to a parse structure for the command |