NAME

Inline::SLang::Types - Support for S-Lang types in Perl

SYNOPSIS

use Inline SLang => Config => BIND_SLFUNCS => [ "vmessage" ];
use Inline SLang;
use Math::Complex;

# the S-Lang Complex_Type variable is automatically converted
# to a Math::Complex object in Perl.
#
my $val = makecplx();
print "Perl has been sent $val\n";

# the multiplication is done using Math::Complex objects and
# the result then converted to a S-Lang Complex_Type variable,
# since vmessage is a S-Lang function [the %S means convert
# the variable to its string representation].
#
vmessage( "S-Lang has been sent %S", $val * cplx(0,1) );

my $type = typecplx($val);
print "And the S-Lang datatype is $type\n";
print "        Perl object        " .  $type->typeof . "\n";

__END__
__SLang__

define makecplx() { return 3 + 4i; }
define typecplx(cval) { return typeof(cval); }

The output of this code - which can be found in the source-code distribution as examples/types.pl - is:

Perl has been sent 3+4i
S-Lang has been sent (-4 + 3i)
And the S-Lang datatype is Complex_Type
        Perl object        DataType_Type

DESCRIPTION

The aim is to allow a user to program "naturally" in Perl and S-Lang, and so native data types are used wherever possible. However, objects are used when necessary - for some ill-defined definition of necessary - to preserve type information. The type system is also changing as I use the module more and come across things that seemed fine when designing the module but are just annoying to use (hopefully there won't be too many of these changes).

As an example, consider swapping a complex number between S-Lang and Perl. In S-Lang it would be represented as a Complex_Type and in Perl we choose to use a Math::Complex object. Something simple - such as an array reference containing two elements - could have been used, but then we would not be able to convert it back into a Complex_Type variable in S-Lang (well, not without telling the computer this is what we wanted).

I promise that soon (not many more releases after v0.10) the module will support the Perl Data Language (ie PDL), since it provides variables ("piddles") which retain type information and are optimised for numeric work.

Supported S-Lang Data Types

The following S-Lang types may be returned from a S-Lang function to Perl. Note that the list does not include all synonyms for a type, although they are recognised; for instance the Int_Type is accepted but converted to Integer_Type.

See below for further details.

  • NULL

    Converted to a perl undef.

  • [Char|UChar|Short|UShort|Integer|UInteger|Long|ULong]_Type

    Converted to a perl integer. The unsigned types are converted as unsigned values, whatever difference that may make.

  • [Float|Double]_Type

    Converted to a perl floating-point number.

  • Complex_Type

    Converted to a Math::Complex object.

  • String_Type

    Converted to a perl string.

  • Array_Type

    Converted to one of: a Perl array reference, an Array_Type object, or a piddle. Currently only the Perl array reference is supported.

  • Assoc_Type

    Converted to an Assoc_Type object.

  • Struct_Type and "named" structures

    Struct_Type variables are converted to a Struct_Type object, whilst "named" structures are converted to objects with the same name as the S-Lang struct name.

  • Other S-Lang types are converted to a Perl class that matches the S-Lang type name.

Supported Perl Data Types

The following data types may be passed from Perl into S-Lang. Any other type results in the Perl interpreter issuing a croak.

See below for further details.

  • undef

    Converted to NULL.

  • Integer

    Converted to S-Lang Integer_Type.

  • Floating Point

    Converted to S-Lang Double_Type.

  • Math::Complex

    Converted to S-Lang Complex_Type.

  • String

    Converted to S-Lang String_Type.

  • Array reference

    Converted to S-Lang Array_Type.

  • Perl Array_Type object

    Converted to S-Lang Array_Type.

  • Piddles

    Will be converted to S-Lang Array_Type. NOT YET AVAILABLE.

  • Hash reference

    Converted to S-Lang Assoc_Type [Any_Type].

  • Perl Assoc_Type object.

    Converted to S-Lang Assoc_Type with the datatype of the array being determined by the contents of the object.

  • Perl Struct_Type and derived objects.

    Converted to the matching S-Lang type (Struct_Type or the "named" struct).

  • "Opaque" objects

    S-Lang data types that are handled as so-called "opaque" variables are converted back into the correct S-Lang variable type.

DATATYPE CLASSES

Objects are used to represent those S-Lang data types for which there is no corresponding Perl data type: for complex numbers we use the Math::Complex module which is distributed with Perl; for numeric types we may use piddles (see the documentation for the Perl Data Language); and for other types we use a class specific to Inline::SLang.

  • Complex numbers

    Complex numbers are represented as Complex_Type in S-Lang and as a Math::Complex object in Perl. See the Math::Complex documentation for information on how to use this class.

  • Struct_Type and "named" structs

    S-Lang structures - variables with a type of Struct_Type - are represented using Struct_Type objects in Perl. Named structs - ie those created via a typedef struct {} XXX call - are represented using XXX objects in Perl; these objects are sub-classes of the Struct_Type class. The objects behave similarly to a hash reference, except that you can not add or delete keys and there are a number of method calls that match the S-Lang language.

    See Inline::SLang::Struct for more information.

  • Associative arrays

    S-Lang associative arrays (Assoc_Type) are represented in Perl as Assoc_Type objects. These objects behave just as a hash reference does but have additional methods to match the S-Lang language.

    See Inline::SLang::Assoc for more information.

  • Arrays

    Support for S-Lang arrays (Array_Type) comes in three "flavours":

    1. As a Perl array reference.

    2. As a piddle (if you are using the Perl Data Language).

      This is NOT YET AVAILABLE.

    3. As a Perl Array_Type object.

      It is expected that this object will only be used rarely.

    See Inline::SLang::Array for more information.

  • S-Lang data type.

    S-Lang Datatype_Type values are represented using Perl DataType_Type objects.

  • Other types.

    A number of S-Lang types do not map to an obvious Perl type. For these types, Inline::SLang creates an object of class <type>, where <type> is the name of the S-lang datatype (i.e. the output of S-Lang's typeof function). Examples are the Ref_Type and Any_Type S-Lang variable types.

    The objects are treated as "opaque" containers; you can store them and send them back to S-Lang but there's essentially nothing else you can do with them directly in Perl.

    This currently includes the filehandle types File_Ptr_Type and File_FD_Type since it looks like the Perl I/O system is quite scary "under the hood" in v 5.8.0!

PERL OBJECTS

Each class provides a number of methods. These methods are not exported into the calling packages namespace, so they can only be accessed using the "object-oriented" form, i.e.

$obj->foo()

Note that the new() method is not defined for some classes, which means you can only create them by calling a S-Lang function.

Common methods

All classes provide the following methods:

o

typeof()

Returns a string containing the name of the S-Lang datatype of the object (which corresponds to the name of the Perl class).

o

stringify()

The "print" method for the objects has been over-loaded to use the stringify() method: for most - probably all - types it will return the datatype name (namely the output of the typeof() method).

The class descriptions below describe the output format if it does not match that of the typeof() method.

o

is_struct_type()

Returns a 1 if the object represents a S-Lang structure - including "named" structures created via a typedef - and 0 otherwise.

Array_Type Objects

See Inline::SLang::Array.

Assoc_Type Objects

See Inline::SLang::Assoc.

Struct_Type Objects

See Inline::SLang::Struct.

DataType_Type Objects

The class-specific methods are:

new()
$dtype = DataType_Type->new([$type]);

The new() method accepts a string ($type) containing the name of the S-Lang datatype (e.g. "UChar_Type"). If no variable is supplied then "DataType_Type" is assumed.

Synonyms of types (eg 'Int_Type' for 'Integer_Type') are accepted but automatically converted to the 'original' type name.

Note that if you supply a name that does not map to a S-Lang datatype then the return value is undef.

stringify()

The name of the datatype represented by the object is returned.

For instance

$type = DataType_Type->new("Any_Type");
print("And the type is '$type'\n");

outputs

And the type is 'Any_Type'.

To see a list of all the possible datatypes recognised by a particular program use the INFO option provided by the Inline module, as described in the "What functions and namespaces have been bound to Perl?" section of Inline::SLang::Config.

A possible future enhancement is to provide a set of functions that match the datatype name and that return a DataType_Type object of the given class. This would then allow you to say

Integer_Type()

rather than

DataType_Type->new("Integer_Type")

Other objects - aka "opaque" variables

These objects are used to store S-Lang data types for which there is no obvious - or perhaps easy - way to represent in Perl. Examples are the Ref_Type and Any_Type S-Lang variable types.

The Perl objects can only be created from S-Lang (i.e. there are no new() methods). In fact, there is little that you can do with these objects in Perl; if you want to access/change the value referred to then you need to pass the object back to S-Lang.

There are no class-specific methods. This means that there is no way of creating one of these objects except from S-Lang (i.e. there is no object constructor in Perl).

An example using S-Lang references - available as examples/use_refs.pl in the source code - is:

use Inline 'SLang';

my $ref = getfoo();
print "\$ref is a " . ref($ref) . " object\n";
print "And when printed as a string = $ref\n";
printfoo($ref);
changefoo($ref,"no it isn't");
printfoo($ref);

__END__
__SLang__

variable foo = "this is a string";
define getfoo() { return &foo; }
define printfoo(x) { () = printf("foo = [%s]\n", @x ); }
define changefoo(x,y) { @x = y; }

The output of this script is:

$ref is a Ref_Type object
And when printed as a string = Ref_Type
foo = [this is a string]
foo = [no it isn't]

Note that to change the value pointed to by the reference we had to send the variable back to S-Lang and do the processing there.

For Any_Type variables (this is also available as examples/use_anytype.pl):

use Inline 'SLang';

my $a0 = getfoo(0);
my $a1 = getfoo(1);
my $a2 = getfoo(2);
print "\nIn Perl:\n";
printf "typeof(foo[0]) = %s\n", $a0->typeof;
printf "typeof(foo[1]) = %s\n", $a1->typeof;
printf "typeof(foo[2]) = %s\n",
  defined($a2) ? $a2->typeof : "undef";

__END__
__SLang__

variable foo = Any_Type [3];
foo[0] = "a string";
foo[1] = 23;

define getfoo(x) { return foo[x]; }
message( "In S-Lang:" );
vmessage( "typeof(foo[0]) = %s", string(typeof(foo[0])) );
vmessage( "typeof(foo[1]) = %s", string(typeof(foo[1])) );
vmessage( "typeof(foo[2]) = %s", string(typeof(foo[2])) );

The output of this script is:

In S-Lang:
typeof(foo[0]) = Any_Type
typeof(foo[1]) = Any_Type
typeof(foo[2]) = Null_Type

In Perl:
typeof(foo[0]) = Any_Type
typeof(foo[1]) = Any_Type
typeof(foo[2]) = undef

Note that the Null_Type value (in S-Lang) has been converted into a Perl undef value.

SEE ALSO

Inline::SLang::Array, Inline::SLang::Assoc, Inline::SLang::Struct, Inline::SLang, Math::Complex, PDL