Quote:
>I was thinking of an approach where you can detect if a routine exists
>(during runtime) , detect the adress of it and call it.
>There must be a way to do this ?. Or not ??
There are probably several ways to do this, but you're asking for an optimized
method of implementing an extremely inefficient coding design (a
self-interpretive program).
One thing you could do is put at the top of each subroutine some assignment
statement that looks like:
LET A$="wierdlyconfiguredstring"
Then, you can look at the executable file at run-time for this string value.
I suppose the logical thing to make these strings would be the names of the
subroutines, but if you use short subroutine names, there is a chance that you
might accidentally "duplicate" those values in your compiled code (somehow,
though I doubt it would be very likely).
Note that this method would require a lot of vicious disk I/O, though you
could build a string at run-time that contained the name of each routine
previously invoked and use INSTR() to decide whether you've already found it.
You could also build a string to indicate which routines were NOT present, to
minimize disk I/O for repeated failures.
However, you might waste a lot of precious memory by doing this.
Here are some less desirable ideas to consider, in case they can be
implemented more easily than I think is possible:
You might look at using numeric variables as boolean indicators. For
instance, suppose you have a subroutine named GOOP and you want to know if
GOOP is available at run-time. Do:
if GOOP then GOOP(params...)
You would have to include a line at the top of the program that says:
LET GOOP = 1
Of course, this is impracticle with hundreds of subroutines, but you could
probably organize them in some sort of collating sequence and then assign a
string of 1s and 0s to a single variable at the top of the program. If the
corresponding "1" is in the string, you know the subroutine is there.
Quote:
>Then i want to take it even a step further.
>I want to implement an interpreter that can execute basic BASIC commands like
>print,cls,input,save,load,goto,open a file , write to a file etc ...
>That way the user can write small programs inside my program.( Look at them
>as scripts or macros)
What a pity that
powerbasic and the other Microsoft BASICs don't implement the
Business BASIC EXECUTE command. This command takes a string and treats it as
if it were keyboard input. You could, in theory, write a Business BASIC
program that would make use of the subroutine name and place a GOSUB in front
of it to "execute" a GOSUB to that routine.
This still doesn't tell you whether the routine is present in the program, but
you could always put an error branch on the EXECUTE line to pass control of
the program to some routine that could say: "This routine is not present."
Quote:
>This program of mine controls equipment attached to the pc. normally the
>program is interacting with the user via menus.
>For serviceing purposes i want to give the operator the possibility to write
>small programs that make the machine do something. But i do not want to give
>him control of the entire machine. He would onyl be able to execute the
>standard functions of the control library. This will prevent him form
>executing commands that could{*filter*}up the whole machine. That is the reason
>why i will not write my program in an interpreted basic nor give him a
>compiler where he can patch the program ,recompile and run it.
Well, you could get a run-time module for some of the interpretive BASICs,
which doesn't provide a READY> prompt for the user. That effectively locks
them out of messing with your code.
What you might want to look at, however, is writing a two-stage program that
interprets your subroutines as well as the user input. This will not execute
as fast as you may want it to, but if you code it well, and depending on what
the routines are expected to do, you may not have any complaints.
The subroutines should be written in a macro language for which all the
appropriate subroutines are present in your "interpreter". Try to keep the
command set small. Also, use as many paramter lists as you can, so you can
dynamically create "variables" at run-time and associate the names used in
your sub-routines with the specific addresses you create through VARPTR (my
syntax is rusty, so check me here) or a similar method like use of data types
with pointers.
For instance, suppose your macro language supports an "ADD" command. You
could make the syntax to be:
ADD(one,two,three)
Now, let's say you always store the result in the first parameter.
So, you parse the line to see how many parameters there are, creating a
"stack" of the secondary parameters.
You should get three parameters from the parse:
"one", "two", and "three"
"two" and "three" will be in your secondary stack
Then you check your variable table for the name "one". If it's there, you get
the address for that variable and use it. If it's not there, you create the
"variable" and set it to 0. "Creation" implies adding the variable into the
table.
Then you parse your stack and for each item in it you retrieve the associated
variable (or create a new one, initializing it to zero) and add that value to
the variable for "one".
NOTE: If you want to use constants, your parser will either have to look for
something that tags them as constants or you will have to restrict variable
names to start only with letters, and assume anything else is a constant.
You can also implement a label table so that your macro language can support
labels.
Frankly, I think I would try what I suggested at the start of this article,
and if that didn't work, I'd just invest in an interpretive BASIC that lets
me lock out the user (assuming you have the money for that).
--
++ ++ "Well Samwise: What do you think of the elves now?"
++ ++------------------------------------------------------