Aaron Sherman:
# On Thu, 2002-09-12 at 21:10, Brent Dax wrote:
# > Aaron Sherman:
# > # I'm thinking XS thoughts
# 
# > # Something like:
# > # 
# > #     module somesuch;
# > #     use External (language=>"C");
# > #     sub chdir(string $path //= $ENV{HOME}) is 
# > # external(returns=>'int');
# > 
# > I prefer:
# > 
# >     module System::FS is version(1.0.0);
# >     use Parrot::XS 'load';
# >     
# >     sub chdir(string $path //= $ENV{HOME}) is external returns(int);
# >     sub curdir() is external returns(string);
# >     # 'returns' would be Perl's normal way to declare return
# >     # value, not a special thing for external functions only.
# 
# I like "returns" as a property. Much cleaner, and I really 
# like the ability to specify a return type generally.
# 
# You do need to be able to specify the target language, though.

I don't think so.  As long as it's something that C<load> can load in,
why should you have to specify the language?

# >     load module => System::FS, version => 1.0;
# 
# I would think that this version number and the one in the 
# module statement before would always be the same (since 
# they're in the same file, and the XS is generated by this 
# file). What's more, this whole statement could be considered 
# "implied" by the use of C<Parrot::XS>.

Except that I might want to implement this with a number of
platform-specific modules, to make sure I don't try to pull in another
platform's module:

        given($*OS) {  #Or whatever $^O becomes
                #Make sure I don't try to use something designed for
                # a different platform
                when /Solaris/ { load module => System::FS::Solaris,
version => 1.0 }
                when /Linux/   { load module => System::FS::Linux  ,
version => 1.0 }
                ...
        }

Since the loaded module need not have the same name as the surrouding
module, the version number is needed.

# >     #include <chdir's_header.h>
# 
# Too magical. You need to have some way to specify an 
# arbitrary string in your module that will be exported to the 
# target language ala my "PREP" parameter. That C<#include> 
# statement would go in the string along with any glue 
# functions required.

I consider this more generic--the C<inline> command is for any arbitrary
code.

# So, to re-write both of our suggestions as one:
# 
#         module System::FS is version(1.0.0);
#         use Parrot::XS language => 'C', prep => q{
#               #include <unistd.h>
#       };
#         
#         sub chdir(string $path //= $ENV{HOME}) is external 
# returns(class int);
#         sub curdir() is external returns(class string);
# 
# I stuck the "class" keyword in with the returns property 
# because otherwise I think it's ambiguous.

Why do you need your own class?  Presumably XS would know how to convert
between C's C<int> and Perl's C<int>...

# However, that was my simple example. Here again (and slightly 
# re-written based on your suggestions) is my more complex example:
# 
#     module getpw is version(1.0.0);
#     use Parrot::XS language => 'C', prep => q{
#         #include<pwd.h>
#         #include<sys/types.h>
#     };
#     
#     class uid_t := class real;  # Proposed class alias syntax 
# (see below)
#     class gid_t := class real;
#     class passwd {
#         my string $.pw_name;    # Proposed pseudo-classes 
# "string" and "real"
#         my string $.pw_passwd;  # are required to determine 
# how to convert
#         my int    $.pw_uid;     # the value to C

C<string> is already a built-in type, and presumably XS would understand
how to convert a C<char *> into a C<string>.  But why use C<real>?  Are
C<int> and C<num> not enough?  (Or are you using C<real> instead of
C<num> because you don't know about C<num>?  Or does it say somewhere
that it's C<real> and I'm incorrect in thinking it's C<num>?)

#         my int    $.pw_gid;
#         my string $.pw_gecos;
#         my string $.pw_dir;
#         my string $.pw_shell;
#         method storage { # storage returns a string name of the C type
#                          # or a listref to the field names if it's a
#                          # struct. If it's a scalar type in C, then
#                          # this class must contain a $.internal of the
#                          # appropriate Perl pseudo-class type (string,
#                          # int or real).
#                 return
#                         [qw{
#                                 pw_name pw_passwd pw_uid pw_gid
#                                 pw_gecos pw_dir pw_shell
#                         }]
#         }
#     }

Why not:

        class passwd is xs_struct(
                qw(pw_name pw_passwd pw_uid pw_gid pw_gecos pw_dir
pw_shell)
        ) {
                ...

And for simpler types:

        class Parrot::String is xs_type('Parrot_String' => $.ptr) {
                my Parrot::XS::Pointer $.ptr;
                ...

#     sub getpwuid(uid_t $uid //= $_) is external returns(class passwd);

Once again, why the C<class>?

--Brent Dax <[EMAIL PROTECTED]>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)

"In other words, it's the 'Blow up this Entire Planet and Possibly One
or Two Others We Noticed on our Way Out Here' operator."
    --Damian Conway

Reply via email to