As another small step towards cleaning up the `external' mess in GPC, I'm now implementing `external name', i.e.
procedure Foo; external name 'bar';
will be equivalent to
procedure Foo; external; asmname 'bar';
`external name' is BP compatible, AFAIK.
I'm not yet changing the fact that `asmname' implies `external' for routines -- this should be done, too, but I'd rather do it together with other incompatible changes later.
However, unless there's heavy resistance, I'd like to deprecate the `c' and `c_language' directives, and drop them in a later release. So,
procedure Foo; c;
should be turned to:
procedure Foo; external name 'foo';
What about a plain `external' without `name' or `asmname'? Currently, this keeps the "default" asmname (first letter uppercase, the rest lowercase). Some time in the future, we'll need name mangling (for qualified identifiers and overloading), so the default asmname will be something ugly which one should not have to know about in order to write interfacing C code or such.
Of course, it would be possible to make `external' set the first-uppercase-asmname even then, but I'm not sure how useful this is. (Currently, it's chosen as the default to avoid linker conflicts with "usual" C routines, but with name mangling, this won't be an issue.)
So, to me it seems more reasonable to make a plain `external' set the asmname to all-lowercase (just like `c' and `c_language' do now). Then,
procedure Foo; c;
can be turned to simply:
procedure Foo; external;
But a current
procedure Foo; external;
will have to be turned to:
procedure Foo; external name 'Foo';
(or the corresponding C code turned to `foo' in lowercase, which I'd usually recommend -- since these routines are explicitly coded, you usually know that there are no conflicts with libc etc.).
Another question is whether `asmname' should be dropped entirely. In external declarations (the most common case), it can be turned into `external name' as described above. But there are cases where you need to set the asmname of a non-external routine or variable. But perhaps we can just use `name' then, e.g.:
var Foo: Integer; name 'bar';
(instead of asmname 'bar'). The advantage would be to have another non-standard (conditional) keyword less. Or we could even use `attribute', something like:
var Foo: Integer; attribute (name ('foo'));
(or `asmname' -- that doesn't matter since within `attributes' we don't have the problems of keywords, anyway). This way, `name' would not be a real keyword (only special after `external'), at the cost of a little stranges syntax.
But while we're at it, I think the attribute syntax can be simplified to
var Foo: Integer; attribute (name = 'foo');
(also for other attributes with parameters, and without changing the existing syntax -- there wouldn't be any conflicts).
I think this could be an acceptable way (syntactically), so `asmname' can be dropped.
Frank
Frank Heckenbach wrote:
As another small step towards cleaning up the `external' mess in GPC, I'm now implementing `external name', i.e.
procedure Foo; external name 'bar';
will be equivalent to
procedure Foo; external; asmname 'bar';
I think that external should indicate language -- C may is good as default, but incompatible name mangling schemes profilerate. Currentely Pascal, Fortran, C++ and Ada in GCC all use different schemes (and with a.out assembler <> C). It seems much better to avoid users doing mangling by hand. And even if support for other languages is delayed it is better to reserve the syntax in advance.
Waldek Hebisch wrote:
Frank Heckenbach wrote:
As another small step towards cleaning up the `external' mess in GPC, I'm now implementing `external name', i.e.
procedure Foo; external name 'bar';
will be equivalent to
procedure Foo; external; asmname 'bar';
I think that external should indicate language -- C may is good as default, but incompatible name mangling schemes profilerate. Currentely Pascal, Fortran, C++ and Ada in GCC all use different schemes (and with a.out assembler <> C).
Are you referring to the prepended underscore in DJGPP (using COFF)? AFAIK, that's just for compatibility with other Dos C compilers which use Intel asm syntax where an identifier such as `ax' (which is valid in C, of course) would conflict with a processor register. So, I think for all higher languages, the underscore is "invisible" (i.e., when interfacing between C and Pascal, you don't have to worry about it), only those who write interfacing asm code have to add it explicitly.
It seems much better to avoid users doing mangling by hand. And even if support for other languages is delayed it is better to reserve the syntax in advance.
Well, which syntax? The existing and suggested syntax only covers explicitly specified asmnames (which should always be possible, of course).
So if we want to support other language's mangling schemes in the future (which is probably more than one can of worms, and I'm not sure if will be feasible, given that even different C++ compilers use different schemes), we need some additional syntax.
A new `attribute' can always be added (no danger of conflicts).
If you're thinking of something like `external 'C' ...' (similar to `extern "C"' in C++), there might be conflicts since BP actually allows (which GPC doesn't support yet, but might in the future):
external 'library-name' name 'asmname';
So, which syntax do you propose?
BTW, I do not think one should emulate other language's mangling manually, either. But it also works if all languages allow you to specify an explicit linker name for the interface routines -- in C that's trivial (no mangling at all), in GPC that's `asmname' (subject to the proposed changes), in C++ it's `extern "C"' (not for objects, though, but the incompatibilities between C++ and GPC objects are much deeper than the name mangling, anyway). I don't know enough Fortran or Ada to tell if there are such mechanisms ...
Frank
Frank Heckenbach wrote:
Waldek Hebisch wrote:
It seems much better to avoid users doing mangling by hand. And even if support for other languages is delayed it is better to reserve the syntax in advance.
Well, which syntax? The existing and suggested syntax only covers explicitly specified asmnames (which should always be possible, of course).
So if we want to support other language's mangling schemes in the future (which is probably more than one can of worms, and I'm not sure if will be feasible, given that even different C++ compilers use different schemes), we need some additional syntax.
A new `attribute' can always be added (no danger of conflicts).
If you're thinking of something like `external 'C' ...' (similar to `extern "C"' in C++), there might be conflicts since BP actually allows (which GPC doesn't support yet, but might in the future):
external 'library-name' name 'asmname';
So, which syntax do you propose?
I would be happy with an attribute, say procedure Foo(x: real); attribute (external, name = 'foo(double)', linkage = 'C++');
BTW, I do not think one should emulate other language's mangling manually, either. But it also works if all languages allow you to specify an explicit linker name for the interface routines -- in C that's trivial (no mangling at all), in GPC that's `asmname' (subject to the proposed changes), in C++ it's `extern "C"' (not for objects, though, but the incompatibilities between C++ and GPC objects are much deeper than the name mangling, anyway). I don't know enough Fortran or Ada to tell if there are such mechanisms ...
Ada has linkage pragmas. Both Ada and C++ have overloaded functions, one cannot export them using C linkage. Of course one can solve such problems using wrappers, but that doubles the volume of code needed for interfacing (and adds runtime overhead).
Waldek Hebisch wrote:
Frank Heckenbach wrote:
Waldek Hebisch wrote:
It seems much better to avoid users doing mangling by hand. And even if support for other languages is delayed it is better to reserve the syntax in advance.
Well, which syntax? The existing and suggested syntax only covers explicitly specified asmnames (which should always be possible, of course).
So if we want to support other language's mangling schemes in the future (which is probably more than one can of worms, and I'm not sure if will be feasible, given that even different C++ compilers use different schemes), we need some additional syntax.
A new `attribute' can always be added (no danger of conflicts).
If you're thinking of something like `external 'C' ...' (similar to `extern "C"' in C++), there might be conflicts since BP actually allows (which GPC doesn't support yet, but might in the future):
external 'library-name' name 'asmname';
So, which syntax do you propose?
I would be happy with an attribute, say procedure Foo(x: real); attribute (external, name = 'foo(double)', linkage = 'C++');
OK, that will be easy to add anytime (i.e., when someone implements the hard bits).
`attribute (external)' isn't implemented yet (though it could be, semantically, equivalent to plain `external'). Do you think I should do so?
Frank
Frank Heckenbach wrote:
... snip ...
However, unless there's heavy resistance, I'd like to deprecate the `c' and `c_language' directives, and drop them in a later release. So,
procedure Foo; c;
should be turned to:
procedure Foo; external name 'foo';
What about a plain `external' without `name' or `asmname'? Currently, this keeps the "default" asmname (first letter uppercase, the rest lowercase). Some time in the future, we'll need name mangling (for qualified identifiers and overloading), so the default asmname will be something ugly which one should not have to know about in order to write interfacing C code or such.
The whole asmname/external name thing is non-standard, so it should be as plainly understandable as possible. Thus I would favor 'externalname' as the ONLY available method. The standard allows for directives following the procedure declaration, and I am not sure if the separate words in 'external foo' qualify. 'external' by itself is a common usage.
CBFalconer wrote:
Frank Heckenbach wrote:
... snip ...
However, unless there's heavy resistance, I'd like to deprecate the `c' and `c_language' directives, and drop them in a later release. So,
procedure Foo; c;
should be turned to:
procedure Foo; external name 'foo';
What about a plain `external' without `name' or `asmname'? Currently, this keeps the "default" asmname (first letter uppercase, the rest lowercase). Some time in the future, we'll need name mangling (for qualified identifiers and overloading), so the default asmname will be something ugly which one should not have to know about in order to write interfacing C code or such.
The whole asmname/external name thing is non-standard, so it should be as plainly understandable as possible. Thus I would favor 'externalname' as the ONLY available method. The standard allows for directives following the procedure declaration, and I am not sure if the separate words in 'external foo' qualify. 'external' by itself is a common usage.
ISO 7185 says:
: 6.1.4 Directives : : A directive shall only occur in a procedure-declaration or a : function-declaration. The only directive shall be the required : directive forward (see 6.6.1 and 6.6.2). No directive shall have : the same spelling as any word-symbol. : : directive = letter { letter | digit } . : : NOTE -- Many processors provide, as an extension, the directive : external, which is used to specify that the procedure-block or : function-block corresponding to that procedure-heading or : function-heading is external to the program-block. Usually it is : in a library in a form to be input to, or that has been produced : by, the processor.
So any directive except `forward' is an extension. GPC's principle is to (aim to) support ISO Pascal without extensions in CP and EP modes, and to support various extensions otherwise. So, any kind of external directive should not be accepted in CP/EP mode, and that's how it is currently.
Now, in BP, we have `external name 'foo''. Sure, this is not even syntactically in accordance with 6.1.4 -- but neither would be `externalname 'foo'' since 6.1.4 doesn't allow for "arguments" (the string) of directives. Since there's no way (even syntactically) in ISO to make a directive with a name (neither `attribute', of course), we have to do something outside of ISO -- and if nothing else matters, we might as well use the BP syntax ...
Besides, please note that `external' and `[asm]name' are really two distinct things (which, unfortunately, GPC doesn't strictly separate yet). There are cases where you only need to specify the name (so it can be referred to from other languages), and other times you want to make it external without specifying the name (well, provided the name is something that can be relied upon, such as the Pascal identifier converted to lower-case).
Therefore, we do need several directives -- in my suggestion `external', `external name ...', and `attribute (name = ...)'.
I agree with you that we should not have too many redundant directives. That's why I suggest to drop the (currently existing) `asmname', `c' and `c_language' directives (and keep only the, also already existing, `external' and `attribute').
Frank
Frank Heckenbach wrote:
I'm not yet changing the fact that `asmname' implies `external' for routines -- this should be done, too, but I'd rather do it together with other incompatible changes later.
However, unless there's heavy resistance, I'd like to deprecate the `c' and `c_language' directives, and drop them in a later release. So,
procedure Foo; c;
should be turned to:
procedure Foo; external name 'foo';
Well, I think it is good use to write preprocessor macros for different cases. So, if the compiler changes, it would be a matter of changing the macro.
What about a plain `external' without `name' or `asmname'? Currently, this keeps the "default" asmname (first letter uppercase, the rest lowercase). Some time in the future, we'll need name mangling (for qualified identifiers and overloading), so the default asmname will be something ugly which one should not have to know about in order to write interfacing C code or such.
Of course, it would be possible to make `external' set the first-uppercase-asmname even then, but I'm not sure how useful this is. (Currently, it's chosen as the default to avoid linker conflicts with "usual" C routines, but with name mangling, this won't be an issue.)
So, to me it seems more reasonable to make a plain `external' set the asmname to all-lowercase (just like `c' and `c_language' do now). Then,
May I suggest a compiler switch --fliteral-asmnames ? It would set the asmname to match the name in the procedure/function header literally. With this switch, in the interface part of a unit the declaration
procedure myProc;
would imply
procedure myProc; asmname 'myProc'; external;
The practical background is interfacing with the MacOS Carbon toolbox. In the current situtation, I have to add a GPC-conditional "asmname 'myCarbonProc"" to 15.000 API routines either by hand (not nice) or with a sed script (that maybe somebody has ready for me).
procedure Foo; c;
can be turned to simply:
procedure Foo; external;
But a current
procedure Foo; external;
will have to be turned to:
procedure Foo; external name 'Foo';
(or the corresponding C code turned to `foo' in lowercase, which I'd usually recommend -- since these routines are explicitly coded, you usually know that there are no conflicts with libc etc.).
Another question is whether `asmname' should be dropped entirely. In external declarations (the most common case), it can be turned into `external name' as described above. But there are cases where you need to set the asmname of a non-external routine or variable. But perhaps we can just use `name' then, e.g.:
var Foo: Integer; name 'bar';
(instead of asmname 'bar'). The advantage would be to have another non-standard (conditional) keyword less. Or we could even use `attribute', something like:
var Foo: Integer; attribute (name ('foo'));
(or `asmname' -- that doesn't matter since within `attributes' we don't have the problems of keywords, anyway). This way, `name' would not be a real keyword (only special after `external'), at the cost of a little stranges syntax.
But while we're at it, I think the attribute syntax can be simplified to
var Foo: Integer; attribute (name = 'foo');
(also for other attributes with parameters, and without changing the existing syntax -- there wouldn't be any conflicts).
I think this could be an acceptable way (syntactically), so `asmname' can be dropped.
Fine for me (but for the above reasons I would like to know what it will be in the next compiler release).
Regards,
Adriaan van Os
Adriaan van Os wrote:
Frank Heckenbach wrote:
I'm not yet changing the fact that `asmname' implies `external' for routines -- this should be done, too, but I'd rather do it together with other incompatible changes later.
However, unless there's heavy resistance, I'd like to deprecate the `c' and `c_language' directives, and drop them in a later release. So,
procedure Foo; c;
should be turned to:
procedure Foo; external name 'foo';
Well, I think it is good use to write preprocessor macros for different cases.
I think one generally shouldn't use preprocessor macros in Pascal at all. ;-)
So, if the compiler changes, it would be a matter of changing the macro.
It's not like this syntax is supposed to change again and again -- that's why I'm trying to determine the best future syntax now. There are some changes necessary for several reasons, and I can't do them all at once, but at least I'll try to do them so that each thing will be changed at most once.
What about a plain `external' without `name' or `asmname'? Currently, this keeps the "default" asmname (first letter uppercase, the rest lowercase). Some time in the future, we'll need name mangling (for qualified identifiers and overloading), so the default asmname will be something ugly which one should not have to know about in order to write interfacing C code or such.
Of course, it would be possible to make `external' set the first-uppercase-asmname even then, but I'm not sure how useful this is. (Currently, it's chosen as the default to avoid linker conflicts with "usual" C routines, but with name mangling, this won't be an issue.)
So, to me it seems more reasonable to make a plain `external' set the asmname to all-lowercase (just like `c' and `c_language' do now). Then,
May I suggest a compiler switch --fliteral-asmnames ? It would set the asmname to match the name in the procedure/function header literally. With this switch, in the interface part of a unit the declaration
procedure myProc;
would imply
procedure myProc; asmname 'myProc'; external;
No, it wouldn't. `external' means that the procedure is defined somewhere else, while a normal interface definition means that it is defined in the implementation of the unit (mostly like a `forward' declaration).
Secondly, the letter-casing of Pascal identifiers should have no relevance to the program semantics, i.e.
procedure MYpROC; external;
and
procedure myProc; external;
must yield the same thing.
The practical background is interfacing with the MacOS Carbon toolbox. In the current situtation, I have to add a GPC-conditional "asmname 'myCarbonProc"" to 15.000 API routines
I suggest you write `external; asmname 'foo';' now, and with the next GPC you can do a simple global replacement `external; asmname' -> `external name'.
either by hand (not nice) or with a sed script (that maybe somebody has ready for me).
If the declarations are all one-liners, and the letter-casing is the same that should be used for asmnames, try this (using GNU awk -- I'm not using sed because it doesn't seem to have an easy way to match `procedure' and `function' case-insensitively, and because an awk script can be better extended if necessary):
#!/bin/sh gawk ' BEGIN { IGNORECASE = 1 } $1 == "procedure" || $1 == "function" { n = $2 sub ("[^a-z0-9_].*", "", n) print $0 " external name '"'"'" n "'"'"';" } '
Frank
On Tue, Feb 25, 2003 at 02:47:46PM +0100, Frank Heckenbach wrote:
As another small step towards cleaning up the `external' mess in GPC, I'm now implementing `external name', i.e. procedure Foo; external name 'bar';
Looks good, as far as
var Name: Integer; external name 'name';
works. ("Name" is a very popular identifier).
However, unless there's heavy resistance, I'd like to deprecate the `c' and `c_language' directives, and drop them in a later release. So, procedure Foo; c; should be turned to: procedure Foo; external name 'foo';
What about: procedure Foo; external cname 'foo'; in case of resistance ;-)
What about a plain `external' without `name' or `asmname'? Currently, this keeps the "default" asmname (first letter uppercase, the rest lowercase). Some time in the future, we'll need name mangling (for qualified identifiers and overloading), so the default asmname will be something ugly which one should not have to know about in order to write interfacing C code or such.
I do not want to rewrite all my units interfacing C code. In C, all function names are lowercase with "_" between (gtk_window_new). In Pascal, this function would be called "GtkWindowNew". So something simlar to "asmname", "external name", or "attribute (name = 'XXX')" would be good.
Another question is whether `asmname' should be dropped entirely. In external declarations (the most common case), it can be turned into `external name' as described above. But there are cases where you need to set the asmname of a non-external routine or variable. But perhaps we can just use `name' then, e.g.: var Foo: Integer; name 'bar'; (instead of asmname 'bar'). The advantage would be to have another non-standard (conditional) keyword less. Or we could even use `attribute', something like: var Foo: Integer; attribute (name ('foo'));
This syntax looks unnatural to me, is it Lisp code?
var Foo: Integer; attribute (name = 'foo');
Looks better!
I think this could be an acceptable way (syntactically), so `asmname' can be dropped.
OK, with "attribute" at hand.
Eike
Eike Lange wrote:
On Tue, Feb 25, 2003 at 02:47:46PM +0100, Frank Heckenbach wrote:
As another small step towards cleaning up the `external' mess in GPC, I'm now implementing `external name', i.e. procedure Foo; external name 'bar';
Looks good, as far as
var Name: Integer; external name 'name';
works. ("Name" is a very popular identifier).
Yes, this will work. (To make sure it will remain so, I'm putting it in a test program eike4.pas.)
However, unless there's heavy resistance, I'd like to deprecate the `c' and `c_language' directives, and drop them in a later release. So, procedure Foo; c; should be turned to: procedure Foo; external name 'foo';
What about: procedure Foo; external cname 'foo'; in case of resistance ;-)
I think if there's resistance, it will be against any change. I don't think there's a particular problem with `external name' (and it's BP compatible, unlike `external cname' or any other new creation would be).
What about a plain `external' without `name' or `asmname'? Currently, this keeps the "default" asmname (first letter uppercase, the rest lowercase). Some time in the future, we'll need name mangling (for qualified identifiers and overloading), so the default asmname will be something ugly which one should not have to know about in order to write interfacing C code or such.
I do not want to rewrite all my units interfacing C code. In C, all function names are lowercase with "_" between (gtk_window_new). In Pascal, this function would be called "GtkWindowNew".
That's independent of the meaning of plain `external' since it will not work here, anyway (neither the existing, nor any possible future meaning), because of the underscores. (If, however, the Pascal function would be called Gtk_Window_New, which I don't suggest(!), a plain `external' would work after the proposed change.)
So something simlar to "asmname", "external name", or "attribute (name = 'XXX')" would be good.
Of course, we need at least one of these. In such a case, I'd then recommend `external name', though `external; attribute (name = ...)' would also work (but is longer) according to my suggestions.
We "need" `external name' for BP compatibility (and there doesn't seem to be a problem with it -- the preceding `external' avoids any syntax conflicts, even if `name' is no real keyword), so we might as well use it ...
And we need something for non-external routines. `attribute' might be good there, and if we do it, it will also work for external routines ...
var Foo: Integer; attribute (name ('foo'));
This syntax looks unnatural to me, is it Lisp code?
No, GCC extension. (OK, so where's the difference? ;-)
Frank
On 25 Feb 2003 at 18:19, Frank Heckenbach wrote:
[...]
What about: procedure Foo; external cname 'foo'; in case of resistance ;-)
I think if there's resistance, it will be against any change. I don't think there's a particular problem with `external name' (and it's BP compatible, unlike `external cname' or any other new creation would be).
I agree that we should, if possible, not go off on a frolic of our own and invent something new. Therefore, I suggest that we keep as much BP compatibility as we can. So, why not go for:
procedure Foo; external name 'foo'; { for imports } Procedure Bar; name 'bar'; { for exports }
If "name" is not supplied, then GPC could supply sensible defaults: Procedure Foo; external; { GPC supplies "name 'Foo'" automatically) Procedure Bar; { GPC supplies "name 'Bar'" automatically)
We also need to keep the attributes. So for example, I will need to be able to do something like this: procedure Foo; external name 'foo'; attribute(stdcall); procedure Bar; name 'bar'; attribute(stdcall);
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
Prof A Olowofoyeku (The African Chief) wrote:
I agree that we should, if possible, not go off on a frolic of our own and invent something new. Therefore, I suggest that we keep as much BP compatibility as we can. So, why not go for:
procedure Foo; external name 'foo'; { for imports }
OK.
Procedure Bar; name 'bar'; { for exports }
Is this also BP syntax? (Or Delphi?)
This might be more problematic, actually. In the case above, `name' is harmless since `external' is the (conditional) keyword. Here `name' would have to be the keyword. But it's also a very common identifier.
If "name" is not supplied, then GPC could supply sensible defaults: Procedure Foo; external; { GPC supplies "name 'Foo'" automatically) Procedure Bar; { GPC supplies "name 'Bar'" automatically)
As I said, I'd prefer all-lowercase then.
We also need to keep the attributes. So for example, I will need to be able to do something like this: procedure Foo; external name 'foo'; attribute(stdcall); procedure Bar; name 'bar'; attribute(stdcall);
Sure, I have no plans to drop them.
Frank
Frank Heckenbach wrote:
Prof A Olowofoyeku (The African Chief) wrote:
If "name" is not supplied, then GPC could supply sensible defaults: Procedure Foo; external; { GPC supplies "name 'Foo'" automatically) Procedure Bar; { GPC supplies "name 'Bar'" automatically)
As I said, I'd prefer all-lowercase then.
All-lowercase is arbitrary, as was the previous convention. Any default name mangling scheme that is out of control of the programmer (with switches) is arbitrary. The best default will depend on the habits of a platform. The two largest API sets in the world (Win32 and MacOS) have Pascal-style capitalization and nobody wants to write nEWhAnDLe instead of NewHandle or hEaPaLlOc instead of HeapAlloc.
If the declarations are all one-liners, and the letter-casing is the same that should be used for asmnames, try this (using GNU awk -- I'm not using sed because it doesn't seem to have an easy way to match `procedure' and `function' case-insensitively, and because an awk script can be better extended if necessary):
#!/bin/sh gawk ' BEGIN { IGNORECASE = 1 } $1 == "procedure" || $1 == "function" { n = $2 sub ("[^a-z0-9_].*", "", n) print $0 " external name '"'"'" n "'"'"';" } '
Thanks for the example (and I found coworkers on a MacPascal mailing list that offered further help here).
Regards,
Adriaan van Os
Adriaan van Os wrote:
Frank Heckenbach wrote:
Prof A Olowofoyeku (The African Chief) wrote:
If "name" is not supplied, then GPC could supply sensible defaults: Procedure Foo; external; { GPC supplies "name 'Foo'" automatically) Procedure Bar; { GPC supplies "name 'Bar'" automatically)
As I said, I'd prefer all-lowercase then.
All-lowercase is arbitrary, as was the previous convention. Any default name mangling scheme that is out of control of the programmer (with switches) is arbitrary. The best default will depend on the habits of a platform. The two largest API sets in the world (Win32 and MacOS) have Pascal-style capitalization
This just means that for such routines you need to specify the asmname explicitly, anyway, since there's no way for the compiler to "guess" such a scheme.
and nobody wants to write nEWhAnDLe instead of NewHandle or hEaPaLlOc instead of HeapAlloc.
I don't understand what you mean here.
Again, Pascal is case-insensitive, so the capitalization of Pascal identifiers must not matter. So if you want
procedure NewHandle; external;
to get an asmname `NewHandle', then
procedure nEWhAnDLe; external;
must also get `NewHandle', and I don't think that's possible to do (in general).
You're right, any default convention is arbitrary, but I think we should choose a somewhat "natural" default. AFAICS, the only "natural" convention in C is all-lowercase. It's what most if not all standard C and POSIX functions use. It's also what many C programmers write; other write mixed style, but as I said above, we can't get that automatically anyway, so we have to ignore that; whereas I haven't seen anyone who would write all C identifiers with first-uppercase-rest-lowercase, so this wouldn't be a useful default convention I think (while it's useful for "internal" Pascal identifiers where the goal is to avoid conflicts with other languages, i.e. quite the contrary).
Frank
My feeling is that as long as you don't lose
procedure Foo; external;
whatever you choose doesn't matter (for me!). I think it'd be an idea to leave open the option that the user wants to directly refer to the external name (as in the example above) and resolve any renaming issue via wrappers or the export mechanism should they choose to. It may have a run-time overhead, but it might make for easier initial interfacing to large external libraries.
FWIW, I prefer the options to be:
procedure foo; external; procedure foo; external 'name=_foo' ; procedure foo; external 'name=_foo; language=c' ; procedure foo; external 'language=c' ;
Where language could be any number of things: asm, c, c++, etc.
You can alter the stuff in the quotes to your heart's content without breaking the overall syntax of:
procedure <name> ; [ external [ '<attribute-list>' ] ; ] <attribute-list> ::= '<attribute-item> { ; <attribute-item> }' <attribute-item> ::= name | language = <string>
Obviously, you could invent other syntaxes (is that a word?) for the attribute list.
One thing I like is that since the attribute keywords are within quotes, its obvious they don't conflict with any identifiers that the user might choose to use (ie. they have a very explicit context in which they exist).
I suppose you could argue that the external keyword gives the context so the quotes are not needed, but I still feel happier with them inside quotes as in principle you could have it such that all keywords not in quotes are globally recognised as defined-keywords (and hence conflict with user's identifiers) and only those in quotes are treated as "local" (and hence not conflicting with user's identifiers). It'd make for one simple rule for identifier that's easy to follow.
Just my 2c...
Grant
At 2:47 PM +0100 25/2/03, Frank Heckenbach wrote:
As another small step towards cleaning up the `external' mess in GPC, I'm now implementing `external name', i.e.
procedure Foo; external name 'bar';
will be equivalent to
procedure Foo; external; asmname 'bar';
`external name' is BP compatible, AFAIK.
I'm not yet changing the fact that `asmname' implies `external' for routines -- this should be done, too, but I'd rather do it together with other incompatible changes later.
However, unless there's heavy resistance, I'd like to deprecate the `c' and `c_language' directives, and drop them in a later release. So,
procedure Foo; c;
should be turned to:
procedure Foo; external name 'foo';
What about a plain `external' without `name' or `asmname'? Currently, this keeps the "default" asmname (first letter uppercase, the rest lowercase). Some time in the future, we'll need name mangling (for qualified identifiers and overloading), so the default asmname will be something ugly which one should not have to know about in order to write interfacing C code or such.
Of course, it would be possible to make `external' set the first-uppercase-asmname even then, but I'm not sure how useful this is. (Currently, it's chosen as the default to avoid linker conflicts with "usual" C routines, but with name mangling, this won't be an issue.)
So, to me it seems more reasonable to make a plain `external' set the asmname to all-lowercase (just like `c' and `c_language' do now). Then,
procedure Foo; c;
can be turned to simply:
procedure Foo; external;
But a current
procedure Foo; external;
will have to be turned to:
procedure Foo; external name 'Foo';
(or the corresponding C code turned to `foo' in lowercase, which I'd usually recommend -- since these routines are explicitly coded, you usually know that there are no conflicts with libc etc.).
Another question is whether `asmname' should be dropped entirely. In external declarations (the most common case), it can be turned into `external name' as described above. But there are cases where you need to set the asmname of a non-external routine or variable. But perhaps we can just use `name' then, e.g.:
var Foo: Integer; name 'bar';
(instead of asmname 'bar'). The advantage would be to have another non-standard (conditional) keyword less. Or we could even use `attribute', something like:
var Foo: Integer; attribute (name ('foo'));
(or `asmname' -- that doesn't matter since within `attributes' we don't have the problems of keywords, anyway). This way, `name' would not be a real keyword (only special after `external'), at the cost of a little stranges syntax.
But while we're at it, I think the attribute syntax can be simplified to
var Foo: Integer; attribute (name = 'foo');
(also for other attributes with parameters, and without changing the existing syntax -- there wouldn't be any conflicts).
I think this could be an acceptable way (syntactically), so `asmname' can be dropped.
Frank
-- Frank Heckenbach, frank@g-n-u.de, http://fjf.gnu.de/, 7977168E GPC To-Do list, latest features, fixed bugs: http://www.gnu-pascal.de/todo.html GPC download signing key: 51FF C1F0 1A77 C6C2 4482 4DDC 117A 9773 7F88 1707
Grant Jacobs wrote:
My feeling is that as long as you don't lose
procedure Foo; external;
whatever you choose doesn't matter (for me!). I think it'd be an idea to leave open the option that the user wants to directly refer to the external name (as in the example above) and resolve any renaming issue via wrappers or the export mechanism should they choose to.
I don't quite understand. Which "the" external name are you referring to? Without any specification, that's undefined -- or rather, we're going to define it here. As I said, I suggest all-lowercase then.
FWIW, I prefer the options to be:
procedure foo; external; procedure foo; external 'name=_foo' ; procedure foo; external 'name=_foo; language=c' ; procedure foo; external 'language=c' ;
Where language could be any number of things: asm, c, c++, etc.
You can alter the stuff in the quotes to your heart's content without breaking the overall syntax of:
procedure <name> ; [ external [ '<attribute-list>' ] ; ] <attribute-list> ::= '<attribute-item> { ; <attribute-item> }' <attribute-item> ::= name | language = <string>
Stop for a minute. My intent in this thread is to *reduce* the number of parallel and redundant syntaxes, not to invent even more!
We already have `attribute' as a general container (similar to what you suggest within the quotes). We already have BP's syntax (which may not always be perfect, but as I said, all other things equal, it's better to follow it than make up something new).
So, unless there are other dialects whose compatibility we might consider, or the new syntax has real advantages (which I don't see), I don't see a point ...
One thing I like is that since the attribute keywords are within quotes, its obvious they don't conflict with any identifiers that the user might choose to use (ie. they have a very explicit context in which they exist).
Same for `attribute'. Besides, quotes have a particular meaning in Pascal in general (string constants), and I don't really like the idea of (mis?)using them for something else.
I suppose you could argue that the external keyword gives the context so the quotes are not needed, but I still feel happier with them inside quotes as in principle you could have it such that all keywords not in quotes are globally recognised as defined-keywords (and hence conflict with user's identifiers) and only those in quotes are treated as "local" (and hence not conflicting with user's identifiers). It'd make for one simple rule for identifier that's easy to follow.
If you're referring to the issues in my other mail -- this might work for these particular directives, but surely not for all the other problematic keywords, which certainly can't be enclosed in quotes.
Frank
On 25 Feb 2003 at 14:47, Frank Heckenbach wrote:
As another small step towards cleaning up the `external' mess in GPC, I'm now implementing `external name', i.e.
procedure Foo; external name 'bar';
[...]
But there are cases where you need to set the asmname of a non-external routine or variable. But perhaps we can just use `name' then, e.g.:
var Foo: Integer; name 'bar';
That is orthogonal with the above usage and so is less confusing than:
var Foo: Integer; attribute (name ('foo'));
There is nothing inherently wrong with using "attribute." However, there is a lack of symmetry between:
var Foo: Integer; external; name 'bar'; { external variable }
and:
var Foo: Integer; attribute (name ('foo')); { global variable }
It would seem to be desirable to have global and external entity names specified with similar syntax. So I would suggest either specifying both with "name" or both with "attribute" but not a mix of the two.
I don't know enough Fortran or Ada to tell if there are such mechanisms...
In Ada, both imports of external entities and exports of global entities are specified via the "pragma" compiler directive:
Foo : Integer; pragma Import (C, Foo, "foo");
or:
Foo : Integer; pragma Export (C, Foo, "foo");
...where the first parameter is the interfacing convention, the second is the Ada name of the affected entity, and the third is the name as viewed from the target interface. So the proposed "attribute" syntax is actually quite close to this, e.g.:
Foo : Integer; pragma Import (C, Foo, "foo"); -- Ada
...would be equivalent to:
var Foo: Integer; external; attribute (name = 'foo'); { Pascal }
The full Ada syntax is:
pragma Import( [Convention =>] convention_identifier, [Entity =>] local_name [, [External_Name =>] string_expression] [, [Link_Name =>] string_expression]);
pragma Export( [Convention =>] convention_identifier, [Entity =>] local_name [, [External_Name =>] string_expression] [, [Link_Name =>] string_expression]);
-- Dave
J. David Bryan wrote:
On 25 Feb 2003 at 14:47, Frank Heckenbach wrote:
As another small step towards cleaning up the `external' mess in GPC, I'm now implementing `external name', i.e.
procedure Foo; external name 'bar';
[...]
But there are cases where you need to set the asmname of a non-external routine or variable. But perhaps we can just use `name' then, e.g.:
var Foo: Integer; name 'bar';
That is orthogonal with the above usage and so is less confusing than:
var Foo: Integer; attribute (name ('foo'));
There is nothing inherently wrong with using "attribute." However, there is a lack of symmetry between:
var Foo: Integer; external; name 'bar'; { external variable }
It's `external name' in BP -- without a semicolon in between.
and:
var Foo: Integer; attribute (name ('foo')); { global variable }
It would seem to be desirable to have global and external entity names specified with similar syntax. So I would suggest either specifying both with "name" or both with "attribute" but not a mix of the two.
Specifying both with `attribute' is no problem -- I've implemented this now, and both `attribute (name ('foo'))' and `attribute (name = 'foo')' will work.
The problem with `var Foo: Integer; name 'bar';' would be that `Name' is often used as an identifier.
If we'll handle such conditional keywords like I suggested in the other thread, it would mean that `var Foo: Integer; name 'bar';' would work as long as `Name' is not used as an identifier (while `var Foo: Integer; external name 'bar';' would work as long as `External' is not used as an identifier, whereas `Name' might be).
I'd say this is acceptable -- if you want to use `name' (without `external') as a directive, just don't use it as an identifier. And if you want to use these identifiers, you can always use `attribute' (which is a little longer to write, but without conflicts -- of course, as long as you don't use `attribute' as an identifier ;-).
So I think allowing for both ways (`attribute' and plain `name') for both external and non-external declarations is reasonable.
Frank