=head1 NAME Inline::SLang::Details - How Inline::SLang works =head1 DESCRIPTION This document is intended to provide details of how L weaves its magic. It's probably going to be most use in cases when you find apparently bizarre behaviour and wonder if it is a bug or a feature. The implementation for Inline::SLang was initally based on the code found in Neil Watkiss' L and L modules. However, all bugs are my own creation. =head2 What happens when Perl starts? If the Perl code has not been evaluated before - or if it has been changed since the previous run - the L code kicks in to evaluate the S-Lang code. This involves: =over 2 =item 1 The S-Lang interpreter is started and queried to find out all functions that are defined in the namespaces listed in the C configuration option. The user-supplied S-Lang code is then evaluated and the same set of namespaces are again queried for the names of defined functions. We also pick up any new namespaces that may have been defined if the C option is set to C. The names of the new functions - i.e. those functions added by the user-supplied S-Lang code which the S-Lang function C<_apropos()> lists when the flag value is set to 3 - are stored for later use. Complications: =over 2 =item * The C<_inline> namespace is ignored since this is used by the module and should be considered off-limits. =item * The list of functions in C is added to the list of functions to bind. This list can include functions defined as part of the S-Lang Run-Time Library. =item * The fact that the module allows users to change the name that namespaces and (some) functions have when mapped to Perl. =back =item 2 The list of defined S-Lang data types is found. This includes user-defined types added by any imported modules and "named" structures created via a S-Lang C statement. Utility functions are created in Perl in the C package which are wrappers around calls to the C constructor. This allows users to say C rather than C<< DataType_Type->new("UShort_Type") >>. For those types we do not recognise - essentially all user-defined types - we create objects with names equal to the S-Lang variable name. The objects have very few methods, and are just a way of carrying around a reference to the S-Lang variable within Perl. The S-Lang variable is saved in an associative array within the C<_inline> namespace, to ensure that it is not destroyed, and this is used when the Perl variable is sent to a S-Lang function. The "native" S-Lang types included in this list are: C, C, C, C, and C. It would be useful if we could handle these directly, but it is not easy (for instance I believe it would be hard to use the file handles with C code since C makes assumptions about who has opened the file). The conversion between S-Lang and PDL types - e.g. what type of piddle should an C array be converted to - has only been tested on 32-bit machines. It may well fail on 64 bit machines. =item 3 The information - including the S-Lang source code - is written to a configuration file by L. The default location for the file is within the F<_Inline/> directory, but this can be changed, as discussed in the L. =back If the code has previously been run then this information can just be read from the configuration file. The information - whether read from file or calculated directly - is used to: =over 2 =item * Set up the bindings between Perl and S-Lang functions. =item * Set up the Perl classes to handle the various datatypes that can not be processed natively within Perl. =item * Set up the functions and variables in the C<_inline> namespace (these should B be accessed by user code). =back Once the S-Lang code has been processed the Perl code is run. =head1 CALLING A S-LANG FUNCTION For each S-Lang function we want to bind to Perl, a small Perl subroutine is created which pushes the S-Lang function name (including any necessary namespace) onto the start of the stack and then calls the C subroutine (which is defined in F and should B be called directly). By including the S-Lang function name on the stack we allow the Perl and S-Lang names to be different, as required by the C and C L. The C routine performs 4 operations: =over 2 =item 1 The S-Lang interpreter is checked to see if the routine is defined (this step could be removed). =item 2 The remaining items on the Perl stack (the arguments to the function) are converted to S-Lang variables and pushed onto the S-Lang stack. The conversion from Perl to S-Lang types is done by the C routine which is defined in F. =item 3 The S-Lang function is called. The S-Lang error hook is used to catch any errors that the S-Lang interpreter may throw; these are converted to Perl errors by calling the C function so that they can be trapped by Perl's C routine. =item 4 The S-Lang stack is examined and any variables returned by the function are popped off, converted to Perl variables, and pushed onto the Perl stack. The order of the S-Lang stack is reversed when creating the Perl stack so that the S-Lang statement ( x, y ) = some_func(); can be converted to ( my $x, my $y ) = some_func(); The conversion from S-Lang to Perl types is done by the C routine which is defined in F. =back The major part of the whole module is the conversion between Perl and S-Lang variables, namely the C and C routines. The routines are not pretty - they could be re-written to allow additional convertors to be "plugged in" - but they seem to work. =head1 NOTES =head2 How to find out what S-Lang functions and datatypes are recognised The C option of L can be used to find out what functions and data types are bound to Perl. If the code is stored in the file F, use perl -MInline=info script.pl L are available in the L. =head2 Execution of S-Lang code The S-Lang code is executed I any Perl code. This can be seen in the following example (available as F in the source distribution): use Inline 'SLang' => 'message("This is S-Lang");'; print "This is Perl\n"; When run, the script displays: This is S-Lang This is Perl =head2 Exporting symbols The system used to bind functions to Perl - in particular to make the symbols available to Perl - is a "simplified" version of the Exporter Perl module (since I have been unable to successfully use Exporter directly). =head1 SEE ALSO L, L