No formal parameters of procedure or function form? lazarus / 62-General ---------------------------------------------------------------------- nagle · 2017-01-09 20:10 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.) ---------------------------------------------------------------------- marcov · 2017-01-09 20:28 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type TEachProc = procedure (v:varnodep); 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. ---------------------------------------------------------------------- molly · 2017-01-09 20:37 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program test; {$MODE ISO} type  varnodep = pointer; procedure ThisVar(v: varnodep);begin  Writeln('ThisVar');end; procedure vardrive(procedure eachvar(v: varnodep));begin  eachvar(nil);end; begin  vardrive(ThisVar);end.  I haven't tried the complete source though but, you can always attempt to give it a go. ---------------------------------------------------------------------- nagle · 2017-01-09 22:20 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 · 2017-01-09 23:29 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 · 2017-01-10 00:15 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 "
", expected "" 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typepvarnodep = procedure(v: varnodep);         { procedure param }...procedure vardrive(eachvar: pvarnodep);    { called for each var }begin...end;  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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {    dumpvarownership  --  dump variable ownership data}procedure dumpvarownership(var f: text);    { output file }{    dumpvarowner  --  dump ownership data for one variable}procedure dumpvarowner(v: varnodep);begin    write(f,' ':8,v^.vardata.itemname,' ':4);    ...end {dumpvarowner}; begin {dumpvarownership}    vardrive(@dumpvarowner);  writeln(f);end {dumpvarownership};  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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$MODESWITCH NESTEDPROCVARS} at the beginning of the program, and adding "is nested" to the procedure pointer type declaration. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i 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.