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