7.5. Fortran Interface to Scilab's Core

The interface to Scilab's core is widely undocumented. There are two levels, a lower-level Fortran77-derived, and an interface that resembles Scilab's C-interface (see also Section 7.6). Up to version 2.5 the lower-level API was defined in SCI/routines/interf/stack1.f, but from version 2.5.1 on it is defined in SCI/routines/interf/stack1.h and SCI/routines/interf/stack1.c. This means that the implementation has been ported from Fortran77 to C. The higher-level API is defined in SCI/routines/interf/stack2.h and SCI/routines/interf/stack2.c.

All lower-level functions expect the user-function name in the first parameter, whereas the higher-level functions need a variable of type ParameterStackIndex.

To save the reader frequent lookups in the defining files, we have compiled the most important ones in the following sections: query, access, creation of objects, and miscellaneous functions.

7.5.1. Query

The functions in this group retrieve information about the parameters a function has been called with, and about the properties of objects on the stack.

7.5.1.1. checkrhs

Synopsis

function CheckRhs
    (SelfName        : in String;
     MinNumParameter : in Natural;
     MaxNumParameter : in Natural)
    return Boolean;
           
Description

Check the number of actual parameters on the right-hand side to be in the range MinNumParameter : MaxNumParameter. Return True if it is in the range, otherwise raise error 77 associated with SelfName and return False.

Example

Ensure that at least 2, but not more than 5 parameters are passed to the function:


      if (.not. checkrhs(fname, 2, 5)) return
           

We have assumed that fname is set to the function's name.

See also

CheckLhs, Lhs, Rhs

7.5.1.2. checklhs

Synopsis

function CheckLhs
    (SelfName        : in String;
     MinNumParameter : in Natural;
     MaxNumParameter : in Natural)
    return Boolean;
           
Description

Check the number of output variables, i.e. arguments on the right-hand side to be in the range MinNumParameter : MaxNumParameter. Return True if it is in the range, otherwise raise error 78 associated with SelfName and return False.

Note that it is no error to supply less output parameters than the function actually returns. The extra values are silently discarded. This is true for the case of zero output values, too; then ans gets the first output value. Thus, a function called without any output parameters is assigned an Lhs of 1.

Example

Ensure that there are not more than 2 output parameters, when the function is called:


      if (.not. checklhs(fname, 1, 2)) return
           

We have assumed that fname is set to the function's name.

See also

CheckRhs, Rhs, Lhs

7.5.1.3. lhs

Synopsis

Lhs : Natural;
           
Description

The number of actual output parameters, i.e. those on the left-hand side of the assignment operator, is stored in the global variable Lhs. Inside a user function, Lhs should be used as a constant.

See also

CheckLhs, CheckRhs, Rhs

7.5.1.4. rhs

Synopsis

Rhs : Natural;
           
Description

The number of actual input parameters, i.e. those on the right-hand side of the assignment operator, is stored in the global variable Rhs. Inside a user function, Lhs should be used as a constant.

See also

CheckRhs, CheckLhs, Lhs

7.5.2. Access Object

The functions in this section grant the programmer access to parameters that are stored on the Scilab stack. In general all of these functions work alike: An index to the current (i.e. as on entry of the function) top of the parameter stack, "BasePointer", and an index to the desired argument, "StackPointer", are passed to the API. On return the user gets all necessary information about the argument like sub-type, dimension as well as the indices, "FooIndex" that index into the Scilab heap. The indices act like pointers to the actual contents. This way only meta-data is passed, saving time-consuming copy operations.

7.5.2.1. getmat

Synopsis

function GetMat
    (SelfName       : in     String;
     BasePointer    : in     ParameterStackAddress;
     StackPointer   : in     ParameterStackAddress;
     IsComplex      :    out ComplexFlag;
     Rows           :    out Natural;
     Columns        :    out Natural;
     RealIndex      :    out DataStackIndex;
     ImaginaryIndex :    out DataStackIndex)
    return Boolean;
           
Description

Retrieve the address(es) and dimensions of a real or complex matrix from the parameter stack. The BasePointer must be set to the parameter stack pointer's value on entry of the calling function. StackPointer points to the desired parameter on the parameter stack. If successful, GetMat returns True, and IsComplex, Rows, Columns, and RealIndex are valid. If IsComplex = ComplexVariable then ImaginaryIndex is valid, too. If the parameter indexed by StackPointer is not a matrix GetMat returns False.

The output parameter IsComplex indicates whether the matrix on the data stack is purely real or complex. In the first case RealIndex points to the matrix, in the second case RealIndex points to the real part of matrix, and ImaginaryIndex points to the imaginary part. In any case Rows and Columns are the number of rows and columns of the matrix.

Example

Fetch the addresses of a possibly complex m-times-n matrix from position top of the parameter stack.


      if (.not. getmat(fname, topk, top, iscmpx, m, n, are, aim)) return
           

It is assumed that fname has been set to the function's name, and topk carries the position of the stack on entry to the calling function.

See also

GetRMat, GetRVect, GetVect

7.5.2.2. getrmat

Synopsis

function GetRMat
    (SelfName     : in     String;
     BasePointer  : in     ParameterStackAddress;
     StackPointer : in     ParameterStackAddress;
     Rows         :    out Natural;
     Columns      :    out Natural;
     RealIndex    :    out DataStackIndex)
    return Boolean;
           
Description

Function GetRMat works like function GetMat, but restricts the accepted matrices to purely real ones.

See also

GetMat, GetRVect

7.5.2.3. getrvect

Synopsis

function GetRVect
    (SelfName     : in     String;
     BasePointer  : in     ParameterStackAddress;
     StackPointer : in     ParameterStackAddress;
     Rows         :    out Natural;
     Columns      :    out Natural;
     RealIndex    :    out DataStackIndex)
    return Boolean;
           
Description

Function GetRVect works like function GetRMat, but restricts the accepted matrices to either single rowed (1-times-N) or single columned (N-times-1).

See also

GetVect, GetRMat

7.5.2.4. getvect

Synopsis

function GetVect
    (SelfName       : in     String;
     BasePointer    : in     ParameterStackAddress;
     StackPointer   : in     ParameterStackAddress;
     IsComplex      :    out ComplexFlag;
     Rows           :    out Natural;
     Columns        :    out Natural;
     RealIndex      :    out DataStackIndex;
     ImaginaryIndex :    out DataStackIndex)
    return Boolean;
           
Description

Function GetVect works like function GetMat, but restricts the accepted matrices to either single rowed (1-times-N) or single columned (N-times-1).

See also

GetMat, GetRVect

7.5.2.5. getscalar

Synopsis

function GetScalar
    (SelfName     : in     String;
     BasePointer  : in     ParameterStackAddress;
     StackPointer : in     ParameterStackAddress;
     Index        :    out DataStackIndex)
    return Boolean;
           
Description

Retrieve the address and dimensions of a real or complex scalar from the parameter stack. The BasePointer must be set to the parameter stack pointer's value on entry of the calling function. StackPointer points to the desired parameter on the parameter stack. If successful, GetScalar returns True, and Index is valid. If the parameter indexed by StackPointer is not a scalar GetScalar returns False.

See also

GetVect, GetMat

7.5.2.6. getexternal

Synopsis

type FortranIdentifier is 
    array (1 .. 6) of Character;  -- Fortran's 6 char limit

-- SimpleFunctionType is just an example
type SimpleFunctionType is access
    function(X : in Float) return Float;

type InstallerProcedureType is access
    procedure(FunctionName       : in     FortranIdentifier;
              FunctionEntryPoint : in     SimpleFunctionType);

function GetExternal
    (SelfName     : in     String;
     BasePointer  : in     ParameterStackAddress;
     StackPointer : in     ParameterStackAddress;
     FunctionName : in out FortranIdentifier;
     IsExternal   :    out Boolean;
     Installer    : in     InstallerProcedureType)
    return Boolean;
           
Description

The first three parameters SelfName, BasePointer, and StackPointer work exactly the same as in the other functions, so does the return value. They explanations are not repeated here, see e.g. Section 7.5.2.1.

The fourth parameter, FunctionName is the name of the function to be called. This parameter can designate an external function, i.e. code that has been compiled seperately and then linked to Scilab via, for example link, or the name of a Scilab function that has been defined with function or deff. In any case it is simply the name of the function. On return the IsExternal parameter signals True if the function is a external and False otherwise.

The last parameter is very special. It specifies the installation procedure Installer that manipulates a dispatcher function DispatchFunction. After a call to Installer the dispatcher points to the user function given by FunctionName.

Note

The programmer should not issue such a call; it is already done by GetExternal.

Examples of dispatcher functions, the associated hooks and dispatch tables are e.g. found in SCI/routines/default/FTables.{h,c}. We will discuss dispatch tables in Section 7.3.3.

Support Functions

The GetExternal function relies heavily on various support functions. The supporting function have to be set up previous to the first call. Usually they are installed by the user's extention package unless she/he decides to (ab)use existing dispatcher tables and functions.


package ExternalSupport is
    procedure InstallProcedure
        (FunctionName       : in     FortranIdentifier; 
         FunctionEntryPoint : in     SimpleFunctionType);
end ExternalSupport;
           

package body ExternalSupport is

    with Ada.Characters.Latin_1;

    type FunctionTableEntry is
        record
            FunctionName    : FortranIdentifier;
            FunctionAddress : SimpleFunctionType;
        end record;

    type FunctionTableType is
        array (Positive range <>) of FunctionTableEntry;


    -- SimpleExample is of type SimpleFunction
    function SimpleExample(X : Float) return Float;
    begin
        return X;
    end Hook;


    FunctionTable : FunctionTableType(1 .. 2) :=
        (1 => (FunctionName    => "exampl", 
               FunctionAddress => SimpleExample'Access),
         2 => (FunctionName    => (others => Ada.Characters.Latin_1.NUL),
               FunctionAddress => null));


    DispatchFunction : SimpleFunctionType;


    -- function Hook is the hard-coded target for all
    -- internal calls

    function Hook(X : Float) return Float;
    begin
        return DispatchFunction.all(X);
    end Hook;


    -- bend hook function to point to FunctionEntryPoint

    procedure InstallProcedure
        (FunctionName       : in     FortranIdentifier; 
         FunctionEntryPoint : in     SimpleFunctionType);
    begin
        DispatchFunction := SetFunction(FunctionName,
                                        FunctionEntryPoint,
                                        FunctionTable);
    end InstallProcedure;

end ExternalSupport;
           
Example

For a self-contained example, see Section 7.3.2.

See also

Functionals, Dispatch Tables

7.5.3. Create Object

The object creation functions are mainly used to setup temporary variables for the current procedure or the procedures to be called; they bear a lot of resemblance with the object access functions (see also Section 7.5.2). The difference is that a new object is created and therefore stack space is used.

7.5.3.1. Cremat

Synopsis

function CreMat
    (SelfName       : in     String;
     StackPointer   : in     ParameterStackAddress;
     WantComplex    : in     ComplexFlag;
     Rows           : in     Natural;
     Columns        : in     Natural;
     RealIndex      :    out DataStackIndex;
     ImaginaryIndex :    out DataStackIndex)
    return Boolean;
           
Description

FIXME: write it

7.5.4. Miscellaneous

FIXME: Write it!