home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!zaphod.mps.ohio-state.edu!pacific.mps.ohio-state.edu!linac!att!cbnewsm!cbnewsl!att-out!oucsboss!oucsace!tswingle
- From: tswingle@oucsace.cs.ohiou.edu (Tom Swingle)
- Newsgroups: comp.lang.pascal
- Subject: Re: Procedural Variables
- Message-ID: <1992Sep2.233128.8426@oucsace.cs.ohiou.edu>
- Date: 2 Sep 92 23:31:28 GMT
- References: <1992Aug31.145029.16564@doug.cae.wisc.edu>
- Organization: Ohio University CS Dept,. Athens
- Lines: 113
-
- In article <1992Aug31.145029.16564@doug.cae.wisc.edu> chris@castlab.engr.wisc.edu (Christian Rohrmeier) writes:
- >Thanks to all those who sent me replies to my question about dynamically calling
- >a procedure via a variable.
- >
- >It seems that is comes down to procedural variables.
- >
- >The problem is, I can't seem to assign a variable to the proc. variable!
- >
- >Here sample code given to me by Kjell:
- >
- >Program TestProc;
- >
- >Uses Crt;
- >
- >Var Proc: procedure;
- >
- >Begin
- > Proc:= ClrScr;
- > Proc;
- >End;
- >
- >This works. However, if I try Proc:='name_of_my_procedure' or to try and assign a
- >string varibale to it I get a type mismatch.
- >
- >Any ideas from the net?
- >
- >-Chris
-
- This solution is "borrowed" from the comp.lang.c newsgroup, where I have seen
- this question posted many times before.
-
- The problem is that, except for debugging information that may or may not be
- included in the executable file that you compile to, the names of your
- procedures or functions no longer exist. Your program must provide the
- correlation between the name of the subroutine being called and its location.
- The best way to do this is to bind them together as fields in an array of
- records as follows:
-
- -- Begin included program --
-
- program showprocnames;
-
- uses crt;
-
- const
- numcommands=4;
- commandlist:array[1..numcommands] of record
- proc:procedure;
- name:string;
- end=((proc:clrscr;name:'clrscr'),
- (proc:clreol;name:'clreol'),
- (proc:insline;name:'insline'),
- (proc:delline;name:'delline'));
-
- var
- command:string;
- i,line:integer;
-
- begin
- repeat
- clrscr;
- writeln('Enter a command below from the following list:');
- writeln;
- for i:=1 to numcommands do writeln(i:3,'. ',commandlist[i].name);
- writeln;
- writeln('I''ll put the cursor on the line below and execute it:');
- line:=wherey; { Figure out what line to put the cursor on }
- writeln('Your command will be executed here.');
- writeln('We are trained professionals. Don''t try this at home :-).');
- writeln('This is just filler to show the effect of the command.');
- writeln;
- write('Enter your command or "quit" to quit: ');
- readln(command);
- if command<>'quit' then
- for i:=1 to numcommands do
- if commandlist[i].name=command then begin
- gotoxy(1,line); { Go to the appropriate line }
- commandlist[i].proc; { Do the command }
- gotoxy(1,25);
- write('Command executed. Press any key...');
- while readkey=#0 do; { Empty keypress read }
- end;
- until command='quit';
- end.
-
- -- End included program --
-
- The body of the program is really unimportant, it is just to show that it
- works. The important thing to notice is the way I have declared the record to
- be a sort of "lookup table" so you can find what procedure to call when you
- have put your command together.
-
- Note, however, that all the procedures I used here have no parameters. If you
- want to call procedures with parameters, you need to also do the following:
-
- - Declare a procedural type for each combination of number and type of
- parameter you will be encountering, and either declare separate arrays of
- records to hold each type, or use a variant record so you can store all
- of these types in the same data structure.
- - In addition to the name of the procedure, also store the number and types
- of parameters in the data structure somewhere.
- - Be sure you can reference any variables that your procedure call requires,
- possibly by doing the same trick; i.e., keep a list of variable names and
- pointers to those variables.
-
- What you actually end up doing is writing a little mini-interpreter with only
- a subset of commands that are necessary to what you are doing. A pretty
- formidable project if it grows to significant complexity.
- --
- "The problem you are experiencing is | "To be sure of hitting the target,
- not with the network nor with the | shoot first and, whatever you hit,
- station. Please adjust your set." | call it the target."
- More ramblings from: tswingle@oucsace.cs.ohiou.edu/tswingle@bigbird.cs.ohiou.edu
-