The goal of the top-level package file is to make as many function of the MPFQ API reachable. The top-level package file also must define a Perl object. We discuss by example the file provided in the MPFQ distribution as an example, under src/gf7/gf7.pm.
We proceed through this file line by line (comments, which exist in the file, are stripped off here).
package gf7; use strict; use warnings;
Not much to say about the first fragment above. The package name must match the file name.
use Mpfq::engine::handler;
our @ISA = qw/Mpfq::engine::handler/;
sub new { return bless({},shift); }
Here we set up the object mechanism. Not much (well actually nothing) is conveyed within the object in terms of data[1]. The main use of the object is to contain a reference to a given package.
use Mpfq::defaults;
use Mpfq::defaults::flatdata;
use Mpfq::defaults::poly;
our @parents = qw/
Mpfq::defaults
Mpfq::defaults::flatdata
Mpfq::defaults::poly
/;
The fragment above lists the parents of the given package. All package files may mention such parents.
our $resolve_conflicts = {
vec_set => 'Mpfq::defaults::flatdata',
vec_ur_set => 'Mpfq::defaults::flatdata',
};
This is optional, and is used to disambiguate possible conflicts.
sub code_for_add { return [ 'inline(K!, z, x, y)', "z = (x+y)%7;" ]; }
This is one of the code generation functions expected in this file.
sub code_for_sub_helper {
return {
kind=>'inline(z, x, y)',
name=>'sub_helper',
requirements=>'dst_elt src_elt src_elt',
code=>'z = x-y;',
};
}
# The function called by the automatic generator should return as usual
# its proto and its code, but additionnally a hash describing the helper
# function (there might be several of them).
sub code_for_sub {
my $proto = 'inline(k, z, x, y)';
my $code = '';
$code .= "@!sub_helper(z, x, y);\n";
$code .= "if ((long)z < 0)\n";
$code .= " z += 7;\n";
return [ $proto, $code ], code_for_sub_helper();
}
This example is slightly more complicated and uses the extended syntax allowed for code_for_xxx, where dependencies between functions are possible.
sub init_handler {
my $types = {
elt => "typedef unsigned long @!elt\[1\];",
dst_elt => "typedef unsigned long * @!dst_elt;",
src_elt => "typedef const unsigned long * @!src_elt;",
elt_ur => "typedef unsigned long @!elt_ur\[1\];",
dst_elt_ur => "typedef unsigned long * @!dst_elt_ur;",
src_elt_ur => "typedef const unsigned long * @!src_elt_ur;",
field => 'typedef void * @!field;',
dst_field => 'typedef void * @!dst_field;',
};
return { types => $types };
}
1;
This finished the package file (note the 1;). The init_handler provides some typedefs to be included in the generated code.