Constants in generics

classic Classic list List threaded Threaded
96 messages Options
12345
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Ryan Joseph
Since we introduced “const” keywords to generic params does it make sense to use an optional “type” keyword also? That just occurred to me as something worth discussing. No opinion either way except there’s a inconsistency now which may bother some people.

generic TStuff<type T; const A> = record end;

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Free Pascal - General mailing list
In reply to this post by Ryan Joseph
Am So., 6. Jan. 2019, 19:07 hat Ryan Joseph <[hidden email]> geschrieben:
Last question I have I think.

Is this the best way to get "pretty name" string for a set? Having to loop through the entire range of the set is not so great but I don’t see another way. I feel like there should be some utility functions to get names for ord defs also but I just did a crude string conversion for now.

I don't think that there is a better way. Also up to now it wasn't necessary for the compiler to do this, thus there are no utility functions for it. 

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Free Pascal - General mailing list
In reply to this post by Ryan Joseph
Am So., 6. Jan. 2019, 22:38 hat Ryan Joseph <[hidden email]> geschrieben:
Since we introduced “const” keywords to generic params does it make sense to use an optional “type” keyword also? That just occurred to me as something worth discussing. No opinion either way except there’s a inconsistency now which may bother some people.

generic TStuff<type T; const A> = record end;

We can always add it in later if we think it's needed. Let's keep it out for now. 

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Ryan Joseph
I updated the github with the requested changes. Is that everything? I’ll submit a patch if so.

https://github.com/genericptr/freepascal/tree/generic_constants

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Ben Grasset
You still have two C-style operator += instances in pgenutil.pas FYI, that don't compile with the default settings.

On Sun, Jan 6, 2019 at 8:36 PM Ryan Joseph <[hidden email]> wrote:
I updated the github with the requested changes. Is that everything? I’ll submit a patch if so.

https://github.com/genericptr/freepascal/tree/generic_constants

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Ben Grasset
In reply to this post by Ryan Joseph
Also, there's:

pgenutil.pas(158,28) Warning: Class types "tenumdef" and "torddef" are not related

which breaks compilation because the compiler is built with -sew turned on if you do it through the normal makefiles. I think you need tests before you do a patch, also? (Unless you already have them ready somewhere and just didn't upload them yet.)

On Sun, Jan 6, 2019 at 8:36 PM Ryan Joseph <[hidden email]> wrote:
I updated the github with the requested changes. Is that everything? I’ll submit a patch if so.

https://github.com/genericptr/freepascal/tree/generic_constants

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Ryan Joseph


> On Jan 6, 2019, at 11:32 PM, Ben Grasset <[hidden email]> wrote:
>
> Also, there's:
>
> pgenutil.pas(158,28) Warning: Class types "tenumdef" and "torddef" are not related
>
> which breaks compilation because the compiler is built with -sew turned on if you do it through the normal makefiles. I think you need tests before you do a patch, also? (Unless you already have them ready somewhere and just didn't upload them yet.)

Thanks, I got these fixes and updated git.

I found some bugs with booleans so I need to fix those also. I’ve got a few tests I’ll post next to make sure they cover everything.



Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Free Pascal - General mailing list
In reply to this post by Ryan Joseph
Am 07.01.2019 um 02:05 schrieb Ryan Joseph:
> I updated the github with the requested changes. Is that everything? I’ll submit a patch if so.
>
> https://github.com/genericptr/freepascal/tree/generic_constants
Looks better.

The following points remain:
- make sure that you don't have any unrelated changes (just look at all
the completely unrelated changes in this commit
https://github.com/genericptr/freepascal/commit/bd76667453914106a51d31672d841b1344066e6a 
)
- make sure that the code you added follows the compiler's formatting
(there are quite some locations where you have spaces between
identifiers and operators)
And most importantly:
- add tests: both for successful compilations as well as ones that
should fail (though everything that produces an error needs to be its
own test); I suggest tests/test/tgenconst*.pp as a name (for more infos
you can look at http://wiki.freepascal.org/Testing_FPC )

You should also make sure that your changes don't break anything, so you
should run the testsuite once without your changes, save
tests/output/<cpu>-<os>/{faillog,log,longlog} and then run the testsuite
again with your changes and compare especially faillog (see
http://wiki.freepascal.org/Testing_FPC#Recommended_Workflow ).

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Ryan Joseph
Yesterday I discovered I wasn’t doing proper range checking for ordinal constants so for example, a generic with “const U: byte” could be specialized as <1000>. We want ordinal constants to respect range checks right?

I made a little utility function which works in most cases but I don’t think it’s correct and more importantly this function probably already exists in the compiler.

    function compare_orddef_by_range(param1,param2:torddef): boolean;
      var
        orddef1,orddef2:tdef;
      begin
         range_to_type(param1.low,param1.high,orddef1);
         range_to_type(param2.low,param2.high,orddef2);
         result:=compare_defs(orddef1,orddef2,nothingn)>=te_convert_l1;
      end;


Is there an existing function for this or a better way to do it?

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Jonas Maebe-3
On 08/01/19 17:34, Ryan Joseph wrote:

> I made a little utility function which works in most cases but I don’t think it’s correct and more importantly this function probably already exists in the compiler.
>
>      function compare_orddef_by_range(param1,param2:torddef): boolean;
>        var
>          orddef1,orddef2:tdef;
>        begin
>           range_to_type(param1.low,param1.high,orddef1);
>           range_to_type(param2.low,param2.high,orddef2);
>           result:=compare_defs(orddef1,orddef2,nothingn)>=te_convert_l1;
>        end;
>
>
> Is there an existing function for this or a better way to do it?

defutils.testrange


Jonas
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Ryan Joseph
I’ve made constants respect their proper definition now so we can do range checking but this broke some other things. For example there’s a range check error with static arrays now because “U” has a value of 0 so 0-1 = -1:

type
        generic TList<const U:byte> = record
                list: array[0..U-1] of integer; // ERROR: high value < low value (0..-1)
        end;


There’s a couple ways to resolve this:

1) Add some extra flags to nodes/syms so “U-1” can be known to contain a generic parameter and errors can be ignored. That’s the most complicated solution and I wasn’t able to figure that out easily because flags need to be transferred in multiple locations.

2) The easy solution is to add another tdef member to tconstsym which can be used for range checking in generics and let the tconstsym.typedef def be undefined like it used to be (which fixes the above bug and perhaps others). This means another def needs to be added to the PPU write/read system though.

3) Be lazy and don’t do range checking. :)

Any idea about this?

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Free Pascal - General mailing list
Am Di., 8. Jan. 2019, 21:01 hat Ryan Joseph <[hidden email]> geschrieben:
I’ve made constants respect their proper definition now so we can do range checking but this broke some other things. For example there’s a range check error with static arrays now because “U” has a value of 0 so 0-1 = -1:

type
        generic TList<const U:byte> = record
                list: array[0..U-1] of integer; // ERROR: high value < low value (0..-1)
        end;


There’s a couple ways to resolve this:

1) Add some extra flags to nodes/syms so “U-1” can be known to contain a generic parameter and errors can be ignored. That’s the most complicated solution and I wasn’t able to figure that out easily because flags need to be transferred in multiple locations.

This is the preferred solution as otherwise you'd also defeat the purpose of type safety and probably open another can of worms when constant parameters are used in more complex expressions. 

The symbols should already have sp_generic_param set (if not that should definitely be changed so that it matches the type symbols). Now you only need a way to differentiate whether the symbol is an undefined generic parameter or not. 
For type parameters it abuses the fact that the undefined defs of the parameters are children of the generic while the final types are never children of the generic. Maybe we can use something similar for the constants? 
If not we can always add some flag to tconstsym... 

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Benito van der Zander
Hi,

that reminds me of https://bugs.freepascal.org/view.php?id=34232



Bye,
Benito 

Am 08.01.19 um 23:28 schrieb Sven Barth via fpc-pascal:
Am Di., 8. Jan. 2019, 21:01 hat Ryan Joseph <[hidden email]> geschrieben:
I’ve made constants respect their proper definition now so we can do range checking but this broke some other things. For example there’s a range check error with static arrays now because “U” has a value of 0 so 0-1 = -1:

type
        generic TList<const U:byte> = record
                list: array[0..U-1] of integer; // ERROR: high value < low value (0..-1)
        end;


There’s a couple ways to resolve this:

1) Add some extra flags to nodes/syms so “U-1” can be known to contain a generic parameter and errors can be ignored. That’s the most complicated solution and I wasn’t able to figure that out easily because flags need to be transferred in multiple locations.

This is the preferred solution as otherwise you'd also defeat the purpose of type safety and probably open another can of worms when constant parameters are used in more complex expressions. 

The symbols should already have sp_generic_param set (if not that should definitely be changed so that it matches the type symbols). Now you only need a way to differentiate whether the symbol is an undefined generic parameter or not. 
For type parameters it abuses the fact that the undefined defs of the parameters are children of the generic while the final types are never children of the generic. Maybe we can use something similar for the constants? 
If not we can always add some flag to tconstsym... 

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Free Pascal - General mailing list
Am Di., 8. Jan. 2019, 23:49 hat Benito van der Zander <[hidden email]> geschrieben:

Yes, that falls into the same category... 

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Ryan Joseph
In reply to this post by Benito van der Zander


> On Jan 8, 2019, at 3:49 PM, Benito van der Zander <[hidden email]> wrote:
>
> that reminds me of https://bugs.freepascal.org/view.php?id=34232

In this case maybe generics should just not give range errors unless they’re specialized? This bug and the problem I have are only for unspecialized generics. That would be the easiest and laziest thing to do but it would mean this would compile:

type
        generic TList<T> = record
                list: array[0..0-1] of integer;
        end;


Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Constants in generics

Free Pascal - General mailing list
Am Mi., 9. Jan. 2019, 17:03 hat Ryan Joseph <[hidden email]> geschrieben:


> On Jan 8, 2019, at 3:49 PM, Benito van der Zander <[hidden email]> wrote:
>
> that reminds me of https://bugs.freepascal.org/view.php?id=34232

In this case maybe generics should just not give range errors unless they’re specialized? This bug and the problem I have are only for unspecialized generics. That would be the easiest and laziest thing to do but it would mean this would compile:

type
        generic TList<T> = record
                list: array[0..0-1] of integer;
        end;

Which is why I said that this is not the way to go. You need to disable range checks only for those symbols that must not use it. Maybe add a "undefined" flag to tconstsym which is set in your tconstsym.create_undefined and not changed when the const type is changed. 

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
12345