[top] [up] [next]

Clause arguments


TPINT TP_API myClause( TPINT32 Version, TPCALL *Call, TPARGUMENT *First, TPEXCEPTION *Exc )

The First parameter of a clause function is a TPARGUMENT structure. The type of the argument (variable, atom, number, integer, list, etc.) and the name of the argument are stored inside this structure. Trinc-Prolog creates a single linked list of argument structures for predicates that have more than 1 parameter. For instance: for a call to test/2 a linked list of two TPARGUMENT structures is created.

if( Call->_Arity == 3 ) {
    //Arity of 3, get the second parameter
    TPARGUMENT *SecondArg = First->_Next;
    //Get the third parameter
    TPARGUMENT *ThirdArg = Second->_Next;
    }
Delphi example
arrow.gif (1632 bytes) It is not necessary to delete the memory occupied by TPARGUMENT structures, these structures are managed by Trinc-Prolog.

The next step is to check the type of the arguments and if these are of the incorrect type throw an exception. The possible argument types are:

T_ARG_VAR_EMPTY an empty variable
T_ARG_ATOM atom
T_ARG_INTEGER an integer number
T_ARG_FLOAT a floating point number
T_ARG_LIST a list
T_ARG_EMPTY_LIST an empty list
T_ARG_OP an operator
T_ARG_SINGLE_QUOTED an atom enclosed by single quotes
T_ARG_VARIOUS all remaining possible types

Suppose that the second argument may not be an empty variable and that the third argument must be an atom.

if( SecondArg->_Type & T_ARG_VAR_EMPTY ) {
    //Create an exception goal and copy it to the exception parameter
    Exc->_Str = TP_MEMALLOC( 32 );
    strcpy(Exc->_Str, "instantiation_error.");
    //Return the exception result code
    return TP_EXCEPTION;
    }

if( (ThirdArg->_Type & T_ARG_ATOM) == 0 ) {
    //Create an exception goal and copy it to the exception parameter
    Exc->_Str = TP_MEMALLOC( 32 + strlen(ThirdArg->_Lexeme) );
    sprintf(Exc->_Str, "type_error(atom, %s).", ThirdArg->_Lexeme);
    //Return the exception result code
    return TP_EXCEPTION;
    }
Delphi example

arrow.gif (1632 bytes) If memory must be allocated for a value to return to Trinc-Prolog then the function TP_MEMALLOC must always be used. The block of memory will be deleted by Trinc-Prolog.
arrow.gif (1632 bytes) Never change the lexeme string of an argument structure.

As can be seen from the example above the bit operator & is used to check the type of an argument. This is necessary because it is possible that several type flags are present for a single clause argument.

If a list or a Prolog structure is an argument for an external Prolog clause then the _Child attribute of TPARGUMENT is used. The _Child attribute points to the first child argument.

void IterateArgs( TPARGUMENT *First, <other-parameters> ) {

    //Check if the current argument structure has a subexpression, if so examine it
    if( First->_Child ) {
        IterateArgs( First->_Child, <other-parameters> );
        }

    //Check if there is a next argument structure, if so examine it
    if( First->_Next ) {
        IterateArgs( First->_Next, <other-parameters> );
        }
}
Delphi example

For instance: if 'a(b, c)' is the value of a parameter for a Prolog clause then three TPARGUMENT structures are created, one for 'a' and the 'a' argument structure has two child arguments, these are 'b' and 'c'.

[top] [up] [next]

 

info@trinc-prolog.com