diff -Naur little-lang.orig/tcl/generic/Lcompile.c little-lang.test/tcl/generic/Lcompile.c --- little-lang.orig/tcl/generic/Lcompile.c 2016-06-13 10:16:17.323465900 +0200 +++ little-lang.test/tcl/generic/Lcompile.c 2016-06-13 13:24:12.657345200 +0200 @@ -341,6 +341,9 @@ /* Extract the L state from the interp. */ L = Tcl_GetAssocData(interp, "L", NULL); + /* This will reset a previous syntax error flag */ + L->err = 0; + /* * Verify that lib L was loaded. L fails badly if lib L isn't * there, and this catches cases where the user overrides the diff -Naur little-lang.orig/tk/generic/tkMain.c little-lang.test/tk/generic/tkMain.c --- little-lang.orig/tk/generic/tkMain.c 2016-06-13 10:16:40.906409100 +0200 +++ little-lang.test/tk/generic/tkMain.c 2016-06-13 13:23:04.503270500 +0200 @@ -192,6 +192,7 @@ Tcl_Channel chan; InteractiveState is; + /* * Ensure that we are getting a compatible version of Tcl. */ @@ -387,6 +388,7 @@ * windows left, Tk_MainLoop returns and we exit. */ + Tcl_SetVar(interp, "::L", "0", 0); Tk_MainLoop(); Tcl_DeleteInterp(interp); Tcl_Release(interp); @@ -424,6 +426,9 @@ InteractiveState *isPtr = clientData; Tcl_Channel chan = isPtr->input; Tcl_Interp *interp = isPtr->interp; + Tcl_DString dstr, Ldstr; + Tcl_Obj *LangObj; + int isL = 0; count = Tcl_Gets(chan, &isPtr->line); @@ -445,6 +450,26 @@ } isPtr->gotPartial = 0; + /* + * Check for the #lang comments and sub them out for + * meaningful commands. + */ + LangObj = Tcl_GetVar2Ex(interp, "::L", NULL, 0); + Tcl_GetIntFromObj(interp, LangObj, &isL); + Tcl_DStringInit(&dstr); + if (!isL && strlen(cmd) >= 7 && strncasecmp(cmd, "#lang l", 7) == 0) { + cmd = Tcl_DStringAppend(&dstr, "set ::L 1\n", 10); + } else if (isL && strlen(cmd) >= 9 && strncasecmp(cmd, "#lang tcl", 9) == 0) { + cmd = Tcl_DStringAppend(&dstr, "set('::L',0);\n", 14); + } + + if (isL) { + Tcl_DStringInit(&Ldstr); + Tcl_DStringAppend(&Ldstr, "L {", 3); + Tcl_DStringAppend(&Ldstr, cmd, strlen(cmd)-1); + cmd = Tcl_DStringAppend(&Ldstr, "}\n", 2); + } + /* * Disable the stdin channel handler while evaluating the command; * otherwise if the command re-enters the event loop we might process @@ -479,6 +504,12 @@ Prompt(interp, isPtr); } Tcl_ResetResult(interp); + + /* Free dynamic strings */ + Tcl_DStringFree(&dstr); + if (isL) { + Tcl_DStringFree(&Ldstr); + } } /* diff -Naur little-lang.orig/tk/library/console.tcl little-lang.test/tk/library/console.tcl --- little-lang.orig/tk/library/console.tcl 2016-06-13 10:16:42.133502700 +0200 +++ little-lang.test/tk/library/console.tcl 2016-06-13 13:23:38.834558000 +0200 @@ -44,7 +44,7 @@ if {![consoleinterp eval {set tcl_interactive}]} { wm withdraw . } - + consoleinterp eval {set ::L 0} if {[tk windowingsystem] eq "aqua"} { set mod "Cmd" } else { @@ -247,6 +247,18 @@ } elseif {[info complete $cmd]} { .console mark set output end .console tag delete input + + # Check for #lang comments and replace them for meaningful commands + set isL [consoleinterp eval {set ::L}] + if {!$isL && [string equal -nocase -length 7 "#lang l" $cmd]} { + set cmd "set ::L 1\n" + } elseif {$isL && [string equal -nocase -length 9 "#lang tcl" $cmd]} { + set cmd "set('::L',0);\n" + } + if {$isL} { + set cmd "L [list $cmd]" + } + set result [consoleinterp record $cmd] if {$result ne ""} { puts $result