Recent

Author Topic: No formal parameters of procedure or function form?  (Read 3779 times)

nagle

  • Newbie
  • Posts: 4
No formal parameters of procedure or function form?
« on: January 09, 2017, 09:10:08 pm »
I'm converting a large 1980s system written in Berkeley Pascal to FreePascal. It makes heavy use of formal parameters which are procedures, like this:

    procedure vardrive(procedure eachvar(v: varnodep));

(Entire source file here.)

This is standard ISO Pascal, per section 6.6.3.1 of the ISO standard.. FreePascal doesn't seem to support those, per http://www.freepascal.org/docs-html/3.0.0/ref/refse90.html#x175-19700014.4)

Is there a standard workaround for this? Thanks.

(The program is a proof of correctness system for a dialect of Pascal. See https://github.com/John-Nagle/pasv. Conversion was going well, with the first pass working, until this obstacle.)
« Last Edit: January 09, 2017, 09:12:01 pm by nagle »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11452
  • FPC developer.
Re: No formal parameters of procedure or function form?
« Reply #1 on: January 09, 2017, 09:28:58 pm »
If you care about ISO dialect, you need to explicitely enable ISO mode, since mainline Pascal versions nowadays are Borland (Turbo Pascal, Delphi), not ISO compatible.

You can enable iso mode with parameter -Miso or using {$mode iso}. If that doesn't help, the Borland compatible way is to define the procedure as procedural type first.

Code: Pascal  [Select][+][-]
  1. type TEachProc = procedure (v:varnodep);
  2.  
  3. procedure vardrive(eachvar:TEachproc);

I tried to compile the file but it complained about undeclared variable "SINK" on the first line.

As FPC is traditionally a Borland compatible, the ISO mode is fairly new.
« Last Edit: January 09, 2017, 09:30:31 pm by marcov »

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: No formal parameters of procedure or function form?
« Reply #2 on: January 09, 2017, 09:37:06 pm »
Indeed, as marcov wrote you can declare the procedure as type in order to pass it along.

However a small iso mode example compiled for me without issues (fpc 3.0):
Code: Pascal  [Select][+][-]
  1. program test;
  2.  
  3. {$MODE ISO}
  4.  
  5. type
  6.   varnodep = pointer;
  7.  
  8. procedure ThisVar(v: varnodep);
  9. begin
  10.   Writeln('ThisVar');
  11. end;
  12.  
  13. procedure vardrive(procedure eachvar(v: varnodep));
  14. begin
  15.   eachvar(nil);
  16. end;
  17.  
  18. begin
  19.   vardrive(ThisVar);
  20. end.
  21.  

I haven't tried the complete source though but, you can always attempt to give it a go.

nagle

  • Newbie
  • Posts: 4
Re: No formal parameters of procedure or function form?
« Reply #3 on: January 09, 2017, 11:20:37 pm »
Thanks. 

I tried ISO mode, and it helps some.  But every place an enum is written with "write" or "writeln", I get the error message:

    p2trvar.i(29,9) Fatal: Unknown compilerproc "fpc_write_text_enum_iso". Check if you use the correct run time library.

This is at compile time, not link or run time. Is ISO mode output of enums unimplemented?

I'll try to convert the code to use Free Pascal's standard mode. I already changed "integer" to "longint" everywhere, got rid of old-style indirection on file variables, got rid of "get" and "put", switched to the newer form of "reset" with "assign", and fixed forward declared functions and procedures to duplicate the forward declaration at the actual declaration. So I may as well continue in that direction rather than trying to deal with obscure ISO mode problems.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: No formal parameters of procedure or function form?
« Reply #4 on: January 10, 2017, 12:29:11 am »
iso mode is a (fairly new) work in progress. So yes, it might be that some things are currently unsupported or not working as expected.

In case you bothered to convert then i can only encourage that, and would perhaps be the better deal in the end (that is, if you do not care about iso compatibility).

nagle

  • Newbie
  • Posts: 4
Re: No formal parameters of procedure or function form?
« Reply #5 on: January 10, 2017, 01:15:56 am »
I'm converting to Free Pascal's native mode as much as possible.

Ran into a closure problem.

p2dump.i(245,27) Error: Incompatible type for arg no. 1: Got "<address of procedure(varnodep) is nested;Register>", expected "<procedure variable type of procedure(varnodep);Register>"

This program has lots of "drive" procedures which iterate over complex data structures and call a procedure for each one. By declaring a procedure type, I can get that to work.

Code: Pascal  [Select][+][-]
  1. type
  2. pvarnodep = procedure(v: varnodep);         { procedure param }
  3. ...
  4. procedure vardrive(eachvar: pvarnodep);    { called for each var }
  5. begin
  6. ...
  7. end;
  8.  

So far so good. But here's some code that uses it. There's an outer procedure, with a file argument where the output is supposed to go. There's an inner procedure, "dumpvarowner", which imports that variable from the outer procedure scope. Then "dumpvarowner" is passed to "vardrive".

That's a closure, and Free Pascal doesn't like it.

Code: Pascal  [Select][+][-]
  1. {
  2.     dumpvarownership  --  dump variable ownership data
  3. }
  4. procedure dumpvarownership(var f: text);    { output file }
  5. {
  6.     dumpvarowner  --  dump ownership data for one variable
  7. }
  8. procedure dumpvarowner(v: varnodep);
  9. begin
  10.     write(f,' ':8,v^.vardata.itemname,' ':4);
  11.     ...
  12. end {dumpvarowner};
  13. begin {dumpvarownership}
  14.     vardrive(@dumpvarowner);
  15.     writeln(f);
  16. end {dumpvarownership};
  17.  

This is really a closure - a passed scope with access to an outer scope. (Closures, lambdas, and anonymous functions are not the same thing.)

This program is full of this kind of construct. It's something that was done before objects were invented.

I tried putting

Code: Pascal  [Select][+][-]
  1. {$MODESWITCH NESTEDPROCVARS}

at the beginning of the program, and adding "is nested" to the procedure pointer type declaration.

Code: Pascal  [Select][+][-]
  1. pvarnodep = procedure(v: varnodep) is nested;

Now all the closures are accepted by the compiler. Not ready to run yet; a few more minor problems remain. Thanks.



 

TinyPortal © 2005-2018