[fpc-pascal] Generic type declaration example versus manual.
Anthony Walter
sysrpl at gmail.com
Sun Nov 22 23:29:31 CET 2009
On Sun, Nov 22, 2009 at 12:03 PM, Michael Van Canneyt
<michael at freepascal.org> wrote:
> Well, in
>
> Var
> A : Integer;
>
> The 'Var' is strictly speaking also redundant, as the : is used only in
> variable declarations. But the 'var' makes it easier to read, and Pascal is
> a verbose language. Additionally, the parsing is easier to do, as you know
> what to expect next. By that rationale, the 'generic' keyword was deemed
> appropriate when FPC made it's implementation.
>
> We'll resolve the incompatibility - remaining backwards compatible to FPC
> itself - when someone finds the time and desire to do so.
>
> Or when someone from our beloved users sends us a patch to this effect.
Michael,
Actually, you are pretty far off. I've written a few parsers for
Delphi and before generics it has ALWAYS gone like this:
// comments are considered transparent
After: {unit|program|library} ident ; [interface] [uses section]
Next must be either: {block|function/procedure|section}
A block always starts with one the following keywords:
{var|const|type|resourcestring}
A section can be one of the followings:
[implementation|initialization|finalization]
When block is detected {var|threadvar|const|resourcestring|type} it
always goes like this:
block
ident {:|=} body [end];
{repeat above flow|{block|function/procedure|section}}
A block example:
const
// okay, starting a new block {const}
// next parsed token must be an ident
// repeat *NEXT TOKEN MUST BE* an ident
WM_SOMETHING
// okay, got ident
// in {const} block next token must now be =
=
// next tokens must a constant expression
WM_USER + $FF
// okay we read a constant express
;
// okay, terminated
// now expecting {ident|[block|function/procedure|section]}
WM_OTHERTHING = WM_SOMETHING + 1;
WM_LASTTHING = OTHERTHING + 1;
var
// okay, starting a new block {var}
// next parsed token must be an ident
...
So this has always been the case. When the parser encounters
{var|const|type|resourcestring} in the context of creating a new
block, the next token is always, ALWAYS an identifier.
type
// okay, starting new block {type}
// next token must be an identifier
TTime
// okay, got ident
// in {type} block next token must now be =
=
// next token must be one of the following
// {ident|array|class|record|set|(|type}
Double
// read ident, verify value refers to an already typed ident
// next token must be ;
;
// okay, terminated
// now expecting {ident|{block|function/procedure|section}}
TPoint = record X: Integer; Y: Integer; end;
Go it? So whenever you have {var|threadvar|const|type|resourcestring}
in the context of creating a block, the next token will always be an
ident, or the code is invalid.
You've always had the case where
program A;
type
// the next thing read must be an ident
That's how it's always been. Delphi has always been about
{block|function/procedure|section}.
Block has ALWAYS been like this:
block
ident {:|=} body [end];
{repeat above flow|{block|function/procedure|section}}
Putting the word "generic" infront of the ident breaks the long
established trend.
type generic TList<T> = class end;
See, we started a block {type} and introduced a keyword {generic}
before the identifier {TList}. This unnecessarily breaks the pattern
and is inconsistent.
More information about the fpc-pascal
mailing list