windley@iris.ucdavis.edu (Phil Windley) (06/03/88)
In article <213@lafcol.UUCP> pilgrimk@lafcol.UUCP (Pilgrim Kenwyn A) writes: >Has anyone tried to pass procedures or functions as parameters within >user written procedures? Yes, see my example below. > For example, the write(ln) procedure can be >used with functions > > e.g. write(Centered(Message)) > -where Centered is a user-written function > with Message as a parameter > I don't understand your example. It seems that Centered(Message) will be evaluated and the result sent to write(), no magic here. From your first question I presume you want to do something like this: ------------ cut here -------------------------------- program sumtest(input, output); function sum(function term(x: integer): integer; a: integer; function next(y: integer): integer; b: integer):integer; begin if (a > b) then sum := 0 else sum := term(a) + sum(term, next(a), next, b); end; function sumCubes(a: integer; b: integer): integer; function cube(x:integer):integer; begin cube := x * x * x; end; function onePlus(x: integer): integer; begin onePlus := x + 1 end; begin sumCubes := sum(cube, a, onePlus, b); end; begin writeln(sumCubes(1,10)); end. --------------- end of example ------------------- Note that sum() is a function that takes two functions as parameters. We can define sumCubes() using sum(). (I have an example using sum() to do integration as well.) This program compiles on Berkeley pascal and as far as I know uses no non-standard Pascal constructs. Phil Windley | windley@iris.ucdavis.edu Robotics Research Lab | ucbvax!ucdavis!iris!windley University of California, Davis |
abcscnuk@csuna.UUCP (News Manager) (06/08/88)
In article <2165@ucdavis.ucdavis.edu> windley@iris.UUCP (Phil Windley) writes: >In article <213@lafcol.UUCP> pilgrimk@lafcol.UUCP (Pilgrim Kenwyn A) writes: >>Has anyone tried to pass procedures or functions as parameters within >>user written procedures? > >Yes, see my example below. > >> For example, the write(ln) procedure can be >>used with functions >> >> e.g. write(Centered(Message)) >> -where Centered is a user-written function >> with Message as a parameter >> > >I don't understand your example. It seems that Centered(Message) will be >evaluated and the result sent to write(), no magic here. To paraphrase the previous poster, "Centered(Message)" is an expression, which is passed to "Centered." This is different from passing a function as a parameter. The example passed the value returned from the function, not the function itself. The example given is effectively no different from: var str : string; (* assuming Turbo Pascal 4.0 *) ... str := Centered(Message); write(str); > >From your first question I presume you want to do something like this: (* example deleted *) >--------------- end of example ------------------- > >Note that sum() is a function that takes two functions as parameters. We >can define sumCubes() using sum(). (I have an example using sum() to do >integration as well.) This program compiles on Berkeley pascal and as far >as I know uses no non-standard Pascal constructs. > > >Phil Windley | windley@iris.ucdavis.edu >Robotics Research Lab | ucbvax!ucdavis!iris!windley >University of California, Davis | If your compiler is a REAL pascal compiler, it would have this feature, if it doesn't, well, I'd consider it to be Wirth-less :-) (sorry I couldn't resist). Putting all the joking aside, TP4 isn't all that bad, except for a few features of standard not being implemented. If you look carefully at the manual for Turbo (Appendix B p 532) you'll see it clearly stated that procedural or functional parameters are not allowed in Turbo. The only way I could suggest it would be done is to do something along these lines: - Where you might use a procedure or function parameter (in a standard pascal program), do the following: procedure foo( function bar : integer); (* standard *) | change to V procedure foo( bar : pointer ); (* turbo 4.0 *) - In the body of the procedure or function that uses a procedure or function parameter, you'll then have to make sure that all the necessary parameters are pushed on the stack before a doing a call (either near or far, depending on how you want it, but make sure that use the right one) to the passed routine (the pointer to the function or procedure) by using the "inline" directive. I don't have the necessary code with me right now... Make sure that you handle function calls and procedure calls appropriately, (I don't recall right off hand where the return value of a function is returned, so you'll have to find out yourself). Since Turbo 4.0 allows inline macros, you could define one for doing a near or far call. Also, if the passed function or procedure expects parameters, you have to PUSH the appropriate stuff onto the stack (by using inline's) before you perform a near or far call to it. - Pass the address of the procedure or functions using the '@' operator in the main program: foo(@plbbt); With this approach you could get procedural and functional parameters to work in Turbo, but the only problem is that YOU have to make sure that when you want to pass a function that you are passing one, and not a procedure, and likewise for the other case, otherwise this would cause some pretty strange things to happen. If anybody knows of a better way, (besides using a different compiler) let me know. //-n-\\ Naoto Kimura _____---=======---_____ (csun!csuna!abcscnuk) ====____\ /.. ..\ /____==== // ---\__O__/--- \\ Enterprise... Surrender or we'll \_\ /_/ send back your *&^$% tribbles !!
maurice@xanth.cs.odu.edu (Dale Ross Maurice) (06/08/88)
In article <12387@cci632.UUCP>: >would be necessary. the procedure "call" would be an assembly macro (inline) >which T$ supports (about time!). Although I don't have specific code for >"call", on an 80x86 it could be done with: > CALL DWORD PTR [BP+{offset of A on stack}] > This is off the top of my head, so don't pound on me if it is wrong. The easy way is as such: (This assumes no passing of varibles of course) Var ProcPtr : Pointer; . . ProcPtr := @ProcName; Inline($FF/$1E/ProcPtr); { Call Far [ProcPtr] } . . [Any responses to this will have to wait 3 weeks. It's vacation time again!] -- uslessnessuselessnessuselessnessuselessnessuselessnessuselessnessuselessnesusel * Dale Ross Maurice UUCP: maurice@xanth.UUCP e * Old Dominion University or: ...!uunet!xanth!maurice s s BIRTHRIGHT PARTY IN SUPPORT New ARPA: maurice@cs.edu.odu s s OF THE SPACE EFFORT Old ARPA: maurice%xanth.UUCP@SUN.COM n enesselesussensselesussensselesussensselesussensselesussensselesussensselesusse
agollum@engr.uky.edu (Kenneth Herron) (06/10/88)
>>>Has anyone tried to pass procedures or functions as parameters within >>>user written procedures? >If you >look carefully at the manual for Turbo (Appendix B p 532) you'll see it >clearly stated that procedural or functional parameters are not allowed >in Turbo. (Actually it's page 520) Well, the database toolbox SORT unit manages it. It's kinda tricky though...let's see how well I can describe it without violating their copyright on the source code :-) 1) Define your procedures/functions like this: {$F+} {this is required} Procedure Foo; begin [...] end; {foo} Function Bar(var X, Y: byte): boolean; begin [...] end; {bar} {$F-} 2) Declare a pointer like this var GluePtr: Pointer; { generic pointer type } 3) Declare a function or procedure like this, with GluePtr declared outside it: {$F+} procedure CallProc; inline($FF/$1E/GluePtr); {CALL DWORD PTR GluePtr} function CallFunc(var x, y: byte):boolean; inline($FF/$1E/GluePtr); {CALL DWORD PTR GluePtr} {$F-} Note the actual parameter list should exactly match the parameter list of the function/procedure pointed to by GluePtr. You'll need to declare a different CallProc (with different names, natch) for a procedure with a different paramater list. Same for CallFunc. 4) Call the darn thing like this: GluePtr := @Foo; {Foo is a procedure with no arguments} CallProc; {Foo will be executed} GluePtr := @Bar; {Bar is a procedure with two byte args, boolean return} if CallFunc(x,y) then... For a more real-world example, check out the toolbox. Kenneth Herron
conliffe@caen.engin.umich.edu (Darryl C. Conliffe) (06/12/88)
In article <2165@ucdavis.ucdavis.edu>, windley@iris.ucdavis.edu (Phil Windley) writes: > > From your first question I presume you want to do something like this: > >[ code deleted ] > > > Note that sum() is a function that takes two functions as parameters. We > can define sumCubes() using sum(). (I have an example using sum() to do > integration as well.) This program compiles on Berkeley pascal and as far > as I know uses no non-standard Pascal constructs. > > > Phil Windley | windley@iris.ucdavis.edu > Robotics Research Lab | ucbvax!ucdavis!iris!windley > University of California, Davis | Apollo Pascal also compiles and executes without special options. -- ___________________ Darryl C. Conliffe conliffe@caen.engin.umich.edu (313) 721-6069 -------------------