Frank Heckenbach wrote:
Bison (building GPC)
Bison version 2.0 has been released. It can be obtained at ftp://ftp.gnu.org/gnu/bison/bison-2.0.tar.gz. This is now the recommended version for all GPC compilations. Fortunately, we now don't depend on changing alpha/beta versions of bison anymore. Bison is required when building a minimal distribution of GPC (which now doesn't include the Bison generated files anymore, as it did temporarily); when building a full source distribution and not modifying the bison input files (*.y), bison is not strictly needed, but in case of doubt, it can't hurt to install the new bison version.
I am adding a few notes about building on Mac OS X.
The following tools may be needed:
- bison 2.0 a too old version is installed with XCode or OS X ftp://ftp.gnu.org/gnu/bison/bison-2.0.tar.gz
- sed 4.0.x a too old version is installed with XCode or OS X (I use 4.0.5, but I assume later versions work also) ftp://ftp.gnu.org/gnu/sed/
- flex 2.5.27 a too old version is installed with XCode or OS X http://sourceforge.net/project/showfiles.php?group_id=72099
- help2man 1.35 not installed with XCode or OS X ftp://ftp.gnu.org/gnu/help2man/help2man-1.35.1.tar.gz
Configure these tools with --prefix=/usr, configure help2man with --prefix=/usr --enable-nls=no
There is a bug in Mac OS X that causes problems when configuring flex and other tools (see e.g.<http://lists.gnu.org/archive/html/bug-coreutils/2004-08/ msg00039.html>). The system call sysctl ((int[]) {CTL_HW, HW_MACHINE_ARCH}, 2, buffer, &bufsize, 0, 0) returns a negative number, which causes the coreutils command "uname -p" to report "unknown". This confuses config.guess.
To solve the flex configure problem, apply the following patch to the flex 2.5.27 sources:
--- config.guess.orig Fri Feb 18 21:22:32 2005 +++ config.guess Fri Feb 18 21:25:28 2005 @@ -1098,7 +1098,7 @@ EOF echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;; *:Darwin:*:*) - echo `uname -p`-apple-darwin${UNAME_RELEASE} + echo powerpc-apple-darwin${UNAME_RELEASE} exit 0 ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p`
WIth the right tools in place, build the gpc compiler with "make bootstrap" instead of "make". This is necessary because of peculiarities of the apple-gcc system compiler. The alternative is to bootstrap an fsf-gcc compiler on your system first and then use that fsf-gcc compiler for successive builds of gpc (and other gnu packages). Then, successive builds will be faster, because a bootstrap is not needed.
Regards,
Adriaan van Os
Adriaan van Os wrote:
I am adding a few notes about building on Mac OS X.
The following tools may be needed:
- sed 4.0.x
a too old version is installed with XCode or OS X (I use 4.0.5, but I assume later versions work also) ftp://ftp.gnu.org/gnu/sed/
Well, I have 3.02 here (very old) and didn't notice any problems.
- help2man 1.35
not installed with XCode or OS X ftp://ftp.gnu.org/gnu/help2man/help2man-1.35.1.tar.gz
(1.24 here, also ok.)
Frank
Frank Heckenbach wrote:
Adriaan van Os wrote:
I am adding a few notes about building on Mac OS X.
The following tools may be needed:
- sed 4.0.x
a too old version is installed with XCode or OS X (I use 4.0.5, but I assume later versions work also) ftp://ftp.gnu.org/gnu/sed/
Well, I have 3.02 here (very old) and didn't notice any problems.
I don't know what bizarre version of sed Apple distributes - the default system sed on Mac OS X doesn't have a version switch and gpc reports that it is "crippled".
Regards,
Adriaan van Os
Adriaan van Os wrote:
Frank Heckenbach wrote:
Adriaan van Os wrote:
I am adding a few notes about building on Mac OS X.
The following tools may be needed:
- sed 4.0.x
a too old version is installed with XCode or OS X (I use 4.0.5, but I assume later versions work also) ftp://ftp.gnu.org/gnu/sed/
Well, I have 3.02 here (very old) and didn't notice any problems.
I don't know what bizarre version of sed Apple distributes - the default system sed on Mac OS X doesn't have a version switch and gpc reports that it is "crippled".
Ah ok, probably a non-GNU sed then; many of those I've seen are "crippled", in that they don't even support full regular expressions (i.e. Chomsky type 3 languages, or finite automata), which makes it hard to work around. So probably any GNU sed version will so. (You might want to mention this in the "heading", although you give the GNU URL, since there exist other sed's, and by chance one of them might have version number 4.0.x (or a bigger number, and a reader would think it's ok.)
Frank
Frank Heckenbach wrote:
Adriaan van Os wrote:
I am adding a few notes about building on Mac OS X.
The following tools may be needed:
- sed 4.0.x
a too old version is installed with XCode or OS X (I use 4.0.5, but I assume later versions work also) ftp://ftp.gnu.org/gnu/sed/
Well, I have 3.02 here (very old) and didn't notice any problems.
I don't know what bizarre version of sed Apple distributes - the default system sed on Mac OS X doesn't have a version switch and gpc reports that it is "crippled".
[G5:~] adriaan% strings `which sed-old` | grep Regents The Regents of the University of California. All rights reserved.
So, it's a FreeBSD sed (not a "too old version")
Regards,
Adriaan van Os
I would like to use the built-in Round() function, but its getting masked by the round() function if fp.pas in the Universal Interfaces, and they are not compatible (one returns a Integer, the other a double).
In the past, with other Pascal dialects, I have solved this by using System.Round() to get the built-in routine, but I don't believe this syntax is supported by GPC.
I could in theory arrange my uses clause to avoid using the fp unit, but as it turns out I only ever use Round() in routines that also require the fp unit's functions.
Is there a simple solution to this?
Regards, Steven
I would like to use the built-in Round() function, but its getting masked by the round() function if fp.pas in the Universal Interfaces, and they are not compatible (one returns a Integer, the other a double).
In the past, with other Pascal dialects, I have solved this by using System.Round() to get the built-in routine, but I don't believe this syntax is supported by GPC.
I could in theory arrange my uses clause to avoid using the fp unit, but as it turns out I only ever use Round() in routines that also require the fp unit's functions.
Is there a simple solution to this?
The simplest solution is to rename `round' from fp.pas on import like:
import fp (round => fp_round);
The `System.Round' syntax is supported, but ATM have different meaning: it requests `Round' form module `System'. In gpc `System' module does not export `Round' (and it have to be explicitly imported). Also, ATM gpc does not support exporting built-in indentifiers, so the best one can do is to make a little module like:
module gpcround; export gpcround = (RoundRealInt => Round); function RoundRealInt(r : Real): Integer; end; function RoundRealInt(r : Real): Integer; begin RoundRealInt := Round(r) end; end .
and then import `gpcround', for example like:
import qualified gpcround;
The second way requires gpc-20050217 (qualified indentifiers).
On 20 Feb 2005, at 18:37, Waldek Hebisch wrote:
The simplest solution is to rename `round' from fp.pas on import like:
import fp (round => fp_round);
Yes, that works for a simple test program.
Which gives me another problem. I've never used 'import' before, just 'uses'. Looking at the GPC manual, 'import' can only be use in a program file not a unit/module. This is rather limiting for me, if true, as my problem code is spread around several units.
Another thing. I noticed is that trunc() has been renamed to truncd() in fp.pas and there is a comment on the microbizz site (http://www.microbizz.nl/gpcdiffs.html) that says this...
<quote> 11. Trunc
In ISO Pascal Trunc is a predefined function that returns an integer value. It is an error if the result value of Trunc doesn't exist in the Integer type. The fp.pas unit of Apple’s PInterfaces declares a trunc function that returns a value of type Double_t.
To solve this ambivalence, the trunc function in fp.pas has been renamed to truncd. </quote>
So this looks like the same problem as I have with Round(), but with a different solution. So I'm now beginning to think think this is a GPCPInterfaces bug (or at least inconsistency). Should round() in fp.pas not have been renamed roundd() for the same reasons?
Regards, Steven
Which gives me another problem. I've never used 'import' before, just 'uses'. Looking at the GPC manual, 'import' can only be use in a program file not a unit/module. This is rather limiting for me, if true, as my problem code is spread around several units.
You mean:
: There must be at most one import part in a program.
That statement is wrong. Correct statement is:
There must be at most one import part at the begining of a block. Each module or function/procedure (and also main program) can have its own import part. Single import part can import arbitrarly many interfaces.
The point is that:
import unit1; import unit2;
is illegal, but:
import unit1; unit2;
is legal.
Waldek Hebisch wrote:
Which gives me another problem. I've never used 'import' before, just 'uses'. Looking at the GPC manual, 'import' can only be use in a program file not a unit/module. This is rather limiting for me, if true, as my problem code is spread around several units.
You mean:
: There must be at most one import part in a program.
That statement is wrong. Correct statement is:
There must be at most one import part at the begining of a block. Each module or function/procedure (and also main program) can have its own import part. Single import part can import arbitrarly many interfaces.
Thanks, I'm changing it.
Additionally, he may have been confused because the example only mentioned a program (unlike the example for `uses'). But that's not a restriction, just an omission in the reference.
Frank
steven.borley wrote:
In ISO Pascal Trunc is a predefined function that returns an integer value. It is an error if the result value of Trunc doesn't exist in the Integer type. The fp.pas unit of Apple’s PInterfaces declares a trunc function that returns a value of type Double_t.
To solve this ambivalence, the trunc function in fp.pas has been renamed to truncd.
</quote>
So this looks like the same problem as I have with Round(), but with a different solution. So I'm now beginning to think think this is a GPCPInterfaces bug (or at least inconsistency). Should round() in fp.pas not have been renamed roundd() for the same reasons?
Yes, this was reported before - on the maccompiler mailing list. We decided to change "round" in fp.pas to "roundd". Then - we completely forgot about it. Peter, can we make a change in the interfaces script now, so that it will be included in the next release ?
Regards,
Adriaan van Os
"steven.borley" wrote:
On 20 Feb 2005, at 18:37, Waldek Hebisch wrote:
The simplest solution is to rename `round' from fp.pas on import like: import fp (round => fp_round);
Yes, that works for a simple test program.
Which gives me another problem. I've never used 'import' before, just 'uses'. Looking at the GPC manual, 'import' can only be use in a program file not a unit/module. This is rather limiting for me, if true, as my problem code is spread around several units.
Although I haven't tested it with the latest versions of GPC, I have in the past used Extended Pascal's renaming feature in a uses clause so "uses (round => fp_round)" is alternative to try if you prefer uses clauses to import specifications.
Another thing. I noticed is that trunc() has been renamed to truncd() in fp.pas and there is a comment on the microbizz site (http://www.microbizz.nl/gpcdiffs.html) that says this...
<quote> 11.��� Trunc
In ISO Pascal Trunc is a predefined function that returns an integer value. It is an error if the result value of Trunc doesn't exist in the Integer type. The fp.pas unit of Apple�s PInterfaces declares a trunc function that returns a value of type Double_t.
To solve this ambivalence, the trunc function in fp.pas has been renamed to truncd.
</quote>
So this looks like the same problem as I have with Round(), but with a different solution. So I'm now beginning to think think this is a GPCPInterfaces bug (or at least inconsistency). Should round() in fp.pas not have been renamed roundd() for the same reasons?
It is more of an inconsistency than anything else. It is more or less a case of six of one and a half a dozen of the other of which method to use to resolve the name conflicts. Either way, in order to use GPC's ISO Pascal round and trunc in the same scope as fp's round and trunc, fp's round and trunc have to be renamed either the GPCPInterfaces's declarations or with a renaming clause on using/importing them into a unit or module where one wants to use them in the same scope as ISO Pascal's round and trunc.
Regardless of how the GPCPInterfaces fp inconsistency is resolved, I don't think there is anyway to resolve the name conflicts between Apple's fp API and ISO Pascal's predefined functions in a manner which will work transparently for GPC and Metrowerks/CodeWarrior Pascal common source code usage. (There is a linker error/bug in corresponding MWPInterfaces fp using truncd instead of trunc so don't rely upon that as the correct way to handle the conflict with Metrowerks/CodeWarrior Pascal.) So, if you want the capability of compiling your source code with both compilers use conditional compilation tests on __GPC__ and MWERKS to handle to compiler specific means of resolving the conflict.
Gale Paeper gpaeper@empirenet.com
Gale Paeper wrote:
"steven.borley" wrote:
On 20 Feb 2005, at 18:37, Waldek Hebisch wrote:
The simplest solution is to rename `round' from fp.pas on import like: import fp (round => fp_round);
Yes, that works for a simple test program.
Which gives me another problem. I've never used 'import' before, just 'uses'. Looking at the GPC manual, 'import' can only be use in a program file not a unit/module. This is rather limiting for me, if true, as my problem code is spread around several units.
Although I haven't tested it with the latest versions of GPC, I have in the past used Extended Pascal's renaming feature in a uses clause so "uses (round => fp_round)" is alternative to try if you prefer uses clauses to import specifications.
This doesn't work anymore. It was removed because of syntactic conflicts. But `import' works for units as well, so you can use this instead.
Frank
"steven.borley" wrote:
I would like to use the built-in Round() function, but its getting masked by the round() function if fp.pas in the Universal Interfaces, and they are not compatible (one returns a Integer, the other a double).
In the past, with other Pascal dialects, I have solved this by using System.Round() to get the built-in routine, but I don't believe this syntax is supported by GPC.
I could in theory arrange my uses clause to avoid using the fp unit, but as it turns out I only ever use Round() in routines that also require the fp unit's functions.
Is there a simple solution to this?
round is a standard system function returning integer, so it is effectively declared at level 0, and any redeclaration of round will mask it. However you could declare a function at level 1 (global functions) that calls round and returns integer. Call this function sysround, for example. Now the scope of that function is all of level 1, before or after it was declared, so you can't have, and for similar reasons you can't declare a round at level 1. However you can at level 2. Thus:
(* level 0 surrounds the program *)
PROGRAM blah(output);
(* This is level 1 *)
FUNCTION sysround(x : real) : integer; BEGIN sysround = round(x); END;
PROCEDURE foo; FUNCTION round(x : real) : real; BEGIN (* whatever *) END;
(* This is level 2 *) (* in here the new function round is available *)
FUNCTION bar(y : real) : char; BEGIN (* This is level 3 *) (* code calling round *) (* code calling sysround *) END;
BEGIN (* foo *) (* This is level 2 again *) (* code calling round *) (* code calling sysround *) END;
(* Back to level 1 *) (* Now round : real is no longer available *) (* however both sysround and round : integer are *) BEGIN ... END.
I would like to use the built-in Round() function, but its getting masked by the round() function if fp.pas in the Universal Interfaces, and they are not compatible (one returns a Integer, the other a double).
In the past, with other Pascal dialects, I have solved this by using System.Round() to get the built-in routine, but I don't believe this syntax is supported by GPC.
Is there a simple solution to this?
One option would be to make a unit like:
unit SystemRoundUnit;
interface
function SystemRound( x: Real ): Integer;
implementation
function SystemRound( x: Real ): Integer; begin return Round( x ); end;
end.
(untried, untested, uncompiled)
At 10:03 PM +0000 20/2/05, steven.borley wrote:
Another thing. I noticed is that trunc() has been renamed to truncd() in fp.pas and there is a comment on the microbizz site (http://www.microbizz.nl/gpcdiffs.html) that says this...
So this looks like the same problem as I have with Round(), but with a different solution. So I'm now beginning to think think this is a GPCPInterfaces bug (or at least inconsistency). Should round() in fp.pas not have been renamed roundd() for the same reasons?
The argument could certainly made that this is inconsistent. I have no objections to the change, if Gale & Adriaan agree.
Enjoy, Peter.
Peter N Lewis wrote:
steven.borley wrote:
Another thing. I noticed is that trunc() has been renamed to truncd() in fp.pas and there is a comment on the microbizz site (http://www.microbizz.nl/gpcdiffs.html) that says this...
So this looks like the same problem as I have with Round(), but with a different solution. So I'm now beginning to think think this is a GPCPInterfaces bug (or at least inconsistency). Should round() in fp.pas not have been renamed roundd() for the same reasons?
The argument could certainly made that this is inconsistent. I have no objections to the change, if Gale & Adriaan agree.
After discussing this in private email, we agreed to the change:
--- fp.pas.orig Sun Feb 13 12:57:41 2005 +++ fp.pas Mon Feb 21 15:25:13 2005 @@ -667,7 +667,7 @@ function rinttol(x: double_t): SInt32; e * CarbonLib: in CarbonLib 1.0 and later * Mac OS X: in version 10.0 and later } -function round(x: double_t): double_t; external name 'round'; +function roundd(x: double_t): double_t; external name 'round';
{ * roundtol()
Waldek Hebisch wrote:
The second way requires gpc-20050217 (qualified indentifiers).
Do we have a way to qualify built-in routines, e.g. "program.round" (as "system.round" refers to a "system" unit) ?
Regards,
Adriaan van Os
Adriaan van Os wrote:
Waldek Hebisch wrote:
The second way requires gpc-20050217 (qualified indentifiers).
Do we have a way to qualify built-in routines, e.g. "program.round"
No, we don't (except by explicit wrappers, as others have described).
(as "system.round" refers to a "system" unit) ?
Yes, it refers to a `System' unit. But built-in identifiers are not declared in a `System' unit (which would violate EP where `System' is not a special name), but at "level 0" as Chuck calls it (I don't know if the standard has a term for it, I think it just talks of "required procedures and functions" and that they have a "definingÂpoint not contained by the programÂblock").
One could consider whether to add such a facility, but especially for built-in routines with special syntax (such as `WriteLn') this will probably not be easy, so I don't really like the idea.
Frank
On Mon, 21 Feb 2005, Frank Heckenbach wrote:
Adriaan van Os wrote:
Waldek Hebisch wrote:
The second way requires gpc-20050217 (qualified indentifiers).
Do we have a way to qualify built-in routines, e.g. "program.round"
No, we don't (except by explicit wrappers, as others have described).
(as "system.round" refers to a "system" unit) ?
Yes, it refers to a `System' unit. But built-in identifiers are not declared in a `System' unit (which would violate EP where `System' is not a special name), but at "level 0" as Chuck calls it (I don't know if the standard has a term for it, I think it just talks of "required procedures and functions" and that they have a "definingpoint not contained by the programblock").
One could consider whether to add such a facility, but especially for built-in routines with special syntax (such as `WriteLn') this will probably not be easy, so I don't really like the idea.
Would it be easier to have the linker ignore the built-in round() if there was a library module containing round() on the command line?
Russ
Russell Whitaker wrote:
On Mon, 21 Feb 2005, Frank Heckenbach wrote:
Adriaan van Os wrote:
Waldek Hebisch wrote:
The second way requires gpc-20050217 (qualified indentifiers).
Do we have a way to qualify built-in routines, e.g. "program.round"
No, we don't (except by explicit wrappers, as others have described).
(as "system.round" refers to a "system" unit) ?
Yes, it refers to a `System' unit. But built-in identifiers are not declared in a `System' unit (which would violate EP where `System' is not a special name), but at "level 0" as Chuck calls it (I don't know if the standard has a term for it, I think it just talks of "required procedures and functions" and that they have a "definingÂpoint not contained by the programÂblock").
One could consider whether to add such a facility, but especially for built-in routines with special syntax (such as `WriteLn') this will probably not be easy, so I don't really like the idea.
Would it be easier to have the linker ignore the built-in round() if there was a library module containing round() on the command line?
Most built-ins are not plain functions at the linker level. `Round' is done with inline code, `WriteLn' expands to several calls, etc.
But that's not the point, actually -- overriding built-ins is already no problem. It's accessing them when they're shadowed which is not possible (in accordance with the standards).
Since Adriaan and Peter have already renamed their `Round', this particular problem is solved anyway.
Frank
Frank Heckenbach wrote:
Adriaan van Os wrote:
Do we have a way to qualify built-in routines, e.g. "program.round"
No, we don't (except by explicit wrappers, as others have described).
(as "system.round" refers to a "system" unit) ?
Yes, it refers to a `System' unit. But built-in identifiers are not declared in a `System' unit (which would violate EP where `System' is not a special name), but at "level 0" as Chuck calls it (I don't know if the standard has a term for it, I think it just talks of "required procedures and functions" and that they have a "definingpoint not contained by the programblock").
One could consider whether to add such a facility, but especially for built-in routines with special syntax (such as `WriteLn') this will probably not be easy, so I don't really like the idea.
Frank
Special syntax make this feature valuable: there is no way to emulate built-in syntax via wrappers. Also, it is one of biggest remaining BP incompatibilities.
Concerning implementation: I do not see how to do really nice implementation. But IMHO there are two reasonbly easy ways.
One is to check for "magic" module name in the lexer and then do a lookahead for dot and routine name. If there is a match generate apropriate "builtin" token. Of course, one needs an extra state machine in the lexer to avoid false positives. And extra logic in the parser to reject such names in places were qualified names are not allowed
Another way is to put GLR parser to an extreme: remove special treatment for builtins from the lexer and generate both normal parse and a parse as a builtion. Then use merge action to choose correct one.
As I write this yet another idea: parse everthing like `writeln' (it seem to be the most general form of a call) and then check in sematic actions if the routine identifier resolve to built-in. If no then reject calls using extended syntax. Structured value constructors work in similar way. Such approach can even make the compiler simpler then it is now.
Waldek Hebisch wrote:
Frank Heckenbach wrote:
Yes, it refers to a `System' unit. But built-in identifiers are not declared in a `System' unit (which would violate EP where `System' is not a special name), but at "level 0" as Chuck calls it (I don't know if the standard has a term for it, I think it just talks of "required procedures and functions" and that they have a "definingÂpoint not contained by the programÂblock").
One could consider whether to add such a facility, but especially for built-in routines with special syntax (such as `WriteLn') this will probably not be easy, so I don't really like the idea.
Special syntax make this feature valuable: there is no way to emulate built-in syntax via wrappers. Also, it is one of biggest remaining BP incompatibilities.
Concerning implementation: I do not see how to do really nice implementation. But IMHO there are two reasonbly easy ways.
One is to check for "magic" module name in the lexer and then do a lookahead for dot and routine name.
BTW, not only routines, also constants such as `MaxInt', types such as `Integer' and variables such as `Output' (which is particularly strange given the standard properties of `Output', being a program parameter or imported from `StandardOutput').
If there is a match generate apropriate "builtin" token. Of course, one needs an extra state machine in the lexer to avoid false positives. And extra logic in the parser to reject such names in places were qualified names are not allowed
Or perhaps leave the last part to the parser, i.e. let the lexer return LEX_BUILTIN_MODULE (or whatever), and in the parser recognize `LEX_BUILTIN_MODULE '.' p_New' where `p_New' is allowed.
However, this would conflict with our use of a `System' unit (module) to define some really ugly BP stuff I don't want to build in.
Another way is to put GLR parser to an extreme: remove special treatment for builtins from the lexer and generate both normal parse and a parse as a builtion. Then use merge action to choose correct one.
As I write this yet another idea: parse everthing like `writeln' (it seem to be the most general form of a call)
Syntactically yes. But `New' and `Dispose' with object con-/destructors also require special handling while parsing(!) (since con-/destructor names must be made visible for the second argument, see current_structor_object_type).
`Addr' and `Assigned' do because they need to suppress function calls (though we might be able to get rid of this special case if we reorganize function calls as discussed recently).
And don't forget `System.Fail', `System.Continue', `System.Break' and `System.Exit'. (Yes, BP does allow these!) (Well, actually, the first three are implemented like normal built-ins in GPC, but `Exit' not because of new the UCSD/Mac Pascal syntax, also `Return' not (not BP compatible, but to be consequent ...)
AFAICS, these problems would also preclude the GLR suggestion since such things as `Addr' are syntactically the same. So one at best make two equivalent parse rules and "merge" them (which I'd consider almost an abuse of GLR).
And if, I think we'd have to use dprec rather than merge since merge first evalutes both variants which might lead to spurious errors.
and then check in sematic actions if the routine identifier resolve to built-in. If no then reject calls using extended syntax. Structured value constructors work in similar way. Such approach can even make the compiler simpler then it is now.
If we get rid of all the special cases I mentioned, perhaps, but ATM I don't see how we could.
Frank