From: hachuah on
Hi,

I've been trying to solve this problem for a few weeks already, but
I'm not able to come up with anything yet. Perhaps you guys can help.

I have a file that is a "partial" tcl script written for a proprietary
application. This application has a tcl interpreter built in and can
understand tcl syntax. However, the interpreter can be put in "TCL
mode" or "Native mode". In native mode, there is a set of non-tcl
commands that are available, and in TCL mode, all tcl commands are
available. The keywords "tcl" and "native" are used to switch between
modes.

Therefore, the "partial" tcl script that I have is a mix of tcl and
non-tcl syntax as the script switches between modes. I'm trying to
write a program that hooks on to this script, and changes the
behaviour of certain non-tcl commands (ie. dump some debug data during
certain commands). (I can't change the script itself; there are
hundreds of scripts, and it would be very difficult to modify and
validate all of them).

I tried 2 different approaches so far:

1. Writing an interpreter for this script; ie. parse the file as a
text file line-by-line, intercepting commands and piping the rest to a
tcl interpreter. Unfortunately, this didn't work very well as there
are a lot of tcl constructs that my interpreter has to understand; ie:

if {$foo == 1} {
native
native-command
tcl
}

I can't tell if native-command is being called or not if I'm just
parsing the file.

2. I tried to run everything in tcl; rename "native" to my own proc
that removes all tcl commands and reinstates native-commands that I
wrap around with "unknown", and rename "tcl" to switch everything
back. This doesn't work either, as tcl STILL interprets the [], {} and
I will get errors during:

native-command [blah]

tcl tries to execute blah and fails. The [blah] is actually an
argument to the native-command, which I have implemented in the
unknown proc, but unfortunately the tcl interpreter gets to it first.

So, I'm wondering if there is a way for me to either:

1. Have a proc that is able to access & "readahead" of the
interpreter? OR
2. Make tcl ignore [], {} somehow? dynamically? OR
3. Be able to mark a chunk of code as "data" dynamically during
runtime?

From: Alexandre Ferrieux on
On Aug 9, 4:13 pm, hachuah <hach...(a)gmail.com> wrote:
> Hi,
>
> I've been trying to solve this problem for a few weeks already, but
> I'm not able to come up with anything yet. Perhaps you guys can help.
>
> I have a file that is a "partial" tcl script written for a proprietary
> application. This application has a tcl interpreter built in and can
> understand tcl syntax. However, the interpreter can be put in "TCL
> mode" or "Native mode". In native mode, there is a set of non-tcl
> commands that are available, and in TCL mode, all tcl commands are
> available. The keywords "tcl" and "native" are used to switch between
> modes.
>
> Therefore, the "partial" tcl script that I have is a mix of tcl and
> non-tcl syntax as the script switches between modes. I'm trying to
> write a program that hooks on to this script, and changes the
> behaviour of certain non-tcl commands (ie. dump some debug data during
> certain commands). (I can't change the script itself; there are
> hundreds of scripts, and it would be very difficult to modify and
> validate all of them).
>
> I tried 2 different approaches so far:
>
> 1. Writing an interpreter for this script; ie. parse the file as a
> text file line-by-line, intercepting commands and piping the rest to a
> tcl interpreter. Unfortunately, this didn't work very well as there
> are a lot of tcl constructs that my interpreter has to understand; ie:
>
> if {$foo == 1} {
>    native
>    native-command
>    tcl
>
> }
>
> I can't tell if native-command is being called or not if I'm just
> parsing the file.
>
> 2. I tried to run everything in tcl; rename "native" to my own proc
> that removes all tcl commands and reinstates native-commands that I
> wrap around with "unknown", and rename "tcl" to switch everything
> back. This doesn't work either, as tcl STILL interprets the [], {} and
> I will get errors during:
>
> native-command [blah]
>
> tcl tries to execute blah and fails. The [blah] is actually an
> argument to the native-command, which I have implemented in the
> unknown proc, but unfortunately the tcl interpreter gets to it first.
>
> So, I'm wondering if there is a way for me to either:
>
> 1. Have a proc that is able to access & "readahead" of the
> interpreter? OR
> 2. Make tcl ignore [], {} somehow? dynamically? OR
> 3. Be able to mark a chunk of code as "data" dynamically during
> runtime?

If the native..tcl are consistently at the same nesting level (as in
your [if] example), one simple solution is to preprocess the text, and
replace them with a prefix and an opening and closing braces.
Further assuming that they are recognizable by a trivial regexp (eg
they come alone in a line):

regsub -all -line {^\s*native\s*$} $text "runnative \{" text
regsub -all -line {^\s*tcl\s*$} $text "\}" text

Then you are sure that, at runtime, [runnative] will be passed the
proper blocks of text without unwanted early substitution.

-Alex

From: tom.rmadilo on
On Aug 9, 7:13 am, hachuah <hach...(a)gmail.com> wrote:
> Hi,
>
> I've been trying to solve this problem for a few weeks already, but
> I'm not able to come up with anything yet. Perhaps you guys can help.
>
> I have a file that is a "partial" tcl script written for a proprietary
> application. This application has a tcl interpreter built in and can
> understand tcl syntax. However, the interpreter can be put in "TCL
> mode" or "Native mode". In native mode, there is a set of non-tcl
> commands that are available, and in TCL mode, all tcl commands are
> available. The keywords "tcl" and "native" are used to switch between
> modes.
>
> Therefore, the "partial" tcl script that I have is a mix of tcl and
> non-tcl syntax as the script switches between modes. I'm trying to
> write a program that hooks on to this script, and changes the
> behaviour of certain non-tcl commands (ie. dump some debug data during
> certain commands). (I can't change the script itself; there are
> hundreds of scripts, and it would be very difficult to modify and
> validate all of them).
>
> I tried 2 different approaches so far:
>
> 1. Writing an interpreter for this script; ie. parse the file as a
> text file line-by-line, intercepting commands and piping the rest to a
> tcl interpreter. Unfortunately, this didn't work very well as there
> are a lot of tcl constructs that my interpreter has to understand; ie:
>
> if {$foo == 1} {
>    native
>    native-command
>    tcl
>
> }
>
> I can't tell if native-command is being called or not if I'm just
> parsing the file.
>
> 2. I tried to run everything in tcl; rename "native" to my own proc
> that removes all tcl commands and reinstates native-commands that I
> wrap around with "unknown", and rename "tcl" to switch everything
> back. This doesn't work either, as tcl STILL interprets the [], {} and
> I will get errors during:
>
> native-command [blah]
>
> tcl tries to execute blah and fails. The [blah] is actually an
> argument to the native-command, which I have implemented in the
> unknown proc, but unfortunately the tcl interpreter gets to it first.
>
> So, I'm wondering if there is a way for me to either:
>
> 1. Have a proc that is able to access & "readahead" of the
> interpreter? OR
> 2. Make tcl ignore [], {} somehow? dynamically? OR
> 3. Be able to mark a chunk of code as "data" dynamically during
> runtime?

The fact that the script switches between modes doesn't mean that any
of the script is written in Tcl.

The only solution I can think of is to reproduce the current
application interpreter, which knows about the mode switching and what
to do in native mode...which I assume includes using the original
application to execute the native commands.

From the description it sounds like you want to use scripts written
for one application and somehow use the same scripts in Tcl, just by
replacing the parsing part of the original application's interpreter.
But you still need to execute the commands in either the native
environment or the tcl environment...while maintaining whatever common
state the original interpreter maintained.

Basically you have hundreds of files of source code, but no compiler
or machine to execute the compiled code.


From: Andreas Leitgeb on
hachuah <hachuah(a)gmail.com> wrote:
> if {$foo == 1} {
> native
> native-command [blah]
> tcl
> }
>
> tcl tries to execute blah and fails. The [blah] is actually an
> argument to the native-command, which I have implemented in the
> unknown proc, but unfortunately the tcl interpreter gets to it first.

I'm not sure, if I understood correctly. In native mode, does the
application's interpreter only change the command set, or also the
syntax?
Does native-command expect to see the brackets?

If, within "native" you define a command, or redefine a proc (unknown)
the very next line should be perfectly able to see the changed situation.
so, blah as a command (or the newly setup unknown) *should* be executed.
If that is not so, then it is a bug in your used version of Tcl.
Or perhaps you accidentally tried to define a command literally
named "[blah]" (including brackets) ;-)

If the native mode has entirely different syntax and you really need
to switch off tcl-parsing, then I hope, that Alexander's approach suits
you.