The original implementation of Tcl in Javascript was parsing every statement byte by byte when executing Tcl code. When starting I used that for a while too, but when trying to implement itcl in Tcl, there were big performance problems. One point was the complete parsing of a statement when executing Tcl code, second problem was having itcl implemented in Tcl, which forced a twice time interpretation when interpreting a class definition once by javascript for running Tcl second by Tcl for parsing itcl.
So I decided to write the itcl interpreter in javascript too and as a second issue for better performance to parse initial Tcl code only once and then keep something like an intermediate code a “partially parsed” form of Tcl statements.
Because of Tcl's dynamic structure, that partially parsed form did not extend variable references or commands in braces etc. but did mostly a tokenizing, so the low level parsing had to be done only once. That did help a lot to increase performance. Nevertheless it would be useful in the future to have something similar to the Tcl bytecode and to have an interpreter for that intermediate format written in javascript. Designing and implementing such an intermediate language and an interpreter for it could perhaps be a future GSoC project.
There are three types that are used for a partially parsed Tcl statement. A Tcl statement is mapped to a “stmt” type, the parts of a Tcl statement like the command name and the params are represented as „word“ (statement part) and because a statement part can be composed of different sub parts. A sub part - named a “word_part” - is available, that can be:
To hold that parsed information there are 3 different javascript Objects:
see below for details.
Later on there was another improvement of performance in implementing a cache for variable and command access depending on the callframe and using some epoch mechanism like it is used in TclOO for determining if the cache is still up-to-date. As every command and variable object (javascript Object) has an id in it the maximum id for variables/commands is used to determine, if the cache is still usable, as creating a variable/command modifies that maximum id and renaming/deleting a variable/command has to remove the corresponding cache entries.
Implementing that cache mechanism together with more often using the partially parsed statements gave a performance improvement of 400% for simple setting or getting a variable!
“There is still some room for improvements” - as one of my former colleagues used to say - concerning performance.
(Part of itcl in Javascript Paper)